主題模型(LDA)(一)--通俗理解與簡單應用


https://blog.csdn.net/qq_39422642/article/details/78730662

這篇文章主要給一些不太喜歡數學的朋友們的,其中基本沒有用什么數學公式。
目錄

直觀理解主題模型
LDA的通俗定義
LDA分類原理
LDA的精髓
主題模型的簡單應用-希拉里郵件門
 
  1.直觀理解主題模型

 
聽名字應該就知道他講的是什么?假如有一篇文章text,通過里面的詞,來確定他是什么類型的文章,如果文章中出現很多體育類的詞,比如,籃球,足球之類的,那么主題模型就會把它划分為體育類的文章。
因為主題模型涉及比較多的數學推導,所以我們先用一個小栗子,理解它要做的事。假設有這么一個場景:

一個資深HR收到一份應聘算法工程師的簡歷,他想僅僅通過簡歷來看一下這個人是大牛,還是彩筆,他是怎么判斷呢?

他的一般做法就是拿到這份簡歷,看這個人的簡歷上寫的內容包括了什么?
在此之前呢,他也一定是接觸了很多算法工程師的面試,他根據這些招進來的人判斷,一個大牛,有可能是:

穿條紋襯衫
曾在BAT就職
做過大型項目

這個HR就會看這個面試者是不是穿條紋襯衫,有沒有在BAT就職過,做過什么牛逼的項目,如果都滿足條件,那這個HR就會判斷這個人應該是大牛,如果他只是穿條紋襯衫,沒做過什么拿得出手的項目,那就要猶豫一下了,因為他是彩筆的可能性比較大。
這個例子和主題模型的關系可以用這個圖表示:
 
在LDA眼里,相當於是詞袋,每個袋子里都有一堆詞,用的時候就只管檢測這些詞出現與否就OK了。
用公式可以表示成:P(大牛|特征,簡歷)=此特征在大牛中出現的次數大牛擁有的所有特征 X 此簡歷屬於大牛的特征個數P(大牛|特征,簡歷)=此特征在大牛中出現的次數大牛擁有的所有特征 X 此簡歷屬於大牛的特征個數
 

  2.LDA的通俗定義

什么是LDA?

它是一種無監督的貝葉斯模型。
是一種主題模型,它可以將文檔集中的每篇文檔按照概率分布的形式給出。
是一種無監督學習,在訓練時不需要手工標注的訓練集,需要的是文檔集和指定主題的個數。
是一種典型的詞袋模型,它認為一篇文檔是由一組詞組成的集合,詞與詞之間沒有順序和先后關系。

它主要的優點就是可以對每個主題,都找出一些詞來描述它。

  3.LDA分類原理

先前詳細寫過貝葉斯模型的原理以及它所代表的思想,詳細請戳:神奇的貝葉斯思想,這里只簡單說一下它的原理,用在這里的意思是:P(大牛|簡歷)=P(大牛)P(簡歷|大牛)∑P(大牛)P(簡歷|大牛)P(大牛|簡歷)=P(大牛)P(簡歷|大牛)∑P(大牛)P(簡歷|大牛)經過一系列推導,可以得到這樣一個鏈式的關系:P(詞 | 文檔)=P(詞 | 主題)P(主題 | 文檔)P(詞 | 文檔)=P(詞 | 主題)P(主題 | 文檔)也就是:詞→主題→文檔詞→主題→文檔這樣的關系。
同一主題下,某個詞出現的概率,以及同一文檔下,某個主題出現的概率,兩個概率的乘積,可以得到某篇文檔出現某個詞的概率,我們在訓練的時候,調整這兩個分布就可以了。 

由此可以定義LDA的生成過程:

對每篇文檔,在主題分布中抽取一個主題;(相當於左圖)
對抽到的主題所對應的單詞分布中隨機抽取一個單詞;(在右圖中抽)
重復上述過程直至遍歷整篇文檔中的每個單詞

