[NLP] Word Embedding - CBOW and Skip-Gram
๐ง๐ป๐ป ์ฃผ์ ์ ๋ฆฌ
NLP
Word Embedding
CBOW
Represent the meaning of word
- Two basic neural network models:
- Continuous Bag of Word(CBOW) : use a window of word to predict the middle word.
- Skip-gram (SG) : use a word to predict the surrounbding ones in window.
์์ ๊ฐ์ ์ฐจ์ด๋ฅผ ๋ณด์ ๋๋ค.
ํ๋์ฉ ์ดํด๋ด ์๋ค.
# see http://pytorch.org/tutorials/beginner/nlp/word_embeddings_tutorial.html
import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
torch.manual_seed(1)
๋จผ์ , ์์ ๊ฐ์ด ํ์ํ library๋ฅผ import ํฉ๋๋ค.
CONTEXT_SIZE = 2 # 2 words to the left, 2 to the right # ์์ ๋ช ๋จ์ด๋ฅผ ๋ณผ ๊ฒ์ธ๊ฐ. ์ด 4๊ฐ์ ๋จ์ด๋ฅผ ๋ด.
text = """We are about to study the idea of a computational process.
Computational processes are abstract beings that inhabit computers.
As they evolve, processes manipulate other abstract things called data.
The evolution of a process is directed by a pattern of rules
called a program. People create programs to direct processes. In effect,
we conjure the spirits of the computer with our spells.""".split() # ๋ฐ์ดํฐ
split_ind = (int)(len(text) * 0.8)
# By deriving a set from `raw_text`, we deduplicate the array
'''
์ฒซ ๋ฒ์งธ ์์
. vocavluary๋ฅผ ๋ง๋ฆ. (0, 0, 0, 0, 0, 0, 0) ๋จ์ด๋ฅผ ๋ช ๋ฒ์งธ index๋ง 1๋ก ๋ฐ๊พธ๋ One-hot encoding์ ์ฌ์ฉ.
we = (1, 0, 0, 0, 0, 0, 0)
are = (0, 1, 0, 0, 0, 0, 0)
about = (0, 0, 1, 0, 0, 0, 0)
to = (0, 0, 0, 1, 0, 0, 0)
์ด๋ ๊ฒ ์ ์ฅํ๋ ๊ฒ์ ํ๋ฆ.
'''
# text๋ฅผ ๊ทธ๋ฅ splitํ๋ฉด ๋ชจ๋ ๊ฒ์ด ๋ค ๋์ด.
vocab = set(text) # set์ ์ฌ์ฉํด์ vocalvulary๋ก ๋ง๋ฆ.
vocab_size = len(vocab)
print('vocab_size:', vocab_size)
# ์์์๋ถํฐ ํ๋์ฉ ๋ฐฐ์
w2i = {w: i for i, w in enumerate(vocab)}
i2w = {i: w for i, w in enumerate(vocab)}
# ์์ฐ์ด์์ ๊ฐ์ฅ ๋จผ์ ํ๋ ๊ฒ์ด ์ด๋ฌํ vocalvulary๋ฅผ ๋ง๋๋ ๊ฒ์ด๋ค.
print(w2i)
print(i2w)
์ ์์ ์กฐ๊ธ์ฉ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ , CONTEXT_SIZE = 2๋ฅผ ์ดํด๋ณด๋ฉด, ์ ๋ค๋ก 2๋จ์ด์ฉ์ ์ดํด๋ณผ ์ ์๋ ๊ฒ์ ๋๋ค.
์ด๋ ์ฐ๋ฆฌ๊ฐ ์ ๋ค์ ๋ ๋จ์ด ์ฉ์ ๋ณด๊ณ , ๊ฐ์ด๋ฐ ๋จ์ด๋ฅผ ํ์ต์์ผ์ ์์ธก์ํฌ ์ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ , ๋ฐ์ดํฐ๋ฅผ text์ ๋ด์์ split์ผ๋ก ๋ถ๋ฆฌํ์ฌ ๋จ์ด ํ๋ํ๋์ฉ์ ๋ด์๋ก๋๋ค.
- ์ฒซ ๋ฒ์งธ ์์ . vocavluary๋ฅผ ๋ง๋๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ฐ๋ฐ,
(0, 0, 0, 0, 0, 0, 0) ๋จ์ด๋ฅผ ๋ช ๋ฒ์งธ index๋ง 1๋ก ๋ฐ๊พธ๋ One-hot encoding์ ์ฌ์ฉํฉ๋๋ค.
we = (1, 0, 0, 0, 0, 0, 0)
are = (0, 1, 0, 0, 0, 0, 0)
about = (0, 0, 1, 0, 0, 0, 0)
to = (0, 0, 0, 1, 0, 0, 0)
์ด๋ ๊ฒ ์ ์ฅํ๋ ๊ฒ์ ํ๋ญ๋๋ค.
์๋ง์ ๋จ์ด๋ฅผ One-hot encoding์ ํ๋ ๊ฒ์ ์๋นํ ๋ง์ vectors๊ฐ ํ์ํฉ๋๋ค.
๊ทธ๋ฌํ ํ๊ณ๊ฐ ์์ต๋๋ค.
๊ทธ๋์ ์ซ์๋ก ํ๋์ฉ ๋งค์นญ์์ผ์ฃผ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ,
vocab์ ํด๋น text๋ฅผ set์ผ๋ก ๋ฐ์์ vocabulary๋ฅผ ๋ง๋ญ๋๋ค.
๊ทธ๋์ ์๋์ ๊ฐ์ Output์ ๋ฝ์ ์ ์์ต๋๋ค.
vocab_size: 49
{'computers.': 0, 'other': 1, 'directed': 2, 'that': 3, 'data.': 4, 'processes.': 5, 'evolution': 6, 'pattern': 7, 'called': 8, 'programs': 9, 'effect,': 10, 'beings': 11, 'process': 12, 'We': 13, 'a': 14, 'our': 15, 'manipulate': 16, 'inhabit': 17, 'rules': 18, 'the': 19, 'The': 20, 'is': 21, 'program.': 22, 'direct': 23, 'In': 24, 'study': 25, 'computer': 26, 'with': 27, 'As': 28, 'spirits': 29, 'they': 30, 'People': 31, 'conjure': 32, 'spells.': 33, 'abstract': 34, 'are': 35, 'to': 36, 'of': 37, 'about': 38, 'things': 39, 'we': 40, 'create': 41, 'Computational': 42, 'evolve,': 43, 'by': 44, 'computational': 45, 'process.': 46, 'processes': 47, 'idea': 48}
{0: 'computers.', 1: 'other', 2: 'directed', 3: 'that', 4: 'data.', 5: 'processes.', 6: 'evolution', 7: 'pattern', 8: 'called', 9: 'programs', 10: 'effect,', 11: 'beings', 12: 'process', 13: 'We', 14: 'a', 15: 'our', 16: 'manipulate', 17: 'inhabit', 18: 'rules', 19: 'the', 20: 'The', 21: 'is', 22: 'program.', 23: 'direct', 24: 'In', 25: 'study', 26: 'computer', 27: 'with', 28: 'As', 29: 'spirits', 30: 'they', 31: 'People', 32: 'conjure', 33: 'spells.', 34: 'abstract', 35: 'are', 36: 'to', 37: 'of', 38: 'about', 39: 'things', 40: 'we', 41: 'create', 42: 'Computational', 43: 'evolve,', 44: 'by', 45: 'computational', 46: 'process.', 47: 'processes', 48: 'idea'}
์ ์ง๊ธ๊น์ง vocabulary๋ฅผ ๋ง๋ค์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ dataset์ ๋ง๋ค ์ ์์ต๋๋ค.
CBOW๋ input์ t - 2, t - 1, t + 1, t + 2๋ฅผ ๊ทธ๋ฆฌ๊ณ Output์ผ๋ก t๋ฅผ ๋ด๋๋ ํ์์ ๋๋ค.
์๋์ ๊ฐ์ด create_cbow_dataset ํจ์์์ text๋ฅผ ์ ๋ ฅ์ผ๋ก ๋ฐ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ data๋ 0๋ฒ์งธ ์ธ๋ฑ์ค์ 1๋ฒ์งธ ์ธ๋ฑ์ค๋ ์์ ๋ ๊ฐ์ text๊ฐ ์์ผ๋ฏ๋ก ํด๋น ๊ฒฝ์ฐ๋ ์ ์ธํฉ๋๋ค.
๋๋จธ์ง๋ context, ํ์ฌ t ์ธ๋ฑ์ค์ ๊ฐ์ target์ผ๋ก ์ง์ ํด์ context์ data์ pair๋ก ์ด๋ฃจ์ด์ง data๋ฅผ ๋ง๋ค๊ฒ ์ต๋๋ค.
# context window size is two
# input : t-2, t-1, t+1, t+2
# Output : t
# ๊ฐ ๋จ์ด๊ฐ ๋ค์ด์ค๋ฉด ๋ชฉ์ ์ผ๋ก ํ๋ Output์ ๊ฐ์ ์ ํ๋ฉด ์์ชฝ 2๊ฐ์ฉ์ ๊ฐ์ด ํ์.
def create_cbow_dataset(text):
data = []
for i in range(2, len(text) - 2): # 0๋ฒ์งธ๋๋ ์์์ ๋๋ ๊ฐ๊ฐ ์์์.
context = [text[i - 2], text[i - 1],
text[i + 1], text[i + 2]]
target = text[i] # ๋๋จธ์ง๋ context, ํ์ฌ t๋ฒ์งธ๋ฅผ target์ผ๋ก ์ง์ ํด์ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค๊ฒ ๋ค.
data.append((context, target))
return data
'''
์ฐ๋ฆฌ๋ input์ ํ์ฌ ๋จ์ด, Output์ 4๊ฐ.
๋ณดํต 4๊ฐ์ output์ผ๋ก ํ์ง๋ ์๊ณ ,
t - > t-2
t - > t-1
t - > t + 1
t - > t + 2
์
๋ ฅ ๊ฐ์ ๋ํ context๋ฅผ ํ์ต.
'''
# input : t
# Output : t-2, t-1, t+1, t+2
def create_skipgram_dataset(text):
import random
data = []
for i in range(2, len(text) - 2):
data.append((text[i], text[i-2], 1))
data.append((text[i], text[i-1], 1))
data.append((text[i], text[i+1], 1))
data.append((text[i], text[i+2], 1))
# negative sampling
for _ in range(4):
if random.random() < 0.5 or i >= len(text) - 3:
rand_id = random.randint(0, i-1)
else:
rand_id = random.randint(i+3, len(text)-1)
data.append((text[i], text[rand_id], 0))
return data
cbow_train = create_cbow_dataset(text)
skipgram_train = create_skipgram_dataset(text)
print('cbow sample', cbow_train[0])
print('skipgram sample', skipgram_train[0])
# ๋ฐ์ดํฐ ๋ง๋๋ ๊ฒ๊น์ง ํจ.
๊ทธ๋ฆฌ๊ณ ์์ ๊ฐ์ด create_skipgram_dataset ํจ์๋ฅผ ๊ตฌํํ์ฌ, text๋ฅผ input์ผ๋ก ๋ฐ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ , ์ for๋ฌธ์์๋ ์ฒซ๋ฒ์งธ์ ๋ ๋ฒ์งธ ์ธ๋ฑ์ค๋ ๊ฐ์ด ์ข์ฐ 2๊ฐ์ง ์ซ์๊ฐ ์กด์ฌํ์ง ์์ผ๋ฏ๋ก, ์์ ๊ฐ์ด ๊พธ๋ ค์ง๋๋ค.
input text i๋ฒ์งธ text์ ๋ํด t - 2, t - 1, t + 1, t + 2์ output์ผ๋ก ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ negative sampling์ ์ฌ์ฉํ์ฌ rand_id๋ฅผ ์ธ๋ฑ์ค๋ก ์ฌ์ฉํ์ฌ ๋๋ค์ผ๋ก ๋ฐฐ์นํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ cbow_train, skipgram_train์ ํด๋น ํ์ต์ฉ ๋ฐ์ดํฐ๋ค์ ๋ฃ์ต๋๋ค.
์ฌ๊ธฐ๊น์ง ๋ฐ์ดํฐ๋ฅผ ๋ง๋๋ ๊ฒ๊น์ง ํด๋ดค์ต๋๋ค.
cbow sample (['We', 'are', 'to', 'study'], 'about')
skipgram sample ('about', 'We', 1)
์ ์ฝ๋์ ์ถ๋ ฅ์ ๋๋ค.
๊ทธ๋ผ ์๋์ ๊ฐ์ด CBOW์ SkipGram model์ ์ดํด๋ด ์๋ค,
์๋์ ๊ฐ์ด
class CBOW(nn.Module):
def __init__(self, vocab_size, embd_size, context_size, hidden_size):
super(CBOW, self).__init__()
self.embeddings = nn.Embedding(vocab_size, embd_size)
self.linear1 = nn.Linear(2*context_size*embd_size, hidden_size) # input์ด์ด 4๊ฐ๊ฐ ์์ ๋ํดํด hidden layer ์ง๋ฌ๋ค๊ฐ๊ฐ ๊ฐ๊ฐ.
self.linear2 = nn.Linear(hidden_size, vocab_size) # (0, 0, 0, 0, 0, 1, 0, 0) # 6๋ฒ์งธ์งธ ์ธ๋ฑ์ค๋ฅผ๋ฅผ ๊ฐ๋๋ ๋จ์ด๋ค๋ค.
def forward(self, inputs):
embedded = self.embeddings(inputs).view((1, -1))
hid = F.relu(self.linear1(embedded))
out = self.linear2(hid)
log_probs = F.log_softmax(out)
return log_probs
class SkipGram(nn.Module):
def __init__(self, vocab_size, embd_size):
super(SkipGram, self).__init__()
self.embeddings = nn.Embedding(vocab_size, embd_size)
def forward(self, focus, context):
embed_focus = self.embeddings(focus).view((1, -1))
embed_ctx = self.embeddings(context).view((1, -1))
score = torch.mm(embed_focus, torch.t(embed_ctx))
log_probs = F.logsigmoid(score)
return log_probs
์ ์ฝ๋์์ input๊ณผ vector, ๊ทธ๋ฆฌ๊ณ embedding์ ๋ํ์ฌ ์ดํด๋ณผ ์ ์์ต๋๋ค.
ํด๋น ํจ์๋ค์ ๋ํ input ๊ฐ์ ์ ์ดํด๋ณด์๊ธธ ๋ฐ๋๋๋ค.
๊ทธ๋ฆฌ๊ณ , ํด๋น ๋ชจ๋ธ์ ๋ํ training ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ณผ ์ ์์ต๋๋ค.
embd_size = 100
learning_rate = 0.001
n_epoch = 30
def train_cbow():
hidden_size = 64
losses = []
loss_fn = nn.NLLLoss()
model = CBOW(vocab_size, embd_size, CONTEXT_SIZE, hidden_size)
print(model)
optimizer = optim.SGD(model.parameters(), lr=learning_rate)
for epoch in range(n_epoch):
total_loss = .0
for context, target in cbow_train:
ctx_idxs = [w2i[w] for w in context]
ctx_var = Variable(torch.LongTensor(ctx_idxs))
model.zero_grad()
log_probs = model(ctx_var)
loss = loss_fn(log_probs, Variable(torch.LongTensor([w2i[target]])))
loss.backward()
optimizer.step()
total_loss += loss.item()
losses.append(total_loss)
return model, losses
def train_skipgram():
losses = []
loss_fn = nn.MSELoss()
model = SkipGram(vocab_size, embd_size)
print(model)
optimizer = optim.SGD(model.parameters(), lr=learning_rate)
for epoch in range(n_epoch):
total_loss = .0
for in_w, out_w, target in skipgram_train:
in_w_var = Variable(torch.LongTensor([w2i[in_w]]))
out_w_var = Variable(torch.LongTensor([w2i[out_w]]))
model.zero_grad()
log_probs = model(in_w_var, out_w_var)
loss = loss_fn(log_probs[0], Variable(torch.Tensor([target])))
loss.backward()
optimizer.step()
total_loss += loss.item()
losses.append(total_loss)
return model, losses
cbow_model, cbow_losses = train_cbow()
sg_model, sg_losses = train_skipgram()
์ train ๊ณผ์ ์ ๋ํด์๋ ๊ธฐ๋ณธ์ ์ผ๋ก loss, model call, optimization, epoch ๋ฐ๋ณต์ผ๋ก ์ด๋ฃจ์ด์ ธ ์์ต๋๋ค.
์์ธํ ๋ด์ฉ์ ์๋ตํ๊ฒ ์ต๋๋ค.
์ถ๋ ฅ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
BOW(
(embeddings): Embedding(49, 100)
(linear1): Linear(in_features=400, out_features=64, bias=True)
(linear2): Linear(in_features=64, out_features=49, bias=True)
)
<ipython-input-5-49cae8ab3769>:12: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.
log_probs = F.log_softmax(out)
SkipGram(
(embeddings): Embedding(49, 100)
)
๊ทธ๋ฆฌ๊ณ ,
test ๋ถ๋ถ์ ๋๋ค.
# test
# You have to use other dataset for test, but in this case I use training data because this dataset is too small
def test_cbow(test_data, model):
print('====Test CBOW===')
correct_ct = 0
for ctx, target in test_data:
ctx_idxs = [w2i[w] for w in ctx]
ctx_var = Variable(torch.LongTensor(ctx_idxs))
model.zero_grad()
log_probs = model(ctx_var)
_, predicted = torch.max(log_probs.data, 1)
predicted_word = i2w[predicted.item()] # predicted๋ tensor์. ์ด๊ฒ์์ ์ด๋ ํํ ๊ฐ์ผ๋ก๋ก ๋ฐ๊ฟ์ผํจํจ. ๊ทธ๊ฒ์ด์ด Item.
print('predicted:', predicted_word)
print('label :', target)
if predicted_word == target:
correct_ct += 1
print('Accuracy: {:.1f}% ({:d}/{:d})'.format(correct_ct/len(test_data)*100, correct_ct, len(test_data)))
def test_skipgram(test_data, model):
print('====Test SkipGram===')
correct_ct = 0
for in_w, out_w, target in test_data:
in_w_var = Variable(torch.LongTensor([w2i[in_w]]))
out_w_var = Variable(torch.LongTensor([w2i[out_w]]))
model.zero_grad()
log_probs = model(in_w_var, out_w_var)
_, predicted = torch.max(log_probs.data, 1)
predicted = predicted[0]
if predicted == target:
correct_ct += 1
print('Accuracy: {:.1f}% ({:d}/{:d})'.format(correct_ct/len(test_data)*100, correct_ct, len(test_data)))
test_cbow(cbow_train, cbow_model)
print('------')
test_skipgram(skipgram_train, sg_model)
์๋ training๊ณผ ๊ฐ์ ๋ฐ์ดํฐ์ ์ ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ์๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ๊ฐ ์๋ ์ฝ๋ ๊ทธ ์์ฒด๋ฅผ ๋ณด๊ณ ๊ณต๋ถํด์ฃผ์ธ์.
์ถ๋ ฅ ๊ฒฐ๊ณผ์ ์ผ๋ถ๋ง ์ฒจ๋ถํ๊ฒ ์ต๋๋ค.
====Test CBOW===
predicted: about
label : about
predicted: to
label : to
predicted: study
label : study
predicted: the
label : the
predicted: idea
label : idea
predicted: of
label : of
predicted: a
label : a
:
:
:
predicted: with
label : with
Accuracy: 100.0% (58/58)
------
====Test SkipGram===
Accuracy: 50.0% (232/464)
<ipython-input-5-49cae8ab3769>:12: UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.
log_probs = F.log_softmax(out)
์, ๊ฒฐ๊ณผ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ ๊ฒฐ๊ณผ์์ CBOW๋ ์ ํ๋๊ฐ 100ํ๋ก๊ฐ ๋์์ต๋๋ค.
๊ทธ๋ฌ๋, SkipGram์ ์ ํ๋๊ฐ 50ํ๋ก์ ๋๋ค.
๋ ๊ฒฝ์ฐ ๋ชจ๋ training set๊ณผ test set์ด ๊ฐ์ ๊ฒฝ์ฐ์ธ๋ฐ ์ ๊ทธ๋ด๊น์?
SkipGram์ ์ ๋ชป ๋ง์ถ๋ ์ด์ .
data์ ๋ํด cbow๋ ์ ๋ ฅ 4๊ฐ์ ๋ํด output 1๊ฐ, skipgram์ ์ ํ๋๊ฐ ๋ ๋ฎ์๊น?
-> ๋ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ ํ์์ด, cbow๋ ์ ๋ ฅ 4๊ฐ์ ๋ํด 1๊ฐ๋ฅผ ๋ง์ถ๋ ๊ฒ.
-> skipgram์ ํน์ ๋จ์ ๋ํ 4๊ฐ์ ๋จ์ด๋ฅผ ํ์ตํ์.
t๊ฐ ๋ค์ด์๋ t -2, t-1, t+1, t+2๊ฐ ๋์์ด๋ฏ๋ก ์ ํ๋๊ฐ ๋จ์ด์ง๋ค.
์ ํ๋๊ฐ ๋ฎ๋ค๊ณ ์ ์ข์ ๋ชจ๋ธ์ด ์๋๋ค. ๋จ์ด๋ฅผ ๋ง์ถ๋ ๊ฒ ๋ชฉ์ ์ด ์๋๋ค. Weight๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ๋ชฉ์ ์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก skipgram์ด์ด ๋ ์ฑ๋ฅ์ด ์ข๋ค. cbow๋ 4๊ฐ๋ฅผ ๋ฐ๊ณ ํ๋์ ๋ํด ํ์ตํ๋ฉฐ, ๊ต์ฅํ specificํ ๊ฒฝ์ฐ์ ๋ํด์ ํ์ตํ๊ฒ ๋๋ ๊ฒ์ด๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ SkipGram์ด ๋ ์ผ๋ฐ์ ์ผ๋ก ์ ์ฑ๋ฅ์ด ์ข๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค.
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
def showPlot(points, title):
plt.figure()
fig, ax = plt.subplots()
plt.plot(points)
showPlot(cbow_losses, 'CBOW Losses')
showPlot(sg_losses, 'SkipGram Losses') # loss ํ์ต ์ฐจ์ด๋ฅผ ๋ณผ ์ ์๋ค.
์์ ๊ฐ์ด loss๋ฅผ ํตํด ํ์ต ์ฐจ์ด๋ฅผ ์ดํด๋ณผ ์ ์์ต๋๋ค.
<matplotlib.figure.Figure at 0x7fe1a5910f28>
CBOW
<matplotlib.figure.Figure at 0x7fe1ac39f2e8>
SkipGram
'Artificial Intelligence > Natural Language Processing' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[NLP] Word Embedding - GloVe [practice] (0) | 2023.03.31 |
---|---|
[NLP] Word Embedding - GloVe (0) | 2023.03.31 |
[NLP] Word Embedding - Word2Vec (0) | 2023.03.27 |
[NLP] Word Embedding - Skip Gram (0) | 2023.03.27 |
[NLP] Word Embedding - CBOW (1) | 2023.03.27 |