文章目录
- 分词方法
- 规则分词
- 统计分词
- 混合分词
- 代码实现
- 自定义字典
- jieba 核心代码
- hanlp
分词方法
英文单词天然以空格分隔,汉语对词的构成边界
很难进行界定。
中文分词(Chinese Word Segmentation)方法可归纳为
- 规则分词
- 统计分词
- 混合分词(规则+统计)
规则分词
人工设立词库,按照一定方式进行匹配切分
优点:简单高效
缺点:无法处理未录入词库的新词(未登陆词)
需要不断维护和更新词典;在切分语句时,将语句的每个字符串 与词表中的每个词 进行逐一匹配,找到则切分,找不到则不予切分。
匹配方法:
- 正向最大匹配(Maximum Match),简称为MM法
- 逆向最大匹配,简称为RMM法
从被处理文档的末端开始匹配扫描,每次取最末端的m个字符。
由于汉语中偏正结构较多,逆向匹配可以适当提高精确度。 - 双向最大匹配
将MM 得到的分词结果,和RMM 得到的结果进行比较,按照最大匹配原则,选取词数切分最少的作为结果。
统计分词
随着机器学习技术发展而流行。
主要思想:把每个词看作 由词的各个字组成的,如果相连的字在不同的文本中出现的次数越多,就证明 这相连的字很可能就是一个词。
实现步骤
- 建立统计语言模型;
- 对句子进行 单词划分,然后对划分结果进行概率计算,获得概率最大的分词方式。
这里用到了统计学习算法,如 HMM、CRF 等。
神经网络分词算法 是深度学习方法在NLP上的应用。通常采用CNN、LSTM等深度学习网络 自动发现一些 模式和特征,然后结合CRF、softmax等分类算法进行分词预测。
- 优点:容易发现新词
不用耗费人力维护词典;较好的处理未登陆词。 - 缺点:太过于依赖语料的质量;计算量相较于规则分词要大得多。
混合分词
最常见的方式就是先基于词典的方式进行分词,然后再用统计分词方法进行辅助。如此,能在保证词典分词准确率的基础上,对未登录词和歧义词有较好的识别。
Jieba分词工具便是基于这种方法实现的。
代码实现
问题
- 当分词工具分词不准确时,该怎么办?
加载自定义字典?该如何加载?
加载字典也不行,使用正则匹配 - 当分词字典的词冲突,相互影响该怎么办?
调整词频和字典顺序
自定义字典
jieba 核心代码
import jieba
jieba.load_userdict("dict.txt") # 创建文件 dict.txt,然后加载自定义字典
dict.txt 中一个词占一行,以换行符分割,如:
三聚氰胺
色甘酸钠
硫磺酸
如果使用了字典,还不会被单独切出,可以使用 jieba.suggest_freq 函数调整词频
jieba.suggest_freq('台中', tune=True)
多个词
fp=open("dict.txt",'r',encoding='utf8')
for line in fp:
line=line.strip()
jieba.suggest_freq(line, tune=True)
使用一句话标识:
[jieba.suggest_freq(line.strip(), tune=True) for line in open("dict.txt", 'r', encoding='utf8')]
hanlp
修改 hanlp.properties
文件的 CustomDictionaryPath 键,如下:
CustomDictionaryPath=data/dictionary/custom/CustomDictionary.txt; 现代汉语补充词库.txt; 全国地名大全.txt ns; 人名词典.txt; 机构名词典.txt; resume_nouns.txt; 上海地名.txt ns;data/dictionary/person/nrf.txt nrf;
还需要删除缓存的 bin 文件,否则可能不生效。
如果字典里有两个词,后者是前者子集。比如 数据库设计
和 数据库
。
hanlp 会按照字典内部词的加载顺序来决定切词。所以将 数据库设计
放在 数据库
前面。以下代码将字典文件中的词进行排序。
#encoding=utf8
import os
dict_file=open("module"+os.sep+"hanlp"+os.sep+"data"+os.sep+"dictionary"+os.sep+"custom"+os.sep+"resume_nouns.txt",'r',encoding='utf8')
d={}
[d.update({line:len(line.split(" ")[0])}) for line in dict_file]
f=sorted(d.items(), key=lambda x:x[1], reverse=True)
dict_file = open("module" + os.sep + "hanlp" + os.sep + "data" + os.sep + "dictionary" + os.sep + "custom" + os.sep + "resume_nouns1.txt", 'w', encoding='utf8')
[dict_file.write(item[0]) for item in f]
dict_file.close()
os.sep 可以适配不同环境下的分隔符