系列介紹:文本挖掘比較常見,系列思路:1-基本情況介紹(分詞,詞雲展示);2-根據語料庫的tf-idf值及創建自己的idf文件;3-基於snownlp語料情感分析;4-基於gensim進行lda主題挖掘分析;
本文簡介:對於大量的短文本需要進行分析的話,會使用到分詞及可視化展示,中文分詞沒有明顯的邊界自行處理還不太方便。“結巴”中文分詞是一個優秀的 Python 中文分詞庫,wordcloud是一個詞雲圖庫,對他進行學習,可以快速進行基礎的文本分析。
目的:介紹jieba庫(v0.41)的基本使用,並結合分詞結果進行詞雲展示
讀者:應用用戶。
參考鏈接:
jieba官方介紹:https://github.com/fxsjy/jieba/blob/master/README.md
[python] 使用scikit-learn工具計算文本TF-IDF值:https://blog.csdn.net/eastmount/article/details/50323063
Jieba分詞詞性標注以及詞性說明:https://www.cnblogs.com/zhenyauntg/p/13206473.html
主要內容:
1、jieba庫基本使用
1.1、分詞
1.2、添加自定義詞典
1.3、詞性標注
1.4、基於TF-IDF算法的關鍵字抽取
2、jieba+wordcloud簡單分析
1、jieba庫基本使用
import jieba # 分詞庫 import jieba.posseg as pseg # 詞性標注 import jieba.analyse as analyse # 關鍵字提取
1.1、分詞
jieba庫分詞有三種模型,一般來說,使用默認模式即可。
content = "韓國東大門單鞋女方頭絨面一腳蹬韓版休閑2020春季新款平底毛毛鞋" seg_list = jieba.cut(content, cut_all=True) print("Full Mode: " + "/ ".join(seg_list)) # 全模式 seg_list = jieba.cut(content, cut_all=False) print("Default Mode: " + "/ ".join(seg_list)) # 默認模式 seg_list = jieba.cut_for_search("韓國東大門單鞋女方頭絨面一腳蹬韓版休閑2020春季新款平底毛毛鞋") # 搜索引擎模式 print("Search Mode: " + "/ ".join(seg_list))
輸出:
Full Mode: 韓國/ 東大/ 東大門/ 大門/ 單鞋/ 女方/ 方頭/ 絨面/ 一腳/ 腳蹬/ 韓/ 版/ 休閑/ 2020/ 春季/ 新款/ 平底/ 毛毛/ 鞋 Default Mode: 韓國/ 東大門/ 單鞋/ 女方/ 頭/ 絨面/ 一/ 腳蹬/ 韓版/ 休閑/ 2020/ 春季/ 新款/ 平底/ 毛毛/ 鞋 Search Mode: 韓國/ 東大/ 大門/ 東大門/ 單鞋/ 女方/ 頭/ 絨面/ 一/ 腳蹬/ 韓版/ 休閑/ 2020/ 春季/ 新款/ 平底/ 毛毛/ 鞋
1.2、添加自定義詞典
以"Default Mode"輸出為例,毛毛鞋被拆分成了毛毛和鞋兩個部分,原因是P(毛毛鞋) < P(毛毛)×P(鞋),“毛毛鞋”詞頻不夠導致其成詞概率較低。
有兩個方法可以添加自定義詞典,添加自定義字典並不會替換自帶的詞典,會追加上去。其他自定義也是。
一個是載入詞典:
jieba.load_userdict(file_name) # file_name 為文件類對象或自定義詞典的路徑
詞典格式和 dict.txt(jiaba包文件夾下) 一樣,一個詞占一行;每一行分三部分:詞語、詞頻(可省略)、詞性(可省略),用空格隔開,順序不可顛倒。file_name 若為路徑或二進制方式打開的文件,則文件必須為 UTF-8 編碼。
另一個是動態調整:
使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中動態修改詞典。 使用 suggest_freq(segment, tune=True) 可調節單個詞語的詞頻,使其能(或不能)被分出來。 注意:自動計算的詞頻在使用 HMM 新詞發現功能時可能無效。 刪除該詞 jieba.del_word('今天天氣')
現在采用動態調整詞典后,毛毛鞋能正確識別。
jieba.add_word('毛毛鞋', freq=None, tag=None) seg_list = jieba.cut(content, cut_all=False) print("Update Default Mode: " + "/ ".join(seg_list)) # 默認模式
Update Default Mode: 韓國/ 東大門/ 單鞋/ 女方/ 頭/ 絨面/ 一/ 腳蹬/ 韓版/ 休閑/ 2020/ 春季/ 新款/ 平底/ 毛毛鞋
1.3、詞性標注
在老版本中,詞性標注采用的字典會與jieba.cut不一致,新版本已修復。
# 詞性標注 words = pseg.cut(content) print("詞性標注: " + "/ ".join([word + '-' + flag for word, flag in words]))
詞性標注: 韓國-ns/ 東大門-x/ 單鞋-n/ 女方-n/ 頭-n/ 絨面-n/ 一-m/ 腳蹬-n/ 韓版-nt/ 休閑-v/ 2020-m/ 春季-t/ 新款-n/ 平底-t/ 毛毛鞋-x
1.4、基於TF-IDF算法的關鍵字抽取
簡單的詞頻統計並不能很好的反映詞的重要性,tf-idf是一個識別關鍵字的算法。大概思路如下:
一個容易想到的思路,就是找到出現次數最多的詞。如果某個詞很重要,它應該在這篇文章中多次出現。於是,我們進行"詞頻"(Term Frequency,縮寫為TF)統計。
結果你肯定猜到了,出現次數最多的詞是----"的"、"是"、"在"----這一類最常用的詞。它們叫做"停用詞"(stop words),表示對找到結果毫無幫助、必須過濾掉的詞。
假設我們把它們都過濾掉了,只考慮剩下的有實際意義的詞。這樣又會遇到了另一個問題,我們可能發現"zg"、"蜜蜂"、"養殖"這三個詞的出現次數一樣多。這是不是意味着,
作為關鍵詞,它們的重要性是一樣的?顯然不是這樣。因為"zg"是很常見的詞,相對而言,"蜜蜂"和"養殖"不那么常見。如果這三個詞在一篇文章的出現次數一樣多,有理由
認為,"蜜蜂"和"養殖"的重要程度要大於"zg",也就是說,在關鍵詞排序上面,"蜜蜂"和"養殖"應該排在"zg"的前面。所以,我們需要一個重要性調整系數,衡量一個詞是
不是常見詞。如果某個詞比較少見,但是它在這篇文章中多次出現,那么它很可能就反映了這篇文章的特性,正是我們所需要的關鍵詞。 用統計學語言表達,就是在詞頻的基礎上,要對每個詞分配一個"重要性"權重。最常見的詞("的"、"是"、"在")給予最小的權重,較常見的詞("zg")給予較小的權重,較少
見的詞("蜜蜂"、"養殖")給予較大的權重。這個權重叫做"逆文檔頻率"(Inverse Document Frequency,縮寫為IDF),它的大小與一個詞的常見程度成反比。
知道了"詞頻"(TF)和"逆文檔頻率"(IDF)以后,將這兩個值相乘,就得到了一個詞的TF-IDF值。某個詞對文章的重要性越高,它的TF-IDF值就越大。所以,排在最前面的幾個詞,
就是這篇文章的關鍵詞。
介紹完基本的思路以后,這里我們發現有兩個文件,一個是停用詞,一個是idf值。jieba庫默認有一些基本的停用詞及idf文件(jieba\analyse\idf.txt)。
# jieba\analyse\tfidf.py STOP_WORDS = set(( "the", "of", "is", "and", "to", "in", "that", "we", "for", "an", "are", "by", "be", "as", "on", "with", "can", "if", "from", "which", "you", "it", "this", "then", "at", "have", "all", "not", "one", "has", "or", "that", ))
那么jieba計算tf-idf的值的過程,大致為,講輸入的文檔進行分詞並計算tf值,通過已經生成好的idf文件獲取相應單詞的idf值,如果沒有,使用中位數值。
如自定義詞典,停用詞和idf文檔也可以自定義。
jieba.analyse.set_idf_path(file_name) # file_name為自定義語料庫的路徑 jieba.analyse.set_stop_words(file_name) # file_name為自定義語料庫的路徑
最后的使用:
# topK:輸入前topK個關鍵字,為None則輸出全部 # withWeight:是否返回權重 # allowPOS:只計算哪類詞性,'n','v','ns' # withFlag:是否返回詞性標注 tfidf_fre =analyse.extract_tags(content, topK=20, withWeight=True, allowPOS=(),withFlag=True) df = pd.DataFrame(data=tfidf_fre,columns=['單詞','tf-idf']) print(tfidf_fre)
關鍵字提取: [('單鞋', 1.0159638824153847), ('東大門', 0.9195975002230768), ('韓版', 0.9195975002230768), ('2020', 0.9195975002230768), ('毛毛鞋', 0.9195975002230768), ('絨面', 0.8781362309384615), ('平底', 0.8157569835384616), ('腳蹬', 0.7435823959523076), ('新款', 0.6984920066438461), ('女方', 0.6978741472823077), ('休閑', 0.6547389170892307), ('春季', 0.6055691639807692), ('韓國', 0.5340907908538461)]
2、jieba+wordcloud簡單分析
最后做一個簡單的應用分析。數據使用“2019年新年賀詞.txt"。文檔如下。
# 數據讀取 with open('2019新年賀詞.txt','r') as f : text = f.read()
# 統計詞頻函數 def jieba_count_tf(words,is_filter_stop_words = True): stop_words = [] if is_filter_stop_words: # 獲取Jieba庫載入的停用詞庫 stop_words = analyse.default_tfidf.stop_words freq = {} for w in words: if len(w.strip()) < 2 or w.lower() in stop_words: continue freq[w] = freq.get(w, 0.0) + 1.0 # 總詞匯數量 total = sum(freq.values()) return freq words = jieba.cut(text, cut_all=False) tfs = jieba_count_tf(words,is_filter_stop_words = False) # 形成表格數據 df = pd.DataFrame(data=list(zip(list(tfs.keys()),list(tfs.values()))),columns=['單詞','頻數']) df
# 關鍵字分析 tfidf_fre =analyse.extract_tags(text, topK=100, withWeight=True, allowPOS=(),withFlag=True) # 形成表格數據 df = pd.DataFrame(data=tfidf_fre,columns=['單詞','tf-idf'])

# 生成詞雲圖展示 alice_mask = np.array(Image.open('test.png')) # 使用圖片作為背景 font_path='C:\Windows\Fonts\simfang.ttf' # 設置文本路徑 # 創建圖雲對象 wc = WordCloud(font_path=font_path, background_color='white',mask = alice_mask,width=400, height=200,stopwords = None) wc.fit_words(dict(zip(df['單詞'], df['tf-idf']))) # 輸入詞頻字典,或者 {詞:tf-idf} wc_img = wc.to_image() # 輸出為圖片對象 wc.to_file("alice.png")
結論,從初步的新年賀詞的展示來看,賀詞中主要關注點為tuop,預示着對tuop攻堅戰的祝福和肯定。
同時,從詞匯的展示中,一些如同“我們”,“他們”,“大家”的一些停用詞沒有去掉,可以參考1.3添加停用詞典,或在詞雲對象中添加停用詞列表。
更新后如下:
更新以后,關鍵字更加明顯。“ggkf”、“發展”等詞匯要凸顯了出來。祝祖國繁榮昌盛。
總結:
1、需要擁有一個好的詞典,不同場景應使用不同詞典。
2、一個好的停用詞典。
3、一個較廣的idf文件,可進一步自行構建idf文件。