반응형

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는 관찰된 문서 내 단어들을 기반으로, 다음 두 가지를 베이즈 추론으로 동시에 추정합니다.
- 문서별 토픽 분포
- 토픽별 단어 분포
이때 사전 확률 분포로 디리클레(Dirichlet) 분포를 사용합니다.
- 디리클레 분포 – 다항 분포의 사전 분포
- 베타 분포 – 이항 분포의 사전 분포
3.2 LDA 수행 절차(개념 흐름)
- Count 기반 문서-단어 행렬 생성
- 토픽 개수(K)를 사전에 지정
- 각 단어에 임의의 토픽을 초기 할당
- 특정 단어 하나를 선택
- 해당 단어를 제외하고
- 문서-토픽 분포, 토픽-단어 분포 재계산
- 선택한 단어를 새로운 토픽 확률에 따라 재할당
- 모든 단어에 대해 4~5단계를 반복
- 지정된 반복 횟수 또는 수렴 시 종료
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 기반 벡터화가 필수이며, 토픽 개수 설정이 중요합니다.
- 결과 해석은 사람이 수행해야 하지만, 대규모 문서 분석에 매우 강력합니다.
반응형
'Programming' 카테고리의 다른 글
| 데이터 시각화 핵심 개념 한 번에 정리 (0) | 2026.02.15 |
|---|---|
| Mercari Price Suggestion— 대규모 텍스트 + 카테고리 데이터를 활용한 가격 예측 실전 프로젝트 (0) | 2026.02.14 |
| 감성분석(Sentiment Analysis) 정리: 지도학습 vs 감성사전(SentiWordNet/VADER) + IMDB 실습 (0) | 2026.02.14 |
| CountVectorizer부터 Pipeline/GridSearchCV까지: 뉴스그룹 분류로 배우는 피처 벡터화 + 희소행렬(COO/CSR) (0) | 2026.02.14 |
| NLP(Natural Language Processing)와 텍스트 전처리 핵심 정리― 개념부터 NLTK 실습까지 한 번에 이해하기 (0) | 2026.02.14 |