分词及词性标注总结

近期,尝试了各类的分词及词性标注工具,包括如下软件:

工具 中英文支持 其他说明
中科院的ICTCLAS 中英 CPP,多语言接口
清华大学的THULANC 中,英较差 多语言支持
哈工大的LTP CPP,多语言接口
复旦的FudanDNN Java
东北大学的NiuParser 中,英较差 CPP
斯坦福的Stanford 中英 Java
Ansj Java
Jieba Python
Word Java
HanLP Java
LingPipe 英,中较差 Java
OpenNLP Java
NLTK Python
Gate Java,GUI,但不太符合程序员思维逻辑
lucene-analyzers-smartcn Java,只分词,不标词性

此外,还有几个工具,由于时间关系,没有进行测试,有兴趣的话可以看一下:
mmseg4j
paoding
jcseg
IK-Analyzer

总结如下:
1、无论是英文还是中文,其分词及标注词性的技术已经相对比较成熟;
2、英文和中文完全是两个体系,中文还是国内做的好一些
3、算法是公开的,因此很多时候,模型库比算法要一些
4、模型库够用就好,不是越大越好。尤其是特定语境下的模型库,自己训练的会更好用
5、英文的模型库比国内好太多了,看着好羡慕啊
6、希望国内的科研可以更有套路、更有组织、更专业化一些

使用Word进行分词及词性标注

1、下载Jar或源码
https://github.com/ysc/word/

2、写一些代码

public static void tag(String sentence) throws Exception {
        List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.BidirectionalMaximumMatching);
        PartOfSpeechTagging.process(words);
        System.out.println(words);
    	/*
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.BidirectionalMaximumMinimumMatching);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.BidirectionalMinimumMatching);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.FullSegmentation);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.MaximumMatching);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.MaxNgramScore);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.MinimalWordCount);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.MinimumMatching);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.PureEnglish);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.ReverseMaximumMatching);
    	List<Word> words = WordSegmenter.segWithStopWords(sentence, SegmentationAlgorithm.ReverseMinimumMatching);
    	*/
    }

4、输入
zh.txt

别让别人告诉你你成不了才,即使是我也不行。
如果你有梦想的话,就要去捍卫它。
那些一事无成的人想告诉你你也成不了大器。
如果你有理想的话,就要去努力实现。
就这样。

5、输出
zhout.txt

[别让/i, 别人/r, 告诉/v, 你/r, 你/r, 成不了/l, 才/d, 即使/c, 是/v, 我/r, 也/d, 不行/v, 如果/c, 你/r, 有/v, 梦想/n, 的话/u, 就要/d, 去/v, 捍卫/v, 它/r, 那些/r, 一事无成/l, 的/uj, 人/n, 想/v, 告诉/v, 你/r, 你/r, 也/d, 成不了/l, 大器/n, 如果/c, 你/r, 有理想/i, 的话/u, 就要/d, 去/v, 努力实现/nr, 就这样/i]

使用HanLP进行分词及词性标注

1、下载Jar、配置文件及训练库
http://hanlp.linrunsoft.com/services.html

2、修改配置文件中的根目录,到训练库的根目录

3、写一些代码

	public static void tag(String sentence) throws Exception {
		List<Term> terms = StandardTokenizer.segment(sentense);
		System.out.println(terms);

		//terms = NLPTokenizer.segment(sentense);
		//System.out.pr1intln(terms);
		
		//terms = IndexTokenizer.segment(sentense);
		//System.out.println(terms);
		
		//terms = SpeedTokenizer.segment(sentense);
		//System.out.println(terms);
		
		//terms = new NShortSegment().seg(sentense);
		//System.out.println(terms);
		
		//terms = new DijkstraSegment().seg(sentense);
		//System.out.println(terms);
        }

4、输入
zh.txt

别让别人告诉你你成不了才,即使是我也不行。
如果你有梦想的话,就要去捍卫它。
那些一事无成的人想告诉你你也成不了大器。
如果你有理想的话,就要去努力实现。
就这样。

5、输出
zhout.txt

[别/d, 让/v, 别人/rr, 告诉/v, 你/rr, 你/rr, 成不了/l, 才/d, ,/w, 即使/c, 是/vshi, 我/rr, 也/d, 不行/a, 。/w, 如果/c, 你/rr, 有/vyou, 梦想/n, 的/ude1, 话/n, ,/w, 就要/d, 去/vf, 捍卫/v, 它/rr, 。/w, 那些/rz, 一事无成/vl, 的/ude1, 人/n, 想/v, 告诉/v, 你/rr, 你/rr, 也/d, 成不了/l, 大/a, 器/ng, 。/w, 如果/c, 你/rr, 有/vyou, 理想/n, 的话/udh, ,/w, 就要/d, 去/vf, 努力/ad, 实现/v, 。/w, 就/d, 这样/rzv, 。/w]

