LDAモデル原理+コード+実践運用

LDA モデルは、主にトピックの生成に使用されます。


序文

LDA モデルを理解するには、特定の数学的基礎が必要ですが、ブラック ボックスとしても使用できます。

1.原則

この原理については、次の情報から詳しく知ることができます。

[python-sklearn] 中国語テキスト | トピック モデル分析 - LDA (Latent Dirichlet Allocation)_哔哩哔哩_bilibili

https://www.jianshu.com/p/5c510694c07e

トピック モデル: LDA 原則の詳細な説明と適用

トピック モデル - 潜在的ディリクレ配分 (LDA)_哔哩哔哩_bilibili

Latent Dirichlet Allocation (LDA) はトピック モデル、典型的な bag-of-words モデルです。つまり、ドキュメントは単語のグループで構成されたセットであると考えており、単語と単語の関係にシーケンスや単語はありません。序列関係。ドキュメントには複数のトピックを含めることができ、ドキュメント内の各単語はトピックの 1 つによって生成されます。ドキュメント セット内の各ドキュメントのトピックを確率分布の形で与え、教師なし学習に属する記事のトピックを要約することができます。

区別する必要があるのは、もう 1 つの古典的な次元削減手法である線形判別分析 (線形判別分析、略して LDA とも呼ばれます) です。この LDA は、パターン認識 (顔認識、船舶認識など) の分野で非常に幅広い用途があります。

LDA は、トレーニング中に手動でラベル付けされたトレーニング セットを必要としませんが、ドキュメント セットと指定されたトピックの数 k のみが必要です。さらに、LDA のもう 1 つの利点は、各トピックについて、それを説明するいくつかの単語を見つけることができることです。モデル内のトピックの数を選択 - パラメータを手動で設定すると、入力された各記事がトピックの確率を示します. 各トピックは次の単語の確率を示します. トピックの具体的な実装は自分で決定します.

特定の生成モデル クラスを次の図に示します。

二、コード

1. ライブラリのインポート

import os
import pandas as pd
import re
import jieba
import jieba.posseg as psg

 2.パス読み取り

output_path = '../result'
file_path = '../data'
os.chdir(file_path)
data=pd.read_excel("data.xlsx")#content type
os.chdir(output_path)
dic_file = "../stop_dic/dict.txt"
stop_file = "../stop_dic/stopwords.txt"

 同じディレクトリに次の 3 つのフォルダーを作成します: result、data、stop_dic

3.単語の分割

def chinese_word_cut(mytext):
    jieba.load_userdict(dic_file)
    jieba.initialize()
    try:
        stopword_list = open(stop_file,encoding ='utf-8')
    except:
        stopword_list = []
        print("error in stop_file")
    stop_list = []
    flag_list = ['n','nz','vn']
    for line in stopword_list:
        line = re.sub(u'\n|\\r', '', line)
        stop_list.append(line)
    
    word_list = []
    #jieba分词
    seg_list = psg.cut(mytext)
    for seg_word in seg_list:
        word = re.sub(u'[^\u4e00-\u9fa5]','',seg_word.word)
        find = 0
        for stop_word in stop_list:
            if stop_word == word or len(word)<2:     #this word is stopword
                    find = 1
                    break
        if find == 0 and seg_word.flag in flag_list:
            word_list.append(word)      
    return (" ").join(word_list)
data["content_cutted"] = data.content.apply(chinese_word_cut)

このステップには少し時間がかかります。単語の分割処理

4.LDA分析

from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation

sklearn ライブラリが必要です

def print_top_words(model, feature_names, n_top_words):
    tword = []
    for topic_idx, topic in enumerate(model.components_):
        print("Topic #%d:" % topic_idx)
        topic_w = " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
        tword.append(topic_w)
        print(topic_w)
    return tword

n_features = 1000 #提取1000个特征词语
tf_vectorizer = CountVectorizer(strip_accents = 'unicode',
                                max_features=n_features,
                                stop_words='english',
                                max_df = 0.5,
                                min_df = 10)
tf = tf_vectorizer.fit_transform(data.content_cutted)

n_topics = 8
lda = LatentDirichletAllocation(n_components=n_topics, max_iter=50,
                                learning_method='batch',
                                learning_offset=50,
#                                 doc_topic_prior=0.1,
#                                 topic_word_prior=0.01,
                               random_state=0)
lda.fit(tf)

5. 各トピックに対応する単語を出力する

n_top_words = 25
tf_feature_names = tf_vectorizer.get_feature_names()
topic_word = print_top_words(lda, tf_feature_names, n_top_words)

6. 各記事の対応トピックを出力する 

import numpy as np
topics=lda.transform(tf)
topic = []
for t in topics:
    topic.append(list(t).index(np.max(t)))
data['topic']=topic
data.to_excel("data_topic.xlsx",index=False)
topics[0]#0 1 2 

7.可視化 

import pyLDAvis
import pyLDAvis.sklearn
pyLDAvis.enable_notebook()
pic = pyLDAvis.sklearn.prepare(lda, tf, tf_vectorizer)
pyLDAvis.save_html(pic, 'lda_pass'+str(n_topics)+'.html')
pyLDAvis.show(pic)

8.当惑

import matplotlib.pyplot as plt
plexs = []
scores = []
n_max_topics = 16
for i in range(1,n_max_topics):
    print(i)
    lda = LatentDirichletAllocation(n_components=i, max_iter=50,
                                    learning_method='batch',
                                    learning_offset=50,random_state=0)
    lda.fit(tf)
    plexs.append(lda.perplexity(tf))
    scores.append(lda.score(tf))

n_t=15#区间最右侧的值。注意:不能大于n_max_topics
x=list(range(1,n_t))
plt.plot(x,plexs[1:n_t])
plt.xlabel("number of topics")
plt.ylabel("perplexity")
plt.show()
n_t=15#区间最右侧的值。注意:不能大于n_max_topics
x=list(range(1,n_t))
plt.plot(x,scores[1:n_t])
plt.xlabel("number of topics")
plt.ylabel("score")
plt.show()

3、実際の操作

実行中にいくつか問題が発生しました. 確認および検索した結果、環境とバージョンの問題であり、バージョンを調整することで解決しました. conda=4.12.0, pandas=1.3.0, pyLDAvis で実行することをお勧めします. =2.1.2、基本的には問題ありません。

最終結果は次のとおりです。


要約する

LDA モデルの理解が不十分. csv ファイルをコードの操作に使用する場合, read_csv() を変更するだけで済みます. エンコードとデコードの問題もあります. gbk などを変更してみてください. 、ニワトリ、アドバイスできる大物がいるといいのですが。

おすすめ

転載: blog.csdn.net/weixin_46451009/article/details/127671146