开放NLP是来自Apache的强大的Java NLP库。它为NLP提供各种工具,其中之一是词类(POS)标记器。通常使用POS标记器来查找文本中的结构语法结构,使用带标签的数据集,其中每个词(短语的一部分)都标有标签,您可以从该数据集中构建一个NLP模型,然后获得新文本使用该模型为文本中的每个单词生成标签。
预先训练的模型
基本上,该模型可以学习训练数据中的信息和结构,并可以用它来标记一个看不见的文本。OpenNLP带有一些预先训练过的模型,如英语模型,训练结构化英文文本以检测名词,动词等。
训练你自己的模型
但是,如果您的域或 用例 中的文本不符合严格的英语规则,那么预先训练好的模型可能对您而言效果不佳。在这种情况下,您可以选择构建自己的训练数据,并针对您的用例训练自定义模型。
我们将展示如何使用POS tagger来学习电子商务搜索查询中的实体(类似于NER)。
获取下面使用的数据集:
训练数据格式
训练数据作为文本文件传递,其中每行是一个数据项。该行中的每个单词应该以“word_LABEL”的格式进行标注,单词和标签名称之间用下划线’_’分隔。
以下是输入培训文件的示例:
anki_Brand overdrive_Brand
just_ModelName dance_ModelName 2018_ModelName
aoc_Brand 27″ _ScreenSize monitor_Category
horizon_ModelName zero_ModelName dawn_ModelName
cm_Unknown 700_Unknown modem_Category
computer_Category
bt_Category transmitter_Category
120hz_Unknown led_Unknown tv_Category
vizio_Brand 4k_Unknown tv_Category
battlefront_ModelName 2_ModelName ps4_Unknown
注意:每个单词需要一个label/tag。在这里,我们不关心我们使用的标签“Unknown”。
构建训练数据集
根据您的domain,您可以自动或手动构建这样的数据集。手动构建这样一个数据集可能会非常痛苦,像Dataturks POS tagger这样的工具可以帮助使这个过程变得更容易。
训练模型
这里的重要的类是POSModel。我们用POSTaggerME类来做模型建设。以下是从训练数据文件构建模型的代码
public POSModel train(String filepath) {
POSModel model = null;
Training parameters parameters = TrainingParameters.defaultParams();
parameters.put(TrainingParameters.ITERATIONS_PARAM, “100”);
try {
try (InputStream dataIn = new FileInputStream(filepath)) {
ObjectStream<String> lineStream = new PlainTextByLineStream(new InputStreamFactory() {
@Override
public InputStream createInputStream() throws IOException {
return dataIn;
}
}, StandardCharsets.UTF_8);
ObjectStream<POSSample> sampleStream = new WordTagSampleStream(lineStream);
model = POSTaggerME.train(“en”, sampleStream, parameters, new POSTaggerFactory());
return model;
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
将模型保存到文件
我们可以输出到模型文件,然后再从文件中读回
public void writeToFile(POSModel model, String modelOutpath) {
try (OutputStream modelOut = new BufferedOutputStream(new FileOutputStream(modelOutpath))) {
model.serialize(modelOut);
}
catch (Exception e) {
e.printStackTrace();
}
}
public POSModel getModel(String modelPath) {
try {
try (InputStream modelIn = new FileInputStream(modelPath)) {
POSModel model = new POSModel(modelIn);
return model;
}
}
catch (Exception e) {
e.printStackTrace();
}
return model;
}
使用模型来做标记。
最后,我们可以看到该模型如何用于标记看不见的查询:
public void doTagging(POSModel model, String input) {
input = input.trim();
POSTaggerME tagger = new POSTaggerME(model);
Sequence[] sequences = tagger.topKSequences(input.split(” “));
for (Sequence s : sequences) {
List<String> tags = s.getOutcomes();
System.out.println(Arrays.asList(input.split(” “)) +” =>” + tags);
}
}
以下是使用我们的模型的示例输出
String[] tests = new String[] {“apple watch”, “samsung mobile phones”, ” lcd 52 inch tv”};
for (String item : tests) {
doTagging(model, item);
}
Output
[apple, watch] =>[Brand, Category]
[apple, watch] =>[Category, Category]
[apple, watch] =>[ModelName, Category]
[samsung, mobile, phones] =>[Brand, Category, Category]
[samsung, mobile, phones] =>[Brand, ModelName, ModelName]
[samsung, mobile, phones] =>[Brand, ModelName, Category]
[lcd, 52, inch, tv] =>[ModelName, ModelName, ScreenSize, Category]
[lcd, 52, inch, tv] =>[Category, Unknown, ScreenSize, Category]
[lcd, 52, inch, tv] =>[Category, Unknown, Unknown, Category]