무냐의 개발일지
[3/21] NLP 프로젝트 3_BOW, TF-IDF,, Word2Vec, Word Embedding 본문
[3/21] NLP 프로젝트 3_BOW, TF-IDF,, Word2Vec, Word Embedding
무냐코드 2024. 3. 21. 17:03문서의 유사도를 구하기
텍스트를 숫자로 변환하는 Vectorization - 벡터화 방법으로는 크게 (1) 통계와 머신 러닝을 활용 (2) 인공 신경망을 활용
1. BOW & 코사인 유사도
- Bag of words 는 단어의 순서를 고려하지 않고, 단어의 등장 빈도(frequency)만을 고려해서 단어를 벡터화하는 방법입니다.
- Bag of Words는 단어들의 순서는 무시하고, 단어들의 빈도 정보는 그대로 보존해요.
- 각 key는 단어, 각 value는 각 단어가 주어진 문서에 등장한 횟수에요. 이때, 문서 내 단어의 순서는 중요하지 않습니다.
- keras Tokenizer , sklearn CountVectorizer 두 방법으로 만들 수 있다.
- 단어장(Vocabulary) 이라는 또 다른 개념을 이해해 보겠습니다. 문헌에 따라 사전 또는 단어 집합이라고 불리는데요. 단어장이란 중복을 제거한 단어들의 집합을 말합니다.
* 코사인 유사도
- 두 벡터 간의 유사도를 측정하는 방법 중 하나이며 두 벡터의 방향이 얼마나 유사한지를 나타내는 측정 지표로, 두 벡터가 이루는 각도의 코사인 값으로 계산됩니다.
- 코사인 유사도는 보통 -1과 1 사이의 값으로 나타내며, 두 벡터의 방향이 완전히 동일한 경우 1이 됩니다. 반대로, 두 벡터의 방향이 완전히 반대인 경우 -1이 됩니다. 두 벡터가 서로 독립적인 경우에는 0에 가까운 값이 나타납니다.
- 텍스트 데이터 분석, 추천 시스템, 이미지 처리 등 다양한 분야에서 활용됩니다.

2. TF-IDF (Term Frequency-Inverse Document Frequency)
DTM(Document-Term Matrix)
- Bag of words를 사용하여 문서 간 유사도를 비교하기 위한 행렬을 만들면, 이를 DTM(문서 단어 행렬, Document-Term Matrix) 이라고 합니다. 문서를 행으로, 단어를 열로 구성한 행렬이죠.
- 직역하면 문서-단어 행렬입니다. DTM은 여러 문서의 Bag of Words를 하나의 행렬로 구현한 것인데요. DTM은 각 문서에 등장한 단어의 빈도수를 하나의 행렬로 통합시킵니다.각 문서에서 사용된 단어의 빈도를 표시하며, 행은 문서를 나타내고 열은 단어를 나타냅니다. 텍스트 데이터의 각 문서를 벡터로 표현할 수 있으며, 이를 활용해 문서 간 유사도를 계산하거나 토픽 모델링 등의 분석을 수행할 수 있습니다.
- DTM의 문서 벡터나 단어 벡터는 대부분의 값이 0이라는 특징을 가지고 있는데, 이런 벡터를 희소 벡터(sparse vector) 라고 합니다
DTM은 문서를 행으로, 단어를 열로 가지는 행렬이지만, 문헌에 따라서는 열을 문서로 하고 단어를 행으로 하여 TDM(Term-Document Matrix) 이라고 부르기도 합니다.
DTM (Document-Term Matrix)은 문서-단어 행렬을 의미합니다.
- DTM을 만드는 방법 : CountVectorizer 활용

