[NLP] 4. Natural Language Embeddings
์๋ณธ ๊ฒ์๊ธ: https://velog.io/@euisuk-chung/NLP-4.-Natural-Language-Embeddings
Natural Language Embeddings
์์ฐ์ด ์ฒ๋ฆฌ(NLP)์์ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ๋ค๋ฃจ๊ธฐ ์ํด ๋ค์ํ ์์ฐ์ด ์๋ฒ ๋ฉ ๊ธฐ๋ฒ(Natural Language Embedding)์ด ์ฌ์ฉ๋ฉ๋๋ค. ์ด๋ฒ ํฌ์คํธ์์๋ ์ด๋ฌํ ๊ธฐ๋ฒ๋ค์ ์์ธํ ์ค๋ช ํ๊ณ , ๊ฐ ๊ธฐ๋ฒ์ ์์๋ฅผ ํตํด ์ดํด๋ฅผ ๋๊ณ ์ ํฉ๋๋ค.
๐ Text Representation Learning & Natural Language Embedding์ด๋?
ํ ์คํธ ํํ ํ์ต(Text Representation Learning)
์ ๋น์ ํ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ์ ํ ๋ฐ์ดํฐ๋ก ๋ณํํ์ฌ ์ปดํจํฐ๊ฐ ์ดํดํ๊ณ ์ฒ๋ฆฌํ ์ ์๊ฒ ๋ง๋๋ ๊ณผ์ ์ ๋๋ค.์์ฐ์ด ์๋ฒ ๋ฉ(Natural Language Embedding)
์ ์ด๋ฌํ ๊ณผ์ ์์ ํ ์คํธ ๋ฐ์ดํฐ๋ฅผ ๋ฒกํฐ ํ์์ผ๋ก ๋ณํํ๋ ๋ค์ํ ๊ธฐ๋ฒ๋ค์ ํฌํจํฉ๋๋ค.- ์ด ๊ณผ์ ์์ ์ค์ํ ๊ฒ์ ๋จ์ด ๊ฐ์ ์๋ฏธ์ ์ ์ฌ์ฑ๊ณผ ๋ฌธ๋งฅ ์ ๋ณด๋ฅผ ์ ์งํ๋ฉด์ ๋ฐ์ดํฐ๋ฅผ ๋ณํํ๋ ๊ฒ์ ๋๋ค.
-
๋น์ ํ ๋ฐ์ดํฐ๋ฅผ ์ ํ ๋ฐ์ดํฐ๋ก ๋ณํํ๊ธฐ
- ๋น์ ํ ๋ฐ์ดํฐ๋ ํ ์คํธ์ ๊ฐ์ ๋น๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ๋ฅผ ๋งํ๋ฉฐ, ์ด๋ฅผ ์ ํ ๋ฐ์ดํฐ๋ก ๋ณํํ๋ ๊ฒ์ด ์์ฐ์ด ์ฒ๋ฆฌ(NLP)์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ์ ๋๋ค.
- ์ด ๊ณผ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ปดํจํฐ๊ฐ ์ดํดํ ์ ์๋ ํํ๋ก ๋ฐ๊พธ๋ ๊ฒ์ ๋ชฉํ๋ก ํฉ๋๋ค.
- ๋น์ ํ ๋ฐ์ดํฐ๋ฅผ
๋ฒกํฐ
๋๋๋งคํธ๋ฆญ์ค
ํ์์ผ๋ก ๋ณํํ์ฌ ์ ํ ๋ฐ์ดํฐ๋ก ๋ง๋ค ์ ์์ต๋๋ค. -
์ฃผ์ ๊ณผ์ :
๋ฐ์ดํฐ ์์ง
: ์์ , ์ธํฐ๋ท ๋ฑ ๋ค์ํ ์์ค๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์์งํฉ๋๋ค.๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
: ์์งํ ๋ฐ์ดํฐ๋ฅผ NLP ๊ธฐ๋ฒ์ ์ด์ฉํด ์ ์ฒ๋ฆฌํฉ๋๋ค.- ๋์๋ฌธ์ ํต์ผ: โTheyโ์ โtheyโ๋ฅผ ๋ชจ๋ ์๋ฌธ์๋ก ํต์ผ.
- ๋ถํ์ํ ๋ฌธ์ฅ ๊ธฐํธ ์ ๊ฑฐ: ์๋ฅผ ๋ค์ด, โ!โ๋ โ?โ ๊ฐ์ ๊ธฐํธ๋ฅผ ์ ๊ฑฐ.
- ์ซ์ ์ ๊ฑฐ: ํ์ ์๋ ์ซ์๋ ์ ๊ฑฐ.
- ๋ถ์ฉ์ด ์ ๊ฑฐ: ๋ฌธ๋ฒ ์์ ๋ฑ ์ค์ํ ์๋ฏธ๋ฅผ ๋ด๊ณ ์์ง ์์ ๋จ์ด ์ ๊ฑฐ.
์ ํ ๋ฐ์ดํฐ๋ก ๋ณํ
: ๋น์ ํ ๋ฐ์ดํฐ๋ฅผ ๋ฒกํฐ ๋๋ ๋งคํธ๋ฆญ์ค ํํ๋ก ๋ณํํฉ๋๋ค.
-
ํ ์คํธ ๋ฒกํฐํ ๊ธฐ๋ฒ
ํ ์คํธ๋ฅผ ๋ฒกํฐ๋ก ๋ณํํ๋ ๋ค์ํ ๊ธฐ๋ฒ์ ์๊ฐํฉ๋๋ค.
2.1 ๋ฐฑ ์ค๋ธ ์์ฆ (Bag-of-Words) ๋ชจ๋ธ
Bag of Words
๋ ๋จ์ด๋ฅผ ๋ฒกํฐ๋ก ํํํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก, ๋จ์ด์ ์์๋ฅผ ๊ณ ๋ คํ์ง ์๊ณ ๋ฌธ์ ๋ด ๋จ์ด์ ๋น๋
๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ฌธ์๋ฅผ ๋ฒกํฐํํฉ๋๋ค.
์๋ก ๋ค๋ฅธ ๋ฌธ์๋ค์ BoW๋ค์ ๊ฒฐํฉํ๋ฉด ๋ฌธ์ ๋จ์ด ํ๋ ฌ(Document-Term Matrix, DTM)
๋๋ ๋จ์ด ๋ฌธ์ ํ๋ ฌ(Term-Document Matrix, TDM)
์ผ๋ก ํํํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์๋ก ๋ค๋ฅธ ๋ฌธ์๋ค๊น์ง ํ์ฅํด์ ๋น๊ตํ ์ ์๊ฒ ๋ฉ๋๋ค.
- ๊ฐ๋ : ๋จ์ด์ ๋ฑ์ฅ ์์๋ฅผ ๊ณ ๋ คํ์ง ์๊ณ , ๋ฌธ์ ๋ด ๋จ์ด์ ๋น๋๋ฅผ ์ธ์ด ๋ฒกํฐ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
- BoW ์์ฑ ๋ฐฉ์:
1
2
(1) ๊ฐ ๋จ์ด์ ๊ณ ์ ํ ์ ์ ์ธ๋ฑ์ค ๋ถ์ฌ.
(2) ๊ฐ ์ธ๋ฑ์ค์ ์์น์ ๋จ์ด ํ ํฐ์ ๋ฑ์ฅ ํ์๋ฅผ ๊ธฐ๋กํ ๋ฒกํฐ ์์ฑ.
- ํน์ง: ๋จ์ด์ ์์๋ฅผ ๋ฌด์ํ๋ฉฐ ๋น๋ ๊ธฐ๋ฐ์ผ๋ก ๋ฒกํฐ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
- ์์:
1
2
3
4
5
6
๋ฌธ์1: "I love machine learning."
๋ฌธ์2: "Machine learning is fun."
BoW ๋ฒกํฐ:
๋ฌธ์1: [1, 1, 1, 1, 0, 0] # "I", "love", "machine", "learning", "is", "fun"์ ์์
๋ฌธ์2: [0, 0, 1, 1, 1, 1]
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from konlpy.tag import Okt
okt = Okt()
def build_bag_of_words(document):
# ์จ์ ์ ๊ฑฐ ๋ฐ ํํ์ ๋ถ์
document = document.replace('.', '')
tokenized_document = okt.morphs(document)
word_to_index = {}
bow = []
for word in tokenized_document:
if word not in word_to_index.keys():
word_to_index[word] = len(word_to_index)
# BoW์ ์ ๋ถ ๊ธฐ๋ณธ๊ฐ 1์ ๋ฃ๋๋ค.
bow.insert(len(word_to_index) - 1, 1)
else:
# ์ฌ๋ฑ์ฅํ๋ ๋จ์ด์ ์ธ๋ฑ์ค
index = word_to_index.get(word)
# ์ฌ๋ฑ์ฅํ ๋จ์ด๋ ํด๋นํ๋ ์ธ๋ฑ์ค์ ์์น์ 1์ ๋ํ๋ค.
bow[index] = bow[index] + 1
return word_to_index, bow
2.2 ๋จ์ด ๊ฐ์ค์น (Word Weighting) - TF-IDF
ํน์ ๋จ์ด๊ฐ ๋ฌธ์์์ ์ผ๋ง๋ ์ค์ํ์ง๋ฅผ ์ธก์ ํ๊ธฐ ์ํด ๋จ์ด ๋น๋(TF, Term-Frequency)
์ ๋ฌธ์ ๋น๋(DF, Document-Frequency)
๋ฅผ ์ฌ์ฉํฉ๋๋ค.
- ๊ฐ๋ : ์์ฃผ ๋ฑ์ฅํ์ง ์๋ ๋จ์ด๊ฐ ํน์ ๋ฌธ์์์ ๋ง์ด ๋ฑ์ฅํ ๊ฒฝ์ฐ ํด๋น ๋จ์ด์ ๊ฐ์ค์น๋ฅผ ๋์ ๋๋ค.
-
TF-IDF ์์ฑ ๋ฐฉ์:
TF (Term Frequency)
: tf(d,t), ํน์ ๋ฌธ์ d์์์ ํน์ ๋จ์ด t์ ๋ฑ์ฅ ํ์.DF (Document Frequency)
: df(t), ํน์ ๋จ์ด t๊ฐ ๋ฑ์ฅํ ๋ฌธ์์ ์.-
IDF (Inverse Document Frequency)
: idf(t), ์ ์ฒด ๋ฌธ์์์ ๋จ์ด๊ฐ ๋ฑ์ฅํ ๋น๋์ ์ญ์- ์์: log(n/(1+df(t)))log({n}/{(1+df(t))})log(n/(1+df(t)))
TF-IDF
: TF์ IDF๋ฅผ ๊ณฑํ์ฌ ๊ณ์ฐ.
- ํน์ง: ๋จ์ ๋น๋์ ๋จ์ ์ ๋ณด์ํ์ฌ ๋จ์ด์ ์ค์์ฑ์ ๋ฐ์ํฉ๋๋ค. (๊ฐ์ค์น ๊ฐ๋ ์ถ๊ฐ)
-
์์:
๋ฌธ์1
: โI love machine learning.โ๋ฌธ์2
: โMachine learning is fun.โ- ๋จ์ด โmachineโ์ ๋ํด:
- n=2n = 2n=2 (์ ์ฒด ๋ฌธ์ ์)
- df(t)=2\text{df}(t) = 2df(t)=2 (โmachineโ์ด ๋ฑ์ฅํ๋ ๋ฌธ์ ์)
- ๋ฐ๋ผ์ IDF๋ ๋ค์๊ณผ ๊ฐ์ด ๊ณ์ฐ๋ฉ๋๋ค:
- IDF(machine)=logโก(21+2)=logโก(23)=logโก(0.6667)โโ0.176\text{IDF}(machine) = \log\left(\frac{2}{1 + 2}\right) = \log\left(\frac{2}{3}\right) = \log(0.6667) \approx -0.176IDF(machine)=log(1+22โ)=log(32โ)=log(0.6667)โโ0.176
- TF ๊ณ์ฐ
- ๋ฌธ์1์์ โmachineโ์ TF: 1
- ๋ฌธ์2์์ โmachineโ์ TF: 1
- TF-IDF ๊ณ์ฐ
- ๋ฌธ์1: TF-IDF(machine)=1รโ0.176=โ0.176\text{TF-IDF}(machine) = 1 \times -0.176 = -0.176TF-IDF(machine)=1รโ0.176=โ0.176
- ๋ฌธ์2: TF-IDF(machine)=1รโ0.176=โ0.176\text{TF-IDF}(machine) = 1 \times -0.176 = -0.176TF-IDF(machine)=1รโ0.176=โ0.176
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
10
from sklearn.feature_extraction.text import TfidfVectorizer
documents = ["I love machine learning.", "Machine learning is fun."]
tfidf_vectorizer = TfidfVectorizer()
tfidf_matrix = tfidf_vectorizer.fit_transform(documents)
print(tfidf_matrix.toarray())
print(tfidf_vectorizer.get_feature_names_out())
2.3 N-Grams ๋ชจ๋ธ
๋จ์ด์ ์์๋ฅผ ๊ณ ๋ คํ๊ธฐ ์ํด N-Grams ๋ชจ๋ธ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๋จ์ด์ ์ฐ์๋ N๊ฐ์ ๋จ์ด ์กฐํฉ์ ํน์ง์ผ๋ก ํฉ๋๋ค.
- ๊ฐ๋
: N๊ฐ์ ์ฐ์๋ ๋จ์ด๋ฅผ ํ๋์ ํ ํฐ์ผ๋ก ์ทจ๊ธํ์ฌ ๋ฒกํฐ๋ฅผ ๊ตฌ์ฑํฉ๋๋ค.
์ ๋๊ทธ๋จ(Unigram)
: ๋จ์ผ ๋จ์ด๋ก ๊ตฌ์ฑ๋ N-๊ทธ๋จ. (N=1)๋ฐ์ด๊ทธ๋จ(Bigram)
: ๋ ๋จ์ด๋ก ๊ตฌ์ฑ๋ N-๊ทธ๋จ. (N=2)ํธ๋ผ์ด๊ทธ๋จ(Trigram)
: ์ธ ๋จ์ด๋ก ๊ตฌ์ฑ๋ N-๊ทธ๋จ. (N=3)4-๊ทธ๋จ(4-gram)
: ๋ค ๋จ์ด๋ก ๊ตฌ์ฑ๋ N-๊ทธ๋จ. (N=4)
- N-Gram ์์ฑ ๋ฐฉ์:
1
2
3
(1) ํ
์คํธ๋ฅผ N๊ฐ์ ๋จ์ด ๋ฌถ์์ผ๋ก ๋๋๋๋ค.
(2) ๊ฐ N-Gram ๋ฌถ์์ ๋ฒกํฐํํฉ๋๋ค.
- ํน์ง: ๋จ์ด์ ์์๋ฅผ ๋ฐ์ํ์ฌ ๋ฌธ๋งฅ์ ๊ณ ๋ คํฉ๋๋ค.
- ์์:
1
2
3
4
5
6
๋ฌธ์ฅ: "I love machine learning"
Unigram: ["I", "love", "machine", "learning"]
Bigram: ["I love", "love machine", "machine learning"]
Trigram: ["I love machine", "love machine learning"]
4-gram: ["I love machine learning"]
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn.feature_extraction.text import CountVectorizer
bigram_vectorizer = CountVectorizer(ngram_range=(2, 2))
trigram_vectorizer = CountVectorizer(ngram_range=(3, 3))
documents = ["I love machine learning."]
bigram_matrix = bigram_vectorizer.fit_transform(documents)
trigram_matrix = trigram_vectorizer.fit_transform(documents)
print("Bigram:\\n", bigram_matrix.toarray())
print("Bigram Features:\\n", bigram_vectorizer.get_feature_names_out())
print("Trigram:\\n", trigram_matrix.toarray())
print("Trigram Features:\\n", trigram_vectorizer.get_feature_names_out())
-
๋ถ์ฐ ํํ (Distributed Representation)
๋ถ์ฐ ํํ์ด๋, ๋จ์ด๋ฅผ ๋ถ์ฐ ๋ฒกํฐ๋ก ํํํ์ฌ ๋จ์ด ๊ฐ์ ์ ์ฌ์ฑ์ ๋ณด์กดํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ์ด๋ ๋จ์ด์ ์๋ฏธ๋ฅผ ๋ฒกํฐ ๊ณต๊ฐ ์์์ ์ ์ฌํ๊ฒ ๋ฐฐ์นํ์ฌ ๋จ์ด ๊ฐ์ ๊ด๊ณ๋ฅผ ํ์ตํ ์ ์๊ฒ ํฉ๋๋ค.
3.1 NNLM (NeuralNet Language Model)
- ๊ฐ๋ : NNLM์ ๋จ์ด์ ์ํ์ค๋ฅผ ์ ๋ ฅ๋ฐ์ ๋ค์์ ์ฌ ๋จ์ด๋ฅผ ์์ธกํ๋ ๋ฐฉ์์ผ๋ก ๋จ์ด ๋ฒกํฐ๋ฅผ ํ์ตํฉ๋๋ค. ์ ๋ ฅ๋ ๋จ์ด ์ํ์ค๋ฅผ ๊ณ ์ ๊ธธ์ด์ ๋ฒกํฐ๋ก ๋ณํํ๊ณ , ์ด๋ฅผ ๋ฐํ์ผ๋ก ๋ค์ ๋จ์ด์ ํ๋ฅ ๋ถํฌ๋ฅผ ์ถ๋ ฅํฉ๋๋ค. (RNN/LSTM ๊ณ์ด ๋ชจ๋ธ)
- NNLM ์์ฑ ๋ฐฉ์:
1
2
3
4
(1) ๋จ์ด ์ํ์ค๋ฅผ ์
๋ ฅ๋ฐ์ ๋จ์ด ์๋ฒ ๋ฉ ๋ ์ด์ด๋ฅผ ํตํด ๊ณ ์ ๊ธธ์ด์ ๋ฒกํฐ๋ก ๋ณํํฉ๋๋ค.
(2) ์๋์ธต์ ๊ฑฐ์ณ ๋ค์ ๋จ์ด์ ํ๋ฅ ๋ถํฌ๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
(3) ๋ชจ๋ธ์ ํ์ตํ์ฌ ๋จ์ด ์๋ฒ ๋ฉ ๋ฒกํฐ๋ฅผ ์ต์ ํํฉ๋๋ค.
- ํน์ง: NNLM์ ๋จ์ด์ ์์๋ฅผ ๊ณ ๋ คํ์ฌ ๋ฌธ๋งฅ์ ๋ฐ์ํ๋ฉฐ, ๋ค์ ๋จ์ด๋ฅผ ์์ธกํ๋ ๋ฐฉ์์ผ๋ก ๋จ์ด ๊ฐ์ ๊ด๊ณ๋ฅผ ํ์ตํฉ๋๋ค.
- ์์:
1
2
3
๋ฌธ์ฅ: "I love machine learning"
>>> ์
๋ ฅ: ["I", "love", "machine"]
>>> ์ถ๋ ฅ: "learning"
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense
# ์ํ ๋ฐ์ดํฐ
sentences = ["I love machine learning", "Machine learning is fun", "I love deep learning"]
# ํ ํฌ๋์ด์ ์์ฑ
tokenizer = Tokenizer()
tokenizer.fit_on_texts(sentences)
total_words = len(tokenizer.word_index) + 1
# ์ํ์ค ์์ฑ
input_sequences = []
for line in sentences:
token_list = tokenizer.texts_to_sequences([line])[0]
for i in range(1, len(token_list)):
n_gram_sequence = token_list[:i+1]
input_sequences.append(n_gram_sequence)
# ํจ๋ฉ
max_sequence_len = max([len(x) for x in input_sequences])
input_sequences = pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre')
# ํน์ง๊ณผ ๋ ์ด๋ธ ๋ถ๋ฆฌ
X, y = input_sequences[:,:-1], input_sequences[:,-1]
# ๋ ์ด๋ธ ์-ํซ ์ธ์ฝ๋ฉ
y = tf.keras.utils.to_categorical(y, num_classes=total_words)
# ๋ชจ๋ธ ์์ฑ
model = Sequential()
model.add(Embedding(total_words, 10, input_length=max_sequence_len-1))
model.add(LSTM(100))
model.add(Dense(total_words, activation='softmax'))
# ๋ชจ๋ธ ์ปดํ์ผ
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# ๋ชจ๋ธ ํ์ต
model.fit(X, y, epochs=100, verbose=1)
# ์์ธก
seed_text = "I love"
next_words = 3
for _ in range(next_words):
token_list = tokenizer.texts_to_sequences([seed_text])[0]
token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')
predicted = model.predict(token_list, verbose=0)
output_word = tokenizer.index_word[np.argmax(predicted)]
seed_text += " " + output_word
print(seed_text)
3.2 Word2Vec
-
๊ฐ๋ : ๋จ์ด๋ฅผ ๋ฒกํฐ ๊ณต๊ฐ์ ๋งคํํ์ฌ ๋จ์ด ๊ฐ์ ์ ์ฌ์ฑ์ ๋ณด์กดํ๋ ์๋ฒ ๋ฉ ๊ธฐ๋ฒ์ ๋๋ค.
-
์ฃผ์ ๋ชจ๋ธ๋ก๋
CBOW(Continuous Bag of Words)
์Skip-gram
์ด ์์ต๋๋ค. -
Word2Vec์ ํ์ตํ ๋๋ CBOW์ Skip-gram ์ค ํ๋๋ฅผ ์ ํ์ ์ผ๋ก ์ฌ์ฉํฉ๋๋ค. ๋ ๋ฐฉ๋ฒ์ ์๋ก ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ๊ฐ๊ฐ์ ์ฅ๋จ์ ์ด ์์ต๋๋ค.
-
CBOW (Continuous Bag of Words):
- ์ฃผ๋ณ ๋จ์ด๋ค๋ก ์ค์ฌ ๋จ์ด๋ฅผ ์์ธกํฉ๋๋ค.
- ์ผ๋ฐ์ ์ผ๋ก ์์ ๋ฐ์ดํฐ์ ์์ ๋ ์ ์๋ํฉ๋๋ค.
- ๋น๋ฒํ ๋จ์ด์ ๋ํด ๋ ๋์ ์ฑ๋ฅ์ ๋ณด์ ๋๋ค.
-
Skip-gram:
- ์ค์ฌ ๋จ์ด๋ก ์ฃผ๋ณ ๋จ์ด๋ค์ ์์ธกํฉ๋๋ค.
- ๋๊ท๋ชจ ๋ฐ์ดํฐ์ ์์ ๋ ์ข์ ์ฑ๋ฅ์ ๋ณด์ ๋๋ค.
- ๋๋ฌธ ๋จ์ด์ ๋ํด ๋ ๋์ ํํ์ ํ์ตํฉ๋๋ค.
-
-
(Method 1) CBOW: ์ฃผ๋ณ ๋จ์ด๋ค๋ก ์ค์ฌ ๋จ์ด๋ฅผ ์์ธก.
-
(Method 2) Skip-gram: ์ค์ฌ ๋จ์ด๋ก ์ฃผ๋ณ ๋จ์ด๋ค์ ์์ธก.
- ํน์ง: ์ ์ฌํ ์๋ฏธ์ ๋จ์ด๋ค์ด ๊ฐ๊น์ด ๋ฒกํฐ๋ก ํํ๋ฉ๋๋ค. ์ ๊ฒฝ๋ง์ ํตํด ๋จ์ด ๋ฒกํฐ๋ฅผ ํ์ตํฉ๋๋ค.
- ์์:
1
2
3
4
5
6
7
8
9
10
11
๋ฌธ์ฅ: "The cat sat on the mat"
์ค์ฌ ๋จ์ด: "sat"
์ฃผ๋ณ ๋จ์ด: ["The", "cat", ___, "on", "the", "mat"]
## CBOW: ์ฃผ๋ณ ๋จ์ด๋ค โ ์ค์ฌ ๋จ์ด ์์ธก
>> ์ธํ: ["The", "cat", "on", "the", "mat"]
>> ์์ํ: "sat"
## Skip-gram: ์ค์ฌ ๋จ์ด โ ์ฃผ๋ณ ๋จ์ด๋ค ์์ธก
>> ์ธํ: "sat"
>> ์์ํ: ["The", "cat", "on", "the", "mat"]
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
10
from gensim.models import Word2Vec
sentences = [["the", "cat", "sat", "on", "the", "mat"],
["the", "dog", "sat", "on", "the", "couch"]]
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, sg=0) # CBOW
vector = model.wv['cat']
print(vector)
3.3 GloVe (Global Vectors for Word Representation)
- ๊ฐ๋
: ๊ธ๋ก๋ธ(Global Vectors for Word Representation, GloVe)๋ ์นด์ดํธ ๊ธฐ๋ฐ๊ณผ ์์ธก ๊ธฐ๋ฐ์ ๋ชจ๋ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ก ์ผ๋ก 2014๋
์ ๋ฏธ๊ตญ ์คํ ํฌ๋๋ํ์์ ๊ฐ๋ฐํ ๋จ์ด ์๋ฒ ๋ฉ ๋ฐฉ๋ฒ๋ก ์ผ๋ก, ๋จ์ด์ ๋์ ๋ฑ์ฅ ํ๋ ฌ์ ํ์ฉํ์ฌ ๋จ์ด ๋ฒกํฐ๋ฅผ ํ์ตํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
LSA ๊ธฐ๋ฒ
์ DTM(TDM)์ด๋ TF-IDF ํ๋ ฌ๊ณผ ๊ฐ์ด ๊ฐ ๋ฌธ์์์์ ๊ฐ ๋จ์ด์ ๋น๋์๋ฅผ ์นด์ดํธ ํ ํ๋ ฌ์ด๋ผ๋ ์ ์ฒด์ ์ธ ํต๊ณ ์ ๋ณด๋ฅผ ์ ๋ ฅ์ผ๋ก ๋ฐ์ ์ฐจ์์ ์ถ์(Truncated SVD)ํ์ฌ ์ ์ฌ๋ ์๋ฏธ๋ฅผ ๋์ด๋ด๊ณ ์ ํฉ๋๋ค.- (๋จ์ ) LSA๋ ์นด์ดํธ ๊ธฐ๋ฐ์ผ๋ก ์ฝํผ์ค์ ์ ์ฒด์ ์ธ ํต๊ณ ์ ๋ณด๋ฅผ ๊ณ ๋ คํ๊ธฐ๋ ํ์ง๋ง, King : Man = Queen : ? (Woman) ๋๋ Korea : Seoul = Japan : ? (Tokyo)์ ๊ฐ์ ๋จ์ด ์๋ฏธ์ ์ ์ถ ์์ (Analogy task)์๋ ์ฑ๋ฅ์ด ๋จ์ด์ง๋๋ค.
Word2Vec ๊ธฐ๋ฒ
์ CBOW์ Skip-gram์ด๋ผ๋ ๋ฅ๋ฌ๋ ํ์ต๋ฐฉ๋ฒ์ ํ์ฉํ์ฌ ์ค์ ๊ฐ๊ณผ ์์ธก๊ฐ์ ๋ํ ์ค์ฐจ๋ฅผ ์์ค ํจ์๋ฅผ ํตํด ์ค์ฌ๋๊ฐ๋ฉฐ ํ์ตํ๋ฉฐ ์ ์ฌ๋ ์๋ฏธ๋ฅผ ๋์ด๋ด๊ณ ์ ํฉ๋๋ค.- (๋จ์ ) Word2Vec๋ ์๋ฒ ๋ฉ ๋ฒกํฐ๊ฐ ๋จ์ด ๊ฐ์ ์๊ด์ฑ์ ๊ณ ๋ คํ์ฌ ํ์ตํ๊ธฐ ๋๋ฌธ์ ์ ์ถ ์์ ์ LSA๋ณด๋ค ๋ฐ์ด๋์ง๋ง, ์๋์ฐ ํฌ๊ธฐ ๋ด์์๋ง ์ฃผ๋ณ ๋จ์ด๋ฅผ ๊ณ ๋ คํ๊ธฐ ๋๋ฌธ์ ์ฝํผ์ค์ ์ ์ฒด์ ์ธ ํต๊ณ ์ ๋ณด๋ฅผ ๋ฐ์ํ์ง ๋ชปํฉ๋๋ค.
- Glove๋ ์ด๋ฌํ ๊ฐ๊ฐ์ ๋ชจ๋ธ์ ์ฅ์ ์ ํฉ์ณ์ ๊ฐ๊ฐ์ ๋จ์ ์ ํด๊ฒฐํ๊ณ ์ ํ์ต๋๋ค.
- GloVe ์์ฑ ๋ฐฉ์:
๋์ ๋ฑ์ฅ ํ๋ ฌ (Co-occurrence Matrix)
์ ์์ฑํฉ๋๋ค.- ์ ์: ์ ์ฒด ์ฝํผ์ค์์ ๊ฐ ๋จ์ด ์์ด ํน์ ๋ฌธ๋งฅ ์๋์ฐ ๋ด์์ ํจ๊ป ๋ฑ์ฅํ๋ ๋น๋๋ฅผ ๋ํ๋ด๋ ํ๋ ฌ์ ๋๋ค.
- ๊ตฌ์กฐ: ํ๊ณผ ์ด์ด ๋ชจ๋ ์ดํ์ ๋จ์ด๋ค๋ก ์ด๋ฃจ์ด์ง ์ ์ฌ๊ฐ ํ๋ ฌ์ ๋๋ค.
- ๊ฐ: ํ๋ ฌ์ ๊ฐ ์ XijX_{ij}Xijโ๋ ๋จ์ด i์ ๋ฌธ๋งฅ์์ ๋จ์ด j๊ฐ ๋ฑ์ฅํ ํ์๋ฅผ ๋ํ๋ ๋๋ค.
๋์ ๋ฑ์ฅ ๋น๋ (Co-occurrence Frequency)
๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋จ์ด ๋ฒกํฐ๋ฅผ ํ์ตํฉ๋๋ค.- ์ ์: ํน์ ๋จ์ด ์์ด ์ ์๋ ๋ฌธ๋งฅ ์๋์ฐ ๋ด์์ ํจ๊ป ๋ฑ์ฅํ๋ ํ์์ ๋๋ค.
- ๊ตฌ์กฐ: ๋ณดํต ์ค์ฌ ๋จ์ด๋ก๋ถํฐ ์ผ์ ๊ฑฐ๋ฆฌ(์๋์ฐ ํฌ๊ธฐ) ๋ด์ ๋จ์ด๋ค์ ๋ฌธ๋งฅ์ผ๋ก ๊ฐ์ฃผํ์ฌ ๊ณ์ฐํฉ๋๋ค.
- ๊ฐ: ์ด ๋น๋๋ ๋จ์ด ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ํ๋ด๋ ์ค์ํ ํต๊ณ์ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ํน์ง: ์ ์ฒด ์ฝํผ์ค์์ ๋จ์ด๊ฐ ํจ๊ป ๋ฑ์ฅํ๋ ๋น๋๋ฅผ ํ์ฉํ์ฌ ์ ์ญ์ ์ธ ํต๊ณ ์ ๋ณด๋ฅผ ๋ฐ์ํฉ๋๋ค.
- ์์:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
๋ฌธ์ฅ๋ค:
1. "The cat sits on the mat"
2. "The dog chases the cat"
3. "A cat and a dog play"
>> ๋ฌธ๋งฅ ์๋์ฐ ํฌ๊ธฐ: 2 (์ค์ฌ ๋จ์ด์ ์์ชฝ์ผ๋ก 2๊ฐ์ ๋จ์ด๊น์ง ๊ณ ๋ ค)
>> ๋์ ๋ฑ์ฅ ํ๋ ฌ:
the cat sits on mat dog chases a and play
the 0 3 1 1 1 1 1 0 0 0
cat 3 0 1 1 1 2 1 2 1 1
sits 1 1 0 1 1 0 0 0 0 0
on 1 1 1 0 1 0 0 0 0 0
mat 1 1 1 1 0 0 0 0 0 0
dog 1 2 0 0 0 0 1 2 1 1
chases 1 1 0 0 0 1 0 0 0 0
a 0 2 0 0 0 2 0 0 1 1
and 0 1 0 0 0 1 0 1 0 1
play 0 1 0 0 0 1 0 1 1 0
- ์์ ์ฝ๋:
- GloVe ์ฌ์ฉ์, Stanford์ pre-trained ๋ฒกํฐ๋ฅผ ๋ค์ด๋ก๋ ํ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค.
-
์ด๋ ๋ค์ ๋งํฌ์์ ์ง์ ๋ฐ์ผ์ค ์๋ ์์ต๋๋ค: https://nlp.stanford.edu/projects/glove/
- ์๋๋ ์ฌ์ ํ์ต๋ Glove ์๋ฐฐ๋ฉ์ ํธ์ถํ๊ณ ,
'cat'
์ด๋ผ๋ ๋จ์ด์ ์๋ฐฐ๋ฉ ๊ฐ์ ํ์ธํด๋ณด๋ ์์ ์ฝ๋์ ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from urllib.request import urlretrieve
import zipfile
# glove ์ฌ์ ํ์ต ํ์ผ ๋ค์ด๋ก๋
urlretrieve("http://nlp.stanford.edu/data/glove.6B.zip", filename="glove.6B.zip")
# glove ์ฌ์ ํ์ต ํ์ผ ์์ถ ํด์
with zipfile.ZipFile('glove.6B.zip', 'r') as zip_ref:
zip_ref.extractall()
from gensim.scripts.glove2word2vec import glove2word2vec
from gensim.models import KeyedVectors
# GloVe ํ์ผ ๊ฒฝ๋ก
glove_input_file = './glove.6B.100d.txt'
# ๋ณํ๋ Word2Vec ํ์ผ ๊ฒฝ๋ก
word2vec_output_file = 'glove.6B.100d.word2vec.txt'
# GloVe ํ์์ Word2Vec ํ์์ผ๋ก ๋ณํ
glove2word2vec(glove_input_file, word2vec_output_file)
# ๋ณํ๋ Word2Vec ํ์์ ํ์ผ์ ๋ก๋
model = KeyedVectors.load_word2vec_format(word2vec_output_file, binary=False)
# ํน์ ๋จ์ด์ ๋ฒกํฐ๋ฅผ ์ถ๋ ฅ
vector = model['cat']
print(vector)
3.3 FastText
- ๊ฐ๋
: FastText๋ Facebook(ํ Meta)์์ ๊ฐ๋ฐํ ์๋ฐฐ๋ฉ ๊ธฐ๋ฒ์ผ๋ก, ๋จ์ด ๋ด๋ถ์ ๋ฌธ์ n-gram์ ํ์ฉํ์ฌ ๋จ์ด ๋ฒกํฐ๋ฅผ ํ์ตํ๋ ๋ฐฉ๋ฒ์
๋๋ค.
- Word2Vec์ FastText์์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์ด๋ผ๋ฉด Word2Vec๋ ๋จ์ด๋ฅผ ๊ธฐ๋ณธ ๋จ์๋ก ์๊ฐํ๋ค๋ฉด, FastText๋ ํ๋์ ๋จ์ด ์์๋ ๋จ์๋ค์ด ์๋ค๊ณ ๊ฐ์ฃผํฉ๋๋ค. ์ฆ, ๋จ์ด์ ํํ์ ์ ๋ณด๋ฅผ ๋ฐ์ํฉ๋๋ค.
- FastText ์์ฑ ๋ฐฉ์:
1
2
3
4
## Subword Model
(1) ๋จ์ด๋ฅผ ๋ฌธ์ n-gram์ผ๋ก ๋ถํดํฉ๋๋ค.
(2) ๊ฐ n-gram ๋ฒกํฐ๋ฅผ ํฉ์ฐํ์ฌ ๋จ์ด ๋ฒกํฐ๋ฅผ ์์ฑํฉ๋๋ค.
- ํน์ง: ๋ฌธ์ n-gram์ ์ฌ์ฉํ์ฌ ๋จ์ด์ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๋ฐ์ํ๋ฉฐ, ๋ชจ๋ฅด๋ ๋จ์ด(Out Of Vocabulary, OOV)๋ ํจ๊ณผ์ ์ผ๋ก ํ์ตํฉ๋๋ค.
- ์์:
1
2
3
4
๋จ์ด: "apple"
๋ฌธ์ n-gram: ["a", "ap", "app", "p", "pp", "ple", "e"]
๋ฒกํฐ ํ์ต: ๊ฐ ๋ฌธ์ n-gram์ ๋ฒกํฐ๋ฅผ ํฉ์ฐํ์ฌ ๋จ์ด ๋ฒกํฐ๋ฅผ ์์ฑํฉ๋๋ค.
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
from gensim.models import FastText
sentences = [["the", "cat", "sat", "on", "the", "mat"],
["machine", "learning", "is", "fun"]]
model = FastText(sentences, vector_size=100, window=5, min_count=1)
vector = model.wv['cat']
print(vector)
-
๋ฌธ์ ์๋ฒ ๋ฉ (Document Embedding)
๋ฌธ์ ์ ์ฒด๋ฅผ ํ๋์ ๋ฒกํฐ๋ก ํํํ๋ ๊ธฐ๋ฒ์ ๋๋ค. ์ด๋ ๋ฌธ์์ ๋ด์ฉ์ ์ข ํฉ์ ์ผ๋ก ๊ณ ๋ คํ์ฌ ๋ฒกํฐํํฉ๋๋ค.
4.1 ๋จ์ด ์๋ฒ ๋ฉ์ ํ๊ท (Averaging Word Embeddings)
- ๊ฐ๋ : ๊ฐ์ฅ ์์ด์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก, ๋ฌธ์ ๋ด์ ๋ชจ๋ ๋จ์ด ์๋ฒ ๋ฉ ๋ฒกํฐ์ ํ๊ท ์ ๊ตฌํ์ฌ ๋ฌธ์ ๋ฒกํฐ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- ์์ฑ ๋ฐฉ์:
1
2
3
(1) ๋ฌธ์ ๋ด์ ๋ชจ๋ ๋จ์ด๋ฅผ ์๋ฒ ๋ฉ ๋ฒกํฐ๋ก ๋ณํํฉ๋๋ค.
(2) ๋ณํ๋ ๋ชจ๋ ๋จ์ด ์๋ฒ ๋ฉ ๋ฒกํฐ์ ํ๊ท ์ ๊ตฌํฉ๋๋ค.
- ํน์ง: ๊ฐ๋จํ๊ณ ๊ณ์ฐ์ด ๋น ๋ฅด์ง๋ง, ํ๊ท ์ ์ฐ์ฐ์ ์ํํ๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๋ด ๋จ์ด ์์๋ ๋ฌธ๋งฅ ์ ๋ณด๋ฅผ ๋ฐ์ํ์ง ๋ชปํฉ๋๋ค.
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
from gensim.models import Word2Vec
sentences = [["I", "love", "machine", "learning"], ["Machine", "learning", "is", "fun"]]
word2vec_model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)
def average_word_embeddings(document):
vectors = [word2vec_model.wv[word] for word in document if word in word2vec_model.wv]
return np.mean(vectors, axis=0)
document = ["I", "love", "machine", "learning"]
document_vector = average_word_embeddings(document)
print(document_vector)
4.2 PV-DM (Distributed Memory Model of Paragraph Vectors)
- ๊ฐ๋ : ๋ฌธ์์ ๋จ์ด๋ฅผ ๋์์ ์๋ฒ ๋ฉํ์ฌ ๋ฌธ์ ๋ฒกํฐ๋ฅผ ํ์ตํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ฌธ๋งฅ ๋จ์ด์ ๋ฌธ์ ๋ฒกํฐ๋ฅผ ์กฐํฉํ์ฌ ์ค์ฌ ๋จ์ด๋ฅผ ์์ธกํฉ๋๋ค.
- ์์ฑ ๋ฐฉ์:
1
2
(1) ๊ฐ ๋ฌธ์์ ๊ณ ์ ํ ID๋ฅผ ๋ถ์ฌํฉ๋๋ค.
(2) ๋ฌธ๋งฅ ๋จ์ด์ ๋ฌธ์ ID๋ฅผ ์
๋ ฅ์ผ๋ก ๋ฐ์ ์ค์ฌ ๋จ์ด๋ฅผ ์์ธกํฉ๋๋ค.
- ํน์ง: ๋ฌธ์์ ๋ฌธ๋งฅ ์ ๋ณด๋ฅผ ๋ฐ์ํ์ฌ ๋ฌธ์ ๋ฒกํฐ๋ฅผ ํ์ตํฉ๋๋ค.
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
10
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
documents = [TaggedDocument(words=["I", "love", "machine", "learning"], tags=['doc1']),
TaggedDocument(words=["Machine", "learning", "is", "fun"], tags=['doc2'])]
model = Doc2Vec(documents, vector_size=100, window=2, min_count=1, workers=4, dm=1) # PV-DM
vector = model.dv['doc1']
print(vector)
4.3 PV-DBOW (Distributed Bag of Words Model of Paragraph Vectors)
- ๊ฐ๋ : ๋จ์ด ์์๋ฅผ ๊ณ ๋ คํ์ง ์๊ณ ๋ฌธ์ ๋ฒกํฐ๋ง์ผ๋ก ์ค์ฌ ๋จ์ด๋ฅผ ์์ธกํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ๋จ์ด์ ์์๋ ๋ฌธ๋งฅ ์ ๋ณด๋ฅผ ๋ฐ์ํ์ง ์์ผ๋ฉฐ, Skip-gram ๋ชจ๋ธ๊ณผ ์ ์ฌํฉ๋๋ค.
- ์์ฑ ๋ฐฉ์:
1
2
3
(1) ๊ฐ ๋ฌธ์์ ๊ณ ์ ํ ID๋ฅผ ๋ถ์ฌํฉ๋๋ค.
(2) ๋ฌธ์ ID๋ฅผ ์
๋ ฅ์ผ๋ก ๋ฐ์ ์ค์ฌ ๋จ์ด๋ฅผ ์์ธกํฉ๋๋ค.
- ํน์ง: ๋จ์ด์ ์์๋ฅผ ๊ณ ๋ คํ์ง ์์ผ๋ฉฐ, ๋ฌธ์ ๋ฒกํฐ๋ง์ผ๋ก ๋จ์ด๋ฅผ ์์ธกํฉ๋๋ค. ๊ณ์ฐ์ด ๊ฐ๋จํ๊ณ ๋น ๋ฆ ๋๋ค.
- ์์ ์ฝ๋:
1
2
3
4
5
6
7
8
9
10
11
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
documents = [TaggedDocument(words=["I", "love", "machine", "learning"], tags=['doc1']),
TaggedDocument(words=["Machine", "learning", "is", "fun"], tags=['doc2'])]
model = Doc2Vec(documents, vector_size=100, window=2, min_count=1, workers=4, dm=0) # PV-DBOW
vector = model.dv['doc1']
print(vector)
์ด๋ฒ ํฌ์คํธ์์๋ ์์ฐ์ด ์๋ฒ ๋ฉ ํ์ต์ ์ํ ๋ค์ํ ๊ธฐ๋ฒ๊ณผ ์๊ณ ๋ฆฌ์ฆ์ ๋ํด ์ค๋ช ํ์ต๋๋ค.
- ๋น์ ํ ๋ฐ์ดํฐ๋ฅผ ์ ํ ๋ฐ์ดํฐ๋ก ๋ณํํ๋ ๊ณผ์ ์์ Bag-of-Words(BoW), TF-IDF, N-Grams ๋ชจ๋ธ์ ํตํด ๋จ์ด์ ๋น๋์ ์์๋ฅผ ๋ฐ์ํ ๋ฒกํฐํ๋ฅผ ์ดํด๋ณด์์ต๋๋ค.
- Word2Vec, GloVe, FastText๋ฅผ ํตํด ๋จ์ด์ ์๋ฏธ์ ์ ์ฌ์ฑ์ ๋ฐ์ํ ๋ถ์ฐ ํํ ๊ธฐ๋ฒ์ ์ดํด๋ณด์์ต๋๋ค.
- ๋ํ, ๋ฌธ์ ์๋ฒ ๋ฉ ๊ธฐ๋ฒ์ ํตํด ๋ฌธ์ ์ ์ฒด๋ฅผ ๋ฒกํฐ๋ก ํํํ๋ ๋ฐฉ๋ฒ๋ ์ค๋ช ํ์์ต๋๋ค.
๊ธด ๊ธ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค ๐