본 강의는 DSBA 강필성 교수님의 강의를 참조하여 작성되었습니다.
Topic Modeling은 기계 학습 및 자연어 처리 분야에서 문서 집합 내에서 잠재적인 주제(Latent Topic)를 발견하기 위해 사용하는 통계적 모델링 기법입니다.
Topic Modeling을 활용하면 방대한 문서 데이터에서 잠재적인 의미 구조(Latent Structure)를 자동으로 학습할 수 있습니다.
이러한 특성으로 인해 데이터 레이블이 부족한 상황에서 유용하게 활용될 수 있으며, 문서 분류
, 추천 시스템
, 정보 검색
등의 다양한 응용 분야에서 중요한 역할을 합니다.
주요 특징
Topic Modeling을 수행하는 다양한 접근법이 존재합니다.
행렬 분해(Matrix Factorization)
기반 접근과 확률 모델(Probabilistic Model)
기반 접근으로 나눌 수 있습니다.행렬 분해 기반(Matrix Factorization) 접근
확률 모델(Probabilistic Model) 기반 접근
정의:
핵심 개념:
고차원 문서-단어 행렬을 저차원 잠재 의미 공간으로 압축 하여 주제를 추출하는 방식
SVD, NMF 등의 기법을 통해 행렬을 분해하고 이를 통해 주제를 학습
SVD
: Singular Value DecompositionNMF
: Non-negative Matrix Factorization 단어와 문서 간의 관계를 벡터 공간 내에서 수치적으로 분석
주요 기법:
Latent Semantic Analysis (LSA)
Non-negative Matrix Factorization (NMF)
(참고) Singular Value Decomposition (SVD)나 Non-negative Matrix Factorization (NMF)는 차원축소 기법의 일종이라고 봐도 무방합니다. (=> 이는 두 기법 모두 Matrix를 분해하기 때문)
- 이와 관련하여 좋은 참고 자료가 있어서 공유합니다. 아래 해당 내용에 대해서 다룰 예정임.
장점:
✔ 연산 속도가 상대적으로 빠르고 구현이 용이함
✔ 노이즈 제거 및 의미적 압축이 가능하여 문서 간 유사성 분석에 적합
✔ 차원 축소를 통해 문서와 단어의 관계를 시각적으로 분석 가능
단점:
✖ 확률 기반 접근이 아니므로 불확실성을 다루기 어려움
✖ 정규 분포를 가정하기 때문에 실제 데이터의 분포를 반영하지 못할 가능성이 있음
✖ 새로운 문서를 추가하면 기존 모델을 다시 학습해야 함
정의:
핵심 개념:
주요 기법:
Probabilistic Latent Semantic Analysis (pLSA)
Latent Dirichlet Allocation (LDA)
장점:
✔ 문서 내에서 각 주제의 확률적 분포를 학습할 수 있음
✔ 새로운 문서가 추가되어도 기존 모델을 재학습할 필요 없이 사전 학습된 주제 분포를 활용 가능
✔ 베이지안 접근을 활용하면 데이터의 불확실성을 보다 잘 반영할 수 있음
단점:
✖ 학습 과정이 상대적으로 복잡하고 계산 비용이 높음
✖ Gibbs Sampling 또는 Variational Inference를 사용해야 하므로 대규모 데이터에서는 학습 시간이 길어질 수 있음
✖ 주제 수(K)를 사전에 정해야 하며, 이를 잘못 설정하면 모델 성능이 저하될 수 있음
📌 행렬 분해 접근 vs 확률 모델 접근 비교 정리
구분 | 행렬 분해 (Matrix Factorization) | 확률 모델 (Probabilistic Model) |
---|---|---|
핵심 아이디어 | 문서-단어 행렬을 저차원으로 압축 | 문서는 여러 개의 주제로 구성되며 각 주제는 특정 단어의 확률적 분포를 가짐 |
주요 기법 | LSA (SVD), NMF | pLSA, LDA |
결과 해석 방식 | 선형 대수 기반 | 확률 기반 |
확률적 해석 가능 여부 | ❌ (확률 모델이 아님) | ✅ (확률적 모델) |
새로운 문서 처리 | 기존 모델을 다시 학습해야 함 | 기존 모델을 활용 가능 |
계산 비용 | 상대적으로 낮음 | 상대적으로 높음 |
적용 사례 | 검색 엔진, 추천 시스템, 문서 유사도 분석 | 문서 분류, 토픽 탐색, 트렌드 분석 |
단점 | 확률적 해석이 어려움 | 계산 비용이 높고 학습이 복잡함 |
(참고) Naïve Approach (MLE, Maximum Likelihood Estimation)
특정 문서 (Document, d)에서 단어 (Word, w)가 등장할 확률을 MLE(최대 우도 추정)로 구하는 방법.
한계점:
보완 방법:
❓ Zero-Frequency Problem (빈도 0 문제)이란?
Zero-Frequency Problem은 학습 데이터에 없는 단어나 단어 조합이 등장했을 때 확률이 0이 되어 모델이 일반화되지 못하는 문제입니다.
- 이를 해결하기 위해 다양한 스무딩(Smoothing) 기법이 사용되며, 데이터의 희소성 정도에 따라 적절한 방법을 선택해야 합니다.
- 간단한 문제 해결에는 Add-k 스무딩(Laplace)이 적절합니다.
- 데이터 희소성이 높은 경우에는 Good-Turing 스무딩이 효과적입니다.
- 실제 언어 모델에서 가장 성능이 좋은 방법은 Kneser-Ney 스무딩입니다.
- 따라서, 스무딩 기법을 적용하면 희소한 데이터에서도 언어 모델이 보다 일반화된 확률을 추정할 수 있으며, 검색, 번역, 텍스트 생성 등 다양한 NLP 작업에서 성능을 향상시킬 수 있습니다.
스무딩 기법 | 특징 | 장점 | 단점 |
---|---|---|---|
Additive Smoothing (Add-k) | 모든 빈도에 작은 값을 추가 | 구현이 간단 | 과도하게 균등한 확률 분포 |
Good-Turing Smoothing | 빈도 0인 단어를 낮은 빈도를 기반으로 추정 | 희소한 데이터에 적합 | 높은 빈도의 단어에 적용이 어려움 |
Kneser-Ney Smoothing | 문맥 내 사용 빈도를 고려 | 가장 효과적이고 정확도 높음 | 구현이 복잡 |
위에서 Topic Modeling을 분류해봤으니 이제 각각의 컨셉에 대해서 자세하게 살펴보도록 하겠습니다.
3.1.1 개념
데이터를 행렬로 표현하면, 행렬의 크기가 너무 크거나, 너무 복잡하여 분석이 어렵거나, 명확한 구조가 드러나지 않는 문제가 발생할 수 있음.
Latent Structure(잠재 구조)는 데이터 속에 숨겨진 패턴이나 구조를 찾아내는 과정을 의미함.
3.1.2 문제점
3.1.3 해결책: Latent Structure 찾기
3.2.1 개념
3.2.2 수학적 표현
3.2.3 특징
3.3.1 개념
❓ Singular Value Decomposition (SVD, 특이값 분해)란?
- Singular Value Decomposition (SVD, 특이값 분해)는 행렬을 세 개의 직교 행렬의 곱으로 분해하는 선형 대수 기법입니다.
- 이를 통해 고차원의 행렬을 저차원 잠재 의미 공간으로 변환할 수 있으며,
차원 축소
,노이즈 제거
,데이터 압축
등에 널리 사용됩니다.- SVD의 핵심 원리
- 행렬을 더 작은 의미 있는 구성 요소로 분해하여 주요한 패턴을 추출
- 데이터 차원을 줄이는 동시에 중요한 정보만 유지 가능
- 특이값(Singular Value)을 사용하여 행렬의 가장 중요한 구조를 학습
💌 SVD 수식 정리
SVD를 통해 입력 행렬 는 세 개의 행렬로 분해되는데, 각 행렬은 서로 다른 역할을 합니다.
💬 기호 설명
(입력 행렬, )
(왼쪽 직교 행렬, )
(대각 행렬, )
(오른쪽 직교 행렬, )
(참고) 👀 SVD 기하학적 해석
📌 SVD는 본질적으로 A라는 선형 변환을 "회전(Rotation)
→크기 조정(Scaling)
→다시 회전(Rotation)
"하는 과정으로 해석할 수 있습니다.
- 1️⃣ : 기저 변환 (Basis Change)
- 데이터(행렬 A)를 적절한 직교 좌표계(Orthogonal Basis)로 변환
- 즉, 원래 좌표계에서 새로운 좌표계로 변환하는 역할
- 2️⃣ : 축 방향 스케일링 (Scaling along Principal Axes)
- 각 좌표축 방향으로 데이터를 변형(크기 조절)
- 즉, 중요한 축(Principal Component) 방향으로 데이터를 늘리고 줄이는 역할
- 3️⃣ : 다시 회전 (Final Rotation back to original space)
- 변형된 데이터를 원래 좌표계로 회전 변환
- 💡 즉, SVD는 데이터를 보다 잘 정렬된 (직교) 좌표계로 변환하고, 그 안에서 주축을 따라 크기 조절한 후, 다시 원래 공간으로 변환하는 과정으로 볼 수 있습니다.
살짝 개념적인 이야기를 하다가 옆으로 빠졌는데 다시 LSA에 대해서 살펴보도록 하겠습니다.
LSA는 문서-단어 행렬(document-term matrix)에 SVD를 적용하여 숨겨진 의미(latent semantics)를 추출하는 기법입니다.
LSA를 통해 아래와 같은 것들을 수행할 수 있습니다:
3.3.2 LSA의 수학적 표현
행렬분해 기법(SVD)인 LSA를 수식으로 표현하면 아래와 같이 나타낼 수 있습니다:
3.3.3 LSA의 주요 과정
Step 1: 원본 행렬 를 SVD로 분해
여기서 는 선택한 잠재 차원의 수
를 사용하여 원래 행렬을 근사함.
Step 2: 주어진 행렬 를 이용하여 데이터 분석
Step 3: 데이터 분석에 활용
LSA를 통해 도출된 각각의 행렬을 활용하여 데이터 분석을 수행할 수 있습니다.
Image Source : https://medium.com/analytics-vidhya/what-is-topic-modeling-161a76143cae
1️⃣ : "토픽별 주요 단어 찾기"
📌 목적: 각 토픽(잠재 의미)을 대표하는 단어를 추출하여 주제를 해석하기 위함.
🤔 설명: 는 단어와 토픽 간의 관계를 나타내는 행렬로, 특정 주제를 구성하는 중요한 단어들을 파악할 수 있습니다.
📊 활용 예시:
2️⃣ : "문서 간 유사도 계산"
📌 목적: 문서 간의 의미적 유사도를 계산하여 비슷한 문서를 찾기 위함.
🤔 설명: 는 문서와 토픽 간의 관계를 나타내는 행렬입니다.
📊 활용 예시:
3️⃣ : "의미 기반 검색 (Query Expansion)"
📌 목적: 단순 키워드 매칭이 아닌, 의미적으로 연관된 문서를 찾기 위함.
🤔 설명: 를 활용하면 단순 키워드 매칭이 아닌, 의미적으로 관련 있는 문서를 검색할 수 있습니다.
📊 활용 예시:
✅ 장점:
❌ 한계:
다음은 LSA 코드 실습입니다.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.decomposition import TruncatedSVD
from sklearn.feature_extraction.text import TfidfVectorizer
# 1. 뉴스 기사 데이터 준비 (예제 문서)
documents = [
"중국의 저비용 인공지능(AI) 딥시크(DeepSeek)의 등장에 엔비디아 등 미국의 인공지능(AI) 관련 빅테크 기업들이 흔들리고 있다.",
"딥시크 등장에 기존 인공지능 기업들의 경쟁력이 의심받으며 최악의 주가 폭락이 일어났다.",
"중국이 값싸고 뛰어난 성능의 인공지능을 개발함으로써, 이 분야에서 미국을 앞설 수 있다는 분석도 나온다.",
"27일 미국 증시에서는 챗지피티(ChatGPT) 등 생성형 인공지능 출시 이후 증시에서 최대 빅테크 기업으로 성장한 엔비디아가 무려 17% 폭락해, 5890억달러가 증발됐다.",
"엔비디아 등 미 증시에서 비중이 큰 빅테크 기업들이 일제히 폭락하며 나스닥 지수는 3.1%, 엔스앤피(S&P)500 지수는 1.5%나 떨어졌다.",
"하지만, 빅테크 기업이 편입되지 않은 다우존스 지수는 0.7% 올랐다.",
"특히, 인공지능 및 반도체 관련주로 구성된 필라델피아 반도체지수는 9.15%나 폭락해, 지난해 9월3일 7.75% 이후 최대로 떨어졌다.",
"이 지수가 9% 이상 폭락하기는 코로나19 충격이 가해졌던 지난 2020년 3월18일 이후 처음이다."
]
# 2. TF-IDF 벡터화
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(documents)
# 3. LSA 적용 (SVD를 사용하여 차원 축소)
num_topics = 2 # 2개의 주요 주제 추출
svd = TruncatedSVD(n_components=num_topics)
X_lsa = svd.fit_transform(X)
# 4. 단어-토픽 행렬 (U_k)
terms = vectorizer.get_feature_names_out()
word_topic_matrix = pd.DataFrame(svd.components_.T, index=terms, columns=[f"Topic {i+1}" for i in range(num_topics)])
# 5. 문서-토픽 행렬 (V_k)
document_topic_matrix = pd.DataFrame(X_lsa, index=[f"Doc {i+1}" for i in range(len(documents))], columns=[f"Topic {i+1}" for i in range(num_topics)])
# 6. 주요 토픽 별 상위 단어 확인 (가장 중요한 단어 10개 출력)
print("📌 LSA 토픽 별 주요 단어")
for i in range(num_topics):
print(f"\n🔹 Topic {i+1}")
print(word_topic_matrix[f"Topic {i+1}"].abs().sort_values(ascending=False).head(10))
# 7. 문서-토픽 분포 시각화
plt.figure(figsize=(10, 6))
sns.heatmap(document_topic_matrix, annot=True, cmap="coolwarm", fmt=".2f")
plt.title("문서별 토픽 분포 (LSA 기반)")
plt.xlabel("토픽")
plt.ylabel("문서")
plt.show()
# 8. 결과 출력
print("\n📌 LSA 단어-토픽 행렬 (U_k)")
print(word_topic_matrix)
print("\n📌 LSA 문서-토픽 행렬 (V_k)")
print(document_topic_matrix)
코드 설명
1. TF-IDF 벡터화를 통해 문서를 수치화된 벡터로 변환 (A 생성)
2. SVD를 사용하여 차원 축소 (𝑘=2)
3. 코사인 유사도(Cosine Similarity) 를 계산하여 문서 간 유사도 측정
4. 유사도 행렬을 출력하여 문서 간의 관계를 확인
분석 수행
(1) , , 분해 결과
위 코드를 돌리면 각각 다음과 같이 , , 가 도출되어 나오는 것을 확인할 수 있습니다.
(2) Topic 분해 결과 - truncated svd (k=2)
Topic 1
: "AI & 증시 폭락 관련"Topic 2
: "증시 및 다우존스 상승/하락 관련"📌 LSA 토픽 별 주요 단어
🔹 Topic 1
지수는 0.314311
인공지능 0.287213
빅테크 0.274496
ai 0.218333
기업들이 0.198402
엔비디아 0.198402
증시에서 0.170829
떨어졌다 0.167795
등장에 0.163324
딥시크 0.163324
Name: Topic 1, dtype: float64
🔹 Topic 2
지수는 0.374815
인공지능 0.248398
올랐다 0.207143
하지만 0.207143
않은 0.207143
다우존스 0.207143
기업이 0.207143
편입되지 0.207143
딥시크 0.196706
등장에 0.196706
Name: Topic 2, dtype: float64
(3) 문서(문장) 별 토픽 분포
다음은 뉴스 기사의 각 문장들이 각각 어떤 topic에 연관성을 띄는지 분석한 그림입니다.
아래와 같이 해석해볼 수 있습니다:
🎓 (심화) 추가 분석 시나리오
- 위에서 정의해보았던 "Step 3: 데이터 분석에 활용"에 대해서 좀 더 심화있게 분석하고 싶다면 아래와 같이 분석을 해보실 수 있습니다.
1️⃣ : 토픽별 주요 단어 찾기
top_n_words = 5 lsa_topic_words = {} for i in range(num_topics): lsa_topic_words[f"Topic {i+1}"] = word_topic_matrix[f"Topic {i+1}"].abs().sort_values(ascending=False).head(top_n_words) lsa_topic_words_df = pd.DataFrame(lsa_topic_words) lsa_topic_words_df
2️⃣ : 문서 간 유사도 계산
from sklearn.metrics.pairwise import cosine_similarity doc_similarity = cosine_similarity(document_topic_matrix) doc_similarity_df = pd.DataFrame(doc_similarity, index=[f"Doc {i+1}" for i in range(len(documents))], columns=[f"Doc {i+1}" for i in range(len(documents))]) doc_similarity_df
3️⃣ : 의미 기반 검색
query = ["AI 주식 시장"] query_vector = vectorizer.transform(query) # TF-IDF 변환 query_lsa = svd.transform(query_vector) # LSA 변환 query_similarity = cosine_similarity(query_lsa, X_lsa) top_n = 3 most_relevant_docs = query_similarity.argsort()[0][-top_n:][::-1] for _doc in most_relevant_docs: print(documents[_doc])
하지만 LSA는 다음과 같은 한계를 가지고 있었습니다.
선형 모델의 한계
확률적 해석의 난해함
새로운 문서 일반화 불가능
메모리 및 계산량 문제
위와 같은 LSA의 한계를 해결하기 위해 Probabilistic Latent Semantic Analysis (pLSA)가 등장하였습니다.
🙌 pLSA의 핵심 가정
- 문서는 여러 개의 토픽(Topic)으로 구성된다.
- 각 토픽은 특정 단어들의 확률 분포(Word Distribution)를 가진다.
- 각 단어는 특정 토픽에서 발생할 확률을 가지며, 문서 내 단어 분포는 이러한 토픽 분포의 혼합으로 표현된다.
pLSA의 확률 모델 구조
즉, 문서 내 단어는 문서의 토픽 분포와 토픽 내 단어 분포의 조합으로 생성됩니다.
🤔 Expectation-Maximization(EM) 알고리즘이란?
EM 알고리즘은 모수에 관한 추정값으로 로그가능도(log likelihood)의 기댓값을 계산하는 기댓값 (E) 단계와 이 기댓값을 최대화하는 모수 추정값들을 구하는 최대화 (M) 단계를 번갈아가면서 적용한다. 최대화 단계에서 계산한 변수값은 다음 기댓값 단계의 추정값으로 쓰인다.
출처 : wikipedia EM 알고리즘 (링크)
1) E-Step (Expectation Step)
E-Step에서는 현재의 모델 파라미터(와 )를 사용하여 잠재 변수(Latent Variable)인 를 추정합니다.
수식은 다음과 같습니다:
:
:
:
이 단계에서는 현재의 모델 파라미터를 사용하여 각 단어가 특정 토픽에서 생성될 확률을 계산합니다.
2) M-Step (Maximization Step)
M-Step에서는 E-Step에서 계산된 를 사용하여 모델의 파라미터인 와 를 업데이트합니다.
문서-토픽 분포 업데이트:
토픽-단어 분포 업데이트:
여기서 는 문서 에서 단어 의 발생 횟수를 나타냅니다.
이 단계에서는 E-Step에서 계산된 를 사용하여 문서-토픽 분포와 토픽-단어 분포를 재계산합니다.
3) 반복 수행
💻 학습 과정 요약
- Initialization:
- 와 를 임의의 값으로 초기화합니다.
- E-Step (Expectation Step):
- 현재의 와 를 사용하여 를 계산합니다.
- 이는 전체 데이터를 사용하여 잠재 변수(Latent Variable)를 추정하는 과정입니다.
- M-step (Maximization Step):
- E-Step에서 계산된 를 사용하여 와 를 업데이트합니다.
- 이는 전체 데이터를 사용하여 파라미터를 최대화하는 과정입니다.
- Iteration/Convergence:
- 종료/수렴할 때까지 E-Step과 M-Step을 반복적으로 수행합니다.
- 각 iteration은 전체 데이터를 사용하므로, 딥러닝의 epoch과 유사한 역할을 합니다.
Image Source: https://www.geeksforgeeks.org/ml-expectation-maximization-algorithm/
확률적 해석 가능
새로운 문서에 대한 일반화 가능
언어 모델링에 더 적합한 구조
오버피팅 문제
Bayesian 확률 모델이 아님
LDA(Latent Dirichlet Allocation)의 등장
Probabilistic Latent Semantic Analysis(pLSA)는 기존의 LSA가 가지던 문제점(확률적 해석 불가능, 일반화 불가능, 계산량 문제)을 해결하는 데 기여했지만, 여전히 다음과 같은 한계를 지니고 있었습니다.
파라미터 수 증가 문제 (Overfitting)
일반화 문제 (Lack of Generative Model)
사전 확률(Prior) 부재
이러한 문제를 해결하기 위해 Latent Dirichlet Allocation (LDA)이 제안되었습니다.
LDA는 문서 내 단어가 여러 잠재적인 토픽(Latent Topics)에서 생성되었다고 가정하는 생성 모델(Generative Model)입니다.
문서 생성의 가정:
문제 해결 목표:
LDA는 문서가 아래와 같은 절차를 통해 생성된다고 가정합니다.
1) 초기 설정
2) 문서 생성 절차
3) 수학적 표현
LDA의 전체 문서 생성 과정은 확률적으로 다음과 같이 표현됩니다:
LDA의 주요 문제는 관측된 단어 만을 기반으로 잠재 변수 를 추정하는 것입니다.
이를 해결하기 위해 LDA에서는 다음과 같은 학습 방법이 사용됩니다.
1) Collapsed Gibbs Sampling
2) Variational Inference
Topic Modeling은 비정형 텍스트 데이터를 구조화하고 의미를 발견하는 강력한 기법으로, 문서 내 숨겨진 주제를 효과적으로 추출할 수 있습니다.
LSA, pLSA, LDA와 같은 대표적인 기법들은 각각의 특성과 한계를 가지며, 활용 목적과 데이터 특성에 따라 적절한 방법을 선택하는 것이 중요합니다.
Topic Modeling에서 핵심적인 요소는 적절한 토픽 개수 설정이며, 토픽 개수가 적절하지 않으면 과적합(Overfitting) 혹은 의미적 혼란이 발생할 수 있습니다.
최근 연구에서는 LDA를 기반으로 한 변형 모델들이 등장하면서 성능이 더욱 향상되고 있습니다.
읽어주셔서 감사합니다 😎