DTM의 한계점
1) DTM에서 문서의 수와 단어의 수가 계속 늘어날수록, 행과 열은 대부분의 값이 0을 가진다는 특징이 있습니다. 이는 저장 공간 측면에서 낭비입니다.
2) 단어의 빈도에만 집중하는 방법 자체의 한계입니다. 예를 들어, 영어 데이터를 가지고 DTM을 만들었을 때, 불용어 'the'는 어떤 문서에서도 자주 등장하는 경향이 있습니다. 문서1과 문서2에서 둘 다 'the'가 많이 등장했다고 하여 이 두 문서가 유사한 문서라고 볼 수는 없다.
그래서 등장한 TF-IDF!
각 단어의 중요도를 판단하여 가중치를 주는 방법
DTM에서 특정 단어가 얼마나 중요한지를 나타내는 지표입니다. 많이 나오는 일반적인 단어들은 중요하지 않은 단어로 간주되고, 문서를 잘 나타내는 중요한 단어들이 높은 점수를 받게 됩니다.
- TF-IDF는 불용어처럼 중요도가 낮으면서 모든 문서에 등장하는 단어들이 노이즈가 되는 것을 완화해 줍니다.
- 사이킷런에서는 TF-IDF를 자동으로 계산하여 출력하는 TfidfVectorizer 을 사용한다
- 모든 문서에서 자주 등장하는 단어는 중요도가 낮다고 판단하며, 특정 문서에서만 자주 등장하는 단어는 중요도가 높다고 판단하는 것
- DTM의 한계점을 극복 (그렇다고 DTM보다 항상 성능이 뛰어나다거나 그런 건 아님)
- 단어의 빈도를 의미하는 TF는 사실 이미 배웠습니다. DTM이 이미 TF 행렬이기 때문이죠! 그리고 DTM의 각 단어에 IDF 값을 곱해주면 TF-IDF 행렬이 완성됩니다.

Q : 전체 문서 수 5개 중, 2개 문서에서만 like 라는 단어가 하나는 200번, 하나는 300번 등장했을 때, like의 IDF값은?
DF=2, N=5, -> like 의 IDF = log(5/2) = 0.916
Q : 문서2와 문서3에서의 like의 TF-IDF값은?
문서2 TF = 200 -> TF-IDF = 200 x log(5/2) = 183.258
문서3 TF = 300 -> TF-IDF = 300 x log(5/2) = 274.887
(* TF 문장을 구성하는 단어들의 원-핫 벡터들을 모두 더해서 문장의 단어 개수로 나눈 것과 같습니다.)
==> 문서 3에서의 TF-IDF값이 높으므로, 중요도가 더 높다.
BOW, TF-IDF의 단점
동음이의어 핸들링하기 어렵다.
단어만 보기 때문에, 의미까지 고려 못한다
-> LSA, Word Embeddings (Word2Vec, Glove), ConceptNet 등
3. LSA, LDA (토픽모델링 알고리즘)
그래서 등장한 LSA(Latent Semantic Analysis), LDA!
1) LSA
DTM을 활용해 문서 간 유사도를 계산하는 방법 중 하나입니다.
단어-문서 행렬에서 잠재적인 의미를 추출하여 문서를 벡터 공간 상에 표현합니다. 이를 통해 문서 간 유사도를 계산할 수 있습니다.
단어와 단어 사이, 문서와 문서 사이, 단어와 문서 사이의 의미적 유사성 점수를 찾아낼 수 있습니다.
문서의 집합에서 토픽을 찾아내는 프로세스를 토픽 모델링(Topic Modelling)이라고 한다.
*SVD : 특잇값 분해(Singular Value Decompotion)
특잇값 분해(Singular Value Decomposition, SVD) 란 m × n 크기의 임의의 사각 행렬 A를 위의 그림의 Full SVD와 같이 특이 벡터(singular vector)의 행렬와 특잇값(singular value)의 대각행렬로 분해하는 것을 말합니다.
정방행렬은 고유분해로 고유값과 고유벡터를 찾을 수 있었다. 정방행렬이 아닌 행렬은 고유분해가 불가능하지만, 대신 고유분해와 비슷한 특이분해를 할 수 있다.
행렬 A에 특잇값 분해를 수행하면 U, Σ, V라는 세 가지 행렬로 분해됩니다. 이때, 특잇값(singular value)은 Σ 행렬의 주대각선 상에 위치한 값들입니다.
*Truncated SVD
특잇값 가운데 가장 큰(다시 말해, 가장 중요한) t개만 남기고 해당 특잇값에 대응되는 특이 벡터(singular vector) 들로 행렬 A를 근사(approximate) 하도록 하면, 이를 절단된 특잇값 분해(Truncated SVD) 라고 합니다.
Truncated SVD를 수행하면 행렬 Σ의 대각 원솟값 중에서 상윗값 t개만 남게 되며, U행렬과 V행렬의 t열까지만 남습니다. 이로 인해 세 행렬에서 값(정보)의 손실이 일어나 기존의 행렬 A를 정확히 복구할 수는 없게 됩니다.
LSA는 DTM이나 TF-IDF 행렬 등에 Truncated SVD를 수행합니다. 이렇게 분해하여 얻은 행렬 3개()는 각각 '문서들과 관련된 의미들을 표현한 행렬', '단어들과 관련된 의미를 표현한 행렬' , '각 의미의 중요도를 표현한 행렬' 이라고 해석할 수 있습니다.

