단어 자체를 벡터화하는 방법
분포가설 : “비슷한 위체에서 등장하는 단어들은 비슷한 의미를 가진다”
비슷한 의미를 지닌 단어는 주변 단어 분포도 비슷하다
I am a student
I : [1 0 0 0] am : [0 1 0 0] a : [0 0 1 0] student : [0 0 0 1]
단어를 고정 길이의 벡터, 차원이 일정한 벡터로 나타내기 때문에 '임베딩'이다
ex) [0.04227, -0.0033, 0.1607, -0.0236, ...] 연속적인 값
단어를 벡터로(Word to Vector) 나타내는 임베딩 방법
특정 단어 양 옆에 있는 두 단어의 관계를 활용하기 때문에 분포가설을 잘 반영한다
ex) "The tortoise jumped into the lake"
중심단어 The, 주변 문맥 단어 tortoise, jumped
학습 샘플 : (the, tortoise), (the, jumped)
중심 단어 : jumped / 주변 문맥 단어 : the, tortoise, into, the
학습 샘플: (jumped, the), (jumped, tortoise), (jumped, into), (jumped, the)
!pip install gensim --upgrade
import gensim
gensim.__version__ → 4.0.1 확인
# 구글 뉴스 말뭉치
import gensim.downloader as api
wv = api.load('word2vec-google-news-300')
# 단어간 유사도 파악 genism패키지의 .similarity이용
pairs = [
('car', 'minivan'),
('car', 'bicycle'),
('car', 'airplane'),
('car', 'cereal'),
('car', 'democracy')
]
for w1, w2 in pairs:
print(f'{w1} ====== {w2}\t {wv.similarity(w1, w2):.2f}')
→ car ====== minivan 0.69
car ====== bicycle 0.54
car ====== airplane 0.42
car ====== cereal 0.14
car ====== democracy 0.08 출력
# .most_similar 메서드 / .doesnt_match메서드도 있다
Word2Vec 방식에 철자기반의 임베딩 방식을 더해준 새로운 임베딩 방식
모델이 학습하지 못한 단어더라도 잘 쪼개서 보면 말뭉치에서 등장했던 단어를 통해 유추해 볼 수 있다
※ fastText가 Character-level(철자 단위) 임베딩을 적용하는 법 : Character n-gram
fastText는 3~6개로 묶은 character 정보(3~6grams)단위를 사용
3~6개 단위로 묶기 이전에 모델이 접두사와 접미사를 인식할 수 있도록 해당 단어 앞뒤로 <, >를 붙인다 그리고 해당 단어를 3~6개 character-level로 잘라서 임베딩을 적용한다
ex) <eating>
3grams → <ea eat ati tin ing ng>
4grams → <eat eati atin ting ing>
# 이런식으로 6grams까지 해서 벡터를 생성하고
# 18개의 character-level n-gram을 얻을 수 있다
from pprint import pprint as print
from gensim.models.fasttext import FastText
from gensim.test.utils import datapath
corpus_file = datapath('lee_background.cor')
model = FastText(vector_size=100)
model.build_vocab(corpus_file=corpus_file)
model.train(
corpus_file=corpus_file, epochs=model.epochs,
total_examples=model.corpus_count, total_words=model.corpus_total_words,
)
ft = model.wv
# 말뭉치에 있는지 없는지 확인
print('night' in ft.key_to_index) → True
print('nights' in ft.key_to_index) → False
# 두 단어의 유사도 파악
print(ft.similarity("night", "nights")) → 0.9999918