Programming

토픽 모델링(Topic Modeling) 완전 정리— LDA 이론부터 20 Newsgroups 실습까지

Lucas.Kim 2026. 2. 14. 14:00
반응형

1. 개요

토픽 모델링(Topic Modeling)은 여러 문서 집합에 잠재되어 있는 공통된 주제(Topic)를 자동으로 추출하는 비지도 학습 기법입니다.
문서 군집화나 문서 유사도 분석과 비슷해 보일 수 있으나, 토픽 모델링은 다음과 같은 차별적인 특징을 가집니다.

  • 문서마다 여러 토픽이 어떤 비율로 섞여 있는지(문서-토픽 분포) 를 제공함
  • 각 토픽이 어떤 단어들로 구성되어 있는지(토픽-단어 분포) 를 제공함
  • 즉, “이 문서는 A 토픽 70%, B 토픽 20%, C 토픽 10%로 구성되어 있다” 와 같은 해석이 가능함

2. 토픽 모델링의 주요 계열

토픽 모델링은 크게 행렬 분해 기반확률 기반으로 나눌 수 있습니다.

2.1 행렬 분해 기반

  • LSA (Latent Semantic Analysis)
  • pLSA (probabilistic LSA)

문서-단어 행렬을 저차원 공간으로 분해하여 잠재 의미를 추출합니다.

2.2 확률 기반

  • pLSA
  • LDA (Latent Dirichlet Allocation)

확률 모델을 통해 문서와 토픽, 토픽과 단어의 관계를 확률 분포로 모델링합니다.
실무 및 이론에서 가장 널리 사용되는 모델이 바로 LDA입니다.


3. LDA(Latent Dirichlet Allocation) 핵심 이론

3.1 LDA의 기본 아이디어

LDA는 관찰된 문서 내 단어들을 기반으로, 다음 두 가지를 베이즈 추론으로 동시에 추정합니다.

  1. 문서별 토픽 분포
  2. 토픽별 단어 분포

이때 사전 확률 분포로 디리클레(Dirichlet) 분포를 사용합니다.

  • 디리클레 분포 – 다항 분포의 사전 분포
  • 베타 분포 – 이항 분포의 사전 분포

3.2 LDA 수행 절차(개념 흐름)

  1. Count 기반 문서-단어 행렬 생성
  2. 토픽 개수(K)를 사전에 지정
  3. 각 단어에 임의의 토픽을 초기 할당
  4. 특정 단어 하나를 선택
    • 해당 단어를 제외하고
    • 문서-토픽 분포, 토픽-단어 분포 재계산
  5. 선택한 단어를 새로운 토픽 확률에 따라 재할당
  6. 모든 단어에 대해 4~5단계를 반복
  7. 지정된 반복 횟수 또는 수렴 시 종료

3.3 LDA의 한계

  • 추출된 토픽은 사람이 직접 의미를 해석해야 함
  • 토픽 개수(K) 설정이 어렵고 주관적임
  • 불용어, 단어 필터링, 파라미터 설정에 따라 결과 민감

4. 사이킷런 LDA 주요 파라미터

사이킷런에서는 LatentDirichletAllocation 클래스를 제공합니다.

  • n_components : 토픽 개수(K)
  • doc_topic_prior : α (문서-토픽 분포의 디리클레 사전)
  • topic_word_prior : β (토픽-단어 분포의 디리클레 사전)
  • max_iter : 반복 횟수

5. 20 Newsgroups 토픽 모델링 실습

5.1 데이터 로딩 및 전처리

8개의 뉴스 그룹 카테고리만 선택하여 실습을 진행합니다.

from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation

cats = [
    'rec.motorcycles', 'rec.sport.baseball',
    'comp.graphics', 'comp.windows.x',
    'talk.politics.mideast', 'soc.religion.christian',
    'sci.electronics', 'sci.med'
]

news_df = fetch_20newsgroups(
    subset='all',
    remove=('headers','footers','quotes'),
    categories=cats,
    random_state=0
)

5.2 CountVectorizer 적용

LDA는 TF-IDF가 아닌 Count 기반 벡터를 사용합니다.

count_vect = CountVectorizer(
    max_df=0.95,
    max_features=1000,
    min_df=2,
    stop_words='english',
    ngram_range=(1,2)
)

feat_vect = count_vect.fit_transform(news_df.data)
print(feat_vect.shape)

출력 결과:

(7862, 1000)

5.3 LDA 모델 학습

lda = LatentDirichletAllocation(
    n_components=8,
    random_state=0
)

lda.fit(feat_vect)

6. 토픽-단어 분포 해석

components_ 속성은 토픽 × 단어 행렬입니다.

print(lda.components_.shape)

(8, 1000)

값이 클수록 해당 토픽에서 중요한 단어임을 의미합니다.

6.1 토픽별 핵심 단어 출력 함수

def display_topic_words(model, feature_names, no_top_words):
    for topic_index, topic in enumerate(model.components_):
        print('\nTopic #', topic_index)
        topic_word_indexes = topic.argsort()[::-1][:no_top_words]
        words = ' '.join([feature_names[i] for i in topic_word_indexes])
        print(words)

feature_names = count_vect.get_feature_names_out()
display_topic_words(lda, feature_names, 15)

6.2 해석 예시

  • Topic #0 : 의료 / 질병 / 건강
  • Topic #2 : 이미지, 파일, 그래픽
  • Topic #4 : 중동 정치 (이스라엘, 아르메니아 등)
  • Topic #6 : 기독교, 종교
  • Topic #7 : 윈도우, DOS, 서버

→ 실제 카테고리와 상당히 유사한 토픽이 자동 추출됨

7. 문서별 토픽 분포 확인

doc_topics = lda.transform(feat_vect)
print(doc_topics.shape)
print(doc_topics[:3])

출력 예:

(7862, 8)

7.1 문서별 토픽 분포 DataFrame

import pandas as pd

topic_names = ['Topic #' + str(i) for i in range(8)]
doc_topic_df = pd.DataFrame(doc_topics, columns=topic_names)
doc_topic_df.head()

이를 통해 다음과 같은 해석이 가능합니다.

  • 특정 문서가 어떤 토픽에 가장 강하게 속하는지
  • 하나의 문서가 여러 토픽에 어떻게 혼합되어 있는지

8. 정리

  • 토픽 모델링은 비지도 학습 기반 주제 추출 기법입니다.
  • LDA는 문서-토픽, 토픽-단어 분포를 확률적으로 모델링합니다.
  • Count 기반 벡터화가 필수이며, 토픽 개수 설정이 중요합니다.
  • 결과 해석은 사람이 수행해야 하지만, 대규모 문서 분석에 매우 강력합니다.
반응형