2) LDA 잠재 디리클레 할당(Latent Dirichlet Allocation, LDA)
- 문서 내의 토픽 분포와 토픽 내 단어 분포를 추정하여 토픽 모델링을 수행하는 방법입니다. 각 문서는 여러 개의 토픽으로 구성되어 있으며, 각 토픽은 단어들의 확률 분포로 나타내어집니다. 이를 통해 각 문서가 어떤 주제를 다루는지를 파악할 수 있습니다.
- 토픽 모델링의 또 다른 대표적인 알고리즘으로, 문서의 집합으로부터 어떤 토픽이 존재하는지를 알아내기 위한 알고리즘
- LDA는 문서들이 토픽들의 혼합으로 구성되어 있으며, 토픽들은 확률 분포에 기반하여 단어들을 생성한다고 가정합니다. 그리고 데이터가 주어지면, LDA는 이 가정에 따라 단어들의 분포로부터 문서가 생성되는 과정을 역추적해 문서의 토픽을 찾아냅니다.
- LDA는 각 토픽의 단어 분포와 각 문서의 토픽 분포를 추정해냅니다.
- LDA는 전체 코퍼스, 즉 다수의 문서들로부터 토픽을 뽑아내기 위해서 하나의 가정을 염두에 두고 있습니다. 모든 문서 하나, 하나가 작성될 때 그 문서의 작성자는 아래와 같은 생각을 했다는 가정입니다.
- LDA를 수행할 때 문서 집합에서 토픽이 몇 개가 존재할지 가정하는 것은 사용자가 해야 할 일입니다. 토픽의 개수를 의미하는 변수를 k라고 하였을 때, k를 2로 한다는 의미입니다.
| LDA 수행 과정
1) 사용자는 알고리즘에게 토픽의 개수 k를 알려줍니다.
2) 모든 단어를 k개 중 하나의 토픽에 할당합니다.
랜덤으로 할당합니다. 이 작업이 끝나면 각 문서는 토픽을 가지며, 토픽은 단어 분포를 가지는 상태입니다. 물론 랜덤으로 할당하였기 때문에 사실 이 결과는 전부 틀린 상태입니다. 만약 한 단어가 한 문서에서 2회 이상 등장하였다면, 각 단어는 서로 다른 토픽에 할당되었을 수도 있습니다.
3) 이제 모든 문서의 모든 단어에 대해서 아래의 사항을 반복 진행합니다. (iterative)
3-1) 어떤 문서의 각 단어 w는 자신은 잘못된 토픽에 할당되어져 있지만, 다른 단어들은 전부 올바른 토픽에 할당되어져 있는 상태라고 가정합니다. 이에 따라 단어 w는 아래의 두 가지 기준에 따라서 토픽이 재할당됩니다.
- p(topic t | document d) : 문서 d의 단어들 중 토픽 t에 해당하는 단어들의 비율
- p(word w | topic t) : 각 토픽들 t에서 해당 단어 w의 분포
결과적으로, LSA는 DTM을 차원 축소하여 축소 차원에서 근접 단어들을 토픽으로 묶는 반면에, LDA는 단어가 특정 토픽에 존재할 확률과 문서에 특정 토픽이 존재할 확률을 결합 확률로 추정하여 토픽을 추출합니다.
---
여기까지는 단어의 분포를 이용한 토큰화였고, 이제 텍스트의 분포를 이용한 토큰화를 알아보자. 한국어는 교착어라서, '을,를,이,가'같은 게 붙어있으면 다 다른 단어로 인식하거든.
* 형태소 분석기로 단어 미등록 문제를 해결할 수 있는 방법
사용자 사전 등록: 사용자가 직접 미등록 단어를 사전에 등록해 주는 방법입니다.
이를 통해 미등록 단어에 대한 분석 정확도를 높일 수 있습니다.
자동사전 생성: 미등록 단어를 자동으로 추출하여 사전에 등록하는 방법입니다. 이를 위해서는 대용량의 텍스트 데이터를 활용하여 빈도 수 등을 기반으로 자동으로 사전을 생성합니다.
기존 단어 활용: 형태소 분석기는 단어의 어간 등을 추출하는 방식으로 동작합니다. 이때, 미등록 단어라도 기존 단어의 어간과 유사한 부분이 있다면, 해당 부분을 활용하여 분석을 수행할 수 있습니다.
문맥 분석: 미등록 단어의 문맥을 분석하여, 해당 단어가 명사, 동사 등의 품사 중 어떤 것에 가까운지를 예측하여 분석을 수행할 수 있습니다. 이를 위해서는 머신 러닝 기반의 분류 모델을 이용하여 분석을 수행합니다.
---
하나의 단어이지만 형태소 분석 결과에서는 전부 분리된 결과를 보여줄 때, 예를 들어, '모두의연구소'라는 문자열이 자주 연결되어 등장한다면 형태소라고 판단하고, '모두의연구소'라는 단어 앞, 뒤에 '최고', 'AI', '실력'과 같은 독립된 다른 단어들이 계속해서 등장한다면 '모두의연구소'를 형태소로 파악하는 식이지요. 이런 아이디어를 가진 형태소 분석기가 soynlp입니다.
soynlp는 품사 태깅, 형태소 분석 등을 지원하는 한국어 형태소 분석기입니다. 자주 등장하는 신조어나 오탈자, 그리고 형태소 분석에서 발생하는 OOV(Out-of-Vocabulary) 문제를 처리하는 데 강점을 가지고 있습니다. 데이터에서 단어 빈도수를 기반으로 단어들을 자동으로 추출하며, 이를 활용해 형태소 분석을 수행합니다.
비지도 학습으로 형태소 분석을 한다는 특징을 갖고 있으며, 데이터에 자주 등장하는 단어들을 형태소로 분석합니다.
soynlp 형태소 분석기는 내부적으로 단어 점수표로 동작합니다. 이 점수는 응집 확률(cohesion probability) 과 브랜칭 엔트로피(branching entropy) 를 활용합니다.
soynlp의 응집 확률(cohesion probability)
응집 확률은 내부 문자열(substring)이 얼마나 응집하여 자주 등장하는지를 판단하는 척도입니다. 응집 확률은 문자열을 문자 단위로 분리하여 내부 문자열을 만드는 과정에서, 왼쪽부터 순서대로 문자를 추가하면서 각 문자열이 주어졌을 때 그다음 문자가 나올 확률을 계산하여 누적 곱을 한 값입니다. 이 값이 높을수록 전체 코퍼스에서 이 문자열 시퀀스는 하나의 단어로 등장할 가능성이 높습니다. 수식은 아래와 같습니다.
soynlp의 브랜칭 엔트로피(branching entropy)
브랜칭 엔트로피(Branching Entropy) 는 확률 분포의 엔트로피값을 사용합니다. 이는 주어진 문자열에서 다음 문자가 등장할 수 있는 가능성을 판단하는 척도입니다. 이해를 위해 퀴즈를 내보겠습니다.
soynlp의 LTokenizer
띄어쓰기 단위로 잘 나뉜 문장은 L 토크나이저(LTokenizer)를 사용하면 좋습니다.
한국어는 띄어쓰기 단위로 나눈 어절 토큰이 주로 L 토큰 + R 토큰의 형식을 가질 때가 많습니다. 예를 들어서 '공원에'는 '공원 + 에'로 나눌 수 있겠지요. 또는 '공부하는'은 '공부 + 하는'으로 나눌 수도 있을 것입니다. L 토크나이저는 L 토큰 + R 토큰으로 나누되, 점수가 가장 높은 L 토큰을 찾아내는 분리 기준을 가지고 있습니다.
원-핫 인코딩(one-hot encoding)
모든 단어의 관계를 독립적으로 정의하는 원-핫 인코딩이라는 방식
원-핫 인코딩을 통해 얻은 벡터를 원-핫 벡터(one-hot vector) 라고 합니다
희소 벡터(Sparse Vector)의 문제점
DTM, TF-IDF, 원-핫 벡터는 단어장의 크기에 영향을 받는 희소 벡터(sparse vector) 라는 특징을 가지고 있습니다
( 희소행렬은 행렬의 값이 대부분 0인 경우를 가리키는 표현)
1) 희소 벡터에는 차원의 저주(curse of dimensionality) 라는 문제가 있습니다.
고차원에서는 정보가 흩어지며 밀도가 작아질 거예요.
2) 원-핫 벡터를 통해서는 단어 벡터 간 유사도를 구할 수 없음 (그냥 다 1,0 으로 표현돼버리니까)
워드 임베딩
- 단어 간에 유사도를 구할 수 있도록 만든 거
- 이에 대한 대안으로 '기계가 단어장 크기보다 적은 차원의 밀집 벡터(dense vector)를 학습'하는 워드 임베딩(word embedding) 이 제안되었습니다. 이를 통해 얻는 밀집 벡터는 각 차원이 0과 1이 아닌 다양한 실숫값을 가지며, 이 밀집 벡터를 임베딩 벡터(embedding vector) 라고 합니다.
- 워드 임베딩에서도 한 단어를 벡터로 바꿉니다. 그런데 그 벡터의 길이를 일정하게 정해줍니다. 더 많은 단어가 있다고 해서 벡터의 길이가 길어지지 않습니다. 일반적으로 벡터의 길이가 단어장 크기보다 매우 작기 때문에 각 벡터 값에 정보가 축약되어야 하고 결국 밀집 벡터(dense vector) 가 됩니다.

