cntopic庫:支持中英文LDA話題分析

cntopic

簡單好用的lda話題模型,支持中英文。該庫基於gensim和pyLDAvis,實現了lda話題模型及可視化功能。

本文視頻講解已上傳到B站(今晚會通過審覈),大家可以關注大鄧的

B站賬號:大鄧和他的python

安裝

pip install cntopic

使用

這裏給大家引入一個場景,假設大家採集新聞數據,忘記採集新聞文本對應的新聞類別,如果人工標註又很費工夫。這時候我們可以用lda話題模型幫我們洞察數據中的規律,發現新聞有n種話題羣體。這樣lda模型對數據自動打標註topic_1, topic_2, topic_3... ,topic_n。

我們研究者的工作量僅僅限於解讀topic_1, topic_2, topic_3... ,topic_n分別是什麼話題即可。

lda訓練過程,大致分爲

  1. 讀取文件

  2. 準備數據

  3. 訓練lda模型

  4. 使用lda模型

  5. 存儲與導入lda模型

1. 讀取文件

這裏我們用一個新聞數據,一共有10類,每類1000條數據,涵蓋

'時尚', '財經', '科技', '教育', '家居', '體育', '時政', '遊戲', '房產', '娛樂'

import pandas as pd

df = pd.read_csv('chinese_news.csv')
df.head()

labelcontent
0體育鮑勃庫西獎歸誰屬?NCAA最強控衛是坎巴還是弗神新浪體育訊如今,本賽季的NCAA進入到了末...
1體育麥基砍28+18+5卻充滿寂寞 紀錄之夜他的痛阿聯最懂新浪體育訊上天對每個人都是公平的,賈維...
2體育黃蜂vs湖人首發:科比衝擊七連勝 火箭兩舊將登場新浪體育訊北京時間3月28日,NBA常規賽洛...
3體育雙面謝亞龍作秀終成做作 誰來爲低劣行政能力埋單是誰任命了謝亞龍?誰放縱了謝亞龍?誰又該爲謝亞...
4體育兔年首戰山西換帥後有虎膽 張學文用喬丹名言勵志今晚客場挑戰浙江稠州銀行隊,是山西汾酒男籃的兔...

label標籤的分佈情況

df['label'].value_counts()
家居    1000
時尚    1000
房產    1000
時政    1000
教育    1000
遊戲    1000
財經    1000
娛樂    1000
體育    1000
科技    1000
Name: label, dtype: int64

2. 準備數據

一般準備數據包括:

  1. 分詞、數據清洗

  2. 按照模塊需求整理數據的格式

注意在scikit-learn中:

  • 英文文本不需要分詞,原封不動傳入即可。

  • 中文文本需要先分詞,後整理爲英文那樣用空格間隔的字符串。形如”我 愛 中國“

import jieba

def text2tokens(raw_text):
    #將文本raw_text分詞後得到詞語列表
    tokens = jieba.lcut(raw_text)
    #tokens = raw_text.lower().split(' ') #英文用空格分詞即可
    tokens = [t for t in tokens if len(t)>1] #剔除單字
    return tokens

#對content列中所有的文本依次進行分詞
documents = [text2tokens(txt) 
             for txt in df['content']]  

#顯示前5個document
print(documents[:5])
[['鮑勃', '庫西', '獎歸', 'NCAA', '最強', '控衛', '坎巴', '還是', '弗神', '新浪', '體育訊', '稱讚', '得分', '能力', '毋庸置疑',...],
['球員', '大東', '賽區', '錦標賽', '全國', '錦標賽', '他場', '27.1', '6.1', '籃板', '5.1', '助攻',..],
['依舊', '如此', '給力', '瘋狂', '表現', '開始', '這個', '賽季', '瘋狂', '表現', '結束', '這個', '賽季', '我們', '全國', '錦標賽', '前進', '並且', '之前', '曾經', '連贏', '贏得', '大東', ...],
['賽區', '錦標賽', '冠軍', '這些', '歸功於', '坎巴', '沃克', '康涅狄格', '大學', '主教練', '吉姆', '卡洪', ...],
['稱讚', '一名', '純正', '控衛', '而且', '能爲', '我們', '得分', '單場', '42', '有過', '單場', '17', '助攻', ...]]

3. 訓練lda模型

現在開始正式使用cntopic模塊,開啓LDA話題模型分析。步驟包括

Step功能代碼
0準備documents,已經在前面準備好了-
1初始化Topic類topic = Topic(cwd=os.getcwd())
2根據documents數據,構建詞典空間topic.create_dictionary(documents=documents)
3構建語料(將文本轉爲文檔-詞頻矩陣)topic.create_corpus(documents=documents)
4指定n_topics,構建LDA話題模型topic.train_lda_model(n_topics)

