딥러닝 기법 Word2Vec 소개

Bag of Words Meets Bags of Popcorn

튜토리얼 파트 2 Word Vectors

  • 딥러닝 기법인 Word2Vec을 통해 단어를 벡터화해본다.
  • t-SNE를 통해 벡터화한 데이터를 시각화해본다.
  • 딥러닝과 지도학습의 랜덤포레스트를 사용하는 하이브리드 방식을 사용한다.

Word2Vec(Word Embedding to Vector)

컴퓨터는 숫자만 인식할 수 있고 한글, 이미지는 바이너리 코드로 저장된다.
튜토리얼 파트1에서는 Bag of Word라는 개념을 사용해서 문자를 벡터화하여 머신러닝 알고리즘이 이해할 수 있도록 벡터화해주는 작업을 하였다.

  • one hot encoding(예 [0000001000]) 혹은 Bag of Word에서 vector size가 매우 크고 sparse 하므로 neural net 성능이 잘 나오지 않는다.
  • 주위 단어가 비슷하면 해당 단어의 의미는 유사하다라는 아이디어
  • 단어를 트레이닝시킬 때 주위 단어를 label로 매치하여 최적화
  • 단어를 의미를 내포한 dense vector로 매칭시키는 것

  • Word2Vec은 분산된 텍스트 표현을 사용하여 개념 간 유사성을 본다. 예를 들어, 파리와 프랑스가 베를린과 독일이 (수도와 나라) 같은 방식으로 관련되어 있음을 이해한다.

word2vec
이미지 출처 : https://opensource.googleblog.com/2013/08/learning-meaning-behind-words.html

CBOW와 Skip-Gram
출처 : https://arxiv.org/pdf/1301.3781.pdf
Tomas Mikolov, Ilya Sutskever, Kai Chen, Greg Corrado, and Jeffrey Dean. Distributed Representations of Words and Phrases and their Compositionality. In Proceedings of NIPS, 2013.

  • CBOW와 Skip-Gram 기법이 있다.

    • CBOW(continuous bag-of-words)는 전체 텍스트로 하나의 단어를 예측하기 때문에 작은 데이터 세트일 수록 유리하다.
    • 아래 예제에서 __ 에 들어갈 단어를 예측한다.
1) __가 맛있다. 
2) __를 타는 것이 재미있다. 
3) 평소보다 두 __로 많이 먹어서 __가 아프다.

* Skip-Gram은 타겟 단어들로부터 원본 단어를 역으로 예측하는 것이다. CBOW와는 반대로 컨텍스트-타겟 쌍을 새로운 발견으로 처리하고 큰 규모의 데이터셋을 가질 때 유리하다.
* 라는 단어 주변에 올 수 있는 단어를 예측한다.

1) *배*가 맛있다. 
2) *배*를 타는 것이 재미있다. 
3) 평소보다 두 *배*로 많이 먹어서 *배*가 아프다.

Word2Vec 참고자료

Gensim

# 출력이 너무 길어지지 않게 하기 위해 찍지 않도록 했으나
# 실제 학습할 때는 아래 두 줄을 주석처리 하는 것을 권장한다.
import warnings
warnings.filterwarnings('ignore')
import pandas as pd

train = pd.read_csv('data/labeledTrainData.tsv', 
                    header=0, delimiter='\t', quoting=3)
test = pd.read_csv('data/testData.tsv', 
                   header=0, delimiter='\t', quoting=3)
unlabeled_train = pd.read_csv('data/unlabeledTrainData.tsv', 
                              header=0, delimiter='\t', quoting=3)

print(train.shape)
print(test.shape)
print(unlabeled_train.shape)

print(train['review'].size)
print(test['review'].size)
print(unlabeled_train['review'].size)

(25000, 3)
(25000, 2)
(50000, 2)
25000
25000
50000

train.head()
id sentiment review
0 5814\_8 1 "With all this stuff going down at the moment ...
1 2381\_9 1 \\The Classic War of the Worlds\" by Timothy ...
2 7759\_3 0 "The film starts with a manager (Nicholas Bell...
3 3630\_4 0 "It must be assumed that those who praised thi...
4 9495\_8 1 "Superbly trashy and wondrously unpretentious ...
# train에 있는 평점 정보인 sentiment가 없다.
test.head()
id review
0 12311\_10 "Naturally in a film who's main themes are of ...
1 8348\_2 "This movie is a disaster within a disaster fi...
2 5828\_4 "All in all, this is a movie for kids. We saw ...
3 7186\_2 "Afraid of the Dark left me with the impressio...
4 12128\_7 "A very accurate depiction of small time mob l...
from KaggleWord2VecUtility import KaggleWord2VecUtility
KaggleWord2VecUtility.review_to_wordlist(train['review'][0])[:10]

['with', 'all', 'this', 'stuff', 'go', 'down', 'at', 'the', 'moment', 'with']

sentences = []
for review in train["review"]:
    sentences += KaggleWord2VecUtility.review_to_sentences(
        review, remove_stopwords=False)
for review in unlabeled_train["review"]:
    sentences += KaggleWord2VecUtility.review_to_sentences(
        review, remove_stopwords=False)
len(sentences)

795538

sentences[0][:10]

['with', 'all', 'this', 'stuff', 'go', 'down', 'at', 'the', 'moment', 'with']

sentences[1][:10]

['mayb', 'i', 'just', 'want', 'to', 'get', 'a', 'certain', 'insight', 'into']