워드 임베딩에서 중요한 것은 두 가지 입니다.
- 한 단어를 길이가 비교적 짧은 밀집 벡터로 나타낸다.
- 그런데 이 밀집 벡터는 단어가 갖는 의미나 단어 간의 관계 등을 어떤 식으로든 내포하고 있다.
임베팅 벡터의 값은 훈련 데이터로부터 어떤 모델을 학습하는 과정에서 '자동'으로 얻어지는데, 주로 언어 모델(Language Model)을 학습하는 가운데 얻어짐.
워드 임베딩을 보완한 3가지
1) Word2Vec
Word2Vec에는 크게 CBoW와 Skip-gram라는 두 가지 방법이 있습니다.

w1, w2 값이 계속 바뀌면서 target 값 (neighbor, input과 가까운 값)을 구할 것이다
분포 가설(Distributional Hypothesis)
Word2Vec은 앞서 말했듯이 단어를 벡터로 표현하는 방법의 일종으로 저차원으로 이루어져 있고, 단어의 의미를 여러 차원에 분산하여 표현한 벡터입니다.
Word2Vec의 핵심 아이디어는 분포 가설(distributional hypothesis) 을 따릅니다
분포 가설에 따르는 Word2Vec은 같이 등장하는 경향이 적은 단어들에 비해 '강아지', '애교, '귀여운'과 같은 단어들을 상대적으로 유사도가 높은 벡터로 만듭니다.
CBoW
중간에 있는 단어를 예측하는 방법
예측해야 하는 단어 "natural"을 중심 단어(center word) 라고 하고, 예측에 사용되는 단어들을 주변 단어(context word) 라고 합니다.
윈도우 크기를 정했다면, 윈도우를 계속 움직여서 주변 단어와 중심 단어를 바꿔가며 학습을 위한 데이터 셋을 만들 수 있는데, 이 방법을 슬라이딩 윈도우(sliding window) 라고 합니다. 윈도우 크기가 1이고, 예측하고자 하는 중심 단어가 "language"라면 앞의 한 단어인 "natural"과 뒤의 한 단어인 "processing"을 참고합니다. 윈도우 크기가 m일 때, 중심 단어를 예측하기 위해 참고하는 주변 단어의 개수는 2m입니다.

