【機器學習】--LDA初始和應用
一、前述
LDA是一種 非監督機器學習 技術,可以用來識別大規模文檔集(document collection)或語料庫(corpus)中潛藏的主題信息。它采用了詞袋(bag of words)的方法,這種方法將每一篇文檔視為一個詞頻向量,從而將文本信息轉化為了易於建模的數字信息。但是詞袋方法沒有考慮詞與詞之間的順序,這簡化了問題的復雜性,同時也為模型的改進提供了契機。每一篇文檔代表了一些主題所構成的一個概率分布,而每一個主題又代表了很多單詞所構成的一個概率分布。由於 Dirichlet分布隨機向量各分量間的弱相關性(之所以還有點“相關”,是因為各分量之和必須為1),使得我們假想的潛在主題之間也幾乎是不相關的,這與很多實際問題並不相符,從而造成了LDA的又一個遺留問題。
二、具體過程
對於語料庫中的每篇文檔,LDA定義了如下生成過程(generativeprocess): 1.對每一篇文檔,從主題分布中抽取一個主題; 2.從上述被抽到的主題所對應的單詞分布中抽取一個單詞; 3.重復上述過程直至遍歷文檔中的每一個單詞。語料庫中的每一篇文檔與T(通過反復試驗等方法事先給定)個主題的一個多項分布 (multinomialdistribution)相對應,將該多項分布記為θ。每個主題又與詞匯表(vocabulary)中的V個單詞的一個多項分布相對應,將這個多項分布記為φ。
三、案例
假設文章1開始有以下單詞:
高斯分為主題二,是因為有一定的概率。
如此反復,當各個概率分布不再發生變化時,即完成了收斂和訓練過程
訓練思想仍然是EM算法(摁住一個,去計算另一個)
對比K-means
實際工程過程中:
每一個主題對每一個詞都有一個基本出現次數(人工設定)
每一篇文章在各個主題上都有一個基本出現詞數
步驟:
新來一片文章,需要確定它的主題分布:
先隨機化主題分布
1.根據主題分布和主題-單詞模型,找尋每個
單詞所對應的主題
2.根據單詞主題重新確定主題分布
1,2反復,直到主題分布穩定 最終得到兩個模型:
1.每篇文章的主題分布
2.每個主題產生詞的概率
用途:
1.根據文章的主題分布,計算文章之間的相似性
2.計算各個詞語之間的相似度
四、代碼
# -*- coding: utf-8 -*- import jieba from sklearn.feature_extraction.text importCountVectorizer from sklearn.decomposition import LatentDirichletAllocation for i in range(4): with open(‘./data/nlp_test%d.txt‘ % i, encoding=‘UTF-8‘) as f: document = f.read() document_cut = jieba.cut(document) result = ‘ ‘.join(document_cut) print(result) with open(‘./data/nlp_test%d.txt‘ % (i+10), ‘w‘, encoding=‘UTF-8‘) as f2: f2.write(result) f.close() f2.close() # 從文件導入停用詞表 stpwrdpath = "./data/stop_words.txt" stpwrd_dic = open(stpwrdpath, ‘r‘, encoding=‘UTF-8‘) stpwrd_content = stpwrd_dic.read() # 將停用詞表轉換為list stpwrdlst = stpwrd_content.splitlines() stpwrd_dic.close() print(stpwrdlst) # 向量化 不需要tf_idf corpus = [] for i in range(4): with open(‘./data/nlp_test%d.txt‘ % (i+10), ‘r‘, encoding=‘UTF-8‘) as f: res = f.read() corpus.append(res) print(res) cntVector = CountVectorizer(stop_words=stpwrdlst) cntTf = cntVector.fit_transform(corpus) print(cntTf) # 打印輸出對應關系 # 獲取詞袋模型中的所有詞 wordlist = cntVector.get_feature_names() # 元素a[i][j]表示j詞在i類文本中的權重 weightlist = cntTf.toarray() # 打印每類文本的詞語權重,第一個for遍歷所有文本,第二個for便利某一類文本下的詞語權重 for i in range(len(weightlist)): print("-------第", i, "段文本的詞語權重------") for j in range(len(wordlist)): print(wordlist[j], weightlist[i][j]) lda = LatentDirichletAllocation(n_components=3,#3個話題 learning_method=‘batch‘, random_state=0) docres = lda.fit_transform(cntTf) print("文章的主題分布如下:") print(docres) print("主題的詞分布如下:") print(lda.components_)
【機器學習】--LDA初始和應用