-
[cs224n] 2강 워드 벡터와 워드 센스 (3/5, 동시발생 (co-occurrence count))AI 2021. 1. 17. 18:05
이건 알고리즘이죠. 여러분이 이 말뭉치를 거치면서 자리마다 움직이며 단어 예측을 하는 거고, 여러분은 파라미터를 업데이트하고 뭔가를 학습하는 거죠. 우리가 본 예제를 보면 동작하는 것 같은데요. 이건 약간 이상하지 않나요? 우리는 큰 덩어리의 데이타가 있고, 저는 통계를 생각하고 있는데요. 그 데이타를 모아서, 여기서 여러분들이 뭔가 할 수 잇는 것이 있을 것 같네요. 여기 단어가 있고, 예를 들어 바나나요. 바나나 문맥에서 어떤 단어가 나타나는지 보죠. 그걸 모두 세어서 그걸 예측에 이용하는 거죠. 분산 표현 테크닉을 포함해서 그런 종류 방법들이 전통적으로 쓰였는데, 잠깐 얘기하자면, 여러분은 잘 교육받아서 망 (net)이 시작하기전인 2013년 전에 일어난 일을 전혀 모르지는 않겠죠. 자, 우리가 할 수 있는 일은 본질적으로 워드2벡과 비슷한 것들입니다 . 5 단어 윈도우가 각 단어 인스턴스 주변에 있구요. 그걸 토큰이라고 하죠. 자연어처리에서, 종종 특별한 종류, 바나나 혹은 사과같은 특별한 인스턴스를 구별하고 싶어합니다. 종종 문헌에서 그걸 토큰 구별이라고 합니다. 단어와 각각의 토큰을 보죠. 그것 주변의 5단어를 보고 어떤 단어가 발생했는지 세 보죠. 그럼 우리는 동시발생 횟수에 대한 행렬을 만들수 있습니다.
다시 이 예를 보죠. 일반적으로 5에서 10을 사용하는데, 저는 1을 써서 카운트가 단순하고 작게 해보겠습니다. 워드2벡이 하듯이 왼쪽과 오른쪽은 무시하구요.
만약 이렇게 아주 작은 말뭉치가 있다면, 여기 이런 동시발생 횟수 행렬이 있고, 윈도우 사이즈 1에서 'I'는 'like'옆에 2번 등장하죠. 그 말은 'like'가 'I' 옆에 2번 등장한다는 거죠. 대칭적입니다. 다른 것들은 모두 한 번이네요. 이건 매우 큰 성긴 동시발생 횟수 행렬이네요. 할 수 있는 일은 이걸 그대로 사용하는 건데, 왜냐면 데이타가 충분하지 않아서요. 여러분이 만약 'like'와 'learning' 같은 단어가 비슷하다고 결정했다면, 그 두 벡터는 결국 서로 비슷하겠죠. 실제로 그렇습니다. 동시발생 횟수로 벡터의 유사성을 측정할 수 있죠.
만약 여러분이 25만개 단어가 있다면 별로 설득력이 없죠. 여러분이 이런 공간에 있고 수학이 나쁘다면, 그건 수조개의 셀을 가진 행렬이죠. 엄청난 공간이 필요한데, 만약 여러분이 영리하다면, 대부분의 셀이 0이라는 것을 알아채고 덜 공간이 필요한 영리한 성긴 매트릭스 표현을 할 수 있겠죠. 여러분의 분류 모델은 이런 성김 (sparsity) 이슈가 있을 겁니다. 왜냐면 그 셀들의 많은 수가 값이 없을 거고, 그건 견고하지 않으니까요.
이 모든 것에 대한 전통적인 답변이 있는데요. 즉, 우리는 큰 동시발생 횟수 행렬이 있고, 어떻게든 그 차원을 줄여서 원래 행렬의 대부분의 정보는 유지하면서 그에 해당하는 낮은 차원의 행렬을 찾는거죠. 아마도 우리는 그 차원을 워드2벡에서 처럼 25~1000으로 줄일 겁니다.
이 차원 줄이기의 표준적인 가장 흔한 방법이 있죠. 모든 수학을 다 이해할 필요는 없어요. 어떤 행렬이던, 여러분은 특이값 분해 (singular value decomposition)이라는 것을 할 수 있습니다. 임의의 행렬을 취해서 3개의 행렬로 분리하는 방법인데, 그렇게 하면 중심 단어는 대각선으로 위치하고 Singular Vector라고 불리는 것을 가집니다. 그건 여러 차원의 가중치죠. 아래로 내려갈 수록 크기는 작아집니다. 그리고 이 U와 V는 해당하는 열과 행에 대해 orthogonal base (직각 기부)입니다. 특히, 워드-워드 벡터보다 훨씬 간단합니다. 왜냐면 여러분은 스퀘어 매트릭스가 있고 그건 사실상 동일하기 때문이죠. 일반적인 경우엔, 이 전체적인 직각 기부를 갖는다고 해도 황토색으로 칠해진 부분들은 상관없게 되는데요. 왜냐면 내적시 사용이 안되기 때문이죠. 만약 차원을 줄이고 싶다면 가장작은 특이값을 버리는 거죠. 크기가 점점 줄어든 다는 걸 기억하죠? 그 얘기는 행렬의 (살구색 칠해진) 열과 행도 효과적으로 버릴 수 있다는 말이죠. 잘 보세요. 원래 3차원 표현에서 이제 2차원 표현이죠. 이게 Reduced SVD입니다. 최소 제곱 에러의 관점에서 고전적인 결과죠. 즉, 이 3개의 내적은 최선의 X k가 되는데 원래 X에 대한 k번째 추정이죠. 이걸 할 수 있으면 워드 벡터를 만들 수 있죠.
넘파이 (NumPy)의 SVD 함수에 행렬을 집어 넣고 워드 벡터를 만드는 거죠.
이건 매우 안 좋아 보이네요. 3개의 중심의 데이타 셋을 줬는데, 그건 정확히는 공정한 비교가 아니에요. 이 테크닉은 밀레니엄이 시작할 때쯤 유행했죠. 일반적으로 단어 어플리케이션에 대해서 하는 거고 잠재적 의미 분석 (Latent Semantic Analysis) 혹은 잠재 의미 인덱싱 (Latent Semantic Indexing)이라는 이름으로 불렸죠. 아이디어는 낮은 차원 공간에서 찾을 수 있는 의미 방향을 가질 수 있다는 거죠. 사람들은 정보추출 같은 테크닉을 위해서 한참동안 이 LSA 근사 같은 것을 연구했죠.약간은 동작했지만 잘 동작하지는 않았죠. 그래서 아주 많이 주목받진 못했어요. 단어 의미로 작업을 하는 GOG psych 커뮤니티에서는 계속 연구 되었습니다.
재미있는 건 2005년에 카네기멜론대학에서 박사 과정 학생이었던 더그 로디 (Dough Rohde)가 했던 연구인데, 그가 찾은 건 로 (raw) 카운트만 하는 게 아니라 카운트를 조작하는 것 (fiddling with count)입니다. 더 좋은 결과를 낼 수 있죠. 로 카운트를 쓰지 않으면서, 그 매우 높은 빈도 단어들을 처리해야 합니다. 하나의 아이디어는 그것에 로그 스케일 (log scale)하는 거죠 , 정보 추출에서도 자주 씁니다. 다른 아이디어는 실링 (ceiling) 함수를 쓰는 거죠. X와 t의 최소값을 취하는 건데, t는 100정도 됩니다. 그는 또 워드2벡에 들어간 다른 해킹하는 아이디어를 썼는데, 그건 전체 윈도우를 똑같이 취급하는게 아니라, 가까운 단어를 더 세는거죠. 워드2벡에서는 먼 것들 보다 가까운 단어를 더 흔히 샘플링합니다. 그래서 그의 시스템에서는 더 가까운 단어를 위해 차이가 있는 카운트를 가져야 합니다. 카운트를 전혀 사용하지 않는 대신에 그는 피어슨 상관 (Pearson correlation)을 쓰기 시작해서 도움이 됐고, 그게 가끔 음수로 되는데, 음수를 제거하면 도움이 된다고 했습니다. 어떤 면에선 핵의 가방 (bag of hacks) 같죠. 다른 한편으론, 이 변형된 카운트가 여러분에게 매우 유용한 워드 벡터를 제공합니다. 사실 약간 다른 형태로, 이와 같은 카운트 중 몇개는 워드2벡에서도 사용됐습니다.
비유로 평가하는 정확한 아이디어는 실제로 개발되어 있었던 것이 아닙니다. 마쉬 미콜로브 (Marsh Mikolov)가 제안한 것이죠. 사실 도그 로디는 매우 재밌는 관찰을 했는데요. 그는 "내 워드 벡터의 의미 표현을 개선하기 위해, 이런 종류의 변형을 하면, 이런 재밌는 특징이 나타난다"라고 했죠.
여러분이 찾을 수 있는 것은 여기 세심하게 만들어진 공간에서 기본적으로 선형 컴포넌트인 의미 벡터죠. 행위자 (doer)로의 동사 방향의 동사가 있죠 . drive, driver, clean, janitor, swim, swimmer, learn, teacher, teach, teacher, treat, doctor, pray, priest 등의요. 이게 완벽하진 않지만, 약간 안맞는 부분이 있지만, 공간에서 해당하는 동사와 행위자간에 대충은 이런 종류의 방향이 있다는 걸 알수 있죠. 아무도 이런 비유의 아이디어를 생각해 내고 테스트하지 못했죠. 그러나 뒤돌아 보면 벡터 스페이스를 만든다면, 이런 선형 특징을 가지는게 명확하죠. 효과적으로 그는 벡터 공간을 만들었고, 비유를 잘했죠. 이건 이 방향은 행위자고, 여러분은 그게 여러분이 얻을 수 있는 행위자 벡터라고 할 수 있습니다. 빼보죠. janitor에서 clean을 빼고, swim을 더하면 swimmer와 가까워 지죠.그의 공간은 그걸 가능하게 했죠.
여러분이 더 카운트를 세심하게 제어하면, 전통적인 방법도 좋은 워드 벡터 공간을 제공합니다. 그것이 우리의 글로브 (GloVe)에 대한 연구의 시작점입니다.
본질적으로 2개의 학파가 있는데, 한쪽은 카운트와 변형 카운트에 기반해서 GOG psy를 더 연구했죠. 그건 더 장점이 있는데, 여러분은 통계를 효율적으로 사용할 수 있죠. 예측을 위해 전체 행렬의 글로벌 통계를 직접적으로 사용해서요. 그건 단어 유사성만 잡아내기 위해 사용되었는데, 그것의 많은 부분은 거대한 카운트에 대해 불균형 중요성 문제를 겪고 있었죠. 더그 로디는 이 두 문제를 풀어 보려고 했고요.
한편으론, 이 신경망 방법들이 있었죠. 직접적인 예측 방법으로 나타날 단어를 예측하기 위해서 우리가 그 확률 분포를 정의하는거죠. 그들도 장점이 있죠. 여러분이 샘플링 한다는 건 아마도 메모리가 부족하지는 않을 거라는 거죠. 반면, 매번 샘플링하기 때문에, 통계의 비효율적인 사용이죠. 한편 미콜라브의 연구는 완벽하게는 아니지만 잘 동작했죠.
제프리 페닝턴 (Jeffrey Pennington)과 리차드 소셔 (Richard Socher)는 이 아이디어들을 합쳐 신경망의 좋은 점을 가진 어떤 종류의 카운트 행렬로 연구를 하려 했죠. 특히, 덜 해키한 (hacky) 방법으로 결과를 얻고 싶었고, 그래서 이 벡터 공간에서 선형 연산인 의미 컴포넌트를 가져서 효과적인 더하기 등이 가능하길 바랬습니다. 이 모델에서 중요한 관찰은 의미 컴포넌트를 인코딩하기 위해서 동시발생 확률의 비율을 사용할 수 있었다는 겁니다. 여기 ice 같은 단어가 있다면, 얼마나 자주 그것과 등장하는 것이 있는 지를 알 수 있죠. solid는 많이 등장하고 gas는 아니죠. water는 같이 많이 등장하고 random은 아니구요. steam에는 solid와 gas가 반대로 나타나죠. 주의깊게 봐야 할 건, large를 가지는 것만으로는 충분하지 않죠. 왜냐면 large가 여기, 여기 두번 나타나고 small도 여기 저기 나타나구요. 재밌는 건 이 컴포넌트들간의 차이인데, 의미 컴포넌트를 가리킨다는 겁니다.
동시발생 확률의 비율을 알 수 있으면, solid와 gas에서 숫자는 의미의 차원입니다. 여기서 다른 단어들은 이 비율이 지워져서 거의 1이 됩니다. 이건 말뭉치로부터 나오는 실제 카운트값입니다. 우리는 대략적으로 solid와 gas간의 의미의 차원 (dimension of meaning)을 얻죠. solid와 gas사이의 의미의 차원을 가지죠. 거의 1로 나오는 것들은 의미의 차원이 아닙니다. 우리가 원하는 건 우리 공간에서 동시발생 확률의 비율이 선형이 되는 거죠.
그게 우리가 하는 것에 대해 말하고 싶은겁니다. 어떻게 할 수 있죠? 만약 내적을 동시발생 확률의 로그와 같게 할 수 있다면, 그 즉시 여러분이 벡터 차이를 갖게 되었을 때, 그것은 동시발생 확률의 비율로 바뀝니다. 그래서 본질적으로, 전체 모델은 우리는 내적 혹은 동시발생 확률의 로그를 갖고 싶은거죠.
'AI' 카테고리의 다른 글
[cs224n] 2강 워드 벡터와 워드 센스 (5/5, 워드 센스 (Word Senses)) (0) 2021.01.18 [cs224n] 2강 워드 벡터와 워드 센스 (4/5, 글로브와 평가 (GloVe, evaluation)) (0) 2021.01.17 [cs224n] 2강 워드 벡터와 워드 센스 (2/5, 최적화 (optimization)) (0) 2021.01.17 [cs224n] 2강 워드 벡터와 워드 센스 (1/5, 워드 벡터와 워드2벡 (word vector, word2vec)) (0) 2021.01.16 [cs231n] 3강 손실 함수와 최적화 (4/4, 경사하강 / Gradient Descent) (0) 2021.01.12