OpenNLP:驾驭文本,分词那些事

1 什么是OpenNLP,其具有哪些"内功"?

OpenNLP是为何物?

维基百科Apache OpenNLP库是一个基于机器学习自然语言文本处理的开发工具包,它支持自然语言处理中一些共有的任务,例如:标记化句子分割词性标注固有实体提取(指在句子中辨认出专有名词,例如:人名)、浅层分析句字分块)、语法分析指代。这些任务通常都需要较为先进的文字处理服务功能。

官方文档:Apache的OpenNLP库是自然语言文本的处理基于机器学习的工具包。它支持最常见的NLP任务,如断词,句子切分,部分词性标注,命名实体提取,分块,解析和指代消解。这些任务通常需要建立更先进的文字处理服务。OpenNLP还包括最大熵和基于感知机器学习。该OpenNLP项目的目标是创造上述任务的成熟工具包。一个附加的目的是提供一种大量预建模型为各种语言,以及这些模型衍生自注释文本资源。

使用:其支持Windows、linux等多个操作系统,本文主要介绍Windows下:

1 命令行界面(CLI):OpenNLP脚本使用JAVA_CMD和JAVA_HOME变量,以确定哪些命令用来执行Java虚拟机。OpenNLP脚本使用OPENNLP_HOME变量来确定OpenNLP的二进制分发的位置。建议这个变量指向当前OpenNLP版本和更新PATH变量的二进制分发版包括$OPENNLP_HOME/bin or %OPENNLP_HOME%\bin。这样的配置允许方便调用OpenNLP。下面的例子假设这个配置已经完成。使用如下:当工具被执行这种方式,模型是装载和工具正在等待来自标准输入的输入。此输入处理,并打印到标准输出。

 


1

$ opennlp ToolName lang-model-name.bin < input.txt > output.txt

2 Java在控制台:进行其API的调用,以下代码演示均采用此法。

  • 在官网(点击下载):apache-opennlp-1.5.3工具包
  • 解压文件:(如:savepath\apache-opennlp-1.5.3\lib)将lib下文件拷贝项目中
  • 去官网模型页面下载bin文件,下载需要的模型,具体如下:
  • 然后去创建java程序做相应处理,诸如:分词、词性标注等。

 

3 示例:至此完成java配置,然后相对 "The quick, red fox jumped over the lazy, brown dogs." 一条句子进行分词,常规方法采用空格分词代码如下:


1

2

3

4

5

6

7

8

9

//英文切词:空格或者换行符

public static void ENSplit(String str)

{

    String[] result=str.split("\\s+");

    for(String s:result){

        System.out.println(s+" ");

    }

    System.out.println();

}

 分词结果:

随着需求的改变,假如我想把标点也分开。实际这也是有意义的,可以通过标点确定句子的边界。下面OpenNLP将采用其方式完成,由此引入本文正题。

回到顶部

2 句子探测器

功能介绍:

句子检测器是用于检测句子边界。

句子探测器返回一个字符串数组。

API:句子探测器还提供了一个API来培养一个新的句子检测模型。三个基本步骤是必要的训练它:

  • 应用程序必须打开一个示例数据流
  • 调用SentenceDetectorME.t​​rain方法
  • 保存SentenceModel到文件或直接使用它

代码实现:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/**

 * 1.句子探测器:Sentence Detector

 * @deprecated Sentence detector is for detecting sentence boundaries. Given the following paragraph:

 * Hi. How are you? This is Mike.

 * 如:Hi. How are you? This is Mike.将返回如下:

 * Hi. How are you?

 * This is Mike.

 * @throws IOException

 * @throws InvalidFormatException

 */

public static void SentenceDetector(String str) throws InvalidFormatException, IOException

{

    //always start with a model, a model is learned from training data

    InputStream is new FileInputStream("./nlpbin/en-sent.bin");

    SentenceModel model = new SentenceModel(is);

    SentenceDetectorME sdetector = new SentenceDetectorME(model);

  

    String sentences[] = sdetector.sentDetect(str);

  

    System.out.println(sentences[0]);

    System.out.println(sentences[1]);

    is.close();

    System.out.println("---------------1------------");

}