윈도우 크기가 m이라면 2m개의 주변 단어를 이용해 1개의 중심 단어를 예측하는 과정에서 두 개의 가중치 행렬(matrix)을 학습하는 것이 목적이죠. 그림에서 주황색 사각형이 첫 번째 가중치 행렬, 초록색 사각형이 두 번째 가중치 행렬입니다.
CBoW는 이 출력층의 벡터를 중심 단어의 원-핫 벡터와의 손실(loss)을 최소화 하도록 학습시킵니다
Skip-gram
중심 단어로부터 주변 단어를 예측한다

중심 단어로부터 주변 단어를 예측한다는 점, 그리고 이로 인해 중간에 은닉층에서 다수의 벡터의 덧셈과 평균을 구하는 과정이 없어졌다 는 점만 제외하면 CBoW와 메커니즘 자체는 동일합니다.
네거티브 샘플링(negative sampling)
- 주어진 데이터에서 무작위로 음성(negative) 샘플을 추출하는 방법입니다.
이를 통해, 양성 샘플과 음성 샘플의 수를 균형있게 맞추어, 모델이 학습할 수 있는 환경을 만들어줍니다. 예를 들어, 이메일 스팸 필터링 모델에서는, 스팸 데이터와 정상적인 이메일 데이터를 균형있게 추출하여 모델을 학습시키면, 더욱 정확한 분류 결과를 얻을 수 있습니다.
- 네거티브 샘플링은 단순히 무작위 샘플링을 하는 것이 아니라, 더 중요한 샘플에 더 많은 가중치를 부여하여 샘플링 비율을 조절할 수 있습니다. 이를 통해, 모델이 보다 중요한 샘플에 더 집중하도록 할 수 있습니다.
- 대체적으로 Word2Vec를 사용할 때는 SGNS(Skip-Gram with Negative Sampling) 을 사용합니다.
- 네거티브 샘플링은 연산량을 줄이기 위해서 소프트맥스 함수를 사용한 개 중 1개를 고르는 다중 클래스 분류 문제 를 시그모이드 함수를 사용한 이진 분류 문제 로 바꾸기로 합니다


