word2vec 기초개념 및 구현실습
Data_Engineering_TIL_(20190508)
study program : https://www.fastcampus.co.kr/extension_des
[학습목표]
- word2vec 기초개념 이해
[학습기록]
1. 자연어처리 관련 기초용어
1) Corpus (말뭉치)
- 언어 연구를 위해 텍스트를 컴퓨터가 읽을 수 있는 형태로 모아 놓은 언어 자료
2) Semantics (의미)
- 언어의 뜻이나 의미
3) Word Embedding
-
단어를 벡터로 표현하여 의미를 나타내는 방법
-
word2vec과 같은 말
4) CBOW (Continuous Bag-of-Words)
- 주변 단어를 가지고 가운데 들어갈 단어를 예측하는 모델
5) Skip-Gram
-
단어 하나를 가지고 주변에 나올 단어를 예측 모델
-
성능이 좋고 트레이닝 속도가 빨라서 인기
2. Word Embedding(word2vec) 개요
- 인간의 언어는 단어와 의미가 연결되어 있다.
ex) ‘컴퓨터’를 생각하면 ‘데스크탑’과 ‘노트북’이 떠오른다.
- one-hot encoding
ex)
1) 컴퓨터 : [0,0,0,0,0,0,1,0,0,0]
2) 노트북 : [0,0,0,0,0,0,0,1,0,0]
3) 슈퍼컴퓨터 : [0,0,0,0,0,0,0,0,1,0]
…
위와 같이 10차원 백터로 한다면 - 10가지의 단어를 표현할 수 있다.
일상단어를 표현하려면 2만 ~ 5만차원, 큰 단어목록은 50만차원 정도가 필요하다고 한다.
원핫인코딩은 단어사이의 관계를 표현할 수 없다는 한계가 있다.
ex) [0,0,0,0,0,0,1,0,0,0]^T x [0,0,0,0,0,0,0,1,0,0] = 0
- Vector Representation
단어사이의 관계표현을 위해 방향성을 가진 벡터로 단어를 표현하는 방법이다.
비슷한 단어들끼리 비슷한곳에 위치하도록 한다.
인접한 단어를 보면 그 단어의 뜻을 할 수 있다.
moden statistical NLP의 핵심이다.
단순히 비슷한 뜻을 가진 단어가 근처에 있는것 뿐만 아니라 벡터공간의 위치가 의미를 가지도록 표현이 가능하다.
3. 언어모델
- 연속된 단어들의 등장확률을 예측하는 모델
ex)
배가고파서 나는 밥을 ___
먹었다? 먹는다? 지었다? …
p(먹었다) = 0.25, p(먹는다) = 0.15, p(지었다) = 0.05, p(자동차) = 0.000001 …
-
문장의 순서나 단어선택 등을 예측할 수 있기에, 자동번역 등 많은 NLP Task에 유용하다.
-
확률적 언어 모델을 만드려면, 이전에 나오는 단어를 많이 참조할수록 정확하다.
ex) 2-gram, 3-gram, 4-gram, .. n-gram
n-gram을 늘릴수록 메모리가 엄청나게 필요하다.
이런 문제점을 해결해주는 것이 RNN(Recurrent Neural Networks)이다.
4. 확률적 언어모델
- 중심 단어가 주어졌을때 주변 단어들이 나올 확률을 구하고, 이 확률을 높이는 방향으로 벡터를 계속해서 조정하는(계속해서 학습해나가는) 모델이다. 따라서 데이터가 많으면 많을수록 좋다.
- 확률적 언어모델을 만드는 방법에는 두가지가 있다. 여러가지 단어가 있으면 빈칸을 채우는 방법이 있고, 하나의 단어가 있으면 주변의 단어가 나올 확률을 계산하는 방법이 있다.
5. word2vec
히든레이어에서 아웃풋레이어로 가는 세타값을 vector representation을 쓰겠다는 것이 Neural Net Language Model이다.
Neural Net Language Model을 학습해서 나오는 것이 위의 그림에서 봤던 벡터에서 남성, 여성 위치 이런결과가 나온다.
- 손쉽게 사용할 수 있는 여러가지 word2vec 구현체
1) Gensim word2vec
2) TensorFlow word2vec
3) Apache Spark MLlib word2vec
4) FastText
- Gensim
1) 텍스트 표현 및 처리를 위한 Python 라이브러리
2) TF-IDF, word2vec, document2vec 등의 알고리즘들을 포함
3) 간편한 사용법과 좋은 성능으로 많이 쓰임
4) 사용시 참고사항
4-1) CPU Multithread Gensim word2vec 이 GPU Word2veckeras 보다 빠르다
관련 URL : https://rare-technologies.com/gensim-word2vec-on-cpu-fasterthan-word2veckeras-on-gpu-incubator-student-blog/
4-2) word2vec 같은것은 여러번 돌려야하는 경우가 많고, 더 많은 데이터를 돌리면 더 잘 학습하는 경향이 있으므로 성능도 중요하게 평가해야함
4-3) Deepdist (http://deepdist.com/)
Gensim + Spark
Stochastic gradient updates 를 이용, 클러스터간 학습값을 공유
4-4) FastText같은 대안 알고리즘도 고려해야한다.
5. gensim 을 이용한 나무위키 string 데이터로 word2vec 학습 실습
[실습프리뷰]
1) gensim 라이브러리 설치
2) Corpus (말뭉치) 준비
나무위키 데이터를 사용한다.
3) Training word2vec model
4) Exploration
similarity 등을 활용하여 모델을 탐색하고 의미있는 사실들을 탐색한다.
[실습 상세내용]
from gensim import corpora, similarities
from gensim.models import Word2Vec
import os
import multiprocessing
input_filename = '_namuwiki_20180326_mini.txt'
model_path = r'C:\Users\minman\Desktop\0507실습'
class SentenceReader(object):
def __init__(self, input_filename):
self.input_filename = input_filename
def __iter__(self):
for line in open(input_filename, 'r', encoding='utf-8'):
yield line.split(' ')
sentences_vocab = SentenceReader(input_filename) # a memory-friendly iterator
sentences_train = SentenceReader(input_filename) # a memory-friendly iterator
config = {
'min_count': 10, # 등장 횟수가 10 이하인 단어는 무시
'size': 300, # 300차원짜리 벡터스페이스에 embedding
'sg': 1, # 0이면 CBOW, 1이면 skip-gram을 사용한다
'batch_words': 10000, # 사전을 구축할때 한번에 읽을 단어 수
'iter': 10, # 보통 딥러닝에서 말하는 epoch과 비슷한, 반복 횟수
'workers': multiprocessing.cpu_count(),
}
word2vec_model = Word2Vec(**config)
i = 0
for sentence in sentences_vocab:
if (i<5):
print(sentence)
i += 1
['\n']
['(신', '세계수의', '미궁', '2에서', '뜬', '!!아앗!!)\n']
['', '\n']
['세계수의', '미궁', '시리즈에', '전통으로', '등장하는', '대사.', '2편', '제왕의', '성배부터', '등장했으며,', '훌륭한', '사망', '플래그의', '예시이다.\n']
['세계수의', '모험가들이', '탐험하는', '던전인', '수해의', '구석구석에는', '채취/벌채/채굴', '포인트가', '있으며,', '이를', '위한', '채집', '스킬에', '투자하면', '제한된', '채집', '기회에', '보다', '큰', '이득을', '챙길', '수', '있다.', '그러나', '분배할', '수', '있는', '스킬', '포인트는', '한정된', '만큼', '채집', '스킬에', '투자하는', '만큼', '전투', '스킬', '레벨은', '낮아지게', '된다.\n']
token_count = sum([len(sentence) for sentence in sentences_vocab])
print(token_count)
5689597
word2vec_model.build_vocab(sentences_vocab)
word2vec_model.train(sentences_train, total_examples = token_count, epochs=word2vec_model.iter)
(37574483, 56895970)
word2vec_model.wv['컴퓨터']
array([-4.89444733e-02, 2.12149277e-01, 3.07926774e-01, -2.36114770e-01,
1.73265319e-02, -1.57664180e-01, -4.73214649e-02, 1.42774835e-01,
-8.91393647e-02, 7.18534924e-03, -3.52233872e-02, -2.98546016e-01,
4.19392347e-01, -7.64974803e-02, 1.64778501e-01, 1.34128377e-01,
-7.67253265e-02, 2.13795349e-01, 2.36256197e-01, 1.42444149e-01,
8.68331119e-02, -5.18982768e-01, -1.13702282e-01, -1.39919281e-01,
3.86519670e-01, 1.22996941e-01, -1.28421724e-01, -1.01735801e-01,
1.36627126e-02, -4.98175651e-01, -2.72755325e-01, -8.12310725e-03,
-2.10460007e-01, -4.30127621e-01, -1.66468680e-01, -1.86461825e-02,
-1.89480141e-01, -1.10138036e-01, -2.47299060e-01, -3.20593685e-01,
-2.56711841e-01, -1.42238215e-01, -2.91226268e-01, 2.41235301e-01,
4.28629994e-01, 3.21999937e-01, -1.61533847e-01, 4.15442772e-02,
2.43607506e-01, 5.79910129e-02, 3.07140261e-01, -1.29492087e-02,
8.81309137e-02, -1.52817547e-01, -3.81114557e-02, 4.56584170e-02,
1.10853642e-01, 1.19951397e-01, -9.52795595e-02, -2.12374069e-02,
-1.01117022e-01, 1.56397134e-01, -5.69580570e-02, 9.60636884e-02,
-2.92044431e-01, 2.34986767e-02, -1.22385994e-01, -3.89746577e-01,
-7.89434239e-02, 2.21513793e-01, -3.10118169e-01, 1.35340378e-01,
6.44859448e-02, -3.97753149e-01, -1.63576379e-01, 2.60230839e-01,
-5.15524268e-01, 2.99857229e-01, -3.85377780e-02, -2.99782306e-02,
1.60701528e-01, 1.20487452e-01, -1.27783805e-01, 2.56736530e-03,
-1.96936220e-01, 2.69296080e-01, 2.97676444e-01, -3.18073630e-01,
1.96385399e-01, -2.97684837e-02, 3.31294686e-02, -2.23016888e-02,
1.62911668e-01, 9.91303399e-02, 3.17770004e-01, -7.44379461e-02,
1.75555393e-01, 3.27698737e-01, -2.64060915e-01, -4.31358963e-01,
1.43389180e-01, 2.37381116e-01, 1.22672938e-01, 4.46838826e-01,
2.49345303e-01, -2.57699937e-01, -2.23078370e-01, -3.79522800e-01,
2.54011471e-02, -1.55587509e-01, 1.55087173e-01, 8.05987418e-02,
5.38553819e-02, 6.51429221e-02, 4.12528850e-02, -1.25661166e-02,
-1.82779655e-01, 1.36582730e-02, 1.80984199e-01, 1.44898057e-01,
3.42630923e-01, -3.34524572e-01, -1.57649979e-01, -1.17889799e-01,
-8.80961359e-01, -1.19090173e-02, 1.41808540e-01, 3.06444407e-01,
-7.28462264e-02, 1.50223851e-01, -6.78099468e-02, -6.63300157e-01,
-4.13778514e-01, -9.74495560e-02, -9.90127474e-02, 6.57032728e-01,
1.35891810e-01, 2.75490582e-01, -3.29174519e-01, 7.61645958e-02,
-2.35637769e-01, 2.38549590e-01, -5.13127863e-01, -1.10978857e-02,
-3.64421159e-02, -1.15836814e-01, 4.75113392e-01, 1.46323726e-01,
-2.05030605e-01, 3.46764326e-01, 2.40394026e-02, -1.55701756e-01,
-5.09365618e-01, 7.78398588e-02, -2.11957380e-01, -1.89215124e-01,
2.89770216e-01, -3.14218998e-01, -5.63240290e-01, -4.18229327e-02,
-1.83634713e-01, -2.54698656e-02, -1.72163680e-01, 9.06114504e-02,
1.05182022e-01, 8.90849382e-02, -1.58668026e-01, -9.72167328e-02,
1.76415756e-01, 1.48433045e-01, 9.67289787e-03, -2.57054001e-01,
3.27202886e-01, 2.22260103e-01, -2.55173445e-01, -1.41979620e-01,
-2.76630241e-02, 2.36994341e-01, -2.53879845e-01, -1.45007983e-01,
-2.39701755e-02, 6.63651526e-02, 1.88900411e-01, -1.39092982e-01,
-1.77085012e-01, 1.26081765e-01, 3.39382797e-01, 3.43103141e-01,
-1.13959890e-02, -2.45139897e-01, 4.78379965e-01, -7.03082755e-02,
2.87705600e-01, -1.02873258e-01, -1.97495371e-01, 1.53617322e-01,
-6.86099753e-02, 4.83210921e-01, -7.61319846e-02, -4.99132015e-02,
1.80054337e-01, -3.01314816e-02, 3.50650758e-01, -5.89101076e-01,
-9.72911179e-01, 9.88111719e-02, -2.88896877e-02, 2.59971470e-01,
-2.63712406e-01, 1.20239727e-01, 3.09962451e-01, 2.77166069e-02,
3.09111506e-01, -2.41481304e-01, -1.18282363e-01, 1.50902331e-01,
3.60565335e-01, 8.88025314e-02, 5.14013112e-01, -1.47602245e-01,
1.33635476e-01, 3.07552159e-01, -3.55134457e-01, 1.99442387e-01,
-3.01021989e-02, 2.04161420e-01, 1.00623384e-01, 9.91701111e-02,
-1.19120762e-01, -1.67358220e-01, -8.85520950e-02, 9.55310315e-02,
6.84137270e-02, 1.26955718e-01, 1.01066671e-01, -1.66425020e-01,
8.73438141e-04, 3.87228094e-02, -1.36450008e-01, 1.73422560e-01,
-2.96802640e-01, 3.07082245e-03, -9.66350175e-03, 4.13359880e-01,
-2.61123758e-02, -2.59313881e-01, -1.62320822e-01, -2.64905989e-01,
-3.41820307e-02, 3.73198986e-02, -4.05382007e-01, 4.75735724e-01,
3.79232973e-01, -1.29022658e-01, -1.18551642e-01, 4.60622162e-01,
3.02868243e-02, -1.58158671e-02, 1.63615137e-01, 2.45047599e-01,
-2.91406125e-01, 1.03874572e-01, -2.45708227e-02, 7.25027174e-02,
-7.14385137e-02, 4.60685313e-01, -2.50908762e-01, -1.79602057e-01,
6.73701763e-02, -2.61987686e-01, -1.17736302e-01, -2.14862078e-01,
-3.96715313e-01, 1.63355872e-01, 2.94565469e-01, 2.95890003e-01,
5.58686733e-01, -9.90497414e-03, -1.95393160e-01, 4.98686522e-01,
2.61075497e-01, 1.52776599e-01, 2.28498921e-01, 2.60978550e-01,
6.41064644e-02, -1.44907115e-02, 2.16054153e-02, 1.47647887e-01,
4.96248841e-01, -2.59023011e-01, 2.15061203e-01, -1.19510461e-02,
-1.08890802e-01, 2.59606868e-01, 3.70812640e-02, 1.28522709e-01,
2.07727119e-01, 2.62176305e-01, -1.95170343e-01, 1.75268576e-01],
dtype=float32)
word2vec_model.most_similar(['컴퓨터'])
[('개인용', 0.5928508043289185),
('공학', 0.5684698224067688),
('컴퓨터를', 0.5363287925720215),
('스마트폰', 0.5359224081039429),
('DAW', 0.535523533821106),
('태블릿', 0.5256739854812622),
('제조사', 0.5225208401679993),
('돌비', 0.5182591676712036),
('툴의', 0.5144219994544983),
('CAD', 0.5068387389183044)]
word2vec_model.most_similar(positive = ['서울', '미국'], negative=['한국'])
[('지하철', 0.41480255126953125),
('뉴욕', 0.3802769184112549),
('역번호.\n', 0.37469372153282166),
('3호선', 0.3733898997306824),
('5호선', 0.3722527027130127),
('경전철', 0.3663251996040344),
('1988', 0.36552858352661133),
('7호선', 0.3651158809661865),
('1호점을', 0.3644155263900757),
('5호선\n', 0.3627084791660309)]