經過以上三步,就可以看一下兩個分布的乘積,是否符合給定文章的分布,以此來調整。
稍微具體點講: (w代表單詞;d代表文檔;t代表主題; 大寫代表總集合,小寫代表個體。)
D中每篇文檔d看作個單詞序列: <w1,w2,...,wn><w1,w2,...,wn>,wi表示第i個單詞。
D中涉及的所有不同單詞組成一個詞匯表大集合V (vocabulary),LDA以文檔集合D作為輸入,希望訓練出的兩個結果向量 (假設形成k個topic,V中共有m個詞):

結果向量1:對每個D中的文檔d,對應到不同主題的概率θdθd:<pt1,...,ptk><pt1,...,ptk>其中ptipti表示d對應k個主題中第i個主題的概率,計算的方法也很簡單:pti=d中有多少個詞是第i個主題也有的d中所有詞的總數pti=d中有多少個詞是第i個主題也有的d中所有詞的總數
結果向量2:對每個T中的主題tT中的主題t,生成不同單詞的概率向量ϕtϕt:<pw1,...,pwm><pw1,...,pwm>其中pwipwi表示主題tt生成V中第i個單詞的概率。計算方法:pwi=主題t對應到V中第i個單詞出現的次數主題t下的所有單詞總數pwi=主題t對應到V中第i個單詞出現的次數主題t下的所有單詞總數
 
  4.LDA的精髓

說了那么多,其實LDA的核心,仍然是這個公式:
P(詞 | 文檔)=P(詞 | 主題)P(主題 | 文檔)P(詞 | 文檔)=P(詞 | 主題)P(主題 | 文檔)用表達式如下:P(w|d)=P(w|t)∗P(t|d)P(w|d)=P(w|t)∗P(t|d)其實就是以主題為中間層,通過前面的兩個向量(θdθd,ϕtϕt),分別給出P(w|t),P(t|d)P(w|t),P(t|d),它的學習過程可以表示為:

LDA算法開始時,先隨機地給θdθd,ϕtϕt賦值(對所有的d和t)
針對特定的文檔dsds中的第i單詞wiwi,如果令該單詞對應的主題為tjtj,可以把 上述公式改寫為:Pj(wi|ds)=P(wi|tj)∗P(tj|ds)Pj(wi|ds)=P(wi|tj)∗P(tj|ds)
枚舉T中的主題,得到所有的pj(wi|ds)pj(wi|ds).然后可以根據這些概率值的結果為dsds中的第i個單詞wiwi選擇一個主題,最簡單的就是取令Pj(wi|ds)Pj(wi|ds)概率最大的主題 tj tj。
如果dsds中的第i個單詞wiwi在這里選擇了一個與原先不同的主題,就會對θdθd,ϕtϕt有影響,他們的影響反過來影響對上面提到的p(w|d)p(w|d)的計算。

對文檔集D中的所有文檔d中的所有w進行一次p(w|d)p(w|d)計算,並重新選擇主題看成是一次迭代。迭代n次之后就可收斂到LDA所需要的分類結果了。

  5.主題模型的簡單應用-希拉里郵件門

我們如果不想要具體了解具體的數學公式推導,理解到這里就差不多了,重點是學會怎么使用?
我們用希拉里郵件門那個案例,看一下應該怎么使用gensim來進行郵件分類。
from gensim import corpora, models, similarities
import gensim
import numpy as np
import pandas as pd
import re
df = pd.read_csv("../input/HillaryEmails.csv")
# 原郵件數據中有很多Nan的值,直接扔了。
df = df[['Id','ExtractedBodyText']].dropna()
df.head()1234567891011
數據樣式:

做一個簡單的預處理:
 