使用Ansj进行分词及词性标注

1、下载源码或Jar包
https://github.com/NLPchina/ansj_seg
http://maven.nlpcn.org/org/ansj/ansj_seg/

2、下载训练库,并解压到项目根目录
http://maven.nlpcn.org/down/

3、写一些代码

	public static void tag(String sentence) throws Exception {
	    //下载训练库
	    //DownLibrary.main(args);
		
	    //List<Term> termsA = BaseAnalysis.parse(sentence);
	    //System.out.println(termsA);
	    //List<Term> termsB = ToAnalysis.parse(sentence);
	    //System.out.println(termsB);
	    List<Term> termsC = NlpAnalysis.parse(sentence);
	    System.out.println(termsC);
	    //List<Term> termsD = IndexAnalysis.parse(sentence);
	    //System.out.println(termsD);
	}

4、输入
zh.txt

别让别人告诉你你成不了才,即使是我也不行。
如果你有梦想的话,就要去捍卫它。
那些一事无成的人想告诉你你也成不了大器。
如果你有理想的话,就要去努力实现。
就这样。

5、输出
zhout.txt

[别让/nrf, 别人/r, 告诉/v, 你/r, 你/r, 成不了/l, 才/d, ,/w, 即使/c, 是/v, 我/r, 也/d, 不行/a, 。/w, 如果/c, 你/r, 有/v, 梦想/n, 的话/udh, ,/w, 就要/d, 去/v, 捍卫/v, 它/r, 。/w, 那些/r, 一事无成/i, 的/uj, 人/n, 想/v, 告诉/v, 你/r, 你/r, 也/d, 成不了/l, 大器/n, 。/w, 如果/c, 你/r, 有/v, 理想/n, 的话/udh, ,/w, 就要/d, 去/v, 努力/ad, 实现/v, 。/w, 就/d, 这样/r, 。/w]

使用Jieba进行分词及词性标注

1、首先下载结巴分词
https://github.com/fxsjy/jieba
或者直接安装

easy_install jieba
pip install jieba

2、写几行测试代码

#!usr/bin/python
#encoding=utf-8

import jieba.posseg as postag

words = postag.cut("别让别人告诉你你成不了才,即使是我也不行。\
如果你有梦想的话,就要去捍卫它。\
那些一事无成的人想告诉你你也成不了大器。\
如果你有理想的话,就要去努力实现。\
就这样。");
for w in words:
  print(w.word, "/", w.flag, " ", end="")

3、测试结果

别 / d  让 / v  别人 / r  告诉 / v  你 / r  你 / r  成不了 / l  才 / d  , / x
即使 / c  是 / v  我 / r  也 / d  不行 / v  。 / x  如果 / c  你 / r  有 / v  梦
想 / n  的话 / u  , / x  就要 / d  去 / v  捍卫 / v  它 / r  。 / x  那些 / r
一事无成 / i  的 / uj  人想 / n  告诉 / v  你 / r  你 / r  也 / d  成不了 / l
大器 / n  。 / x  如果 / c  你 / r  有 / v  理想 / n  的话 / u  , / x  就要 / d
  去 / v  努力实现 / nr  。 / x  就 / d  这样 / r  。 / x

使用LingPipe进行分词及词性标注

1、首先下载LinePipe
http://alias-i.com/lingpipe/

2、测试例子
en.txt

Don't ever let somebody tell you you can't do something, not even me. 
You got a dream, you gotta protect it. 
People can’t do something themselves, they wanna tell you you can’t do it. 
If you want something, go get it. 
Period.

3、运行gui_pos_en_general_brown.bat

4、测试结果
enpos.txt

