OpenNLP - 句子检测
在处理自然语言时,确定句子的开始和结束是需要解决的问题之一。此过程称为S句子B边界D歧义 (SBD) 或简单的句子分解。
我们用来检测给定文本中的句子的技术取决于文本的语言。
使用 Java 进行句子检测
我们可以使用正则表达式和一组简单规则在 Java 中检测给定文本中的句子。
例如,假设句号、问号或感叹号结束给定文本中的句子,那么我们可以使用 String 类的 split() 方法拆分句子。这里,我们必须传递一个字符串格式的正则表达式。
以下是使用 Java 正则表达式(split 方法)确定给定文本中的句子的程序。将此程序保存在名为 SentenceDetection_RE.java 的文件中。
public class SentenceDetection_RE { public static void main(String args[]){ String sentence = " Hi. How are you? Welcome to Tutorialspoint. " + "We provide free tutorials on various technologies"; String simple = "[.?!]"; String[] splitString = (sentence.split(simple)); for (String string : splitString) System.out.println(string); } }
使用以下命令从命令提示符编译并执行保存的 java 文件。
javac SentenceDetection_RE.java java SentenceDetection_RE
执行时,上述程序会创建一个显示以下消息的 PDF 文档。
Hi How are you Welcome to Tutorialspoint We provide free tutorials on various technologies
使用 OpenNLP 进行句子检测
为了检测句子,OpenNLP 使用预定义模型,即名为 en-sent.bin 的文件。这个预定义模型经过训练可以检测给定原始文本中的句子。
opennlp.tools.sentdetect 包包含用于执行句子检测任务的类和接口。
要使用 OpenNLP 库检测句子,您需要 −
使用 SentenceModel 类加载 en-sent.bin 模型
实例化 SentenceDetectorME 类。
使用此类的 sentDetect() 方法检测句子。
以下是编写从给定原始文本中检测句子的程序需要遵循的步骤。
步骤 1:加载模型
模型句子检测由名为SentenceModel的类表示,该类属于opennlp.tools.sentdetect包。
加载句子检测模型 −
创建模型的InputStream对象(实例化FileInputStream并将模型的路径以字符串格式传递给其构造函数)。
实例化SentenceModel类,并将模型的InputStream(对象)作为参数传递给其构造函数,如以下代码块所示−
//加载句子检测器模型 InputStream inputStream = new FileInputStream("C:/OpenNLP_models/ensent.bin"); SentenceModel model = new SentenceModel(inputStream);
步骤 2:实例化 SentenceDetectorME 类
包 opennlp.tools.sentdetect 的 SentenceDetectorME 类包含将原始文本拆分为句子的方法。此类使用最大熵模型评估字符串中的句末字符,以确定它们是否表示句子的结束。
实例化此类并传递上一步中创建的模型对象,如下所示。
//实例化 SentenceDetectorME 类 SentenceDetectorME detector = new SentenceDetectorME(model);
步骤 3:检测句子
SentenceDetectorME 类的 sentDetect() 方法用于检测传递给它的原始文本中的句子。此方法接受 String 变量作为参数。
通过将句子的 String 格式传递给此方法来调用此方法。
//检测句子 String sentence[] = detector.sentDetect(sentence);
示例
以下是检测给定原始文本中的句子的程序。将此程序保存在名为 SentenceDetectionME.java 的文件中。
import java.io.FileInputStream; import java.io.InputStream; import opennlp.tools.sentdetect.SentenceDetectorME; import opennlp.tools.sentdetect.SentenceModel; public class SentenceDetectionME { public static void main(String args[]) throws Exception { String sentence = "Hi. How are you? Welcome to Tutorialspoint. " + "We provide free tutorials on various technologies"; //加载句子检测模型 InputStream inputStream = new FileInputStream("C:/OpenNLP_models/en-sent.bin"); SentenceModel model = new SentenceModel(inputStream); //实例化 SentenceDetectorME 类 SentenceDetectorME detector = new SentenceDetectorME(model); //检测句子 String sentence[] = detector.sentDetect(sentence); //打印句子 for(String sent : sentences) System.out.println(sent); } }
使用以下命令从命令提示符编译并执行保存的 Java 文件 −
javac SentenceDetectorME.java java SentenceDetectorME
执行时,上述程序读取给定的字符串并检测其中的句子并显示以下输出。
Hi. How are you? Welcome to Tutorialspoint. We provide free tutorials on various technologies
检测句子的位置
我们还可以使用 SentenceDetectorME 类 的 sentPosDetect() 方法来检测句子的位置。
下面是编写一个程序的步骤,该程序从给定的原始文本中检测句子的位置。
步骤 1:加载模型
句子检测模型由名为 SentenceModel 的类表示,该类属于 opennlp.tools.sentdetect 包。
要加载句子检测模型 −
创建模型的 InputStream 对象(实例化 FileInputStream 并将模型的路径以字符串格式传递给其构造函数)。
实例化SentenceModel 类,并将模型的 InputStream(对象)作为参数传递给其构造函数,如下面的代码块所示。
//加载句子检测器模型 InputStream inputStream = new FileInputStream("C:/OpenNLP_models/en-sent.bin"); SentenceModel model = new SentenceModel(inputStream);
步骤 2:实例化 SentenceDetectorME 类
包 opennlp.tools.sentdetect 的 SentenceDetectorME 类包含将原始文本拆分为句子的方法。此类使用最大熵模型来评估字符串中的句末字符,以确定它们是否表示句子的结束。
实例化此类并传递上一步中创建的模型对象。
//实例化 SentenceDetectorME 类 SentenceDetectorME detector = new SentenceDetectorME(model);
步骤 3:检测句子的位置
SentenceDetectorME 类的 sentPosDetect() 方法用于检测传递给它的原始文本中句子的位置。此方法接受 String 变量作为参数。
通过将句子的 String 格式作为参数传递给此方法,调用此方法。
//检测句子在段落中的位置 Span[] spans = detector.sentPosDetect(sentence);
步骤 4:打印句子的跨度
SentenceDetectorME 类的 sentPosDetect() 方法返回 Span 类型的对象数组。 opennlp.tools.util 包中的 Span 类用于存储集合的起始和终止整数。
您可以将 sentPosDetect() 方法返回的跨度存储在 Span 数组中并打印它们,如下面的代码块所示。
//打印句子及其跨度 for (Span span : spans) System.out.println(paragraph.substring(span);
示例
以下是检测给定原始文本中的句子的程序。将此程序保存在名为 SentenceDetectionME.java 的文件中。
import java.io.FileInputStream; import java.io.InputStream; import opennlp.tools.sentdetect.SentenceDetectorME; import opennlp.tools.sentdetect.SentenceModel; import opennlp.tools.util.Span; public class SentencePosDetection { public static void main(String args[]) throws Exception { String paragraph = "Hi. How are you? Welcome to Tutorialspoint. " + "We provide free tutorials on various technologies"; //加载句子检测模型 InputStream inputStream = new FileInputStream("C:/OpenNLP_models/en-sent.bin"); SentenceModel model = new SentenceModel(inputStream); //实例化 SentenceDetectorME 类 SentenceDetectorME detector = new SentenceDetectorME(model); //检测句子在原始文本中的位置 Span spans[] = detector.sentPosDetect(paragraph); //打印段落中句子的跨度 for (Span span : spans) System.out.println(span); } }
使用以下命令从命令提示符编译并执行已保存的 Java 文件 −
javac SentencePosDetection.java java SentencePosDetection
执行时,上述程序读取给定的字符串并检测其中的句子并显示以下输出。
[0..16) [17..43) [44..93)
句子及其位置
String 类的 substring() 方法接受 begin 和 end 偏移量 并返回相应的字符串。我们可以使用此方法将句子及其跨度(位置)一起打印,如下面的代码块所示。
for (Span span : spans) System.out.println(sen.substring(span.getStart(), span.getEnd())+" "+ span);
以下程序用于从给定的原始文本中检测句子并显示它们及其位置。将此程序保存在名为 SentencesAndPosDetection.java 的文件中。
import java.io.FileInputStream; import java.io.InputStream; import opennlp.tools.sentdetect.SentenceDetectorME; import opennlp.tools.sentdetect.SentenceModel; import opennlp.tools.util.Span; public class SentencesAndPosDetection { public static void main(String args[]) throws Exception { String sen = "Hi. How are you? Welcome to Tutorialspoint." + " We provide free tutorials on various technologies"; //加载句子模型 InputStream inputStream = new FileInputStream("C:/OpenNLP_models/en-sent.bin"); SentenceModel model = new SentenceModel(inputStream); //实例化 SentenceDetectorME 类 SentenceDetectorME detector = new SentenceDetectorME(model); //检测段落中句子的位置 Span[] spans = detector.sentPosDetect(sen); //打印段落中的句子及其跨度 for (Span span : spans) System.out.println(sen.substring(span.getStart(), span.getEnd())+" "+ span); } }
使用以下命令从命令提示符编译并执行保存的 Java 文件−
javac SentencesAndPosDetection.java java SentencesAndPosDetection
执行时,上述程序读取给定的字符串并检测句子及其位置并显示以下输出。
Hi. How are you? [0..16) Welcome to Tutorialspoint. [17..43) We provide free tutorials on various technologies [44..93)
句子概率检测
SentenceDetectorME 类的 getSentenceProbabilities() 方法返回与最近调用 sentDetect() 方法相关的概率。
//获取最后解码序列的概率 double[] probs = detector.getSentenceProbabilities();
以下是打印与调用 sentDetect() 方法相关的概率的程序。将此程序保存在名为 SentenceDetectionMEProbs.java 的文件中。
import java.io.FileInputStream; import java.io.InputStream; import opennlp.tools.sentdetect.SentenceDetectorME; import opennlp.tools.sentdetect.SentenceModel; public class SentenceDetectionMEProbs { public static void main(String args[]) throws Exception { String sentence = "Hi. How are you? Welcome to Tutorialspoint. " + "We provide free tutorials on various technologies"; //加载句子检测模型 InputStream inputStream = new FileInputStream("C:/OpenNLP_models/en-sent.bin"); SentenceModel model = new SentenceModel(inputStream); //实例化 SentenceDetectorME 类 SentenceDetectorME detector = new SentenceDetectorME(model); //检测句子 String sentence[] = detector.sentDetect(sentence); //打印句子 for(String sent : sentences) System.out.println(sent); //获取最后解码序列的概率 double[] probs = detector.getSentenceProbabilities(); System.out.println(" "); for(int i = 0; i<probs.length; i++) System.out.println(probs[i]); } }
使用以下命令从命令提示符编译并执行已保存的 Java 文件 −
javac SentenceDetectionMEProbs.java java SentenceDetectionMEProbs
执行时,上述程序读取给定的字符串并检测句子并打印它们。此外,它还返回与最近调用 sentDetect() 方法相关的概率,如下所示。
Hi. How are you? Welcome to Tutorialspoint. We provide free tutorials on various technologies 0.9240246995179983 0.9957680129995953 1.0