【文字挖掘】——中文分詞
中文分詞
一、分詞演算法
分詞演算法主要有基於字串的匹配和基於統計和機器學習的分詞
1.基於字串的匹配:以現有的詞典為基礎進行,掃描字串,若發現字串的子串和詞相同,即為匹配,通常加入一些啟發式規則:正向/反向最大匹配、長詞優先等。
{
①
最
大
匹
配
法
:
以
設
定
的
最
大
詞
長
度
為
框
架
,
取
出
其
中
最
長
的
匹
配
詞
。
如
:
“
中
國
共
產
黨
”
會
被
完
整
取
出
,
而
不
會
被
進
一
步
分
詞
②
最
大
概
率
法
:
對
句
子
整
體
進
行
分
詞
,
找
到
最
佳
的
詞
匯
排
列
組
合
規
律
。
如
:
“
中
午
好
“
會
被
分
詞
為
“
中
午
”
/
“
好
”
③
最
短
路
徑
分
詞
法
:
尋
找
單
詞
數
最
少
的
分
詞
方
法
\left\{ \begin{aligned}& ①最大匹配法:以設定的最大詞長度為框架,取出其中最長的匹配詞。 如:“中國共產黨”會被完整取出,而不會被進一步分詞\\ \\&②最大概率法:對句子整體進行分詞,找到最佳的詞彙排列組合規律。如:“中午好“會被分詞為“中午”/“好” \\ \\&③最短路徑分詞法:尋找單詞數最少的分詞方法 \end{aligned} \right.
優點:速度快
缺點:無法很好處理歧義和未登入詞。如:我個人認為這個方案很好;兩個人認為這個方案很好。
2.基於統計和機器學習的分詞方式:基於人工標註的詞性和統計特徵進行建模,通過模型計算分詞概率,如:隱馬爾科夫模型、條件隨機場等。
優點:對歧義和未登入詞處理效果更好
缺點:很顯然,它需要大量人工標註。且其分詞速度也較慢。
二、分詞的難點
①分詞歧義
如:我個人認為這個方案很好;一個人認為這個方案很好
②未登入詞
包括:數字、實體名稱、專業術語、成語、虛詞、語氣詞
三、常見分詞工具
- 中科院計算機所的NLPIR
- ansj分詞器
- 哈工大的LTP
- 清華大學的THULAC
- 斯坦福分詞器
- 結巴分詞(最常用)
四、結巴分詞模式
結巴分詞三種模式:精確模式、全模式、搜尋引擎模式
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格式的檔案,格式如下:每行放一個詞:包括:詞、詞頻(可省略)、詞性(可省略)。
利用jieba.load_userdict(“filename”)匯入詞典,其中filename為詞典所在路徑及其名稱。
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')]