<?xml version="1.0" encoding="GBK"?><output><s i="0"><token pos="np">Don</token><token pos="'">'</token><token pos="ql">t</token> <token pos="rb">ever</token> <token pos="vb">let</token> <token pos="pn">somebody</token> <token pos="vb">tell</token> <token pos="ppo">you</token> <token pos="ppss">you</token> <token pos="md">can</token><token pos="'">'</token><token pos="rbt">t</token> <token pos="do">do</token> <token pos="pn">something</token><token pos=",">,</token> <token pos="*">not</token> <token pos="vb">even</token> <token pos="ppo">me</token><token pos=".">.</token></s> 
<s i="1"><token pos="ppss">You</token> <token pos="vbd">got</token> <token pos="at">a</token> <token pos="nn">dream</token><token pos=",">,</token> <token pos="ppss">you</token> <token pos="vbn">gotta</token> <token pos="vb">protect</token> <token pos="ppo">it</token><token pos=".">.</token></s> 
<s i="2"><token pos="nns">People</token> <token pos="md">can</token><token pos="nil">’</token><token pos="nil">t</token> <token pos="do">do</token> <token pos="pn">something</token> <token pos="ppls">themselves</token><token pos=",">,</token> <token pos="ppss">they</token> <token pos="vb">wanna</token> <token pos="vb">tell</token> <token pos="ppo">you</token> <token pos="ppss">you</token> <token pos="md">can</token><token pos="nil">’</token><token pos="nil">t</token> <token pos="do">do</token> <token pos="ppo">it</token><token pos=".">.</token></s> 
<s i="3"><token pos="cs">If</token> <token pos="ppss">you</token> <token pos="vb">want</token> <token pos="pn">something</token><token pos=",">,</token> <token pos="vb">go</token> <token pos="vb">get</token> <token pos="ppo">it</token><token pos=".">.</token></s> 
<s i="4"><token pos="nn">Period</token><token pos=".">.</token></s></output>

使用Stanford套件进行分词及词性标注

1、首先下载两个工具,分别是分词工具及标定工具
Stanford Word Segmenter
Stanford POS Tagger
http://nlp.stanford.edu/software/
需要安装JDK8的哦。

2、测试例子
en.txt

Don't ever let somebody tell you you can't do something, not even me. 
You got a dream, you gotta protect it. 
People can’t do something themselves, they wanna tell you you can’t do it. 
If you want something, go get it. 
Period.

zh.txt

别让别人告诉你你成不了才,即使是我也不行。
如果你有梦想的话,就要去捍卫它。
那些一事无成的人想告诉你你也成不了大器。
如果你有理想的话,就要去努力实现。
就这样。

3、执行语句

segment.bat ctb zh.txt GBK 0 > zhws.txt
segment.bat ctb en.txt GBK 0 > enws.txt

stanford-postagger models/chinese-distsim.tagger zhws.txt > zhpos.txt
stanford-postagger models/english-bidirectional-distsim.tagger enws.txt > enpos.txt

4、测试结果
enpos.txt

Do_VB n't_RB ever_RB let_VB somebody_NN tell_VB you_PRP you_PRP ca_MD n't_RB do_VB something_NN ,_, not_RB even_RB me_PRP ._.
You_PRP got_VBD a_DT dream_NN ,_, you_PRP got_VBD ta_RB protect_VB it_PRP ._.
People_NNS can_MD '_POS t_NN do_VBP something_NN themselves_PRP ,_, they_PRP wan_VBP na_TO tell_VB you_PRP you_PRP can_MD '_POS t_NN do_VBP it_PRP ._.
If_IN you_PRP want_VBP something_NN ,_, go_VB get_VB it_PRP ._.
Period_NN ._.

zhpos.txt

别#AD 让#VV 别人#NN 告诉#VV 你#PN 你#PN 成不了#AD 才#AD ,#PU 即使#CS 是#VC 我#PN 也#AD 不#AD 行#VV 。#PU
如果#CS 你#PN 有#VE 梦想#NN 的话#SP ,#PU 就要#AD 去#VV 捍卫#VV 它#PN 。#PU
那些#DT 一事无成#VV 的#DEC 人#NN 想#VV 告诉#VV 你#PN 你#PN 也#AD 成#VV 不了#AD 大器#NN 。#PU
如果#CS 你#PN 有理想#VV 的话#SP ,#PU 就要#AD 去#VV 努力#AD 实现#VV 。#PU
就#AD 这样#VA 。#PU

使用OpenNLP进行分词及词性标注

1、下载OpenNLP
http://opennlp.apache.org/maven-dependency.html

2、下载模型文件
http://opennlp.sourceforge.net/models-1.5/

3、编码进行分词并标记

package com.neohope.opennlp.test;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;

import opennlp.tools.cmdline.PerformanceMonitor;
import opennlp.tools.cmdline.postag.POSModelLoader;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSSample;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.tokenize.WhitespaceTokenizer;
import opennlp.tools.util.ObjectStream;
import opennlp.tools.util.PlainTextByLineStream;

public class TestIt {

