AI/자연어처리(NLP)

[Stanford 강의] Lecture 1 : Intro and Word Vectors

CSE 2025. 11. 10. 21:02

 

 
친구와 같이 스탠포드 대학교의 자연어처리(NLP) 수업을 들어보기로 했다.
수업영상은 유튜브에 업로드 되어있다.
영상은 아래 링크를 참고하면 된다.
https://www.youtube.com/watch?v=DzpHeXVSC5I&list=PLoROMvodv4rOaMFbaqxPDoLWjDaRAdP9D&index=2
 
첫 강의이다 보니 과목 개요와 배경 등을 설명해주고 시작한다.
이 부분은 조금 간단히 요약해 기록만 하고 넘어갈 예정이다.
 


Intro

인간은 언어를 통해 유인원들과 차별화된다.
언어는 크게 두 가지의 핵심기능이 있다. 소통(communication)과 고등 사고(higher thought)이다.
 
이후 문자가 발명되어 발전이 더 가속화 되었다.
자연어 처리 분야는 최근 10년간 큰 발전이 있었다.
이전의 키워드만 사용하는 검색에서 문장을 입력해도 검색이 가능해졌고, GPT등의 대규모 언어 모델(LLM)들의 진화가 이루어졌다. 또 이제는 소설을 작성하거나 그림을 생성하는 일까지 가능하다.
 
여기서 한가지 용어를 소개하는데 바로 foundation models이다.
이는 스탠포드에서 만든 용어인데, LLM의 기술을 이미지, 소리, DNA등 다양한 양식으로 확장한 모델을 의미한다.
 


 
이제 컴퓨터와 관련된 얘기로 넘어오면, 컴퓨터에 단어와 그 의미를 어떻게 전달하고 알려줄지 당연히 생각해보게 된다.
 
전통적 방법으로
'tree'라는 단어가 실제 '나무'라는 사물을 가리킨다는 방식인 Denotational Semantics,
단어와 유의어, 포함관계등이 정리된 WordNet 등의 방법이 있었다.

다만 단점은 Good과 Proficient같은 단어들의 뉘앙스 차이를 모르고, 속어 등이 없으며 사람이 수동으로 만들어야한다는 점이 있다.
 
조금 더 발전된 One-Hot Vectors 라는 방법도 있었다.
사전의 수십만개의 단어들 중 해당 단어가 있는 인텍스만 1로 표시하고 나머지는 0으로 표시하는 방법이다.

강의 자료

 
그러나 이 방식은 벡터의 길이가 단어의 개수 만큼이 되어 너무 길다는 단점이 있다.
또한 단어간의 유사성도 표현을 할 수가 없다.
 


Word Vectors

위와 같은 배경에서 '그럼 단어를 알아볼 떄 그 단어 주변의 단어(문맥)을 보고 파악해보자'라는 아이디어가 나오게 되었다.
이는 Distributional Semantics라는 방법이고 이 아이디어를 컴퓨터적으로 구현하기 위해 dense vector라는 개념이 나오게 되었다.

위 사진처럼 벡터가 매우 dense 해진 것을 볼 수 있다. 
이 dense vector의 차원은 벡터의 길이가 된다.
실제로는 200차원, 2000차원이 될 수도 있지만 그렇다고 해도 수십만개의 차원이 필요한 One-Hot vector에 비해면 매우 짧다.
 
단어를 표현하기 위한 dense vector를 word vector 또는 word embeddings 또는 (neural) word representations 처럼 여러 단어로 부른다.
 
이 고차원 공간상에서 비슷한 문맥에서 사용되는 단어들이 서로 가깝게 위치할 수 있도록 학습하는 것이 목표가 된다.
이렇게 학습된 벡터들을 시각화해보면 실제로 그렇다는 것을 알 수 있다.


 

QNA

 
이 부분까지 수업이 진행되고 나서 있던 질문시간의 내용이다.
이 부분을 보면서 느낀 것이 정말 다양한 질문을 많이한다는 것이다.
자유롭게 질문하는 분위기가 그런것도 있겠지만
분위기에 상관없이 질문의 내용이 나는 생각하지도 않았던, 당연히 넘어가는 부분들인 것도 있다는게 대단하다고 느껴졌다.
 