중심 단어와 주변 단어를 입력값으로 받아 이 두 단어가 정말로 이웃 관계면(실제로 중심 단어와 주변 단어의 관계면) 1을 또는 0을 출력하는 문제로 바꾸는 것지요.

0으로 레이블링 해주는 경우는 실제로 이웃 관계(중심 단어와 주변 단어)가 아닌 경우입니다.
임베딩 벡터 시각화 (https://projector.tensorflow.org/)
2) FastText
- 페이스북에서 개발한 FastText는 Word2Vec 이후에 등장한 워드 임베딩 방법으로, 메커니즘 자체는 Word2Vec을 그대로 따르고 있지만, 문자 단위 n-gram(character-level n-gram) 표현을 학습한다는 점에서 다릅니다.
- Word2Vec은 단어를 더 이상 깨질 수 없는 단위로 구분하는 반면, FastText는 단어 내부의 내부 단어(subwords)들을 학습한다는 아이디어를 가지고 있습니다.
- FastText의 n-gram에서 n은 단어들이 얼마나 분리되는지 결정하는 하이퍼파라미터입니다. n을 3으로 잡은 트라이그램(tri-gram)의 경우, 단어 "partial"은 'par', 'art', 'rti', 'tia', 'ial'로 분리하고 이들을 벡터로 만듭니다. 더 정확히는 시작과 끝을 의미하는 <, >를 도입하여 <pa, par, art, rti, tia, ial, al>라는 6개의 내부 단어(subword) 토큰을 벡터로 만듭니다. 여기에 추가적으로 하나를 더 벡터화하는데, 기존 단어에 <, 와 >를 붙인 토큰 <partial>입니다.
FastText의 학습 방법
- 사실 FastText의 학습 방식은 Word2Vec와 크게 다르지 않습니다. FastText도 Word2Vec과 마찬가지로 네거티브 샘플링을 사용하여 학습합니다.
- "(중심 단어, 주변 단어)"의 쌍을 가지고 이 쌍이 포지티브인지 네거티브인지 예측을 진행하는 것이죠. 다만, Word2Vec과 다른 점은 학습 과정에서 중심 단어에 속한 문자 단위 n-gram 단어 벡터들을 모두 업데이트한다는 점입니다
- FastText는 Word2Vec과 달리 OOV와 오타에 강건하다(robust) 는 특징이 있습니다.
3) GloVe
- 글로브(Global Vectors for Word Representation, GloVe) 는 2014년에 미국 스탠포드 대학에서 개발한 워드 임베딩 방법론입니다. 워드 임베딩의 두 가지 접근 방법인 카운트 기반과 예측 기반 두 가지 방법을 모두 사용했다 는 것이 특징입니다.
- 카운트 기반 방법이라는 것은 어떤 의미일까요? 앞서 단어의 빈도를 수치화한 방법인 DTM을 배웠었죠. DTM의 경우에는 단어 간 유사도를 반영할 수 없을 뿐만 아니라, 대부분의 값이 0인 희소 표현이라는 특징이 있었습니다. DTM을 차원 축소하여 밀집 표현(dense representation)으로 임베딩 하는 방법이 LSA(Latent Semantic Analysis) 입니다.
잠재 의미 분석(LSA, Latent Semantic Analysis)
잠재 의미 분석에 대해서는 아래의 링크를 통해 정리해보겠습니다.
LSA를 요약하면 DTM에 특잇값 분해를 사용하여 잠재된 의미를 이끌어내는 방법론 입니다. 그 결과의 행벡터를 사용해서 임베딩 벡터를 얻을 수도 있지요. LSA는 단어를 카운트해서 만든 DTM을 입력으로 하므로 카운트 기반의 임베딩 방법이라고 볼 수 있는데, 이 방법은 몇 가지 한계가 있었습니다.
(1) 차원 축소의 특성으로 인해 새로운 단어가 추가되면 다시 DTM을 만들어 새로 차원 축소를 해야 한다.
(2) 단어 벡터간 유사도를 계산하는 측면에서 Word2Vec보다 성능이 떨어진다.
반면, LSA와 대조되는 방법으로 예측 기반의 방법 은 Word2Vec과 같은 방법을 말합니다. Word2Vec은 인공 신경망이 예측한 값으로부터 실제 레이블과의 오차를 구하고, 손실 함수를 통해서 인공 신경망을 학습하는 방식이었죠. GloVe 연구진은 Word2Vec의 경우에는 LSA보다 단어 벡터 간 유사도를 구하는 능력은 뛰어나지만, LSA처럼 코퍼스의 전체적인 통계 정보를 활용하지는 못한다는 점을 한계로 지적했습니다. 그리고는 카운트 기반과 예측 기반을 모두 사용하여 Word2Vec보다 더 나은 임베딩 방법을 제안하였는데, GloVe가 그 주인공입니다. 하지만 경험적으로 봤을 때, GloVe가 Word2Vec보다 반드시 뛰어나다고 장담하기는 어렵고, Word2Vec에 거의 준하는 성능을 보여준다고 평가되고 있습니다.
윈도우 기반 동시 등장 행렬(Window based Co-occurrence Matrix)
GloVe를 이해하기 위해서는 윈도우 기반 동시 등장 행렬 의 정의에 대해서 이해할 필요가 있습니다. 다음과 같이 3개의 문장이 있는 코퍼스가 있다고 해봅시다.
Example corpus:
- I like deep learning.
- I like NLP.
- I enjoy flying.
이로부터 만들어진 동시 등장 행렬(Co--occurence Matrix)은 다음과 같습니다.