运行结果:

 

回到顶部

3 标记生成器

功能介绍:该OpenNLP断词段输入字符序列为标记。常是这是由空格分隔的单词,但也有例外。例如,“isn't”被分割为“is”与“n't",因为它是AA简要格式”isn't“我们的句子分为以下标记:符号通常是词语,标点符号,数字等OpenNLP提供多种标记生成器的实现:

  • 空白标记生成器 - 一个空白标记生成器,非空白序列被确定为符号
  • 简单的标记生成器 - 一个字符类标记生成器,同样的字符类的序列标记
  • 可学习标记生成器 - 一个最大熵标记生成器,检测基于概率模型符号边界

API:的断词可以被集成到由定义的API的应用程序。该WhitespaceTokenizer的共享实例可以从静态字段WhitespaceTokenizer.INSTANCE进行检索。该SimpleTokenizer的共享实例可以在从SimpleTokenizer.INSTANCE相同的方式进行检索。实例化TokenizerME(中可以学习标记生成器)符号模型必须先创建。

代码实现:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

/**

 * 2.标记生成器:Tokenizer

 * @deprecated Tokens are usually words which are separated by space, but there are exceptions.  For example, "isn't" gets split into "is" and "n't, since it is a a brief format of "is not". Our sentence is separated into the following tokens:

 * @param str

 */

public static void Tokenize(String str) throws InvalidFormatException, IOException {

    InputStream is new FileInputStream("./nlpbin/en-token.bin");

    TokenizerModel model = new TokenizerModel(is);

    Tokenizer tokenizer = new TokenizerME(model);

    String tokens[] = tokenizer.tokenize(str);

    for (String a : tokens)

        System.out.println(a);

    is.close();

    System.out.println("--------------2-------------");

}

运行结果:

 

回到顶部

4 名称搜索

功能介绍:名称查找器可检测文本命名实体和数字。为了能够检测实体名称搜索需要的模型。该模型是依赖于语言和实体类型这是训练。所述OpenNLP项目提供了许多这些各种免费提供的语料库训练有素预训练名取景模式。他们可以在我们的模型下载页进行下载。要查找原始文本的文本必须分割成符号和句子的名字。详细描述中的一句话探测器和标记生成器教程中给出。其重要的,对于训练数据和输入的文本的标记化是相同的。根据不同的模型可以查找人名、地名等实体名。

API:从应用程序中训练名字发现者的建议使用培训API而不是命令行工具。三个基本步骤是必要的训练它:

  • 应用程序必须打开一个示例数据流
  • 调用NameFinderME.t​​rain方法
  • 保存TokenNameFinderModel到文件或数据库

代码实现:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/**

 * 3.名称搜索:Name Finder

 * @deprecated By its name, name finder just finds names in the context. Check out the following example to see what name finder can do. It accepts an array of strings, and find the names inside.

 * @param str

 */

public static void findName() throws IOException {

    InputStream is new FileInputStream("./nlpbin/en-ner-person.bin");

    TokenNameFinderModel model = new TokenNameFinderModel(is);

    is.close();

    NameFinderME nameFinder = new NameFinderME(model);

    String[] sentence = new String[]{

            "Mike",

            "Tom",

            "Smith",

            "is",

            "a",

            "good",

            "person"

            };

    Span nameSpans[] = nameFinder.find(sentence);

    for(Span s: nameSpans)

        System.out.println(s.toString());  

    System.out.println("--------------3-------------");

}

运行结果:

 

回到顶部

5 POS标注器

功能介绍:语音标记器的部分标记符号与基于符号本身和符号的上下文中它们的相应字类型。符号可能取决于符号和上下文使用多个POS标签。该OpenNLP POS标注器使用的概率模型来预测正确的POS标记出了标签组。为了限制可能的标记的符号标记字典可以使用这增加了捉人者的标记和运行时性能。