< QnA >
1. 어떤 두 단어는 비슷할 수도 있지만 다른 문장(문맥)에서는 다른 뜻일 수도 있는데 이런 경우에 해결이 안되지 않는가?
A : 현 수업 내용으로는 해결이 안되는 것이 맞다. 후에 contextual meaning representation 를 통해 다룰 것이다.
 
2. 다의어는 경우에는 고차원 공간에 어떻게 표현되나?
A : 예를 들어 star는 우주의 별과 유명인사의 스타의 의미가 있는데, 이 두 관련집단에 모두 가깝운 위치에 할당되게 된다.
즉, 성운/천체 등이 있는 그룹과 할리우드, 연예인 등의 단어들이 있는 그룹에 모두 가까운 위치에 존재한다.
 
3. 위의 고차원공간 그림은 당연히 우리 눈에 보이기 위해 차원을 낮춰 표현한 것인데, 어떤 방식으로 고차원->낮은차원의 변환을 했나?
A : 비선형 차원 축소 방법인 t-SNE라는 방법을 사용했다.
 
4. word vector에 적절한 차원 수는 어떻게 정할 수 있나?
A : 초반에는 100차원 정도를 사용했지만 점차 모델들이 거대화되면서 현대에 이르러서는 1000~2000차원 정도를 사용하는 것이 일반화 되었다.
 
5. 거리를 통해 유사성을 확인하는데 만약 같은 거리에 여러 단어가 있다면?
A : 단순히 거리만으로 분석하지 않고 방향 등도 사용한다.
 
6. 벡터 안의 원소들은 모두 -1에서 1사이의 값인데 이유가 있나?
A : 그럴 필요는 없지만 숫자가 너무 커지는 것을 막기 위해 regularization이라는 방법을 사용한다.
 
7. 뜻이 여러개인 단어는 여러개의 word vector를 가질 수 있나?
A : 하나만 가지고, 여러 의미에 대한 평균치를 사용한다.


Word2Vec

이제 이렇게 벡터를 학습시키는 구체적인 방법인 word2vec에 대해 알아보자.
이 방법은 간단히 얘기해서 어떤 단어와 그 주변 단어 간의 조건부확률을 계산하는 것이다.
아래 사진의 예시에서는 가운데 단어가 주어졌을 때 주변 단어가 나올 확률을 앞뒤로 2개씩 계산한다.
이후 단어를 하나씩 옮겨 또 계산한다.

 
위의 사진은 window size = 2인 경우이다.
 
 
이제 이를 수학적으로 조금 따져보면 아래와 같다.
문장의 첫 단어부터 끝단어까지 각각의 단어에 대해 주변단어들(window size = m)과의 조건부 확률을 모두 곱해 $L(\theta)$라는 값을 구한다.
우리는 위에서 얘기했듯이 이 확률의 총곱을 최대한 키워야 한다.
그러나 $L(\theta)$대신 수학적 변형을 취해 $J(\theta)$라는 함수를 사용한다.
이 이유로는
1. -를 취하는 이유 : 우리는 무언가를 최소화 시키는 것이 더 익숙하기 때문
2. log를 취하는 이유 : 많은 곱하기를 더하기로 바꾸기 위해
3. $T$로 나누는 이유 : $T$가 커질수록 합도 커지기 때문에 이를 조절하기 위해 

여기서 $\theta$는 모든 단어들의 벡터를 가지고 있는 하나의 큰 벡터라고 생각하면 된다.
 
 
그럼 이제 $P(w_{t+j} | w_t)$를 어떻게 계산할까?
여기서는 아래 사진과 같은 식을 통해 계산한다.

$V$는 단어의 집합이다.
단어 $w$는 center word로 쓰이는지 context word로 쓰이는지에 따라 다른 벡터를 가진다.
$v_w$는 center word일 때의 벡터,
$u_w$는 context word일 때의 벡터이다.
 
즉 분자를 보면 context word와 center word의 유사성을 구하는 것이라고 볼 수 있다.
두 벡터가 비슷할수록 내적은 커지기 때문이다.
 
식에서 exp와 $\sum$ 는 갑자기 왜 나왔을까?
softmax함수를 이용했기 때문이다.
이 함수는 각 값에 exp를 취하고 그 비율을 계산해주는데,
이 성질 때문에 값은 항상 0~1사이가 되고 확률로 해석하기 좋아진다.

 


단어벡터 값 학습

