今天我們來談?wù)?strong>主題模型(Latent Dirichlet Allocation),由于主題模型是生成模型,而我們常用的決策樹,支持向量機芙粱,CNN等常用的機器學(xué)習(xí)模型的都是判別模型。所以筆者首先簡單介紹一下判別模型和生成模型。下面筆者列出了生成模型和判別模型的核心區(qū)別:
- 判別模型:估計的是條件概率分布(conditional distribution)——
作為預(yù)測模型椒舵。
- 生成模型:估計的是聯(lián)合概率分布(joint probability distribution)——
,然后根據(jù)貝葉斯公式
求出條件概率分布
作為預(yù)測模型
簡單的說:
判別模型只需要學(xué)習(xí)特征x约谈,從而就可以去預(yù)測類別y笔宿。做預(yù)測時是判斷新數(shù)據(jù)屬于哪個類別的概率最大,進而確定新數(shù)據(jù)的類別棱诱,判別模型尋找不同類別之間的最優(yōu)分類面泼橘,反映的是異類數(shù)據(jù)之間的差異。
而生成模型學(xué)得是各個類別y迈勋,和各自的特征x(即可看成學(xué)得多個模型)炬灭,做預(yù)測時是判斷新數(shù)據(jù)和已知類別中的哪個最為接近,進而確定新數(shù)據(jù)的類別靡菇,生成模型能夠反映同類數(shù)據(jù)本身的相似度重归。
由于生產(chǎn)模型學(xué)習(xí)的是特征x和類別y的聯(lián)合分布,所以相較于判別模型更為復(fù)雜厦凤。當(dāng)建模過程中存在隱變量是鼻吮,判別模型就無能為力了,而此時生成模型依然能夠發(fā)揮作用较鼓。高斯混合模型(隱變量是類別)和今天的筆者要介紹的主題模型(隱變量是主題)就是屬于含有隱變量的生成模型椎木。
主題模型簡介
主題模型的核心思想是——一篇文章中的每個詞語都是經(jīng)歷以下兩個步驟之后生成而來:
- 一篇文章以一定概率選擇了某個主題,
- 2 .然后并從這個主題中以一定概率選擇某個詞語。
如下圖所示:
:比如某一篇文檔 d香椎,它的主題分布如右方紅色柱狀圖所示漱竖。這篇文檔最有可能是一篇體育,新聞類型的文檔士鸥。
: 而在某一主題下闲孤,它的詞語分布如左方藍(lán)色柱狀圖所示。這個主題應(yīng)該屬于政治類型的主題烤礁。
LDA
所以主題模型本質(zhì)上想說一篇文章是如何誕生的:
1.首先選擇好文章的主題 讼积,
2 .然后選擇好符合主題的詞語組合一下。
有沒有發(fā)現(xiàn)主題模型的簡單粗暴脚仔,它行文時并沒有考慮詞語之間的銜接勤众,語法是否通順等。其實主題模型依舊是一個詞袋模型鲤脏,并沒有考慮語序们颜,語法,語義等高級特征猎醇。不過并不妨礙它能夠帶給我們很多驚喜窥突。
下圖是LDA原論文中截圖,這里定義了4個主題"Art 硫嘶,Budgets阻问,Children,Education"沦疾,
從文章的顏色分布直接可以清晰的判斷出綠色的詞最多称近,所以此文章最大的主題應(yīng)該是:Budgets。其中的大部分詞都是從Budgets 這個主題中選擇出來的哮塞。所以這篇文章可能在講訴:和預(yù)算有關(guān)的事情刨秆。文章確實講訴了某基金逐步撥款資助一些青年藝術(shù)家。主題模型威力就在于它能很便捷的就幫我們挖掘出一篇文章的主題忆畅。
說了這么多了衡未,那下面我們?nèi)绾蔚玫剑缟蠄D所示的信息——(1) 每個主題的詞語分布邻眷,以及(2)每篇文章的主題分布呢眠屎,下面進入實戰(zhàn)部分。
LDA 主題模型實戰(zhàn)
載入數(shù)據(jù)
這里筆者采用的今日頭條之前一個文本分類的數(shù)據(jù)肆饶,就是一些政治,娛樂岖常,財經(jīng)新聞之類的文本驯镊,需要注意的是"政治,娛樂,財經(jīng)",就是所謂的主題板惑。同時進行文本分詞等預(yù)處理等操作橄镜。
from gensim.models import LdaModel
import pandas as pd
from gensim.corpora import Dictionary
import jieba
with open("toutiao_cat_data.txt","r",encoding="utf-8") as f:
data = []
for line in f.readlines():
line = line.strip()
line = ','.join(line.split("_!_")[3:])
data.append(jieba.lcut(line))
數(shù)據(jù)樣式如下圖所示,即文本分詞后的l列表冯乘,從數(shù)據(jù)可以看出洽胶,都是些娛樂,政治,體育新聞文本。
文本向量化
LDA采用的是詞袋模型裆馒,所以將每一條新聞文本姊氓,轉(zhuǎn)化為詞袋(BOW ——Bag of words)向量,這里筆者過濾掉一些頻率過高的詞喷好。
dictionary = corpora.Dictionary(data)
dictionary.filter_n_most_frequent(200)
corpus = [dictionary.doc2bow(text) for text in data ]
模型訓(xùn)練
將向量化之后的文本喂給LDA模型翔横,設(shè)定好主題的個數(shù)(LDA需要指定主題的個數(shù)),這里筆者設(shè)定了10個主題梗搅,運行下方代碼就可以開始訓(xùn)練了禾唁。筆者實驗下來感覺gensim的LDA還是有點慢。
lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=10)
獲取主題詞分布
打印出10個主題的詞語分布中无切,排名前20的主題詞荡短,實際使用LDA時,我們必須看到各個主題詞的分布才能大致了解哆键,某個主題到底是什么掘托。如下圖所示:
第5個主題(id = 4)的主題詞是"勇士,騎士洼哎,世界杯"等烫映,應(yīng)該是和體育相關(guān)。
第10個主題(id =9)的主題詞是"上市噩峦,股票锭沟,黃金"等,應(yīng)該和經(jīng)濟相關(guān)识补。
topic_list=lda.print_topics(20)
print(topic_list)
獲取某一篇文檔的主題分布
下方代碼是將一篇新的文檔的詞袋向量族淮,喂給LDA模型讓模型輸出新文檔的主題分布,如下圖所示:我們把騎士和猛龍的季后賽半決賽新聞的文本丟給剛剛訓(xùn)練好的主題模型凭涂,模型輸出:
此文本主題組成中第五個主題(體育相關(guān))占據(jù)0.85祝辣。
也驗證了模型給出主題分布是應(yīng)該是合理的。
print(data[44])
test_doc=data[44]
doc_bow = dictionary.doc2bow(test_doc) #文檔轉(zhuǎn)換成bow
doc_lda = lda[doc_bow]
doc_lda
結(jié)語
至此切油,我們學(xué)會了如何通過訓(xùn)練一個主題模型蝙斜,拿到獲取各主題的主題詞分布以及如何獲取某一篇文檔的主題分布。今天的介紹澎胡,筆者并沒有涉及主題模型內(nèi)部一些復(fù)雜的數(shù)學(xué)知識孕荠,比如Drichlet 分布娩鹉,共軛分布,吉布斯采樣等稚伍。這些復(fù)雜的數(shù)學(xué)知識我也只是略懂一二弯予,還達(dá)不到說明白的地步,所以也就不提了个曙,感興趣的同學(xué)可以去看參考文獻(xiàn)中作者的原文和網(wǎng)上的一些資料锈嫩。此文章的主要目的想讓大家了解主題模型的思想,以及如何使用gensim訓(xùn)練屬于你自己的主題模型垦搬。
參考文獻(xiàn):
http://www.jmlr.org/papers/volume3/blei03a/blei03a.pdf
https://www.cnblogs.com/Harriett-Lin/p/9621107.html
https://www.cnblogs.com/jhcelue/p/7148935.html