1.中文分词
他说的确实在理
原理:基于大量语料库,利用平均感知机分类器对上面特征做打分,并训练权重系数,这样得出的模型就可以用来分词了,句子右边多出来一个字,用模型计算这些特征的加权得分,得分最高的就是正确的分词方法
基于n元语法模型的方法的优势在于词表里已有的词的分词效果
基于字构词的方法的优势在于未登陆词的识别
流行分词工具
jieba
- 基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG)
- 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合
- 对于未登录词,采用了基于汉字成词能力的 HMM 模型,使用了 Viterbi 算法
- 前两句话是说它是基于词表的分词,最后一句是说它也用了由字构词,所以它结合了两种分词方法
ik分词器
基于词表的最短路径切词
ltp云平台分词
主要基于机器学习框架并部分结合词表的方法
NLPIR汉语分词工具,文档地址:http://pynlpir.readthedocs.io/en/latest/
测试一下NLPIR分词器
import pynlpir
pynlpir.open()
s = '欢迎科研人员、技术工程师、企事业单位与个人参与NLPIR平台的建设工作。'
pynlpir.segment(s)
pynlpir.open()
s = '聊天机器人到底该怎么做呢?'
segments = pynlpir.segment(s)
for segment in segments:
print (segment[0], '\t', segment[1])
key_words = pynlpir.get_key_words(s, weighted=True)
for key_word in key_words:
print (key_word[0], '\t', key_word[1])
s = "猪笼草是如何捕食的?"
调用segment方法指定的pos_names参数可以是’all’, ‘child’, ‘parent’
默认是parent, 表示获取该词性的最顶级词性
child表示获取该词性的最具体的信息
all表示获取该词性相关的所有词性信息,相当于从其顶级词性到该词性的一条路径
可选参数pos_english=False,使用中文输出
segments = pynlpir.segment(s, pos_names='all',pos_english=False)
print("分词:")
for segment in segments:
print (segment[0], '\t', segment[1])
key_words = pynlpir.get_key_words(s, weighted=True)
print("关键词提取:")
for key_word in key_words:
print (key_word[0], '\t', key_word[1])
pynlpir.close()
测试一下jieba
encoding=utf-8
import jieba
seg_list = jieba.cut("我来到北京清华大学", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list)) # 全模式
seg_list = jieba.cut("我来到北京清华大学", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list)) # 精确模式
seg_list = jieba.cut("他来到了网易杭研大厦") # 默认是精确模式
print("Default Mode: " +", ".join(seg_list))
seg_list = jieba.cut_for_search("小明硕士毕业于中国科学院计算所,后在日本京都大学深造") # 搜索引擎模式
print("Search Mode: " + ", ".join(seg_list))
应用:中文单词统计
import jieba
txt = open("..\语料\三国演义.txt", "r", encoding='utf-8').read()
words = jieba.lcut(txt) # 使用精确模式对文本进行分词
counts = {} # 通过键值对的形式存储词语及其出现的次数
for word in words:
if len(word) == 1: # 单个词语不计算在内
continue
else:
counts[word] = counts.get(word, 0) + 1 # 遍历所有词语,每出现一次其对应的值加 1
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True) # 根据词语出现的次数进行从大到小排序
for i in range(3):
word, count = items[i]
print("{0:<5}{1:>5}".format(word, count))
拓展:英文单词统计
def get_text():
txt = open("1.txt", "r", encoding='UTF-8').read()
txt = txt.lower()
for ch in '!"#$%&()*+,-./:;<=>?@[\\]^_‘{|}~':
txt = txt.replace(ch, " ") # 将文本中特殊字符替换为空格
return txt
file_txt = get_text()
words = file_txt.split() # 对字符串进行分割,获得单词列表
counts = {}
for word in words:
if len(word) == 1:
continue
else:
counts[word] = counts.get(word, 0) + 1
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True)
for i in range(5):
word, count = items[i]
print("{0:<5}->{1:>5}".format(word, count))
功能:载入词典
- 开发者可以指定自己自定义的词典,以便包含 jieba 词库里没有的词。虽然 jieba 有新词识别能力,但是自行添加新词可以保证更高的正确率
- 用法: jieba.load_userdict(file_name) # file_name 为文件类对象或自定义词典的路径
- 词典格式和 dict.txt 一样,一个词占一行;每一行分三部分:词语、词频(可省略)、词性(可省略),用空格隔开,顺序不可颠倒。file_name 若为路径或二进制方式打开的文件,则文件必须为 UTF-8 编码。
- 词频省略时使用自动计算的能保证分出该词的词频。
功能:调整词典
- 使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中动态修改词典。
- 使用 suggest_freq(segment, tune=True) 可调节单个词语的词频,使其能(或不能)被分出来。
- 注意:自动计算的词频在使用 HMM 新词发现功能时可能无效。