이제 단어 벡터들이 주어진다면 여러 수학적인 과정을 통해 확률을 구할 수 있게 되었다.
그렇다면 단어 벡터들은 어떻게 구할까?
처음에는 모든 단어 벡터들을 무작위의 값으로 설정하고, 계산된 확률 값이 점차 높아지도록 조작을 하는 방식을 사용한다.
이를 위해 미적분을 통해 계산을 한다.
 
아래 2차원인 경우를 예시로 보면, 왼쪽 위에서의 기울기를 미분을 이용해 구하고,
해당 방향으로 조금씩 이동하다보면 최솟값을 가지는 지점으로 이동하게 된다.

 
우리가 미분할 함수 $J(\theta)$를 보면 로그들의 합이므로 이 함수를 미분하는 것은 로그들을 미분해 더하는 것과 같다.
$\frac{\partial }{\partial \theta}$을 하기 전에 하나의 단어벡터에 대해 먼저 미분해보자.



이고 분수는 로그의 성질에 의해 빼기로 나눌 수 있다.
 
첫 항을 먼저 보면 log와 exp는 상쇄된다.
$u_o ^T v_c$를 $\frac{\partial }{\partial v_c}$하면 $u_o$만 남는다.
 
두번쨰 항은 더 복잡하다.
먼저 로그는 미분하면 $\frac{1}{x}$가 되는 것과 chain rule(한국식으로는 합성함수 미분)을 이용해 계산한다.
곱하기 이후 항만 다시 보자면,  시그마는 앞으로 빼내고 다음 식을 보면 결국 지수함수 미분이 된다.
 
이때 식은 $\sum_{x=1}^{V} p(x|c) u_x$으로 간단하게 바꿀 수 있다.
 
전체 식은 관측값 - 기댓값 이라고 해석할 수 있다.
우리는 이 차이를 줄이는 것이 목표이므로 미분의 값을 0을 만드는 것을 목표로 잡게 된다.

 

여기서 $v_c$가 아닌 벡터들에 대한 미분을 계산해보면,

아래와 같다.

정리하면 아래와 같다.

의미를 좀 살펴보면 

$v_c$는 $u_o$ (정답)방향으로 이동한다.
$u_o$는 $v_c$방향으로 이동한다.
$u_x$(오답)은 $v_c$(center)로부터 멀어지도록 업데이트 된다.


$v_c와 u_o$ 두 벡터는 서로 가까워진다
center word와 context word의 내적을 크게 만드는 것이 목적이므로
두 벡터의 방향이 비슷해져간다고 해석이 가능하다.


예시

마지막의 관측값-기댓값에 대해 
Monkey eats banana and apple.
라는 문장을 예시로 조금 더 쉽게 이해해보자.
 
center word는 eats라고 하고 context word는 monkey라고 가정하면
$u_o$는 monkey의 실제 벡터 값 $u_{monkey}$가 되고
마이너스 뒤의 항은 eats가 나올 때 monkey자리에 들어갈 값의 예측치이다.
예를 들어 monkey가 나올 확률이 50%, ant가 나올 확률이 30%, fish가 나올 확률이 20%, 다른 많은 단어들이 나올 확률은 0%라고 하자.
그러면 두번째항, 즉 기댓값은 $0.5 u_{monkey} + 0.3 u_{ant} + 0.2 u_{fish}$라는 벡터 값을 갖는다.
이 값이 monkey의 실제 벡터 값과 같으면 차이가 0 이 되므로 예측이 잘 된 것이다.
 
그러나 이 것은 (중심단어,주변단어)가 (eats, monkey)일 경우인 것이고

위 사진의 식의 이 부분에서 보듯이 context word를 바꿔가며
(eats, monkey),
(eats, banana)
에 대해서 모두 계산하는 것이다. (m=1일 경우)
만약 monkey의 경우에는 차이가 0이지만 banana의 경우에는 0이 아니라면 고차원 공간에서 그 방향으로의 gradient가 있다는 것이고 이에 따라 공간상에서 eats는 banana 쪽으로 조금 이동하게 되며 학습이 진행되는 것이다.
즉 자신을 둘러싼 단어들의 문맥을 학습할 수 있다.

물론 이 식에서 보듯이 문장의 모든 단어에게 모두 center word가 될 기회를 주며 학습을 진행한다.