API:部分的词类打标签训练API支持一个新的POS模式的培训。三个基本步骤是必要的训练它:

  • 应用程序必须打开一个示例数据流
  • 调用POSTagger.train方法
  • 保存POSModel到文件或数据库

代码实现1:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

/**

 * 4.POS标注器:POS Tagger

 * @deprecated Hi._NNP How_WRB are_VBP you?_JJ This_DT is_VBZ Mike._NNP

 * @param str

 */

public static void POSTag(String str) throws IOException {

    POSModel model = new POSModelLoader().load(new File("./nlpbin/en-pos-maxent.bin"));

    PerformanceMonitor perfMon = new PerformanceMonitor(System.err, "sent");//显示加载时间

    POSTaggerME tagger = new POSTaggerME(model);

    ObjectStream<String> lineStream = new PlainTextByLineStream(new StringReader(str));

    perfMon.start();

    String line;

    while ((line = lineStream.read()) != null) {

        String whitespaceTokenizerLine[] = WhitespaceTokenizer.INSTANCE.tokenize(line);

        String[] tags = tagger.tag(whitespaceTokenizerLine);

        POSSample sample = new POSSample(whitespaceTokenizerLine, tags);

        System.out.println(sample.toString());

        perfMon.incrementCounter();

    }

    perfMon.stopAndPrintFinalResult();

    System.out.println("--------------4-------------");

}

运行结果1:

 

代码实现2:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

/**

 * OpenNLP词性标注工具的例子:最大熵词性标注器pos-maxent

 * JJ形容词、JJS形容词最高级、JJR形容词比较级

 * RB副词、RBR副词最高级、RBS副词比较级

 * DT限定词

 * NN名称、NNS名称复试、NNP专有名词、NNPS专有名词复数:

 * PRP:人称代词、PRP$:物主代词

 * VB动词不定式、VBD过去式、VBN过去分词、VBZ现在人称第三人称单数、VBP现在非第三人称、VBG动名词或现在分词

 */

public static void POSMaxent(String str) throws InvalidFormatException, IOException

{

    //给出词性模型所在的路径

    File posModeFile=new File("./nlpbin/en-pos-maxent.bin");

    FileInputStream posModeStream=new FileInputStream(posModeFile);

    POSModel model=new POSModel(posModeStream);

    //将句子切分成词

    POSTaggerME tagger=new POSTaggerME(model);

    String[] words=SimpleTokenizer.INSTANCE.tokenize(str);

    //将切好的词的句子传递给标注器

    String[] result=tagger.tag(words);

    for (int i=0; i<words.length;i++){

        System.out.print(words[i]+"/"+result[i]+" ");

    }

    System.out.println();

}

  运行结果2:

回到顶部

6 细节化

功能介绍:文本分块由除以单词句法相关部分,如名词基,动词基的文字,但没有指定其内部结构,也没有其在主句作用。

API:该概括化提供了一个API来培养新的概括化的模式。下面的示例代码演示了如何做到这一点:

代码实现:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

/**

 * 5.序列标注:Chunker

 * @deprecated 通过使用标记生成器生成的tokens分为一个句子划分为一组块。What chunker does is to partition a sentence to a set of chunks by using the tokens generated by tokenizer.

 * @param str

 */

public static void chunk(String str) throws IOException {

    POSModel model = new POSModelLoader().load(new File("./nlpbin/en-pos-maxent.bin"));

    //PerformanceMonitor perfMon = new PerformanceMonitor(System.err, "sent");

    POSTaggerME tagger = new POSTaggerME(model);

    ObjectStream<String> lineStream = new PlainTextByLineStream(new StringReader(str));

    //perfMon.start();

    String line;

    String whitespaceTokenizerLine[] = null;

    String[] tags = null;

    while ((line = lineStream.read()) != null) {

        whitespaceTokenizerLine = WhitespaceTokenizer.INSTANCE.tokenize(line);

        tags = tagger.tag(whitespaceTokenizerLine);

        POSSample sample = new POSSample(whitespaceTokenizerLine, tags);

        System.out.println(sample.toString());

            //perfMon.incrementCounter();

    }

    //perfMon.stopAndPrintFinalResult();

     

    // chunker

    InputStream is new FileInputStream("./nlpbin/en-chunker.bin");

    ChunkerModel cModel = new ChunkerModel(is);

    ChunkerME chunkerME = new ChunkerME(cModel);

    String result[] = chunkerME.chunk(whitespaceTokenizerLine, tags);

    for (String s : result)

        System.out.println(s);

    Span[] span = chunkerME.chunkAsSpans(whitespaceTokenizerLine, tags);

    for (Span s : span)

        System.out.println(s.toString());

    System.out.println("--------------5-------------");

}

