1. 程式人生 > 程式設計 >Python中文分詞庫jieba,pkusegwg效能準確度比較

Python中文分詞庫jieba,pkusegwg效能準確度比較

Python中文分詞庫jieba,pkusegwg效能準確度比較

中文分詞(Chinese Word Segmentation),將中文語句切割成單獨的片語。英文使用空格來分開每個單詞的,而中文單獨一個漢字跟詞有時候完全不是同個含義,因此,中文分詞相比英文分詞難度高很多。

分詞主要用於NLP 自然語言處理(Natural Language Processing),使用場景有:

  • 搜尋優化,關鍵詞提取(百度指數)
  • 語義分析,智慧問答系統(客服系統)
  • 非結構化文字媒體內容,如社交資訊(微博熱榜)
  • 文字聚類,根據內容生成分類(行業分類)

Python的中文分詞

Python的中文分詞庫有很多,常見的有:

  • jieba(結巴分詞)
  • THULAC(清華大學自然語言處理與社會人文計算實驗室)
  • pkuseg(北京大學語言計算與機器學習研究組)
  • SnowNLP
  • pynlpir
  • CoreNLP
  • pyltp

通常前三個是比較經常見到的,主要在易用性/準確率/效能都還不錯。我個人常用的一直都是結巴分詞(比較早接觸),最近使用pkuseg,兩者的使用後面詳細講。

結巴分詞

簡介

“結巴”中文分詞:做最好的 Python 中文分片語件

  • 支援三種分詞模式:
    • 精確模式,試圖將句子最精確地切開,適合文字分析;
    • 全模式,把句子中所有的可以成詞的詞語都掃描出來,速度非常快,但是不能解決歧義;
    • 搜尋引擎模式,在精確模式的基礎上,對長詞再次切分,提高召回率,適合用於搜尋引擎分詞。
  • 支援繁體分詞
  • 支援自定義詞典

jieba分詞例項

我們使用京東商場的美的電器評論來看看結巴分詞的效果。如果你沒有安裝結巴分詞庫則需要在命令列下輸入pip install jieba,安裝完之後即可開始分詞之旅。

評論資料整理在檔案meidi_jd.csv檔案中,讀取資料前先匯入相關庫。因為中文的文字或檔案的編碼方式不同編碼選擇gb18030,有時候是utf-8、gb2312、gbk自行測試。

# 匯入相關庫
import pandas as pd
import jieba

# 讀取資料
data = pd.read_csv('meidi_jd.csv',encoding='gb18030')

# 檢視資料
data.head()

Python中文分詞庫jieba,pkusegwg效能準確度比較

# 生成分詞
data['cut'] = data['comment'].apply(lambda x : list(jieba.cut(x)))

data.head()

Python中文分詞庫jieba,pkusegwg效能準確度比較

到這裡我們僅僅通過一行程式碼即可生成中文的分詞列表,如果你想要生成分詞後去重可以改成這樣。

data['cut'] = data['comment'].apply(lambda x : list(set(jieba.cut(x))))

自定義詞典

經過前面的分詞後,我們可以通過檢視分詞是否準確,會發現實際上有些詞被分隔成單獨的漢字,例如:

print(data['cut'].loc[14])

['很','好','很','好']

這時候我們就需要匯入自定義的詞典,以便包含 jieba 詞庫裡沒有的詞。雖然 jieba 有新詞識別能力,但是自行新增新詞可以保證更高的正確率。自定義詞典採用一詞一行,為了演示我添加了“很好”並儲存在dict.txt檔案中,讓我們開始用自定義的詞典吧!

data['cut'] = data['comment'].apply(lambda x : list(jieba.cut(x)))

data.head()

print(data['cut'].loc[14])

['很好','很好','很好']

現在已經按照我們計劃的正確分詞出來了!很好!

停用詞

分詞的過程中我們會發現實際上有些詞實際上意義不大,比如:標點符號、嗯、啊等詞,這個時候我們需要將停用詞去除掉。首先我們需要有個停用詞片語,可以自定義也可以從網上下載詞庫,這裡我們使用網上下載的停用詞檔案StopwordsCN.txt。

# 讀取停用詞資料
stopwords = pd.read_csv('StopwordsCN.txt',encoding='utf8',names=['stopword'],index_col=False)

stopwords.head()

Python中文分詞庫jieba,pkusegwg效能準確度比較

接下里我們只要適當更改分詞的程式碼即可在分詞的時候去掉停用詞:

# 轉化詞列表
stop_list = stopwords['stopword'].tolist()

# 去除停用詞
data['cut'] = data['comment'].apply(lambda x : [i for i in jieba.cut(x) if i not in stop_list])

data.head()

pkuseg

pkuseg簡單易用,支援細分領域分詞,有效提升了分詞準確度。

簡介

pkuseg具有如下幾個特點:

  1. 多領域分詞。不同於以往的通用中文分詞工具,此工具包同時致力於為不同領域的資料提供個性化的預訓練模型。根據待分詞文字的領域特點,使用者可以自由地選擇不同的模型。 我們目前支援了新聞領域,網路文字領域和混合領域的分詞預訓練模型,同時也擬在近期推出更多的細領域預訓練模型,比如醫藥、旅遊、專利、小說等等。
  2. 更高的分詞準確率。相比於其他的分詞工具包,當使用相同的訓練資料和測試資料,pkuseg可以取得更高的分詞準確率。
  3. 支援使用者自訓練模型。支援使用者使用全新的標註資料進行訓練。

