当前位置: 首页 > 知识库问答 >
问题:

无法更新开放NLP模型

单展
2023-03-14

我正在为我的一个项目使用Apache OpenNLP。我正在创建一个新模型来识别位置,因为预训练模型(en-ner-location.bin)没有这个位置。

这是代码:

package com.equinox.nlp;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import opennlp.tools.namefind.NameFinderME;
import opennlp.tools.namefind.NameSample;
import opennlp.tools.namefind.NameSampleDataStream;
import opennlp.tools.namefind.TokenNameFinderModel;
import opennlp.tools.tokenize.SimpleTokenizer;
import opennlp.tools.tokenize.Tokenizer;
import opennlp.tools.util.InvalidFormatException;
import opennlp.tools.util.ObjectStream;
import opennlp.tools.util.PlainTextByLineStream;
import opennlp.tools.util.Span;

public class NlpTesting {
protected Map<String, NameFinderME> finders;
protected Tokenizer tokenizer;

public static void main(String[] args) throws InvalidFormatException,
        IOException {

    String bankura = "In the 2011 census, Bankura municipality had a population of 138,036, out of which 70,734 were males and 67,302 were females.";
    String london = "London is the capital city of England and the United Kingdom.";

    NlpTesting nlpTesting = new NlpTesting();
    NameFinderME nameFinderA = nlpTesting.createNameFinder("./opennlp-models/en-ner-location.bin");
    nlpTesting.findLocation(london, nameFinderA);
    System.out.println("--------------------------");
    nlpTesting.findLocation(bankura, nameFinderA);

    nlpTesting.train();

    NameFinderME nameFinderB = nlpTesting.createNameFinder("./opennlp-models/en-ner-custom-location.bin");

    nlpTesting.findLocation(bankura, nameFinderB);
}

public String findLocation(String str,NameFinderME nameFinder) throws InvalidFormatException,
        IOException {
    String commaSeparatedLocationNames = "";
    tokenizer = SimpleTokenizer.INSTANCE;

    String tokens[] = tokenizer.tokenize(str);
    Span nameSpans[] = nameFinder.find(tokens);
    HashSet<String> locationSet = new HashSet<String>();
    for (int i = 0; i < nameSpans.length; i++) {
        locationSet.add(tokens[nameSpans[i].getStart()]);
    }
    for (Iterator<String> iterator = locationSet.iterator(); iterator
            .hasNext();) {
        String location = iterator.next();
        commaSeparatedLocationNames += location + ",";
    }
    System.out.println(commaSeparatedLocationNames);
    return commaSeparatedLocationNames;
}

public void train() throws IOException {
    File trainerFile = new File("./train/train.txt");
    File output = new File("./opennlp-models/en-ner-custom-location.bin");
    ObjectStream<String> lineStream = new PlainTextByLineStream(
            new FileInputStream(trainerFile), "UTF-8");
    ObjectStream<NameSample> sampleStream = new NameSampleDataStream(
            lineStream);
    System.out.println("lineStream = " + lineStream);
    TokenNameFinderModel model = NameFinderME.train("en", "location",
            sampleStream, Collections.<String, Object> emptyMap());
    BufferedOutputStream modelOut = null;
    try {
        modelOut = new BufferedOutputStream(new FileOutputStream(output));
        model.serialize(modelOut);
    } finally {
        if (modelOut != null)
            modelOut.close();
    }
}

public NameFinderME createNameFinder(String str) throws InvalidFormatException,
        FileNotFoundException, IOException {
    NameFinderME nameFinder = new NameFinderME(new TokenNameFinderModel(
            new FileInputStream(new File(str))));
    return nameFinder;
}

}

到目前为止,它运行良好。

问题是我无法将其他位置添加到我创建的自定义模型中。所以,我浏览了OpenNLP-README文档。

在那里,它说,“注意:为了训练模型,您需要所有的训练数据。目前没有一种机制可以用额外的数据更新随项目分发的模型。”

这是否意味着我也无法更新我的自定义模型?有什么方法可以做到这一点吗?很可能我在创建模型时没有所有数据,并且应该有更新模型的选项。请帮助我。

共有1个答案

公孙霖
2023-03-14

它的意思就是:每次你想添加新的训练实例时,你都需要从头开始重新训练你的整个模型。

如果您需要在不重新训练的情况下更新模型,那么OpenNLP不是您任务的合适工具。

 类似资料:
  • 问题内容: 我有一个让我感到困惑的奇怪问题。我有一个模型: 变体条目如下所示: 我需要添加一个新字段-说“颜色”。所以我这样做是为了批量更新: 但是,“颜色”字段未设置-如果我再次浏览并注释掉该行,则它不会显示。我似乎无法弄清楚为什么要这样做。我有一个onSave事件,该事件已正确触发,因此可以保存。我也没有对版本结构进行任何检查- 即没有代码只允许代码和价格。我显然缺少了一些东西,但几个小时后我

  • 我对Mongoose/Mongo和node非常陌生。js,所以我怀疑这只是我的误解,但是。。。 下面的代码示例是最小的失败示例,而不是我的用例。 这会导致以下错误:将更新应用于文档{_id: ObjectId('54647402cb955748153ea782'),...}后,发现(不可变)字段'_id'已更改为_id: ObjectId('546d9e0e539ed9ec102348f9') 为

  • 问题内容: 我在Mac上使用Flask(python软件包)时,第一次写css时显示正常。但是,当我更新它并尝试检查它时,我只看到第一个CSS样式。我尝试重新启动终端,以及重新安装Flask。有什么建议?谢谢。以下是HTML: 这是CSS: 问题答案: 如前所述,问题与浏览器缓存有关。 为了解决这个问题,你可以向静态(css,js)链接中添加一些动态变量。我更喜欢每个文件的上次修改时间戳。 这是一

  • 我一直在通过http post从c客户机向Spring服务器发送一些数据。但是,当我从java客户机发送相同的数据时,就会出现这些错误。 根本原因 在Spring服务器上,我检查了到达的数据是否有任何差异,但它们之间似乎没有差异。为什么会发生这种情况?

  • 我得到这个错误 食品项插入失败无法添加或更新子行:外键约束失败(.,约束外键()在更新级联上引用() 我试图以一种形式将食谱添加到我的数据库中。我希望输入的数据到3个不同的表。配料表、配方表和recipe_compridient表。recipe表中有一个自动增量id作为主键,而配料id作为recipe表中的外键。 我想要配料名称,数据到配料表和名称,课程,指令到配方表加上配料表中的配料ID 要转到

  • 在Symfony 2(最新版本)下,我试图更新我的实体: 我得到了这个错误消息到我的终端: [Symfony\Component\Config\Definition\Exception\InvalidConfigurationException] 无法识别的选项“security.firewalls.access\u control”下的“0、1、2、3” 我是Symfony的新手,我不知道在哪里