运行结果:

 

回到顶部

7 分析器

功能介绍:尝试解析器最简单的方法是在命令行工具。该工具仅用于演示和测试。请从我们网站上的英文分块解析器模型,并用以下命令启动解析工具。

代码实现:

 


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

/**

 * 6.分析器: Parser

 * @deprecated Given this sentence: "Programcreek is a very huge and useful website.", parser can return the following:

 * (TOP (S (NP (NN Programcreek) ) (VP (VBZ is) (NP (DT a) (ADJP (RB very) (JJ huge) (CC and) (JJ useful) ) ) ) (. website.) ) )

 * (TOP

 *     (S

 *        (NP

 *           (NN Programcreek)

 *        )

 *        (VP

 *           (VBZ is)

 *           (NP

 *              (DT a)

 *              (ADJP

 *                   (RB very)

 *                   (JJ huge)

 *                   (CC and)

 *                   (JJ userful)

 *              )

 *           )

 *        )

 *        (. website.)

 *     )

 * )

 * @param str

 */

public static void Parse() throws InvalidFormatException, IOException {

    // http://sourceforge.net/apps/mediawiki/opennlp/index.php?title=Parser#Training_Tool

    InputStream is new FileInputStream("./nlpbin/en-parser-chunking.bin");

    ParserModel model = new ParserModel(is);

    Parser parser = ParserFactory.create(model);

    String sentence = "Programcreek is a very huge and useful website.";

    opennlp.tools.parser.Parse topParses[] = ParserTool.parseLine(sentence, parser, 1);

    for (opennlp.tools.parser.Parse p : topParses)

        p.show();

    is.close();

}

运行结果:

 

时间: 2024-10-04 11:00:03

OpenNLP:驾驭文本,分词那些事的相关文章

《驾驭大数据》一3.2 多个行业:文本数据的价值

3.2 多个行业:文本数据的价值 驾驭大数据文本是最大的也是最常见的大数据源之一.想想我们周围有多少文本信息的存在,电子邮件.短信.微博.社交媒体网站的帖子.即时通信.实时会议以及可以转换成文本的录音信息.文本数据是现在结构化程度最低的,也是最大的大数据源.幸运的是,我们在驾驭文本数据.利用文本数据来更好地做商业决策方面已经做了很多工作. 文本分析一般会从解析文本开始,然后将各种单词.短语以及包含文本的部分赋予语义.我们可以通过简单的词频统计,或更复杂的操作来进行文本分析.自然语言处理中已经有很

JAVA实现文本情感分析

问题描述 应该怎么做,思路有哪些?求指导? 解决方案 解决方案二:词库检索喜怒哀乐每个词库都弄点词语什么语气助词全填上,然后统计每个词库中出现词语的总次数,最后最多的那一类即文本情感.解决方案三:1.建立情感词库,可能还要为每个词定义权重也叫阈值以及该情感词汇所属的情感类别2.进行文本分词3.根据分词结果提取情感词汇,标记每个词汇出现的次数4.将词汇根据情感类别分类,然后根据每个词的阈值计算每类情感的值:词次数*权重,然后求和5.根据每类情感的值分析文本最可能的情感解决方案四:该回复于2014-

数据仓库专题(10)-文本事实和杂项维度

