Python文字處理NLP:分詞與詞雲圖

王平發表於2019-07-08

​昨晚我們又做了一次技術分享,繼續上次技術分享的話題“文字資料的處理”。上次,我們分享了文字處理的方方面面的知識點,比較巨集觀,這次我們就其中的一點“分詞”展開。

文字處理NLP:分詞與詞雲圖

 

一、為什麼要分詞

“行文如流水”形容的是詩文、書法自然流暢不受拘束。這裡我們借用一下就是,中文句子詞彙之間如流水般無縫,不像英文那樣單詞之間用空格分開。比如:

中文:我在猿人學網站上學Python

英文:I learn Python on YuanRenXue.

在程式裡,從英文中得到一個一個單詞很簡單,用Python字串的split()函式就可以搞定。而對於中文做同樣的事情就比較難了,這時候我們就需要一個分詞程式專門搞這件事。

詞彙是語義表達的基本單位。詞語比單個字表達的意思更為精準。在搜尋引擎裡面,建立倒排索引的時候,需要對文字進行分割為一個個的語素,是分成一個一個的字好呢,還是分割成一個個詞好呢?我們來看看下面的例子。

首先,我們先簡單理解一下“倒排索引”這個概念。我們可以把它類比成一個Python的字典,key是索引的語素(字或詞),value是一個包含這個語素的文件ID的列表。下面我們對“我早上在海邊跑步”這句話進行分割、索引,假設這句話的文件ID是1。

按字分割:我/早/上/在/海/邊/跑/步

索引:

按字分詞

在這個索引裡面搜“上海”,先把查詢詞按照索引時同樣的方法分割為“上”和“海”兩個字,然後分別搜這兩個字,索引裡面都包含這兩個字,它們都對應這ID為1的文件,也就是搜尋到了文件ID為1的文件。但是,這句“我早上在海邊跑步”跟“上海”是沒什麼關心的。

也就是說,按字分割索引會讓搜尋引擎搜出很多不相關的結果出來。那麼,按詞索引呢?

按詞分割:我/早上/在/海邊/跑步

建立索引:

分詞結果

從這個索引裡面找“上海”就不能找到,從而不會返回不相關的結果。

 

二、分詞的原理

分詞是一個技術活也是一個累活兒。如果分詞是建立在新聞類的語料基礎上的,它對其它領域比如化工、醫學等等領域的文字的分詞效果往往不會好。這就需要我們對行業領域詞彙進行收集,加入到分詞詞典中,才能得到更好的效果,這個過程是比較累人的。

分詞的方法一般有以下幾種:

1、基於詞典的方法

這個方法樸素而快速,但不能很好的解決歧義和未收錄詞。歧義就是下面這種句子根據詞典可以有多種分割方法:

“結婚/的/和/尚未/結婚/的”

“結婚/的/和尚/未/結婚/的”

未收錄詞就是分詞詞典沒有包含的那些詞,這個問題可以通過不斷擴充套件詞典在某種程度上解決。

2、機器學習的方法

首先,要人工標註大批量的語料給機器學習演算法進行學習。標註的過程要耗費大量人力,標註的語料越多,機器學習的效果越好。機器學習的方法有HMM、CRF,以及近年流行的深度學習。它對歧義和未收錄詞的問題有較好的解決。但是,大量領域語料的缺失,也導致它不能很好的直接應用於其它專業領域。

 

三、jieba分詞工具

上次技術分享中,我們介紹了多款分詞工具。jieba作為一個純Python實現的工具,使用起來非常方便。它支援簡體和繁體分詞,也可以自定義詞典方便我們擴充套件領域詞。

結巴有三種分詞模式:

  1. 精確模式:適合文字分析。此法最常用
  2. 全模式,把句子中所有可能的詞都列出來。基本沒啥用
  3. 搜尋引擎模式:把長詞切分為短詞,讓搜尋引擎提高召回率。建立搜尋引擎的索引時用

安裝jieba很簡單:

pip install jieba

使用結巴進行分詞主要有兩個函式:

jieba.cut(text, cut_all=False, HMM=True)

jieba.cut_for_search(sentence, HMM=True)

其中,cut()函式最為常用。引數cut_all=True的話就開啟了全模式,這種模式幾乎不需要。預設的HMM=True會使用HMM模型嘗試檢測未登入詞。

寫個簡單的程式來測試一下幾種不同的分詞模式:

