Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 加快OpenNLP';当使用它处理多个文本时,它会进行后期标记_Java_Performance_Serialization_Nlp_Opennlp - Fatal编程技术网

Java 加快OpenNLP';当使用它处理多个文本时,它会进行后期标记

Java 加快OpenNLP';当使用它处理多个文本时,它会进行后期标记,java,performance,serialization,nlp,opennlp,Java,Performance,Serialization,Nlp,Opennlp,我目前正在开发一个关键词提取工具,它可以为网站上的文本或文档提供标签建议。当我遵循本文提出的方法时:我使用OpenNLP工具包的POSTagger作为第一步,即候选选择 一般来说,关键短语提取效果相当好。我的问题是,每当我想使用POSTagger时,我都必须从相应的文件中执行这种昂贵的模型加载: posTagger = new POSTaggerME(new POSModel(new FileInputStream(new File(modelDir + "/en-pos-maxent.bin"

我目前正在开发一个关键词提取工具,它可以为网站上的文本或文档提供标签建议。当我遵循本文提出的方法时:我使用OpenNLP工具包的POSTagger作为第一步,即候选选择

一般来说,关键短语提取效果相当好。我的问题是,每当我想使用POSTagger时,我都必须从相应的文件中执行这种昂贵的模型加载:

posTagger = new POSTaggerME(new POSModel(new FileInputStream(new File(modelDir + "/en-pos-maxent.bin"))));
tokenizer = new TokenizerME(new TokenizerModel(new FileInputStream(new File(modelDir + "/en-token.bin"))));
// ...
String[] tokens = tokenizer.tokenize(text);
String[] tags = posTagger.tag(tokens);
这是因为此代码不在Web服务器本身的范围内,而是在一个“处理程序”内,其生命周期仅包括处理一个特定请求。我的问题是:如何实现只加载一次文件?(我不想花10秒钟等待模型加载,然后再使用200毫秒。)

我的第一个想法是序列化postagermeTokenizerMEresp.)并在每次需要时使用Java的内置机制对其进行反序列化。不幸的是,这不起作用——它引发了一个异常。(我确实序列化了WEKA工具包中的分类器,该工具包在最后对我的候选对象进行了分类,以便不必每次都构建(或训练)分类器。因此我认为这可能也适用于PostAgMe。不幸的是,情况并非如此。)

在标记器的情况下,我可以引用一个简单的WhitespaceTokenizer,它是一个较差的解决方案,但一点也不差:

tokenizer = WhitespaceTokenizer.INSTANCE;

但我不认为这是一个可靠的邮资选择

只需将标记化/词性标记管道包装在中即可

如果底层OpenNLP代码不是线程安全的,请将调用放在同步块中,例如:

// the singletons tokenization/POS-tagging pipeline 
String[] tokens;
synchronized(tokenizer) { 
   tokens = tokenizer.tokenize(text);
}
String[] tags;
synchronized(posTagger) { 
   tags = posTagger.tag(tokens);
}

当您说您试图序列化对象时,您是指将其序列化到磁盘吗?在我看来,没有任何理由认为这会比再次(从磁盘)加载模型更快。我认为解决这个问题的办法在于将模型保存在内存中,但我对您正在部署的环境了解不够。是的,我想将它序列化到磁盘。我的动机是,我认为这类似于序列化WEKA分类器。但我现在意识到事实并非如此:对于分类器,实际使用的内存大小相当小(而创建它的过程非常耗时)——对于POSTagger,无法减小模型的大小。因此,也许我可以利用一个单例来将所有内容只加载到内存中一次。但是在这种情况下,如果许多处理程序试图同时访问它,我可能会遇到问题。是的,dmcer的答案中的方法可能就是您想要的。不过,我认为您不必担心同步问题,因为这些模型只会被读取,而不会被写入。谢谢!我将使用此代码。此外,我将研究是否可以使用n-gram提取方法来选择候选人,例如通过Maui Indexer()进行选择。这在使用内存方面应该更经济。