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訓練過程,大致分爲
讀取文件
準備數據
訓練lda模型
使用lda模型
存儲與導入lda模型
1. 讀取文件
這裏我們用一個新聞數據,一共有10類,每類1000條數據,涵蓋
'時尚', '財經', '科技', '教育', '家居', '體育', '時政', '遊戲', '房產', '娛樂'
import pandas as pd
df = pd.read_csv('chinese_news.csv')
df.head()
label | content | |
---|---|---|
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. 準備數據
一般準備數據包括:
分詞、數據清洗
按照模塊需求整理數據的格式
注意在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) | 構建語料(將文本轉爲文檔-詞頻矩陣) |
4 | lda話題模型 | 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】可得項目數據及代碼,寫文不易,幫忙點贊轉發支持一下