一.杂项维度 在维度建模的数据仓库中,有一种维度叫Junk Dimension,中文一般翻译为"杂项维度".杂项维度是由操作系统中的指示符或者标志字段组合而成,一般不在一致性维度之列. 在操作系统中,我们定义好各种维度后,通常还会剩下一些在小范围内取离散值的指示符或者标志字段.例如:支付类型字段,包括现金和信用卡两种类型,在源系统中它们可能是维护在类型表中,也可能直接保存在交易表中. 一张事实表中可能会存在好几个类似的字段,如果作为事实存放在事实表中,会导致事实表占用空间过大:如果单独

关于文本之间相似度比较的代码

问题描述 最近在研究跨语言链接的部分被安排要做一个计算文本之间相似度的任务本人是java小白在网上找参考只说做了一个文本分词的程序请问论坛中的大神是不是不做错文本的分词程序就无法做相似度计算的程序?如果有哪位好心的大神能否给小白一个相似度计算的代码以助于参考??谢谢 解决方案 解决方案二:完全不知道~相似度是什么,百分比,还是就是像那种文本比较器一样的比较差异的感觉如果是百分比好像很难啊,中文这么多意思计算机怎么知道同一个词放在不同语境里面意思是不是相同

如何用机器学习对文本分类

需求 使用监督学习对历史数据训练生成模型,用于预测文本的类别. 样本清洗 主要将重复的数据删除掉,将错误无效的数据纠正或删除,并检查数据的一致性等.比如我认为长度小于少于13的数据是无效的遂将之删掉. def writeFile(text): file_object = open('result.txt','w') file_object.write(text) file_object.close() def clear(): text = "" file_obj = open(&qu

文本挖掘分词mapreduce化

软件版本 paoding-analysis3.0 项目jar包和拷贝庖丁dic目录到项目的类路径下 修改paoding-analysis.jar下的paoding-dic-home.properties文件设置词典文件路径 paoding.dic.home=classpath:dic 分词程序demo import java.io.IOException; import java.io.StringReader; import org.apache.lucene.analysis.TokenSt

中国人工智能学会通讯——面向知识图谱的自适应中文分词技术

引言 知识图谱用于描述真实世界中存在的各 种实体和概念,知识图谱技术提供了一种从 海量文本和图像中抽取结构化知识的手段[1]. 知识图谱的构建可分为信息抽取.知识融合 和知识计算三部分,其中信息抽取是知识图 谱构建的基础,主要面向各种非结构化数据. 半结构化数据和自由文本数据.这里,自由 文本数据作为一种非结构化数据,是构建知 识图谱的主要数据来源.因此,从中文自由 文本中获取知识需要利用自然语言处理技术 进行信息抽取,诸如实体识别.关系抽取等. 在实体识别过程中,中文分词系统的性能对 实体识别

一文详解如何用 python 做中文分词

打算绘制中文词云图?那你得先学会如何做中文文本分词.跟着我们的教程,一步步用 Python 来动手实践吧.   需求 在此前发布的文章<从零开始教你用 Python 做词云>一文中,我们介绍了英文文本的词云制作方法.大家玩儿得可还高兴? 文中提过,选择英文文本作为示例,是因为处理起来最简单.但是很快就有读者尝试用中文文本做词云了.按照前文的方法,你成功了吗? 估计是不成功的.因为这里面缺了一个重要的步骤. 观察你的英文文本.你会发现英文单词之间采用空格作为强制分隔符. 例如: Yes Mini

用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践

近来在同时做一个应用深度学习解决淘宝商品的类目预测问题的项目,恰好硕士毕业时论文题目便是文本分类问题,趁此机会总结下文本分类领域特别是应用深度学习解决文本分类的相关的思路.做法和部分实践的经验. 业务问题描述: 淘宝商品的一个典型的例子见下图,图中商品的标题是"夏装雪纺条纹短袖t恤女春半袖衣服夏天中长款大码胖mm显瘦上衣夏".淘宝网后台是通过树形的多层的类目体系管理商品的,覆盖叶子类目数量达上万个,商品量也是10亿量级,我们是任务是根据商品标题预测其所在叶子类目,示例中商品归属的类目为