	@SuppressWarnings("deprecation")
	public static void POSTag() throws IOException {
		POSModel model = new POSModelLoader()
				.load(new File("en-pos-maxent.bin"));
		PerformanceMonitor perfMon = new PerformanceMonitor(System.err, "sent");
		POSTaggerME tagger = new POSTaggerME(model);

		String input = "Don't ever let somebody tell you you can't do something, not even me. "
				+ "You got a dream, you gotta protect it. "
				+ "People can’t do something themselves, they wanna tell you you can’t do it. "
				+ "If you want something, go get it. " + "Period.";
		ObjectStream<String> lineStream = new PlainTextByLineStream(
				new StringReader(input));

		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();
	}

	public static void main(String[] args) throws IOException {
		POSTag();
	}
}

4、输出结果

Don't_NNP ever_RB let_VB somebody_NN tell_VB you_PRP you_PRP can't_MD do_VB something,_RB not_RB even_RB me._RBR You_PRP got_VBD a_DT dream,_NN you_PRP gotta_VBP protect_VB it._PRP People_NNS can’t_MD do_VB something_NN themselves,_, they_PRP wanna_MD tell_VB you_PRP you_PRP can’t_MD do_VB it._PRP If_IN you_PRP want_VBP something,_NN go_VB get_VB it._PRP Period._.

使用ICTCLAS进行分词及词性标注

1、测试例子
en.txt

Don't ever let somebody tell you you can't do something, not even me. 
You got a dream, you gotta protect it. 
People can’t do something themselves, they wanna tell you you can’t do it. 
If you want something, go get it. 
Period.

zh.txt

别让别人告诉你你成不了才,即使是我也不行。
如果你有梦想的话,就要去捍卫它。
那些一事无成的人想告诉你你也成不了大器。
如果你有理想的话,就要去努力实现。
就这样。

2、输出结果
enout.txt

Don/n  't/wyy   ever/d   let/v   somebody/r   tell/v   you/rzt   you/rzt   can/vyou   't/wyy   do/vyou   something/r   ,/wd   not/d   even/d   me/rzt   ./wj   
You/rzt   got/v   a/rzv   dream/n   ,/wd   you/rzt   gotta/vd   protect/v   it/rzt   ./wj   
People/n   can’t/n   do/vyou   something/r   themselves/rzv   ,/wd   they/rzt   wanna/v   tell/v   you/rzt   you/rzt   can’t/n   do/vyou   it/rzt   ./wj   
If/c   you/rzt   want/v   something/r   ,/wd   go/v   get/v   it/rzt   ./wj   
Period/n   ./wj   

zhout.txt

别/d   让/v   别人/rr   告诉/v   你/rr   你/rr   成/v   不/d   了/ule   才/d   ,/wd   即使/c   是/vshi   我/rr   也/d   不行/a   。/wj   
如果/c   你/rr   有/vyou   梦想/n   的/ude1   话/n   ,/wd   就要/d   去/vf   捍卫/v   它/rr   。/wj   
那些/rz   一事无成/vl   的/ude1   人/n   想/v   告诉/v   你/rr   你/rr   也/d   成/v   不/d   了/ule   大器/n   。/wj   
如果/c   你/rr   有/vyou   理想/a   的/ude1   话/n   ,/wd   就要/d   去/vf   努力/ad   实现/v   。/wj   
就/p   这样/rzv   。/wj   

使用FudanDNN进行分词及词性标注

1、下载并解压
http://homepage.fudan.edu.cn/zhengxq/deeplearning/

2、测试类
cn.edu.fudan.flow.PosTaggerStart

3、测试例子
zh.txt

别让别人告诉你你成不了才,即使是我也不行。
如果你有梦想的话,就要去捍卫它。
那些一事无成的人想告诉你你也成不了大器。
如果你有理想的话,就要去努力实现。
就这样。

4、测试结果
zhout.txt

别让/V 别人/PN 告诉/V 你/PN 你/PN 成/V 不/AD 了/V 才/NN ,/PU 即使/C 是/V 我/PN 也/AD 不行/V 。/PU 
如果/C 你/PN 有/V 梦想/NN 的/U 话/NN ,/PU 就要/AD 去/V 捍卫/V 它/PN 。/PU 
那些/PN 一事无成/I 的/U 人/NN 想/V 告诉/V 你/PN 你/PN 也/AD 成/V 不/AD 了/V 大器/NN 。/PU 
如果/C 你/PN 有/V 理想/JJ 的/U 话/NN ,/PU 就要/AD 去/V 努力/JJ 实现/V 。/PU