def clean_email_text(text):
    text  = text.replace('\n'," ")
    text = re.sub('-'," ",text)
    text = re.sub(r"\d+/\d+/\d+", "", text) #日期,對主體模型沒什么意義
    text = re.sub(r"[0-2]?[0-9]:[0-6][0-9]", "", text) #時間,沒意義
    text = re.sub(r"[\w]+@[\.\w]+", "", text) #郵件地址,沒意義
    text = re.sub(r"/[a-zA-Z]*[:\//\]*[A-Za-z0-9\-_]+\.+[A-Za-z0-9\.\/%&=\?\-_]+/i", "", text) #網址,沒意義
    pure_text = ''
    for letter in text:
        if letter.isalpha() or letter ==' ':
            pure_text += letter
    text = ' '.join(word for word in pure_text.split() if len(word)>1)
    return text
docs = df['ExtractedBodyText']
docs = docs.apply(lambda x :clean_email_text(x))
1234567891011121314151617
看一下處理成啥樣的:
 
docs.head(2).values1
處理成一個一個詞了
 
即:[[一條郵件字符串],[另一條郵件字符串],...][[一條郵件字符串],[另一條郵件字符串],...]
手寫的停用詞,這還有各色的別人寫好的停用詞:stopwords
 
stoplist = ['very', 'ourselves', 'am', 'doesn', 'through', 'me', 'against', 'up', 'just', 'her', 'ours',
            'couldn', 'because', 'is', 'isn', 'it', 'only', 'in', 'such', 'too', 'mustn', 'under', 'their',
            'if', 'to', 'my', 'himself', 'after', 'why', 'while', 'can', 'each', 'itself', 'his', 'all', 'once',
            'herself', 'more', 'our', 'they', 'hasn', 'on', 'ma', 'them', 'its', 'where', 'did', 'll', 'you',
            'didn', 'nor', 'as', 'now', 'before', 'those', 'yours', 'from', 'who', 'was', 'm', 'been', 'will',
            'into', 'same', 'how', 'some', 'of', 'out', 'with', 's', 'being', 't', 'mightn', 'she', 'again', 'be',
            'by', 'shan', 'have', 'yourselves', 'needn', 'and', 'are', 'o', 'these', 'further', 'most', 'yourself',
            'having', 'aren', 'here', 'he', 'were', 'but', 'this', 'myself', 'own', 'we', 'so', 'i', 'does', 'both',
            'when', 'between', 'd', 'had', 'the', 'y', 'has', 'down', 'off', 'than', 'haven', 'whom', 'wouldn',
            'should', 've', 'over', 'themselves', 'few', 'then', 'hadn', 'what', 'until', 'won', 'no', 'about',
            'any', 'that', 'for', 'shouldn', 'don', 'do', 'there', 'doing', 'an', 'or', 'ain', 'hers', 'wasn',
            'weren', 'above', 'a', 'at', 'your', 'theirs', 'below', 'other', 'not', 're', 'him', 'during', 'which']123456789101112
分詞:
texts = [[word for word in doc.lower().split() if word not in stoplist] for doc in doclist]
texts[0]
當然還可以用包,比如jieba,bltk.
得到的就是一篇文檔一個詞袋。
建立預料庫:每個單詞用數字索引代替,得到一個數組。
 
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]12
得到:
 
這個列表告訴我們,第14(從0開始是第一)個郵件中,一共6個有意義的單詞(經過我們的文本預處理,並去除了停止詞后)
其中,36號單詞出現1次,505號單詞出現1次,以此類推。。。
接着,我們終於可以建立模型了:
 
lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=20)
lda.print_topic(10, topn=5)12
得到第10號分類中,最常見的單詞是:

‘0.007*kurdistan + 0.006*email + 0.006*see + 0.005*us + 0.005*right’
把五個主題打出來看一下:
 

lda.print_topics(num_topics=5,num_words =6)1
 
有空可以練一下gesim:
gensim使用指南
詳細的推導:數學公式版下一篇文章介紹
參考:七月在線
原文鏈接:https://blog.csdn.net/qq_39422642/article/details/78730662


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM