Topic Modeling은 입력으로 들어오는 문장(Sentence) 혹은 문서(Document)를 임베딩(Embedding)하고, 입력값을 대표하는 토픽을 도출하는 분야다. 문장 내에 n-gram을 이용해, 반복적으로 언급되는 단어를 도출하는 경우도 있으며, 사전에 정의한 K개의 단어 중 가장 유사하다고 판단되는 단어를 대표 주제로 선정하는 경우도 있다.
비즈니스 관점으로 바라본다면, 두 가지를 모두 적절히 적용하여야 활용성이 높다고 생각한다. 전자의 경우에는 사전에 정의하지 않은 단어 외에도 새로운 단어들을 반영하여 주제를 선정할 수 있으나, 새로운 주제가 계속 나타날 수 있으며 이를 다시 군집화하는 것이 어려울 수 있다. 반면에, 후자의 경우에는 사전에 정의한 토픽을 명확하게 군집화하여 볼 수 있으나, 새로운 주제가 입력으로 들어오더라도 사전에 정의한 토픽 외에는 파악하는 것이 어렵다는 단점이 존재한다.
과거에 외국계 A사와 협업하여 Topic Modeling을 수행하였을 때는 두 가지 방식을 적절히 사용하여, 문장과 토픽 간의 유사도가 일정 임계값보다 낮은 문장들은 n-gram 혹은 LLM을 통해 새로운 주제를 선정하는 2-stage 방식으로 접근하였다.
언어학(Linguistics)
갑자기 뜬금없이 Topic Modeling을 하는데, 언어학(Linguistics)이 왜 나오는가? 할 수 있다. 이번 글의 제목을 보면 알 수 있듯, Topic Modeling에 대해서 이론적인 접근을 기반으로 한다. 이론적인 접근을 하기 위해서는 언어학을 우선으로 알고 있어야 한다.
최근에 Topic Modeling에서 많이 사용하는 Embedding 모델은 긴 문장을 Embedding할 수 있는 Titan (Amazon)이나, 대표적인 Multi-Lingual 모델인 bge-m3 모델일 것이다.
우리는 모델의 크기가 크면 클수록 성능이 좋다라고 알고 있으며(Scaling Laws, https://arxiv.org/pdf/2001.08361/1000), 가장 크고 SoTA인 Embedding 모델을 가지고 와서 사용하면 된다고 생각할 것이다. 그러나, 기업에서 혹은 일부 환경에서는 비용 혹은 보안 문제로 인해 공개된 Open Source 모델을 사용하는 것에 제약이 있을 수 있다. 이러한 환경에서는 언어학 관점에서의 해석이 좋은 모델을 선정하는 것에 있어서 도움을 줄 수 있다.
그렇다면, 자연어 처리에서의 언어학은 무엇을 의미하는가? 이 글에서 언급하고 싶은 것은 굴절어, 고립어, 교착어를 의미한다.
- 굴절어 (Inflected Language)
단어의 형태(어미)가 문법적 기능(수, 격, 인칭 등)에 따라 굴절(변화)함. 어간과 접사의 경계가 불분명한 경우가 많으며, 대표적인 언어로는 영어, 프랑스어 등이 있다. - 고립어 (Isolating Language)
단어의 형태 변화가 전혀 없고, 문장 내 위치(어순)가 곧 문법적 역할을 결정함. 분석어라고도 하며, 대표적인 언어는 중국어가 있다. - 교착어 (Agglutinative Language)
어근(실질적 의미)에 접사(문법적 기능)가 덧붙어 단어가 구성되며, 어간과 어미가 비교적 명확히 분리되며, 대표적인 언어는 한국어, 일본어 터키어가 있다.
글로 보면 되게 어려워보일 수 있다. 쉽게 설명하자면, 굴절어는 I > My, Like > Likes 등과 같이 단어의 어미가 굴절(변화)하는 언어며, 교착어는 은, 는, 이, 가 와 같은 조사가 붙는 것으로 이해할 수 있다. 고립어는 我(나), 我的(나의) 와 같이 단어의 뜻 자체는 변화하지 않으나 위치에 따라 뜻이 달라지는 것을 의미한다. 영어는 굴절어의 특성을 근간으로 하고 있으나, 고립어의 성질도 일부 가지고 있다(동사, 주어 향태로 위치가 달라지면 의문문으로 변화). 한국어도 마찬가지로, 가+었다 > 갔다. 와 같은 경우에는 굴절어의 특성도 일부 가지고 있다라고 할 수 있다.
이 언어학적 특성을 파악하게 된다면, Positional Embedding의 중요성을 깨닫게 될 것이다. Transformer 구조를 보면, Input Embedding과 Positional Embedding을 합산하여 모델의 입력으로 사용하고 있다(Segment Embedding도 있으나, 일단 여기서는 Skip한다). 문장 내 단어의 순서에 대한 Embedding 값을 부여하는 Positional Embedding은 실제 학습하는 언어의 유형에 따라 다르게 설정될 수 있다라는 것이다(교착어는 단어 위치에 대한 중요도가 낮으나, 고립어는 매우 중요하다). 즉, 학습한 데이터의 종류, 언어 등에 따라 같은 단어라도 모델에 따라, 위치에 따라 Embedding 값이 달라질 것이다. 따라서 모델의 선정함에 있어서 원래 하던 방식 뿐만 아니라, 언어학 관점으로 바라보고 모델을 선정하는 새로운 관점이 생길 수 있다라는 것이다. (언어학 관점은 모델의 선정에 있어서 하나의 도구로 사용하며, 실제 모델 선택에 있어서는 추가적인 것들을 다 고려하여 선정하여야 한다)
연구 환경에 따라, distillation 된 작은 모델을 사용해야 된다면, 우리가 다루어야할 데이터의 성질에 따라 근간 모델의 학습한 데이터의 종류, 양, 언어 비중 등을 파악해야된다는 것을 시사한다.

문장 임베딩 (Sentence Embedding)
Topic Modeling에 있어서 입력으로 주어지는 문장을 어떻게 잘 표현할 지 파악하는 것이 가장 중요하다. 문장을 Embedding하게 된다면, $\mathcal{S} \in \mathbb{R}^{n \times m}$ 형태로 나올 것이다. 가장 기본적인 문장 Embedding Vector를 생성하는 것은 각 토큰별 평균을 취해, $mean(\mathcal{S}) \in \mathbb{R}^{1 \times m}$ 을 하는 것이다($n$는 토큰 수, $m$는 임베딩 차원 수). 단순히 평균을 취하는 것이 문장을 대표하는 하나의 차원으로 볼 수 있으나, 가장 큰 실수 중 하나다.

Word2Vec에서 각 단어끼리 서로 유사한 의미를 지니고 있다면, +/- 를 통해 King에서 Queen으로 바꿀 수 있다는 것을 들어본 적이 있을 것이다. 반면에, 문장은 여러 단어(토큰)들로 구성되어 있기 때문에 단순히 +/- 를 통한 평균을 취하는 것은 많은 정보의 손실을 야기할 수 있다. 잠시 Fourier Transform의 개념을 가지고 와보자. Fourier Transform은 하나의 신호를 여러 신호로 분해하여 다양한 주기를 가지는 sin, cos 형태로 변형하는 것을 의미한다. 갑자기 왜 Fourier Transform을 갖고 오는지 의문이 들 수 있다. 우리가 문장을 신호의 합으로 보고, 문장을 합한 값을 0이라고 가정해보자. 이때, 하나의 토큰은 -1의 값을 가지고, 다른 하나의 토큰은 +1을 가진다면, 우리가 보는 값은 0으로 아무런 시그널이 없는 하나의 점으로 할당될 것이다. 이것이 바로 단순한 합산 혹은 평균으로 문장을 대표하는 점을 할당하는 것에 대한 가장 큰 문제가 될 수 있다.
그렇다면, 합산, 평균 외에 어떤 것을 활용할 수 있을까? 가장 대표적인 방법이 PCA, UMAP, tSNE 등의 차원 축소 기법이 있을 것이다. PCA는 문장을 대표하는 eigen vector (주성분1)를 우선으로 선정하고, eigen vector에 직교(orthogonal)하는 다른 하나의 eigen vector (주성분2)를 선택해 나아가는 방식이다. 원래의 차원 $m$까지 가면 갈수록 설명력은 증가하고, 차원의 크기는 커진다.
$$ \mathcal{S}\in \mathbb{R}^{n \times m} \approx PCA(\mathcal{S}) \in \mathbb{R}^{n \times p}, p \leq m$$
그러나 PCA는 선형대수 관점에서의 접근이기 때문에 만약 단어 간의 비선형 관계가 존재한다면 고려하기 어렵다. 따라서, 이를 고려하기 위해 제안된 차원 축소 기법들이 tSNE, UMAP에 해당한다. 이는 다양체(Manifold) 즉, 위상공간을 고려한 차원 축소 기법이며, 차원 축소 기법에서 널리 사용되고 있다.
선형 관계만 고려하면 왜 좋지 않은가?에 대한 답변으로는, A4 종이를 예시로 많이 설명한다. A4 용지 양 끝 단에 점을 하나씩 찍어보자. 2차원 A4 용지에는 양 두 점이 가장 끝단에 존재하기 때문에 유사하지 않아보일 수 있다. 이때, A4용지의 양끝을 마주보도록 돌돌 말아보자. 이때에는 가장 가까운 점이 될 수 있다. 전자의 경우를 선형이라고 생각하고, 후자의 경우를 비선형이라고 생각하면 이해하기 쉬울 것이다.
다시 돌아가서, 우리가 문장을 임베딩하고, 비선형적인 구조를 파악하기 위한 최종 Matrix 혹은 Tensor가 도출되면, 사전에 정의해둔 단어의 임베딩 값과 내적하고 크기를 나누어주어 유사도를 계산한다. 이때, 유사도를 기준으로 일정 유사도 이하인 단어에 대해서는 새로운 토픽을 생성하는 식으로 모델을 설계할 수 있다.
새로운 토픽 생성
새로운 토픽을 생성하는 방법은 이전 단계에서 유사도가 낮은 문장들을 발췌하여 n-gram으로 문장을 대표하는 단어를 선정할 수 있다. 해당 방식이 일반적으로 사용되나, 최근에는 LLM을 사용하여 토픽을 자동으로 선정하는 방식을 많이 사용한다. n-gram을 사용하게 되면, 실제 문장 내에 문장을 대표하는 단어가 포함되어 있으면 좋은 방법이지만, 대표하는 단어가 포함되지 않은 경우에도 가장 대표할 법한 단어를 도출한다는 것이 문제다. 만약 뉴스에 대한 토픽을 선정하는 경우에는 KeyBERT와 모델을 사용하여 도출할 수 있지만, SNS 와 같은 주제에서는 다소 성능이 떨어질 수 있다.
이럴 때에는 LLM을 활용하여 문장으로 토픽이 될 법한 단어를 추론하는 방법을 사용한다. LLM을 토픽 추출에 사용하려면 LLM의 구조에 대해서 먼저 알아야 한다. LLM은 Next Token Prediction이며, 문장을 입력으로 받고, 다음으로 나올 확률이 가장 높은 단어를 생성하여 답변을 종료한다. 여기서 이야기하는 다음으로 나올 확률이 가장 높은 단어라는 것은 모델의 어휘 사전(Vocabulary) 내에 가장 유사한 단어를 의미한다. 다시 말하자면, 모델의 어휘 사전 내에 우리가 원하는 단어가 없다면 답변 자체를 못한다는 것이다. 이것이 바로 대표적인 할루시네이션(Hallucination) 현상 중 하나다.
그럼, 모델이 할루시네이션을 발생하는 지 안하는지 어떻게 알 수 있을까? 만약 모델을 학습하고 예측값을 볼 수 있다면, Perplexity를 확인하면 된다. Perplexity는 모델이 헷갈려하는 정도를 측정한 지표다. LLM은 Next Token Prediction 과정에서 Beam Search를 활용한다. 다음 생성될 후보 토큰을 선정하고, 계속 확장해 나아가면서 Perplexity가 최소화되는 문장을 선정하는 것이다. 하지만, Perplexity를 고려한다고 하더라도 할루시네이션 현상을 0%로 만드는 것은 어렵다.
그 다음으로는 할루시네이션을 완화할 수 있는 방법에 대해서 알아보자. 가장 대표적인 방법으로는 RAG (Retrieval Agmented Generation), DPO (Direct Preference Optimization), TTT (Test-Time Training) 등이 존재한다. 이번 글에서는 가장 간단한 RAG에 대해서만 다루어 볼 것이다.
RAG는 검색 혹은 Vector Search를 통해, 입력과 유사한 K개의 참고자료를 제공하여 Prompt에 함께 제공하여 모델의 할루시네이션을 줄이는 방식 중 하나다. (최근에는 MCP 를 활용하여 다양한 정보 혹은 LLM을 연결하는 Agentic AI 등도 많이 적용되고 있다) 새로운 주제의 문장이 들어올 때, Vector DB 내에 가장 유사한 문서를 제공하고, 해당 문서가 어떤 주제로 할당되었는지 Q&A 형태로 제공하고, 이에 대해서 LLM이 판단해 새로운 토픽을 생성하게 될 것이다.
위 방식으로 새로운 토픽이 생성되고, 문장에 할당되면 할당된 토픽이 제대로 할당되었는지 확인하고 적용하는 것이 가장 중요하다. 이때, 사용하는 방식이 DPO, TTT 등이 존재한다. 이는 실제 학습까지 이루어져야 하는 것이기 때문에 다음에 다루어 보도록 하자.
마무리
이렇게 Topic Modeling을 하는 과정에서 내가 이론적으로 고려한 부분에 대해서 간략하게나마 설명하였다. 실제 현업에서는 더 다양한 것들을 고려해야하고, ROI가 나와야하기 때문에 LLM을 최대한 적게 사용하여 비용을 절감하는 방식으로도 많이 사용한다. 최근에 LLM이 발전하면서 많은 사람들이 LLM을 통해 모델링을 하고 있다. OpenClaw 등의 Agentic AI를 사용하고 Claude의 Skills.md에 몇 줄만 작성해도 개발을 할 수 있는 세상이 도래하였다. 그 과정에서 이론적으로 접근하는 사람들이 많이 줄어들고, 만능 AI 시대로 발전해 나아가는 것 같아서, 이론으로 접근하는 방식에 대한 글이 있었으면 하는 마음에 작성하게 되었다.
코드는 여기를 참고하면 된다. (https://github.com/ceo21ckim/BERTopic-Tutorial)
'Deep Learning > Natural Language Processing' 카테고리의 다른 글
| [NLP] Pointwise Mutual Information (PMI) (0) | 2023.04.03 |
|---|---|
| [NLP] BERT의 종류 (2) | 2022.08.15 |
| Sequence-to-Sequence (Seq2Seq) (0) | 2022.05.12 |
| [NLP] Stemming and Lemmatization (0) | 2022.01.18 |
| [NLP] Tokenization (0) | 2022.01.18 |