android做網(wǎng)站網(wǎng)站怎么做
FastText 是 Facebook AI Research 提出的 改進(jìn)版 Word2Vec,可以: ? 利用 n-grams 處理未登錄詞
比 Word2Vec 更快、更準(zhǔn)確
適用于中文等形態(tài)豐富的語言
完整的 PyTorch FastText 代碼(基于中文語料),包含:
- 數(shù)據(jù)預(yù)處理(分詞 + n-grams)
- 模型定義
- 訓(xùn)練
- 測試
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import jieba
from collections import Counter
import random# ========== 1. 數(shù)據(jù)預(yù)處理 ==========
corpus = ["我們 喜歡 深度 學(xué)習(xí)","自然 語言 處理 是 有趣 的","人工智能 改變 了 世界","深度 學(xué)習(xí) 是 人工智能 的 重要 組成部分"
]# 分詞
tokenized_corpus = [list(jieba.cut(sentence)) for sentence in corpus]# 構(gòu)建 n-grams
def generate_ngrams(words, n=3):ngrams = []for word in words:ngrams += [word[i:i + n] for i in range(len(word) - n + 1)]return ngrams# 生成 n-grams 詞表
all_ngrams = set()
for sentence in tokenized_corpus:for word in sentence:all_ngrams.update(generate_ngrams(word))# 構(gòu)建詞匯表
vocab = set(word for sentence in tokenized_corpus for word in sentence) | all_ngrams
word2idx = {word: idx for idx, word in enumerate(vocab)}
idx2word = {idx: word for word, idx in word2idx.items()}# 構(gòu)建訓(xùn)練數(shù)據(jù)(CBOW 方式)
window_size = 2
data = []for sentence in tokenized_corpus:indices = [word2idx[word] for word in sentence]for center_idx in range(len(indices)):context = []for offset in range(-window_size, window_size + 1):context_idx = center_idx + offsetif 0 <= context_idx < len(indices) and context_idx != center_idx:context.append(indices[context_idx])if context:data.append((context, indices[center_idx])) # (上下文, 目標(biāo)詞)# ========== 2. 定義 FastText 模型 ==========
class FastText(nn.Module):def __init__(self, vocab_size, embedding_dim):super(FastText, self).__init__()self.embeddings = nn.Embedding(vocab_size, embedding_dim)self.linear = nn.Linear(embedding_dim, vocab_size)def forward(self, context):context_vec = self.embeddings(context).mean(dim=1) # 平均上下文向量output = self.linear(context_vec)return output# 初始化模型
embedding_dim = 10
model = FastText(len(vocab), embedding_dim)# ========== 3. 訓(xùn)練 FastText ==========
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)
num_epochs = 100for epoch in range(num_epochs):total_loss = 0random.shuffle(data)for context, target in data:context = torch.tensor([context], dtype=torch.long)target = torch.tensor([target], dtype=torch.long)optimizer.zero_grad()output = model(context)loss = criterion(output, target)loss.backward()optimizer.step()total_loss += loss.item()if (epoch + 1) % 10 == 0:print(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {total_loss:.4f}")# ========== 4. 獲取詞向量 ==========
word_vectors = model.embeddings.weight.data.numpy()# ========== 5. 計(jì)算相似度 ==========
def most_similar(word, top_n=3):if word not in word2idx:return "單詞不在詞匯表中"word_vec = word_vectors[word2idx[word]].reshape(1, -1)similarities = np.dot(word_vectors, word_vec.T).squeeze()similar_idx = similarities.argsort()[::-1][1:top_n + 1]return [(idx2word[idx], similarities[idx]) for idx in similar_idx]# 測試
test_words = ["深度", "學(xué)習(xí)", "人工智能"]
for word in test_words:print(f"【{word}】的相似單詞:", most_similar(word))
1. 生成 n-grams
- FastText 處理單詞的 子詞單元(n-grams)
- 例如
"學(xué)習(xí)"
會生成["學(xué)習(xí)", "習(xí)學(xué)", "學(xué)"]
- 這樣即使遇到未登錄詞也能拆分為 n-grams 計(jì)算
2. 訓(xùn)練數(shù)據(jù)
- 使用 CBOW(上下文預(yù)測中心詞)
- 窗口大小 = 2,即:
句子: ["深度", "學(xué)習(xí)", "是", "人工智能"] 示例: (["深度", "是"], "學(xué)習(xí)")
3. FastText 模型
- 詞向量是 n-grams 詞向量的平均值
- 計(jì)算公式:?
- 這樣,即使單詞沒見過,也能用它的 n-grams 計(jì)算詞向量!
?4. 計(jì)算相似度
- 用
cosine similarity
找出最相似的單詞 - FastText 比 Word2Vec 更準(zhǔn)確,因?yàn)樗芾?n-grams 捕捉詞的語義信息
特性 | FastText | Word2Vec | GloVe |
---|---|---|---|
原理 | 預(yù)測中心詞 + n-grams | 預(yù)測中心詞或上下文 | 統(tǒng)計(jì)詞共現(xiàn)信息 |
未登錄詞處理 | 可處理 | 無法處理 | 無法處理 |
訓(xùn)練速度 | ?快 | 快 | 慢 |
適合領(lǐng)域 | 中文、罕見詞 | 傳統(tǒng) NLP | 大規(guī)模數(shù)據(jù) |