注:pkuseg目前僅支援Python3,目前已經很多主流庫開始不支援Python2,建議使用Python3版本,如需使用Python2可建立虛擬環境來搭建。

Python中文分詞庫jpkuseg例項

pkuseg的使用跟結巴分詞有一點不一樣,pkuseg需要先建立模型例項再使用例項方法cut。前面有提到pkuseg是支援載入與訓練模型的,這也大大提高了分詞準確性,特別是對細分領域資料集進行分詞,詳細檢視GitHub文件。

import pkuseg

# 以預設配置載入模型
seg = pkuseg.pkuseg() 

# 進行分詞
data['cut'] = data['comment'].apply(lambda x: [i for i in seg.cut(x) if i not in stop_list])

data.head()

Python中文分詞庫jieba,pkusegwg效能準確度比較

自定義詞典

同樣的,pkuseg也支援自定義詞典來提高分詞準確率。

# 使用預設模型,並使用自定義詞典
seg = pkuseg.pkuseg(user_dict='dict.txt') 

# 進行分詞
data['cut'] = data['comment'].apply(lambda x: [i for i in seg.cut(x) if i not in stop_list])

print(data['cut'].loc[14])

自定義預訓練模型

分詞模式下,使用者需要載入預訓練好的模型。pkuseg提供三種不同資料型別訓練得到的模型。

  • MSRA: 在MSRA(新聞語料)上訓練的模型。下載地址
  • CTB8: 在CTB8(新聞文字及網路文字的混合型語料)上訓練的模型。下載地址
  • WEIBO: 在微博(網路文字語料)上訓練的模型。下載地址
  • MixedModel: 混合資料集訓練的通用模型。隨pip包附帶的是此模型。下載地址
# 下載後解壓出來,並複製資料夾路徑
file_path = '/Users/jan/anaconda3/lib/python3.6/site-packages/pkuseg/ctb8'

# 載入其他預訓練模型
seg = pkuseg.pkuseg(model_name=file_path)

text = seg.cut('京東商城信得過,買的放心,用的省心、安心、放心!')

print(text)

jieba與pkusegwg效能對比

結巴的分詞速度說明比較簡單,描述中也沒有效能對比,更像是分詞內容和環境。。

  • 1.5 MB / Second in Full Mode
  • 400 KB / Second in Default Mode
  • 測試環境: Intel(R) Core(TM) i7-2600 CPU @ 3.4GHz;《圍城》.txt

相比之下pkuseg選擇jieba、THULAC等國內代表分詞工具包與pkuseg做效能比較。以下是在不同資料集上的對比結果:

Python中文分詞庫jieba,pkusegwg效能準確度比較

從結果看pkuseg在精確度、召回率和F分數上表現得相當不錯。效能方面我使用jupyter notebook進行簡單測試。

%%timeit
data['cut'] = data['comment'].apply(lambda x : [i for i in jieba.cut(x) if i not in stop_list])
%%timeit
data['cut'] = data['comment'].apply(lambda x: [i for i in seg.cut(x) if i not in stop_list])

輸出結果:

結巴:2.54 s ± 3.77 ms per loop (mean ± std. dev. of 7 runs,1 loop each)

pkuseg:7.45 s ± 68.9 ms per loop (mean ± std. dev. of 7 runs,1 loop each)

從資料結果上看,pkuseg分詞的時間要高於結巴分詞的時間,當然pkuseg提供多程序來進行分詞,效能方面也是可以提高的。

詞頻統計

到這裡我們基本是已經學會用Python庫進行分詞,關於詞頻統計的方式也很多,我們先將所有分詞合併在一起方便統計。

# 將所有的分詞合併
words = []

for content in data['cut']:
  words.extend(content)

方式一:

# 建立分詞資料框
corpus = pd.DataFrame(words,columns=['word'])
corpus['cnt'] = 1

# 分組統計
g = corpus.groupby(['word']).agg({'cnt': 'count'}).sort_values('cnt',ascending=False)

g.head(10)

Python中文分詞庫jieba,pkusegwg效能準確度比較

方式二:

# 匯入相關庫
from collections import Counter
from pprint import pprint
counter = Counter(words)

# 列印前十高頻詞
pprint(counter.most_common(10))

[('不錯',3913),

('安裝',3055),

('好',2045),

('很好',1824),

('買',1634),

('熱水器',1182),

('挺',1051),

('師傅',923),

('美',894),

('送貨',821)]

結尾

我個人的使用建議,如果想簡單快速上手分詞可以使用結巴分詞,但如果追求準確度和特定領域分詞可以選擇pkuseg載入模型再分詞。另外jieba和THULAC並沒有提供細分領域預訓練模型,如果想使用自定義模型分詞需使用它們提供的訓練介面在細分領域的資料集上進行訓練,用訓練得到的模型進行中文分詞。

更多關於Python中文分詞庫jieba,pkusegwg的相關文章可以點選下面的相關連結