Latent Dirichlet Allocation(LDA)

Latent Dirichlet Allocation(LDA) とは?

Latent Dirichlet Allocation(LDA)は、自然言語処理におけるトピックモデルの一種で、文書集合に隠れたトピックを発見するために使われる統計的モデリング手法です。LDAは文書が複数のトピックから成ると仮定し、それぞれの文書のトピック分布と各トピックにおける単語の分布を推定します。このモデルは、2003年にBlei, Ng, and Jordanによって提案されました。

 この記事では、scikit-learnに実装されているLatentDirichletAllocationを利用してLDAを実際に行ってみたいと思います。

ライブラリのインポート

from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer
from nltk.corpus import stopwords
import nltk

自然言語処理を行うためのライブラリや、文書-単語行列を作成するためのクラス等をインポートします。

NLTKのストップワードリストのダウンロード

nltk.download('stopwords')

nltkライブラリから英語のストップワードリストをダウンロードします。ストップワードは分析に不要な一般的な単語(例:'the', 'is', 'at' など)です。

サンプルのテキスト

documents = [
    "Python is an excellent programming language",
    "Python and Java are popular programming languages",
    "Java is also used for software development"
]

今回はプログラミング言語に関わるサンプルのテキストを用意しました。

文章のベクトル化

stop_words = stopwords.words('english') 
vectorizer = CountVectorizer(stop_words=stop_words)
X = vectorizer.fit_transform(documents)

文書-単語行列を生成するためのCountVectorizerを利用します。ストップワードリストを設定しています。

LDAモデルの設定

lda = LatentDirichletAllocation(n_components=3, random_state=0)
lda.fit(X)

LDAモデルの設定を行っています。
fitでトピックを学習します。

トピックと単語の重要度を表示

features = vectorizer.get_feature_names_out()
for topic_idx, topic in enumerate(lda.components_):
    print("Topic #%d:" % topic_idx)
    print(" ".join([features[i] for i in topic.argsort()[:-5 - 1:-1]]))

get_feature_names_outはベクトル化された単語のリストを取得します。トピック毎に重要度の高い上位5単語を表示しています。

結果は下記の通りとなりました。

Topic #0: used software development also language
Topic #1: programming python java popular languages
Topic #2: programming python java language excellent

文書集合からPythonとJavaという二つのプログラミング言語に関する情報を抽出出来ました。