윈도우 기반 동시 등장 행렬은 행과 열을 전체 단어장(vocabulary)의 단어들로 구성하고, 어떤 i 단어의 윈도우 크기(window Size) 내에서 k 단어가 등장한 횟수를 i행 k열에 기재한 행렬 입니다. 위의 경우에는 윈도우 크기를 1로 하였습니다. 이러한 동시 등장 행렬은 전치(transpose)해도 동일한 행렬이 된다는 특징을 가지고 있습니다.
동시 등장 확률(Co-occurrence Probability)
동시 등장 행렬에 대해서 이해했다면, 동시 등장 확률에 대해서 이해해봅시다. 동시 등장 확률 �(�∣�) 는 동시 등장 행렬로부터 특정 단어 i의 전체 등장 횟수를 카운트하고, 특정 단어 i가 등장했을 때 어떤 단어 k가 등장한 횟수를 카운트하여 계산한 조건부 확률입니다. 이때 i를 중심 단어(center word), k를 주변 단어(context word) 라고 합니다.
위 동시 등장 확률 표는 실제 GloVe 논문에 제시되었던 표입니다. 위의 표를 통해 알 수 있는 사실은 ice가 등장했을 때 solid가 등장할 확률은 large인 반면, steam이 등장했을 때 solid가 등장할 확률은 small이라는 점입니다. 이는 solid는 '단단한'이라는 의미를 가졌으니까 '증기'라는 의미를 가지는 steam보다는 당연히 '얼음'이라는 의미를 가지는 ice라는 단어와 더 자주 등장하기 때문입니다.
GloVe의 손실 함수 설계하기
GloVe는 동시 등장 행렬로부터 계산된 동시 등장 확률을 이용해 손실 함수를 설계합니다. 동시 등장 행렬을 사용하고 있으니 코퍼스의 전체적인 통계 정보를 활용하는 '카운트 기반'의 방법론이면서, 손실 함수를 통해 모델을 학습시키므로 '예측 기반'의 방법론이라고 할 수 있는 것이죠.
GloVe의 아이디어를 한 줄 요약하면 다음과 같습니다.
중심 단어 벡터와 주변 단어 벡터의 내적이 전체 코퍼스에서의 동시 등장 빈도의 로그값이 되도록 만드는 것
말을 조금 바꿔보겠습니다.
전체 코퍼스에서의 동시 등장 빈도의 로그값과 중심 단어 벡터와 주변 단어 벡터의 내적값의 차이가 최소화되도록 두 벡터의 값을 학습하는 것
사실 내적이라는 것은 두 단어의 유사도를 측정하는 메트릭 중 하나이기 때문에, 이를 동시 등장 확률 또는 빈도와 연관 지어서 값을 학습한다는 것이 GloVe의 아이디어라고 볼 수 있겠습니다.
손실 함수를 이해하기 위해서 GloVe의 변수들을 다음과 같이 정의합니다
이때, GloVe의 손실 함수는 다음과 같습니다.
위 수식에서 우측의 괄호를 보면 중심 단어와 주변 단어 벡터의 내적이 동시 등장 빈도의 로그값과의 차이를 줄이도록 설계되었음을 볼 수 있습니다.
GloVe의 연구진은 동시 등장 행렬에서 동시 등장 빈도의 값 이 굉장히 낮은 경우에는 거의 도움이 되지 않는 정보라고 판단했습니다. 그래서 이에 대한 가중치를 주기 위해서 GloVe 연구진이 선택한 것은 바로 의 값에 영향을 받는 가중치 함수(Weighting function) 를 도입하는 것입니다.
의 값이 작으면 함수의 값은 작아지고, 값이 크면 함수의 값은 커집니다. 하지만 가 큰 값일 때 지나친 가중치를 주지 않기 위해 함수의 최댓값이 1로 정해져 있습니다. 이는 'It is'와 같은 불용어의 동시 등장 빈도수가 높을 때 지나친 가중을 주지 않기 위함입니다.
'Data Scientist Bootcamp' 카테고리의 다른 글
| [04/04] 추천시스템 시작 ! (1) | 2024.04.04 |
|---|---|
| [3/27] LLM (Large Language Model), 강화학습 (0) | 2024.03.27 |
| [3/20] NLP프로젝트 2_ NLP 과정 (0) | 2024.03.20 |
| [3/20] NLP 프로젝트1 _문자 전처리(split, strip 등) (1) | 2024.03.20 |
| [3/18] 프로젝트_ VGG16 써서 transfer learning으로 Flower 데이터셋 예측 (0) | 2024.03.18 |


