分词算法主要有基于字符串的匹配和基于统计和机器学习的分词
1.基于字符串的匹配:以现有的词典为基础进行,扫描字符串,若发现字符串的子串和词相同,即为匹配,通常加入一些启发式规则:正向/反向最大匹配、长词优先等。
{ ① 最 大 匹 配 法 : 以 设 定 的 最 大 词 长 度 为 框 架 , 取 出 其 中 最 长 的 匹 配 词 。 如 : “ 中 国 共 产 党 ” 会 被 完 整 取 出 , 而 不 会 被 进 一 步 分 词 ② 最 大 概 率 法 : 对 句 子 整 体 进 行 分 词 , 找 到 最 佳 的 词 汇 排 列 组 合 规 律 。 如 : “ 中 午 好 “ 会 被 分 词 为 “ 中 午 ” / “ 好 ” ③ 最 短 路 径 分 词 法 : 寻 找 单 词 数 最 少 的 分 词 方 法 \left\{ \begin{aligned}& ①最大匹配法:以设定的最大词长度为框架,取出其中最长的匹配词。 如:“中国共产党”会被完整取出,而不会被进一步分词\\ \\&②最大概率法:对句子整体进行分词,找到最佳的词汇排列组合规律。如:“中午好“会被分词为“中午”/“好” \\ \\&③最短路径分词法:寻找单词数最少的分词方法 \end{aligned} \right. ⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧①最大匹配法:以设定的最大词长度为框架,取出其中最长的匹配词。如:“中国共产党”会被完整取出,而不会被进一步分词②最大概率法:对句子整体进行分词,找到最佳的词汇排列组合规律。如:“中午好“会被分词为“中午”/“好”③最短路径分词法:寻找单词数最少的分词方法
优点:速度快
缺点:无法很好处理歧义和未登录词。如:我个人认为这个方案很好;两个人认为这个方案很好。
2.基于统计和机器学习的分词方式:基于人工标注的词性和统计特征进行建模,通过模型计算分词概率,如:隐马尔科夫模型、条件随机场等。
优点:对歧义和未登录词处理效果更好
缺点:很显然,它需要大量人工标注。且其分词速度也较慢。
①分词歧义
如:我个人认为这个方案很好;一个人认为这个方案很好
②未登录词
包括:数字、实体名称、专业术语、成语、虚词、语气词
结巴分词三种模式:精确模式、全模式、搜索引擎模式
Jieba库的安装毫无压力,简单粗暴:在Anaconda prompt直接pip install jieba即可
① 精确模式:默认模式;将句子最精确地分开,适用于文本分析
import jieba
t="我是小菜鸟,我也太难了吧"
res=jieba.cut(t,cut_all=False, HMM=False)#精确模式
print(res)#是一个可迭代的generator,可以用for循环来遍历结果,本质上类似list
print('/ '.join(res))#输出用/分隔的分词结果
>> 我/ 是/ 小/ 菜鸟/ ,/ 我/ 也/ 太/ 难/ 了/ 吧
可以看到cut分词后返回的是一个可迭代的generator,可以使用 for 循环来获得分词后得到的每一个词语,即:
res=jieba.cut(t,cut_all=False, HMM=False)
list(word for word in res)
>>['我', '是', '小', '菜鸟', ',', '我', '也', '太', '难', '了', '吧']
也可以利用lcut直接输出为list:
print(jieba.lcut(t,cut_all=False, HMM=False))#直接输出为list
>>['我', '是', '小', '菜鸟', ',', '我', '也', '太', '难', '了', '吧']
在精确模式中可以选择是否使用HMM: HMM=False时,按Unigram语法模型找出联合概率最大的分词组合,实现函数为__cut_DAG;HMM=True时,在联合概率最大的分词组合的基础上,HMM识别未登录词,实现函数为__cut_DAG_NO_HMM。
② 全模式:把所有可以组成词的词语都划分出来。速度很快,但存在歧义问题,会产生噪声
res=jieba.cut(t,cut_all=True, HMM=_)#全模式
print('/'.join(res))
>>我/是/小菜/菜鸟/,/我/也/太/难/了/吧
发现结果中有一个“小菜”但这并不是我们想要的,因此产生了噪声。
③ 搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,会产生噪声。适用于搜索引擎分词
res=jieba.cut_for_search(t)#搜索引擎模式
print('/'.join(res))
>>我/是/小/菜鸟/,/我/也/太难/了/吧
在有些情况下,按照默认设定可能会出现一些划分错误,如:“太难了”在原文中想表示一个长词,但在默认设定下它被划分为“太”、“难"、”了“三部分。因此我们需要对默认词典中添加该词,使其分词正确。
1.动态增删新词
根据分词结果对内存中的词库进行更新:利用add_word(word,freq,tag)进行增加新词,利用del_word(word)删除指定词。其中word代表要添加/删除的词,freq表示词频(可省略),tag为词性(可省略)。
#修改词典
jieba.add_word("太难了")
'/'.join(jieba.cut(t))
>>'我/是/小/菜鸟/,/我/也/太难了/吧'
jieba.del_word("太难了")
'/'.join(jieba.cut(t))
>>'我/是/小/菜鸟/,/我/也/太难/了/吧'
2.使用自定义词典
当要添加的词很多时,我们总不能一个一个挨着加吧!因此我们通常会事先准备一个词典,将所有想要添加的词放进去。词典是一个txt格式的文件,格式如下:每行放一个词:包括:词、词频(可省略)、词性(可省略)。
tyc=pd.read_csv('D:/zwz/停用词.txt',names=['w'],sep="aaa",encoding='utf-8')
res=[w for w in jieba.cut(chapter.txt[1]) if w not in list(tyc.w)]
res=[w for w in jieba.cut(t) if w not in [',']]
print(res)
>>['我', '是', '小', '菜鸟', '我', '也', '太难了', '吧']
3.使用搜狗细胞词库
那么问题来了,词典我们需要自己一行一行敲吗?哦~好累,还好有现成的,搜狗细胞词库为我们提供了很多词典,可从其中进行下载使用。导入词典后,词典一直有效,直到关闭了python或者reload。
在分词后得到的词表是不能直接使用的,因为可以发现做词频统计时,频率最高的是一些对我们分析文本没有什么用处的词,如:的、得、地等。因此需要先去除这些无关的停用词。
常见的停用词:
1.分词后去除停用词
其思想为:先进行分词,然后利用停用词表对分词结果进行去除停用词
#去除停用词
import pandas as pd
tyc=pd.read_csv('D:/zwz/停用词.txt',names=['w'],sep="aaa",encoding='utf-8')
tyc.head()
res=[w for w in jieba.cut(t) if w not in list(tyc.w)]
print(res)
>>['菜鸟', '太难了']
2.extract_tags函数去除停用词
利用TF-IDF算法(暂时还不会这个算法,待学习ing)将特征词提取出来,在提取之前去除停用词
import jieba.analyse as ana
ana.set_stop_words('D:/zwz/停用词.txt')#导入我们事先准备的停用词表
ana.extract_tags(t,topK=20)#topK=20表示取前多少个词
>>['菜鸟', '太难了']
该方法使用时有一个问题即:停用词要在分词中正确分出,才能被剔除
为了后续的一些选词处理,现需要对每个词进行词性标注,可利用jieba的posseg进行。
import jieba.posseg as psg
psg.lcut(t)#注意这里要用posseg 下的cut和lcut
>>[pair('我', 'r'),
pair('是', 'v'),
pair('小', 'a'),
pair('菜鸟', 'n'),
pair(',', 'x'),
pair('我', 'r'),
pair('也', 'd'),
pair('太难了', 'x'),
pair('吧', 'y')]