這裏我們就按照n_topics=10構建lda話題模型,一般情況n_topics可能要實驗多次,找到最佳的n_topics

運行過程中會在代碼所在的文件夾內生成一個output文件夾,內部含有

  • dictionary.dict 詞典文件

  • lda.model.xxx 多個lda模型文件,其中xxx是代指

上述代碼耗時較長,請耐心等待程序運行完畢~

import os
from cntopic import Topic

topic = Topic(cwd=os.getcwd()) #構建詞典dictionary
topic.create_dictionary(documents=documents) #根據documents數據,構建詞典空間
topic.create_corpus(documents=documents) #構建語料(將文本轉爲文檔-詞頻矩陣)
topic.train_lda_model(n_topics=10) #指定n_topics,構建LDA話題模型
<gensim.models.ldamulticore.LdaMulticore at 0x158da5090>

4. 使用LDA模型

上面的代碼大概運行了5分鐘,LDA模型已經訓練好了。

現在我們可以利用LDA做一些事情,包括

Step功能代碼補充
1分詞後的某文檔document = ['遊戲', '體育']
2預測document對應的話題topic.get_document_topics(document)
3顯示每種話題與對應的特徵詞之間關係topic.show_topics()
4數據中不同話題分佈情況topic.topic_distribution(raw_documents)raw_documents是列表或series,如本教程中的df['content']
5可視化LDA話題模型(功能不穩定topic.visualize_lda()可視化結果在output中查找vis.html文件,瀏覽器打開即可

4.1 準備document

假設有一個文檔 '遊戲體育真有意思' 分詞處理得到document

document = jieba.lcut('遊戲體育真有意思')
document
['遊戲', '體育', '真', '有意思']

4.2 預測document對應的話題

我們使用topic模型,看看document對應的話題

topic.get_document_topics(document)
[(0, 0.02501536),
 (1, 0.025016038),
 (2, 0.28541195),
 (3, 0.025018401),
 (4, 0.025018891),
 (5, 0.025017735),
 (6, 0.51443774),
 (7, 0.02502284),
 (8, 0.025015472),
 (9, 0.025025582)]

我們的lda話題模型是按照n_topics=10訓練的,限制調用topic預測某個document時,得到的結果是這10種話題及對應概率的元組列表。

從中可以看到概率最大的是 話題6, 概率有0.51443774。

所以我們可以大致認爲document是話題6

4.3 顯示每種話題與對應的特徵詞之間關係

但是僅僅告訴每個文檔是 話題n,我們仍然不知道 話題n代表的是什麼,所以我們需要看看每種 話題n對應的 特徵詞語

topic.show_topics()
[(0,
  '0.042*"基金" + 0.013*"市場" + 0.011*"投資" + 0.009*"公司" + 0.005*"上漲" + 0.004*"股票" + 0.004*"房地產" + 0.004*"指數" + 0.004*"房價" + 0.004*"2008"'),
 (1,
  '0.010*"中國" + 0.007*"移民" + 0.006*"項目" + 0.005*"發展" + 0.005*"表示" + 0.005*"經濟" + 0.005*"政府" + 0.005*"土地" + 0.004*"政策" + 0.004*"問題"'),
 (2,
  '0.014*"比賽" + 0.009*"他們" + 0.008*"球隊" + 0.007*"籃板" + 0.006*"我們" + 0.005*"球員" + 0.005*"季後賽" + 0.005*"時間" + 0.005*"熱火" + 0.005*"賽季"'),
 (3,
  '0.013*"我們" + 0.013*"一個" + 0.009*"自己" + 0.009*"這個" + 0.007*"沒有" + 0.007*"他們" + 0.006*"可以" + 0.006*"就是" + 0.006*"很多" + 0.006*"記者"'),
 (4,
  '0.020*"電影" + 0.010*"導演" + 0.009*"微博" + 0.008*"影片" + 0.006*"觀衆" + 0.006*"一個" + 0.005*"自己" + 0.005*"票房" + 0.004*"拍攝" + 0.004*"娛樂"'),
 (5,
  '0.018*"學生" + 0.015*"留學" + 0.008*"大學" + 0.008*"可以" + 0.006*"功能" + 0.006*"像素" + 0.006*"拍攝" + 0.006*"採用" + 0.005*"學校" + 0.005*"申請"'),
 (6,
  '0.007*"玩家" + 0.006*"封神" + 0.006*"手機" + 0.006*"online" + 0.006*"the" + 0.006*"遊戲" + 0.005*"陳水扁" + 0.005*"活動" + 0.005*"to" + 0.005*"一個"'),
 (7,
  '0.009*"信息" + 0.009*"考試" + 0.009*"遊戲" + 0.007*"工作" + 0.007*"手機" + 0.006*"四六級" + 0.006*"考生" + 0.005*"發展" + 0.004*"可以" + 0.004*"霸王"'),
 (8,
  '0.015*"我們" + 0.011*"企業" + 0.011*"產品" + 0.010*"市場" + 0.009*"傢俱" + 0.009*"品牌" + 0.008*"消費者" + 0.007*"行業" + 0.007*"中國" + 0.007*"一個"'),
 (9,
  '0.012*"遊戲" + 0.011*"玩家" + 0.010*"可以" + 0.008*"搭配" + 0.008*"活動" + 0.006*"時尚" + 0.005*"OL" + 0.004*"獲得" + 0.004*"任務" + 0.004*"手機"')]

根據上面的 話題n特徵詞 大致可以解讀每個 話題n 是什麼內容的話題。

4.4 話題分佈情況

現在我們想知道數據集中不同 話題n 的分佈情況

topic.topic_distribution(raw_documents=df['content'])
9    1670
1    1443
0    1318
5    1265
4    1015
2     970
8     911
3     865
7     307
6     236
Name: topic, dtype: int64

我們的數據有10類,每類是1000條。而現在LDA話題模型單純的根據文本的一些線索,按照n_topics=10給我們分出的效果還不錯。

最完美的情況是每個 話題n 都是接近1000, 現在 話題9太多, 話題6、 話題7太少。

不過我們也要注意到某些話題可能存在交集,容易分錯,比如

  • 財經、房產、時政

  • 體育娛樂

  • 財經、科技

綜上,目前模型還算可以,表現還能接受。

4.5 可視化(功能不穩定)

現在只有10個話題, 我們用肉眼看還能接受,但是當話題數太多的時,還是藉助可視化工具幫助我們科學評判訓練結果。

這就用到topic.visualize_lda(),

topic.visualize_lda()

運行結束後在

代碼所在的文件夾output文件夾中找vis.html文件,右鍵瀏覽器打開

可視化功能不穩定,存在vis.html打不開的情況;希望海涵

圖中有左右兩大區域

  • 左側 話題分佈情況,圓形越大話題越多,圓形四散在四個象限

  • 右側 某話題對應的特徵詞,從上到下權重越來越低

需要注意的是左側

  • 儘量圓形均勻分佈在四個象限比較好,如果圓形全部集中到有限的區域,模型訓練不好

  • 圓形與圓形交集較少比較好,如果交集太多,說明n_topics設置的太大,應該設置的再小一些

五、存儲與導入lda模型

lda話題模型訓練特別慢,如果不保存訓練好的模型,實際上是在浪費我們的生命和電腦計算力。

好消息是cntopic默認爲大家存儲模型,存儲地址是output文件夾內,大家只需要知道如何導入模型即可。

這裏需要導入的有兩個模型,使用步驟

步驟模型代碼作用
0--準備documents
1-topic = Topic(cwd=os.getcwd())初始化
2詞典topic.load_dictionary(dictpath='output/dictionary.dict')直接導入詞典,省略topic.create_dictionary()
3-topic.create_corpus(documents=documents)構建語料(將文本轉爲文檔-詞頻矩陣)
4lda話題模型topic.load_lda_model(modelpath='output/model/lda.model')導入lda話題模型, 相當於省略topic.train_lda_model(n_topics)

現在我們試一試, 爲了與之前的區分,這裏我們起名topic2

topic2 = Topic(cwd=os.getcwd())
topic2.load_dictionary(dictpath='output/dictionary.dict')
topic2.create_corpus(documents=documents)
topic2.load_lda_model(modelpath='output/model/lda.model')

大家可以自己回去試一試第4部分使用LDA模型的相關功能

往期文章讀完本文你就瞭解什麼是文本分析

綜述:文本分析在市場營銷研究中的應用
從記者的Twitter關注看他們稿件的黨派傾向?

Pandas時間序列數據操作
readability: 英文文本數據可讀性庫

Matplotlib可視化教程~

Matplotlib中的plt和ax都是啥?

70G上市公司定期報告數據集
5個小問題帶你理解列表推導式
文本數據清洗之正則表達式
Python網絡爬蟲與文本數據分析
shreport庫: 批量下載上海證券交易所上市公司年報
Numpy和Pandas性能改善的方法和技巧
漂亮~pandas可以無縫銜接Bokeh
YelpDaset: 酒店管理類數據集10+G

後臺回覆【cntopic】可得項目數據及代碼,寫文不易,幫忙點贊轉發支持一下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章