【问题标题】:Training OpenNLP document classification训练 OpenNLP 文档分类
【发布时间】:2017-06-14 16:28:37
【问题描述】:

我正在尝试使用 OpenNLP 对发票进行分类。根据它的描述,我将它分为两​​类。我已经建立了一个包含 20K 描述的训练文件,并将每个描述标记到正确的类中。

训练数据看起来像(第一列是代码,我用作类,第二列是发票说明):

85171231 IPHONE 5S CINZA ESPACIAL 16GB (ME432BZA)
85171231 Galaxy S6 SM-G920I
85171231 motorola - MOTO G5 XT1672
00000000 MOTONETA ITALIKA AT110
00000000 CJ BOX UNIBOX MOLA 138X57X188 VINHO

使用来自 OpenNLP 的 DocumentCategorizer,我获得了 98.5% 的正确率。但是,为了提高效率,我拿错了分类的文档,并用它来扩展训练数据。

例如,当我第一次运行它时,“MOTONETA ITALIKA AT110”被归类为“85171231”。没关系,因为在第一次运行时“MOTONETA ITALIKA AT110”没有被分类。所以,我教分类器明确地将“MOTONETA ITALIKA AT110”标记为“00000000”。

但是,再次运行它,OpenNLP 坚持将其分类为“85171231”,即使训练数据包含到“000000”的显式映射。

所以我的问题是:我是在教 OpenNLP wright 吗?如何提高效率?

我使用的代码是:

MarkableFileInputStreamFactory dataIn = new MarkableFileInputStreamFactory("data.train");

ObjectStream<String> lineStream = new PlainTextByLineStream(dataIn, StandardCharsets.UTF_8);
ObjectStream<DocumentSample> sampleStream = new DocumentSampleStream(lineStream);

TrainingParameters params = new TrainingParameters();
params.put(TrainingParameters.ITERATIONS_PARAM, "100");
params.put(TrainingParameters.CUTOFF_PARAM, "0");

DoccatModel model = DocumentCategorizerME.train("pt", sampleStream, params, new DoccatFactory());

DocumentCategorizer doccat = new DocumentCategorizerME(model);
double[] aProbs = doccat.categorize("MOTONETA ITALIKA AT110".replaceAll("[^A-Za-z0-9 ]", " ").split(" "));
doccat.getBestCategory(aProbs);

【问题讨论】:

    标签: java opennlp


    【解决方案1】:

    默认情况下,DocumentCategorizer 将使用词袋。这意味着不考虑项的顺序。 如果MOTONETA ITALIKA AT110 中的任何术语在85171231 组中出现频率很高,则分类器将倾向于使用该组。

    你有几个选择:

    • 您可以将MOTONETA ITALIKA AT110 的更多变体添加到000000 组;
    • 尝试更改特征生成器。

    第二个选项是更改模型的创建,如下所示:

    int minNgramSize = 2;
    int maxNgramSize = 3;
    DoccatFactory customFactory = new DoccatFactory(
        new FeatureGenerator[]{
            new BagOfWordsFeatureGenerator(),
            new NGramFeatureGenerator(minNgramSize, maxNgramSize)
        }
    );
    DoccatModel model = DocumentCategorizerME.train("pt", sampleStream, params, customFactory);
    

    您可以通过删除 BagOfWordsFeatureGenerator 并更改最小和最大 ngram 大小来使用特征生成器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-07-22
      • 1970-01-01
      • 2012-06-29
      • 2013-11-07
      • 2016-10-16
      • 2014-09-13
      • 1970-01-01
      相关资源
      最近更新 更多