Python分詞程式碼

得到的結果如下:

精確模式:

猿人/ 學是/ 一個/ 學習/ Python/ 的/ 網站

全模式:

猿人/ 人學/ 是/ 一個/ 學習/ Python/ 的/ 網站

搜尋引擎模式:

猿人/ 學是/ 一個/ 學習/ Python/ 的/ 網站

精確模式下,會把“學是”當做一個詞分出來,這就是HMM計算的結果,當然對於這個例子,它計算錯了。

“猿人學”應該是一個詞,但它沒有分出來。這個時候我們就需要自定義詞典。

新增自定義的詞,有兩種方法:

(1)通過函式新增:

jieba.add_word(‘猿人學’, freq=5, tag=’n’)

可以多次呼叫這個函式,新增更多的詞。

(2)通過詞典檔案:

jieba.load_userdict(file_name)

file_name就是一個詞典檔案的路徑,它是一個文字檔案,每行一個詞,後面可以跟著它的頻率和詞性:

猿人學 8 n

js逆向 7

APP脫殼 n

非同步IO

 

詞性標註

jieba支援詞性標註,具體在它的子模組 jieba.posseg



import jieba.posseg as pseg

words = pseg.cut('我在猿人學學Python')

for word, flag in words:

print('{} {}'.format(word, flag))

我 r

在 p

猿人學 n

學 n

Python eng

詞性標註可以幫助我們更好的篩選文章主題詞(或者叫關鍵詞)。比如,介詞、數量詞不然名詞、動詞的意義更豐富,提取關鍵詞時可以對名詞等賦予更高的權重。

主題詞提取

jieba提供的主題詞提取的功能,具體在 jibba.analyse 子模組。它有兩種演算法的實現,分別是TF-IDF演算法和TextRank演算法。兩者的效果差不多,但後者計算量大很多,比較慢。所以,推薦使用前者。

TF-IDF演算法



jieba.analyse.extract_tags(

text,

topK=20,

withWeight=False,

allowPOS=())

text 為待提取的文字

topK 為返回幾個 TF/IDF 權重最大的關鍵詞,預設值為 20

withWeight 為是否一併返回關鍵詞權重值,預設值為 False

allowPOS 僅包括指定詞性的詞,預設值為空,即不篩選詞-權重

TextRank演算法


jieba.analyse.textrank(

text,

topK=20,

withWeight=False,

allowPOS=('ns', 'n', 'vn', 'v'))

直接使用,介面相同,注意預設過濾詞性。

四、詞雲圖:視覺化主題詞

前面我們通過jieba提取了文章的主題詞,可以使用“詞雲圖”這種方法把它視覺化的表現出來。

Python有個畫詞雲圖的第三方模組:wordcloud。用pip直接安裝:

pip install wordcloud

使用它主要有兩個類:

WordCloud([font_path, width, height, …])

畫詞雲圖的類

ImageColorGenerator(image[, default_color])

從一張彩色圖片中生成詞雲圖的顏色

使用WordCloud類進行詞雲圖繪製過程,需要注意的地方:

中文字型 : 必須指定中文字型,不然中文就畫不出來。

mask :以圖片物體形狀繪製詞雲圖。非物體形狀部分為白色,顏色值為#FFF 或 #FFFFFF

圖片顏色->字型顏色:使用ImageColorGenerator 從mamsk圖片提取顏色,把對應位置的字型顏色設定為同樣的顏色。

下面,我們以Python的logo作為詞雲圖形狀進行繪製。

python logo

文章內容是猿人學網站上的文章《大規模非同步新聞爬蟲的實現思路》,通過jieba提取主題詞,然後進行繪製。程式碼如下 :

python詞雲圖程式碼

執行這段程式碼後,生成了兩個詞雲圖,第一張是隨機生成的字型顏色:

詞雲圖樣式

第二張是根據Python logo 圖片中的顏色繪製字型顏色:

詞雲圖修改顏色

如果你選擇色彩更豐富的圖片,繪製出來的詞雲圖色彩也會更豐富。

這次技術分享,我們把jieba分詞的使用結合例項介紹給大家,最後使用wordcloud做了主題詞的視覺化呈現。

猿人學banner宣傳圖

我的公眾號:猿人學 Python 上會分享更多心得體會,敬請關注。

***版權申明:若沒有特殊說明,文章皆是猿人學 yuanrenxue.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章