1. 程式人生 > 其它 >【文字挖掘】——中文分詞

【文字挖掘】——中文分詞

技術標籤:筆記資料分析資料探勘

中文分詞

一、分詞演算法

  分詞演算法主要有基於字串的匹配和基於統計和機器學習的分詞

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')]