在RNN中词使用one_hot表示的问题
目录
1.词嵌入
1.1.特点
1.3.word2vec介绍
1.3.Word2Vec案例
1.3.1.训练语料
1.3.2.步骤
1.3.3.代码
2.测试代码
定义:指把一个维数为所有词的数量的高维空间嵌入到一个维数低得多的连续向量空间中,每个单词或词组被映射为实数域上的向量。
注:这个维数通常不定,不同实现算法指定维度都不一样,通常在30~500之间。
如下图所示:
Bengio等人在一系列论文中使用了神经概率语言模型使机器“习得词语的分布式表示。
2013年,谷歌托马斯·米科洛维(Tomas Mikolov)领导的团队发明了一套工具word2vec来进行词嵌入。
Word2Vec 是一种广泛使用的词嵌入(Word Embedding)技术,由 Google 团队(Tomas Mikolov 等)于 2013 年提出。它通过神经网络模型将单词映射到低维稠密向量空间,使得语义相似的词在向量空间中距离相近。Word2Vec 是 NLP 领域的基础技术之一,广泛应用于文本分类、机器翻译、推荐系统等任务。
Word2Vec 的核心假设是:“具有相似上下文的单词,其语义也相似”。它通过训练神经网络,使得模型能够从大量文本中学习单词的分布式表示(Distributed Representation)。
1.主要特点
2. Word2Vec 的两种模型
Word2Vec 包含两种不同的训练方式:
(1) CBOW(Continuous Bag of Words)
["the", "cat", "on", "the"]
(上下文窗口=4)"mat"
(中心词)(2) Skip-Gram
"mat"
(中心词)["the", "cat", "on", "the"]
(上下文窗口=4)算法学习实现:https://www.tensorflow.org/tutorials/representation/word2vec
下载gensim库
pip install gensim
由于语料比较大,就提供了一个下载地址:搜狗搜索引擎 - 上网从搜狗开始
1、训练模型
2、测试模型结果
这里需要传入训练好的分词结果:corpus_seg.txt
训练的代码如下
import sys
import multiprocessing
from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
if __name__ == '__main__':
if len(sys.argv) < 3:
sys.exit(1)
# inp表示语料库(分词),outp:模型
inp, outp = sys.argv[1:3]
model = Word2Vec(LineSentence(inp), size=400, window=5, min_count=5, workers=multiprocessing.cpu_count())
model.save(outp)
运行命令
python trainword2vec.py ./corpus_seg.txt ./model/*
指定好分词的文件以及,保存模型的文件
improt gensim
gensim.models.Word2Vec.load("./model/corpus.model")
model.most_similar("警察")
Out:
[('警员', 0.6961891651153564),
('保安人员', 0.6414757370948792),
('警官', 0.6149201989173889),
('消防员', 0.6082159876823425),
('宪兵', 0.6013336181640625),
('保安', 0.5982533693313599),
('武警战士', 0.5962344408035278),
('公安人员', 0.5880240201950073),
('民警', 0.5878666639328003),
('刑警', 0.5800305604934692)]
model.similarity('男人','女人')
Out: 0.8909852730435042
model.most_similar(positive=['女人', '丈夫'], negative=['男人'], topn=1)
Out: [('妻子', 0.7788498997688293)]
步骤 | 功能描述 | 关键点/注意事项 |
---|---|---|
1. 导入库 | 加载必要的Python库 | gensim 用于Word2Vec,nltk 用于分词,os 用于路径操作。 |
2. 检查NLTK数据 | 确保punkt 分词数据存在,若缺失则自动下载 |
- 使用try-except 避免中断。- quiet=True 隐藏下载日志。 |
3. 定义示例数据 | 提供待训练的文本句子 | 实际应用中需替换为大规模文本(如从文件读取)。 |
4. 分词处理 | 将句子拆分为单词列表 | - 优先用word_tokenize 处理标点。- 失败时回退到 split() (效果较差)。 |
5. 训练Word2Vec | 根据分词结果训练词向量模型 | - vector_size=100 : 词向量维度。- sg=1 : 使用Skip-Gram算法(适合小数据)。 |
6. 保存模型 | 将模型保存到磁盘 | 后续可通过Word2Vec.load("word2vec.model") 复用模型。 |
7. 测试模型 | 验证词向量效果(查询词向量和相似词) |
from gensim.models import Word2Vec
from nltk.tokenize import word_tokenize
import nltk
import os
# 确保下载必要的NLTK数据
try:
nltk.data.find('tokenizers/punkt')
print("NLTK punkt data already downloaded")
except LookupError:
print("Downloading NLTK punkt data...")
nltk.download('punkt', quiet=True)
# 某些环境可能需要额外下载punkt_tab
try:
nltk.download('punkt_tab', quiet=True)
except:
print("punkt_tab not available, using only punkt")
# 示例文本数据
sentences = [
"I love natural language processing.",
"Word2Vec is a popular embedding technique.",
"Deep learning is changing the world."
]
# 分词(带错误回退机制)
try:
tokenized_sentences = [word_tokenize(sent.lower()) for sent in sentences]
print("Tokenizer succeeded!")
except LookupError as e:
print(f"Tokenizer failed: {e}")
print("Falling back to simple whitespace tokenizer...")
tokenized_sentences = [sent.lower().split() for sent in sentences]
# 训练 Word2Vec 模型
model = Word2Vec(
sentences=tokenized_sentences,
vector_size=100, # 向量维度
window=5, # 上下文窗口大小
min_count=1, # 忽略低频词
sg=1, # 1=Skip-Gram, 0=CBOW
negative=5, # 负采样数量
epochs=10 # 训练轮次
)
# 保存模型
model.save("word2vec.model")
print("Model saved successfully!")
# 测试词向量
try:
print("Example word vector for 'learning':", model.wv['learning'])
print("Most similar to 'processing':", model.wv.most_similar('processing'))
except KeyError as e:
print(f"Word not in vocabulary: {e}")
# 加载模型
model = Word2Vec.load("word2vec.model")
# 获取单词向量
vector = model.wv["word2vec"] # 获取 "word2vec" 的向量
# 计算相似词
similar_words = model.wv.most_similar("nlp", topn=3)
print(similar_words) # 输出:[('natural', 0.92), ('language', 0.88), ('processing', 0.85)]