一、实验目的
1.了解词嵌入和词向量的基本概念及其在自然语言处理中的应用。
2.掌握使用One-Hot编码和Word2Vec模型构建词向量的方法。
3.掌握Doc2Vec模型构建文档向量的方法以及如何计算文档向量之间的相似度。
二、实验内容
(1)使用One-Hot编码构建词向量。
(2)使用Word2Vec构建词向量。
(3)使用Doc2Vec模型构建文档向量并计算向量间的相似度。
三、实验原理、方法和手段
(1)One-Hot编码
One-Hot编码是一种将词汇转换为向量的方法,每个词汇对应一个独特的向量,向量中只有一个元素为1,其余元素为0。其优点是简单直观,但存在维度高、无法表达词汇之间语义关系等缺点。
(2)Word2Vec
Word Embedding通过将词汇映射到低维连续向量空间中,能够捕捉词汇之间的语义关系。Word2Vec通过Skip-gram或CBOW模型进行训练,能够有效表示词汇的上下文信息。与One-Hot编码相比,Word2Vec能够更好地捕捉词汇间的语义相似性,并且维度较低。
(3)Doc2Vec
Doc2Vec是Word2Vec的扩展,旨在生成整个文档的向量表示。它通过引入文档向量,结合词向量共同训练,从而捕捉文档的整体语义信息。Doc2Vec适用于文本分类、相似度计算等任务。
(4)余弦相似度
余弦相似度是一种衡量两个向量在向量空间中夹角大小的指标,其值范围在-1到1之间。值越接近1,表示两个向量越相似;值越接近-1,表示两个向量越不相似;值为0表示两者正交,无相似性。
四、代码
One-Hot
from sklearn.preprocessing import OneHotEncoder
import numpy as np
# 示例词汇表
vocab = ["今天", "天气", "很好", "我们", "去", "公园"]
# 构建One-Hot编码器
encoder = OneHotEncoder(sparse=False)
vocab_array = np.array(vocab).reshape(-1, 1)
encoder.fit(vocab_array)
# 编码示例
word = "天气"
one_hot = encoder.transform([[word]])
print(f"One-Hot编码为'{word}': {one_hot}")
Word2Vec
from gensim.models import Word2Vec
import jieba
# 示例文本
sentences = [
"今天 天气 很好",
"我们 去 公园",
"公园 很美",
"天气 适合 散步"
]
# 分词处理
tokenized_sentences = [list(jieba.cut(sentence)) for sentence in sentences]
# 训练Word2Vec模型
model = Word2Vec(sentences=tokenized_sentences, vector_size=100, window=5, min_count=1, workers=4)
# 获取词向量
vector = model.wv["天气"]
print(f"Word2Vec词向量为'天气': {vector}")
Doc2Vec
from gensim.models import Doc2Vec
from gensim.models.doc2vec import TaggedDocument
import jieba
import numpy as np
# 示例文本
documents = [
"今天 天气 很好 我们 去 公园",
"公园 很美 天气 适合 散步",
"今天 我们 去 运动",
"运动 让人 感觉 很好"
]
# 分词处理并标记
tagged_data=[TaggedDocument(words=list(jieba.cut(doc)), tags=[f'DOC_{i}']) for i, doc in enumerate(documents)]
# 训练Doc2Vec模型
model = Doc2Vec(vector_size=100, window=5, min_count=1, workers=4, epochs=100)
model.build_vocab(tagged_data)
model.train(tagged_data, total_examples=model.corpus_count, epochs=model.epochs)
# 定义自定义相似度函数
def cosine_similarity(vec1, vec2):
dot_product = np.dot(vec1, vec2)
norm_vec1 = np.linalg.norm(vec1)
norm_vec2 = np.linalg.norm(vec2)
if norm_vec1 == 0 or norm_vec2 == 0:
return 0.0
return dot_product / (norm_vec1 * norm_vec2)
# 获取文档向量
doc0 = model.dv['DOC_0']
doc1 = model.dv['DOC_1']
doc2 = model.dv['DOC_2']
doc3 = model.dv['DOC_3']
# 计算相似度
similarity_0_1 = cosine_similarity(doc0, doc1)
similarity_0_2 = cosine_similarity(doc0, doc2)
similarity_0_3 = cosine_similarity(doc0, doc3)
print(f"DOC_0和DOC_1的相似度为: {similarity_0_1:.4f}")
print(f"DOC_0和DOC_2的相似度为: {similarity_0_2:.4f}")
print(f"DOC_0和DOC_3的相似度为: {similarity_0_3:.4f}")