2

我目前正在开发一个关键词提取工具,它应该为网站上的文本或文档提供标签建议。当我遵循本文提出的方法时:A New Approach to Keyphrase Extraction Using Neural Networks我使用 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);

这是因为这段代码不在网络服务器本身的范围内,而是在一个“处理程序”中,其生命周期只包括处理一个特定的请求。我的问题是:我怎样才能实现只加载一次文件?(我不想花 10 秒等待模型加载并在之后仅使用 200 毫秒。)

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

在 Tokenizer 的情况下,我可以参考一个简单的WhitespaceTokenizer,它是一个较差的解决方案,但一点也不差:

tokenizer = WhitespaceTokenizer.INSTANCE;

但是对于可靠的 POSTagger,我看不到这个选项。

4

1 回答 1

1

只需将您的标记化/POS 标记管道包装在一个单例中。

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

// the singletons tokenization/POS-tagging pipeline 
String[] tokens;
synchronized(tokenizer) { 
   tokens = tokenizer.tokenize(text);
}
String[] tags;
synchronized(posTagger) { 
   tags = posTagger.tag(tokens);
}
于 2010-12-06T20:22:54.493 回答