pyhanlp 中文词性标注与分词简介
pyhanlp实现的分词器有很多,同时pyhanlp获取hanlp中分词器也有两种方式
第一种是直接从封装好的hanlp类中获取,这种获取方式一共可以获取五种分词器,而现在默认的就是第一种维特比分词器
1.维特比 (viterbi):效率和效果的最佳平衡。也是最短路分词,HanLP最短路求解采用Viterbi算法
2.双数组trie树 (dat):极速词典分词,千万字符每秒(可能无法获取词性,此处取决于你的词典)
3.条件随机场 (crf):分词、词性标注与命名实体识别精度都较高,适合要求较高的NLP任务
4.感知机 (perceptron):分词、词性标注与命名实体识别,支持在线学习
5.N最短路 (nshort):命名实体识别稍微好一些,牺牲了速度
第二种方式是使用JClass直接获取java类,然后使用。这种方式除了获取上面的五种分词器以外还可以获得一些其他分词器,如NLP分词器,索引分词,快速词典分词等等
两种使用方式的对比
第一种是使用作者给的HanLP直接获取分词器,直接segment() 会获取 默认的标准分词器也就是维特比分词器,也**可以使用newSegment函数,传入上面的分词器英文名称来获取新的分词器,如使用HanLP.newSegment("crf")来获取CRF分词器。**第二种方式是使用JClass从java中获取我们想要的类,好在这两种方式都比较方便。除此之外要注意的是,在pyhanlp中还给出了SafeJClass类,其为JClass的线程安全版,你也可以使用SafeClass来代替JClass。不过好在HanLP中的很多类本身已经实现了线程安全,因此许多时候两者是可以相互替代的。
[你好/vl, ,/w, 欢迎/v, 使用/v, HanLP/nx, 汉语/gi, 处理/vn, 包/v, !/w, 接下来/vl, 请/v, 从/p, 其他/rzv, Demo/nx, 中/f, 体验/v, HanLP/nx, 丰富/a, 的/ude1, 功能/n, ~/nx]
# 标准分词
text = (
"举办纪念活动铭记二战历史,不忘战争带给人类的深重灾难,是为了防止悲剧重演,确保和平永驻;记二战历史,更是为了提醒国际社会,需要共同捍卫二战胜利成果和国际公平正义,必须警惕和抵制在历史认知和维护战后国际秩序问题上的倒行逆施。"
)
BasicTokenizer = JClass("com.hankcs.hanlp.tokenizer.BasicTokenizer")
print(BasicTokenizer.segment(text))
import time
start = time.time()
for i in range(100000):
HanLP.segment(text)
cost_time = time.time() - start
print("HanLP.segment :%.2f字每秒" % (len(text) * 100000 / cost_time))
start = time.time()
for i in range(100000):
BasicTokenizer.segment(text)
cost_time = time.time() - start
print("BasicTokenizer.segment :%.2f字每秒" % (len(text) * 100000 / cost_time))
[举办/v, 纪念活动/nz, 铭记/v, 二战/n, 历史/n, ,/w, 不忘/v, 战争/n, 带给/v, 人类/n, 的/ude1, 深重/a, 灾难/n, ,/w, 是/vshi, 为了/p, 防止/v, 悲剧/n, 重演/v, ,/w, 确保/v, 和平/n, 永驻/nz, ;/w, 记/v, 二战/n, 历史/n, ,/w, 更是/d, 为了/p, 提醒/v, 国际/n, 社会/n, ,/w, 需要/v, 共同/d, 捍卫/v, 二战/n, 胜利/vn, 成果/n, 和/cc, 国际/n, 公平/a, 正义/n, ,/w, 必须/d, 警惕/v, 和/cc, 抵制/v, 在/p, 历史/n, 认知/vn, 和/cc, 维护/v, 战后/t, 国际/n, 秩序/n, 问题/n, 上/f, 的/ude1, 倒行逆施/vl, 。/w]
HanLP.segment :1518389.32字每秒
BasicTokenizer.segment :2415039.64字每秒
仅仅从刚刚的结果看,可能会不太理解为同一个分词器性能差距这么大?难道是因为中间代码的调度问题,其实也不是。将两段代码前后互换之后,发现无论两者怎么排列,总是在前的速度较慢,在后的较快,因此应该是内存的问题,第二次调用时减少了部分内存的调动。所以同一个分词器才会出现,第二次总比第一次快的现象。
标准分词
说明
1.HanLP中有一系列“开箱即用”的静态分词器,以Tokenizer结尾,在接下来的例子中会继续介绍。
2.HanLP.segment其实是对StandardTokenizer.segment的包装。
3.分词结果包含词性,每个词性的意思请查阅《HanLP词性标注集》。
算法详解
1.《词图的生成》
单独获取词性或者词语
如你所见的是,前面print的结果是[词语/词性,词语/词性,/词语/词性…]的形式,那么如果我们只想获取词语,或者词性应该怎么办呢?
方法也很简单。使用HanLP.Config.ShowTermNature = False修改配置,使其不显示词性即可。
如果想要只获取词性也是可以的,因为原分词器返回的是Java中的ArrayList属性,list中的每个单元都是一个term类,因此我们也可以通过获取term中的word字段来直接获取词语,或者nature属性,直接获取词性。这一特征,我们在之后也会用到。
因为HanLP中是默认开启词性标注的,所以在这里我取名为分词与词性标注,但是因为篇幅原因这里没有对词性标注作过多解释,详细内容请看“词性标注(正篇)”
作者:Font Tian