- OpenNLP 教程
- OpenNLP - 首页
- OpenNLP - 概述
- OpenNLP - 环境
- OpenNLP - 参考 API
- OpenNLP - 句子检测
- OpenNLP - 分词
- 命名实体识别
- OpenNLP - 词性标注
- OpenNLP - 语句解析
- OpenNLP - 短语识别
- OpenNLP - 命令行界面
- OpenNLP 有用资源
- OpenNLP - 快速指南
- OpenNLP - 有用资源
- OpenNLP - 讨论
OpenNLP - 命名实体识别
从给定文本中查找姓名、人员、地点和其他实体的过程称为命名实体识别(NER)。在本章中,我们将讨论如何使用 OpenNLP 库通过 Java 程序执行 NER。
使用 OpenNLP 进行命名实体识别
为了执行各种 NER 任务,OpenNLP 使用不同的预定义模型,例如 en-ner-date.bin、en-ner-location.bin、en-ner-organization.bin、en-ner-person.bin 和 en-ner-time.bin。所有这些文件都是预定义的模型,经过训练可以检测给定原始文本中的相应实体。
opennlp.tools.namefind 包包含用于执行 NER 任务的类和接口。要使用 OpenNLP 库执行 NER 任务,您需要 -
使用TokenNameFinderModel 类加载相应的模型。
实例化NameFinder 类。
查找名称并打印它们。
以下是编写程序以从给定的原始文本中检测命名实体的步骤。
步骤 1:加载模型
句子检测的模型由名为TokenNameFinderModel的类表示,该类属于opennlp.tools.namefind包。
要加载 NER 模型 -
创建模型的InputStream对象(实例化 FileInputStream 并将相应 NER 模型的路径(以字符串格式)传递给其构造函数)。
实例化TokenNameFinderModel类并将模型的InputStream(对象)作为参数传递给其构造函数,如下面的代码块所示。
//Loading the NER-person model InputStream inputStreamNameFinder = new FileInputStream(".../en-nerperson.bin"); TokenNameFinderModel model = new TokenNameFinderModel(inputStreamNameFinder);
步骤 2:实例化 NameFinderME 类
opennlp.tools.namefind包的NameFinderME类包含用于执行 NER 任务的方法。此类使用最大熵模型来查找给定原始文本中的命名实体。
实例化此类并将上一步中创建的模型对象传递给它,如下所示 -
//Instantiating the NameFinderME class NameFinderME nameFinder = new NameFinderME(model);
步骤 3:查找句子中的名称
NameFinderME类的find()方法用于检测传递给它的原始文本中的名称。此方法接受一个字符串变量作为参数。
通过将句子的字符串格式传递给此方法来调用此方法。
//Finding the names in the sentence Span nameSpans[] = nameFinder.find(sentence);
步骤 4:打印句子中名称的跨度
NameFinderME类的find()方法返回一个 Span 类型的对象数组。opennlp.tools.util包中名为 Span 的类用于存储集合的开始和结束整数。
您可以将find()方法返回的跨度存储在 Span 数组中并打印它们,如下面的代码块所示。
//Printing the sentences and their spans of a sentence for (Span span : spans) System.out.println(paragraph.substring(span);
NER 示例
以下程序读取给定的句子并识别其中人员名称的跨度。将此程序保存在名为NameFinderME_Example.java的文件中。
import java.io.FileInputStream; import java.io.InputStream; import opennlp.tools.namefind.NameFinderME; import opennlp.tools.namefind.TokenNameFinderModel; import opennlp.tools.util.Span; public class NameFinderME_Example { public static void main(String args[]) throws Exception{ /Loading the NER - Person model InputStream inputStream = new FileInputStream("C:/OpenNLP_models/en-ner-person.bin"); TokenNameFinderModel model = new TokenNameFinderModel(inputStream); //Instantiating the NameFinder class NameFinderME nameFinder = new NameFinderME(model); //Getting the sentence in the form of String array String [] sentence = new String[]{ "Mike", "and", "Smith", "are", "good", "friends" }; //Finding the names in the sentence Span nameSpans[] = nameFinder.find(sentence); //Printing the spans of the names in the sentence for(Span s: nameSpans) System.out.println(s.toString()); } }
使用以下命令从命令提示符编译并执行保存的 Java 文件 -
javac NameFinderME_Example.java java NameFinderME_Example
执行后,上述程序读取给定的字符串(原始文本),检测其中的所有人名,并显示其位置(跨度),如下所示。
[0..1) person [2..3) person
名称及其位置
String 类的substring()方法接受开始和结束偏移量并返回相应的字符串。我们可以使用此方法一起打印名称及其跨度(位置),如下面的代码块所示。
for(Span s: nameSpans) System.out.println(s.toString()+" "+tokens[s.getStart()]);
以下是检测给定原始文本中的名称并连同其位置一起显示它们的程序。将此程序保存在名为NameFinderSentences.java的文件中。
import java.io.FileInputStream; import java.io.InputStream; import opennlp.tools.namefind.NameFinderME; import opennlp.tools.namefind.TokenNameFinderModel; import opennlp.tools.tokenize.TokenizerME; import opennlp.tools.tokenize.TokenizerModel; import opennlp.tools.util.Span; public class NameFinderSentences { public static void main(String args[]) throws Exception{ //Loading the tokenizer model InputStream inputStreamTokenizer = new FileInputStream("C:/OpenNLP_models/entoken.bin"); TokenizerModel tokenModel = new TokenizerModel(inputStreamTokenizer); //Instantiating the TokenizerME class TokenizerME tokenizer = new TokenizerME(tokenModel); //Tokenizing the sentence in to a string array String sentence = "Mike is senior programming manager and Rama is a clerk both are working at Tutorialspoint"; String tokens[] = tokenizer.tokenize(sentence); //Loading the NER-person model InputStream inputStreamNameFinder = new FileInputStream("C:/OpenNLP_models/enner-person.bin"); TokenNameFinderModel model = new TokenNameFinderModel(inputStreamNameFinder); //Instantiating the NameFinderME class NameFinderME nameFinder = new NameFinderME(model); //Finding the names in the sentence Span nameSpans[] = nameFinder.find(tokens); //Printing the names and their spans in a sentence for(Span s: nameSpans) System.out.println(s.toString()+" "+tokens[s.getStart()]); } }
使用以下命令从命令提示符编译并执行保存的 Java 文件 -
javac NameFinderSentences.java java NameFinderSentences
执行后,上述程序读取给定的字符串(原始文本),检测其中的所有人名,并显示其位置(跨度),如下所示。
[0..1) person Mike
查找地点名称
通过加载各种模型,您可以检测各种命名实体。以下是一个 Java 程序,它加载en-ner-location.bin模型并在给定的句子中检测地点名称。将此程序保存在名为LocationFinder.java的文件中。
import java.io.FileInputStream; import java.io.InputStream; import opennlp.tools.namefind.NameFinderME; import opennlp.tools.namefind.TokenNameFinderModel; import opennlp.tools.tokenize.TokenizerME; import opennlp.tools.tokenize.TokenizerModel; import opennlp.tools.util.Span; public class LocationFinder { public static void main(String args[]) throws Exception{ InputStream inputStreamTokenizer = new FileInputStream("C:/OpenNLP_models/entoken.bin"); TokenizerModel tokenModel = new TokenizerModel(inputStreamTokenizer); //String paragraph = "Mike and Smith are classmates"; String paragraph = "Tutorialspoint is located in Hyderabad"; //Instantiating the TokenizerME class TokenizerME tokenizer = new TokenizerME(tokenModel); String tokens[] = tokenizer.tokenize(paragraph); //Loading the NER-location moodel InputStream inputStreamNameFinder = new FileInputStream("C:/OpenNLP_models/en- ner-location.bin"); TokenNameFinderModel model = new TokenNameFinderModel(inputStreamNameFinder); //Instantiating the NameFinderME class NameFinderME nameFinder = new NameFinderME(model); //Finding the names of a location Span nameSpans[] = nameFinder.find(tokens); //Printing the spans of the locations in the sentence for(Span s: nameSpans) System.out.println(s.toString()+" "+tokens[s.getStart()]); } }
使用以下命令从命令提示符编译并执行保存的 Java 文件 -
javac LocationFinder.java java LocationFinder
执行后,上述程序读取给定的字符串(原始文本),检测其中的所有人名,并显示其位置(跨度),如下所示。
[4..5) location Hyderabad
NameFinder 概率
NameFinderME类的probs()方法用于获取最后解码序列的概率。
double[] probs = nameFinder.probs();
以下是打印概率的程序。将此程序保存在名为TokenizerMEProbs.java的文件中。
import java.io.FileInputStream; import java.io.InputStream; import opennlp.tools.tokenize.TokenizerME; import opennlp.tools.tokenize.TokenizerModel; import opennlp.tools.util.Span; public class TokenizerMEProbs { public static void main(String args[]) throws Exception{ String sent = "Hello John how are you welcome to Tutorialspoint"; //Loading the Tokenizer model InputStream inputStream = new FileInputStream("C:/OpenNLP_models/en-token.bin"); TokenizerModel tokenModel = new TokenizerModel(inputStream); //Instantiating the TokenizerME class TokenizerME tokenizer = new TokenizerME(tokenModel); //Retrieving the positions of the tokens Span tokens[] = tokenizer.tokenizePos(sent); //Getting the probabilities of the recent calls to tokenizePos() method double[] probs = tokenizer.getTokenProbabilities(); //Printing the spans of tokens for( Span token : tokens) System.out.println(token +" "+sent.substring(token.getStart(), token.getEnd())); System.out.println(" "); for(int i = 0; i<probs.length; i++) System.out.println(probs[i]); } }
使用以下命令从命令提示符编译并执行保存的 Java 文件 -
javac TokenizerMEProbs.java java TokenizerMEProbs
执行后,上述程序读取给定的字符串,对句子进行分词并打印它们。此外,它还返回最后解码序列的概率,如下所示。
[0..5) Hello [6..10) John [11..14) how [15..18) are [19..22) you [23..30) welcome [31..33) to [34..48) Tutorialspoint 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0