中文分詞(Chinese Word Segmentation),將中文語句切割成單獨的詞組。英文使用空格來分開每一個單詞的,而中文單獨一個漢字跟詞有時候徹底不是同個含義,所以,中文分詞相比英文分詞難度高不少。app
分詞主要用於NLP 天然語言處理(Natural Language Processing),使用場景有:dom
搜索優化,關鍵詞提取(百度指數) 語義分析,智能問答系統(客服系統) 非結構化文本媒體內容,如社交信息(微博熱榜) 文本聚類,根據內容生成分類(行業分類)機器學習
Python的中文分詞庫有不少,常見的有:性能
jieba(結巴分詞)學習
THULAC(清華大學天然語言處理與社會人文計算實驗室)測試
pkuseg(北京大學語言計算與機器學習研究組)字體
SnowNLP優化
pynlpirui
CoreNLP搜索引擎
pyltp
一般前三個是比較常常見到的,主要在易用性/準確率/性能都還不錯。我我的經常使用的一直都是結巴分詞(比較早接觸),最近使用pkuseg,二者的使用後面詳細講。
「結巴」中文分詞:作最好的 Python 中文分詞組件
支持三種分詞模式:
精確模式,試圖將句子最精確地切開,適合文本分析;
全模式,把句子中全部的能夠成詞的詞語都掃描出來, 速度很是快,可是不能解決歧義;
搜索引擎模式,在精確模式的基礎上,對長詞再次切分,提升召回率,適合用於搜索引擎分詞。
支持繁體分詞
支持自定義詞典
咱們使用京東商場的美的電器評論來看看結巴分詞的效果。若是你沒有安裝結巴分詞庫則須要在命令行下輸入pip install jieba,安裝完以後便可開始分詞之旅。
評論數據整理在文件meidi_jd.csv文件中,讀取數據前先導入相關庫。由於中文的文本或文件的編碼方式不一樣編碼選擇gb18030,有時候是utf-八、gb23十二、gbk自行測試。
# 導入相關庫 import pandas as pd import jieba # 讀取數據 data = pd.read_csv('meidi_jd.csv', encoding='gb18030') # 查看數據 data.head()
# 生成分詞 data['cut'] = data['comment'].apply(lambda x : list(jieba.cut(x))) data.head()
到這裏咱們僅僅經過一行代碼便可生成中文的分詞列表,若是你想要生成分詞後去重能夠改爲這樣。
data['cut'] = data['comment'].apply(lambda x : list(set(jieba.cut(x)))) ['很', '好', '很', '好', '很', '好', '很', '好', '很', '好', '很', '好', '很', '好', '很', '好', '很', '好', '很', '好', '很', '好']
這時候咱們就須要導入自定義的詞典,以便包含 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()
接下里咱們只要適當更改分詞的代碼便可在分詞的時候去掉停用詞:
# 轉化詞列表
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()
到這裏咱們基本是已經學會用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)
# 導入相關庫 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並無提供細分領域預訓練模型,若是想使用自定義模型分詞需使用它們提供的訓練接口在細分領域的數據集上進行訓練,用訓練獲得的模型進行中文分詞。
import jieba import jieba.analyse import codecs import re from collections import Counter from wordcloud import WordCloud import matplotlib.pyplot as plt import wordcloud str = "我在河南大學上學,今年22歲了" seg_list = jieba.cut(str,cut_all=True) print("全模式:"+"/".join(seg_list)) seg_list = jieba.cut(str,cut_all=False) print("默認(精確模式):"+"/".join(seg_list)) # 搜索引擎模式 seg_list = jieba.cut_for_search(str) print("搜索引擎模式:"+"/".join(seg_list)) # 添加用戶自定義詞典 str = "大連聖亞在大連" seg_list = jieba.cut(str,cut_all=False) print("默認(精確模式):"+"/".join(seg_list)) # 添加自定義詞典後 jieba.load_userdict(r"./user_dict.txt") seg_list = jieba.cut(str,cut_all=False) print("默認(精確模式):"+"/".join(seg_list)) str = "我家在河南省駐馬店市汝南縣東官莊鎮" seg_list = jieba.cut(str) #默認是精確模式 print("精確模式:"+"/".join(seg_list)) # 動態調整詞典 jieba.add_word("東官莊鎮") seg_list = jieba.cut(str) print("精確模式:"+"/".join(seg_list)) # 加載停用詞 # 建立停用詞列表 def stopwordlist(): stopwords = [line.strip() for line in open('./hit_stopwords.txt',encoding='UTF-8').readlines()] return stopwords # 對句子進行中文分詞 def seg_depart(sentence): print('正在分詞') sentence_depart = jieba.cut(sentence.strip()) # 建立一個停用詞列表 stopwords = stopwordlist() # 輸出結果爲 outstr outstr = '' # 去停用詞 for word in sentence_depart: if word not in stopwords: if word != '\t': outstr += word outstr += " " return outstr # 給出文檔路徑 filename = "./text.txt" outfilename = "./out.txt" inputs = open(filename,'r',encoding='UTF-8') outputs = open(outfilename,'w',encoding='UTF-8') jieba.add_word("停用詞") # 將輸出結果寫到out.txt中 for line in inputs: line_seg = seg_depart(line) outputs.write(line_seg + '\n') print("-------------------------正在分詞和去停用詞--------------------------") print("原文:"+line) print("去停用詞:"+line_seg) outputs.close() inputs.close() print("刪除停用詞和分詞成功!!!") # class WordCounter(object): def count_from_file(file,top_limit=0): with codecs.open(file,'r','UTF-8') as f: content = f.read() # 將多個空格替換爲一個空格 content =re.sub(r'\s+',r' ',content) content = re.sub(r'\.+',r' ',content) # 去停用詞 content = seg_depart(content) return count_from_str(content,top_limit=top_limit) def count_from_str(content,top_limit=0): if top_limit <= 0: top_limit = 100 # 提取文章的關鍵詞 tags = jieba.analyse.extract_tags(content,topK=100) words = jieba.cut(content) counter = Counter() for word in words: if word in tags: counter[word] += 1 return counter.most_common(top_limit) # if __name__ == '__main__': # counter = WordCounter() # retult = counter.count_from_file(r'./text.txt',top_limit=10) # print(retult) print("打印詞頻==============") retult = count_from_file(r'./text.txt',top_limit=10) print(retult) print("*"*100) # 例子 # sentence = 'Ilikeyou ' # wc = wordcloud.WordCloud() # pic = wc.generate(sentence) # plt.imshow(pic) # plt.axis("off") # plt.show() # wc.to_file('test.png') print("分詞並生成詞雲圖") def create_word_cloud(file): content = codecs.open(file,'r','UTF-8').read() # 結巴分詞 wordlist = jieba.cut(content) wl = " ".join(wordlist) print(wl) # 設置詞雲圖 wc = wordcloud.WordCloud( # 設置背景顏色 background_color='pink', # 設置最大顯示的詞數 max_words=100, # 設置字體路徑 font_path = 'C:\Windows\Fonts\msyh.ttc', height = 1200, width=1600, # 設置字體最大值 max_font_size=300, # 設置有多少種配色方案,即多少種隨機生成狀態 random_state=30, ) # 生成詞雲圖 myword = wc.generate(wl) # 展現詞雲圖 plt.imshow(myword) plt.axis("off") plt.show() wc.to_file('py_pic.png') # content = codecs.open("./text.txt",'r','UTF-8').read() create_word_cloud("text.txt")