第N5周:调用Gensim库训练Word2Vec模型

一、Woed2Vec详解

1.什么是Woed2Vec

Word2Vec是一种计算模型,它将词汇表中的每个词映射到一个固定大小的向量。这种技术是自然语言处理(NLP)领域的一个重要突破,由Google在2013年左右推出。Word2Vec模型能够捕捉词汇表中词之间的语义和语法关系,这些关系被编码在词向量(word embeddings)中。

Word2Vec主要有两种架构:连续词袋(CBOW)和Skip-Gram

连续词袋(CBOW)

  • CBOW模型通过一个词的上下文(即周围的词)来预测这个词。简单来说,CBOW模型考虑一个词周围的几个词(例如,一个5词窗口),然后将这些词作为输入来预测中心的词。
  1. 输入层:选择一个中心词的上下文单词,通常包括中心词前后的几个词(例如,一个5词窗口)。
  2. 投影层:将输入的上下文单词的词向量求和或平均,得到一个单一的向量。
  3. 隐藏层:这个投影层向量通常是直接用作隐藏层的输入。
  4. 输出层:输出层是一个softmax单元,它预测给定上下文的情况下中心词的概率分布。
  5. 训练:通过比较预测的分布和真实的分布(即中心词的实际分布),计算损失函数(通常是交叉熵损失),并通过反向传播更新权重。

CBOW模型通常在较大的数据集上训练得更快,因为它试图预测一个词而不是多个词。CBOW在预测常见词方面表现得更好,因为它考虑了多个上下文词。

Skip-Gram

  • Skip-Gram模型则相反,它使用一个词来预测其上下文。在Skip-Gram模型中,模型试图根据中心词来预测周围的词。
    这两种架构都使用神经网络作为训练机制,通过大量文本数据学习,生成词向量。这些词向量通常能够捕捉到丰富的语言学规律,例如,向量之间的距离可以表示词义之间的相似性("国王"和"王后"这样的词在向量空间中可能靠得很近),而且还能表现出一些语言学关系,比如性别、时态等。Skip-Gram模型的架构如下:
  1. 输入层:输入是单个词的词向量。
  2. 隐藏层:输入层直接连接到隐藏层,这里的隐藏层可以看作是输入层的复制。
  3. 输出层:输出层是一组softmax单元,每个单元对应词汇表中的一个词。这些单元的目的是预测给定输入词的上下文中每个词的概率。
  4. 训练:与CBOW类似,通过比较预测的分布和真实的分布计算损失函数,并通过反向传播更新权重。
    Skip-Gram模型在处理稀有词和复杂模式方面表现得更好,因为它试图为每个上下文单词生成预测。然而,Skip-Gram的训练通常比CBOW慢,因为它需要预测多个输出。

总结

  • CBOW:适用于大规模数据集和频繁词的向量表示,训练速度较快。
  • Skip-Gram:适用于处理稀有词和复杂的语言模式,训练速度较慢。

2.使用方法

gensim.models.Word2Vec 是 Gensim 库中的一个函数,用于训练 Word2Vec 模型。Gensim 是一个 Python 库,用于主题建模和文档相似性分析,它提供了 Word2Vec 模型的实现。下面是 gensim.models.Word2Vec 函数的基本用法和各个参数的含义:

gensim.models.word2vec.Word2Vec(sentences=None, corpus_file=None, size=100, alpha=0.025, window=5, min_count=5, max_vocab_size=None, sample=0.001, seed=1, workers=3, min_alpha=0.0001, sg=0, hs=0, negative=5, ns_exponent=0.75, cbow_mean=1, hashfxn=<built-in function hash>, iter=5, null_word=0, trim_rule=None, sorted_vocab=1, batch_words=10000, compute_loss=False, callbacks=(), max_final_vocab=None)

主要参数:

sentences (iterable of iterables, optional): 供训练的句子,可以使用简单的列表。

corpus_file (str, optional): LineSentence格式的语料库文件路径。

size (int, optional): word向量的维度。

window (int, optional): 一个句子中当前单词和被预测单词的最大距离。

min_count (int, optional): 忽略词频小于此值的单词。

workers (int, optional): 训练模型时使用的线程数。

sg ({0, 1}, optional): 模型的训练算法: 1: skip-gram; 0: CBOW.

hs ({0, 1}, optional): 1: 采用hierarchical softmax训练模型; 0: 使用负采样。

negative (int, optional): 0: 使用负采样,设置多个负采样(通常在5-20之间)。

ns_exponent (float, optional): 负采样分布指数。1.0样本值与频率成正比,0.0样本所有单词均等,负值更多地带样低频词。

cbow_mean ({0, 1}, optional): 0: 使用上下文单词向量的总和; 1: 使用均值,适用于使用CBOW。

alpha (float, optional): 初始学习率。

min_alpha (float, optional): 随着训练的进行,学习率线性下降到min_alpha。

seed (int, optional): 随机数发生器种子。

max_vocab_size (int, optional): 词汇构建期间RAM的限制,如果有更多的独特单词,则修剪不常见的单词。每1000万个类型的字需要大约1GB的RAM。

max_final_vocab (int, optional): 自动选择匹配的min_count将词汇限制为目标词汇大小。

sample (float, optional): 高频词随机下采样的配置阈值,范围是(0,1e-5)。

hashfxn (function, optional): 哈希函数用于随机初始化权重,以提高训练的可重复性。

iter (int, optional): 迭代次数。

trim_rule (function, optional): 词汇修剪规则,指定某些词语是否应保留在词汇表中,修剪掉或使用默认值处理。

sorted_vocab ({0, 1}, optional): 如果为1,则在分配单词索引前按降序对词汇表进行排序。

batch_words (int, optional): 每一个batch传递给线程单词的数量。

compute_loss (bool, optional): 如果为True,则计算并存储可使用get_latest_training_loss()检索的损失值。

callbacks (iterable of CallbackAny2Vec, optional): 在训练中特定阶段执行回调序列。

使用示例:

from gensim.models import Word2Vec
# 训练数据
sentences = [['this', 'is', 'the', 'first', 'sentence'], ['this', 'is', 'the', 'second', 'sentence']]
# 创建Word2Vec模型
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)
# 训练模型
model.train(sentences, total_examples=model.corpus_count, epochs=model.iter)
# 获取词向量
word_vector = model.wv['word']
# 保存模型
model.save('word2vec.model')
# 加载模型
model = Word2Vec.load('word2vec.model')

二、训练前数据处理

1. 原始语料分词

import os 
os.chdir(r'C:/Users/Dell/AppData/Roaming/Python/Python311/site-packages/')
# 这里改变路径是因为我没办法把jieba库下载在anaconda里面,只能下载在本地然后读取路径
import jieba
import jieba.analyse
os.chdir('C:\\Users\\Dell\\训练营')#这里需要改回路径不然pytorch环境里面的其他东西都用不了了

jieba.suggest_freq('沙瑞金', True) # 加入一些词,使得jieba分词准确率更高
jieba.suggest_freq('田国富', True)
jieba.suggest_freq('高育良', True)
jieba.suggest_freq('侯亮平', True)
jieba.suggest_freq('钟小艾', True)
jieba.suggest_freq('陈岩石', True)
jieba.suggest_freq('欧阳菁', True)
jieba.suggest_freq('易学习', True)
jieba.suggest_freq('王大路', True)
jieba.suggest_freq('蔡成功', True)
jieba.suggest_freq('孙连城', True)
jieba.suggest_freq('季昌明', True)
jieba.suggest_freq('丁义珍', True)
jieba.suggest_freq('郑西坡', True)
jieba.suggest_freq('赵东来', True)
jieba.suggest_freq('高小琴', True)
jieba.suggest_freq('赵瑞龙', True)
jieba.suggest_freq('林华华', True)
jieba.suggest_freq('陆亦可', True)
jieba.suggest_freq('刘新建', True)
jieba.suggest_freq('刘庆视', True)
jieba.suggest_freq('赵德汉', True)
with open(r'C:\Users\Dell\训练营\in_the_name_of_people.txt',encoding='utf-8') as f:
    result_cut = []
    lines = f.readlines()
    for line in lines:
        result_cut.append(list(jieba.cut(line)))
    f.close()

输出
Building prefix dict from the default dictionary …
Loading model from cache C:\Users\Dell\AppData\Local\Temp\jieba.cache
Loading model cost 0.576 seconds.
Prefix dict has been built successfully.

2.确定停用词

在自然语言处理(NLP)中,停用词(stop words)是指在文本中频繁出现但对于传达实际意义贡献不大的词。这些词通常是冠词、介词、连词等,例如“的”、“和”、“是”、“在”等。停用词在文本中几乎无处不在,但它们并不携带太多实际的语义信息。
停用词在NLP中的作用主要体现在以下几个方面:

  1. 减少噪声:去除停用词可以减少文本数据中的噪声,让模型更加关注那些携带更多语义信息的词。
  2. 提高效率:在文本处理过程中,去除停用词可以减少计算量和存储空间的需求,提高处理效率。
  3. 改善结果:在一些NLP任务中,如文本分类、情感分析等,去除停用词可以减少无意义的特征,有助于提高模型的性能和准确度。

在实际训练中,处理停用词的方法通常包括以下几个步骤:

  1. 获取停用词表:可以使用现成的停用词表,如NLTK、spaCy等库提供的停用词列表,也可以根据具体任务自定义停用词表。
  2. 文本预处理:在文本清洗和预处理阶段,将文本中的停用词去除。
  3. 特征提取:在提取文本特征时,忽略停用词。
  4. 模型训练:使用去除停用词后的文本数据进行模型训练。

需要注意的是,并不是所有的NLP任务都需要去除停用词。在某些任务中,如命名实体识别(NER)、词性标注(POS Tagging)等,停用词也可能携带一些有用的信息,因此是否去除停用词需要根据具体任务的需求来决定。停用词列表并不是一成不变的,它应该根据具体的语料库和应用场景进行调整。在社交媒体文本分析中,“哈哈”、“嗯嗯”这类词可能被视为停用词,因为它们出现频率高但语义信息少。

# 添加自定义停用词  
stopwords_list = [",","。","\n","\u3000"," ",":","!","?","…"]  
#\u3000 是一个 Unicode 编码的字符,它代表一个全角的空白字符,通常在中文文本中用作空格。
#这个字符在许多亚洲语言中用于文本排版,因为它比普通的半角空格( )宽。
  
def remove_stopwords(ls): # 去除停用词   
    return [word for word in ls if word not in stopwords_list]  
  
result_stop=[remove_stopwords(x) for x in result_cut if remove_stopwords(x)]
print(result_stop[100:103])

输出
在这里插入图片描述

NLP文本去噪技巧

在自然语言处理(NLP)中,去噪是一个关键的预处理步骤,它有助于提高后续处理步骤的质量。

  1. 文本标准化
    • 将文本转换为小写(或大写),以消除大小写的差异。
    • 扩展缩写词,例如将“can’t”转换为“cannot”。
    • 规范化数字的表示,例如将“$1000”转换为“1000美元”。
  2. 去除无关字符
    • 移除标点符号、特殊字符和不可见的控制字符。
    • 清理文档中的HTML标签或其他格式化代码。
  3. 处理停用词
    • 移除常见的停用词,如“的”、“和”、“是”等,这些词在大多数NLP任务中不携带重要的语义信息。
  4. 词干提取和词形还原
    • 使用词干提取(stemming)将单词缩减为其词干形式,例如将“running”缩减为“run”。
    • 使用词形还原(lemmatization)将单词转换为它们的词典形式(lemma),例如将“cars”还原为“car”。
  5. 纠正拼写错误
    • 使用拼写检查工具来识别和纠正文本中的拼写错误。
  6. 处理重复文本
    • 移除或合并连续出现的重复单词或句子。
  7. 处理非标准文本
    • 对于社交媒体文本或用户生成的内容,可能需要处理表情符号、网络用语、非标准拼写等。
  8. 语言检测和翻译
    • 如果处理多语言数据,可能需要检测文本的语言并进行必要的翻译。
  9. 使用NLP库和工具
    • 利用NLP库,如NLTK、spaCy、TextBlob等,它们提供了丰富的工具和资源来帮助去噪和文本预处理。
  10. 自定义去噪规则
    • 根据特定任务的需求,可能需要定义一些自定义的去噪规则。
  11. 迭代和评估
    • 在去噪过程中,迭代地测试不同的方法,并评估去噪对后续NLP任务性能的影响。
  12. 文档结构分析
    • 对于结构化的文档,如报告或学术论文,分析文档的标题、摘要、章节等结构,以提取关键信息。

去噪是一个迭代的过程,可能需要根据具体的应用场景和可用资源进行调整。在实际应用中,去噪的效果通常通过后续NLP任务的性能来评估,如分类准确性、主题模型的连贯性等。

三、训练Woed2Vec模型

from gensim.models import Word2Vec  
  
model = Word2Vec(result_stop,     # 训练的语料数据
                 vector_size=100, # 特征向量的维度,默认为100。   
                 window=5,        # 一个句子中当前单词和被预测单词的最大距离。   
                 min_count=1)     # 可以对字典做截断。词频少于min_count次数的单词会被丢弃掉,默认值为5。

四、模型应用

1.计算词汇相似度

model.wv.similarity 函数是 Gensim 库中 Word2Vec 模型的一个方法,用于计算两个词向量的余弦相似度。余弦相似度是一种衡量两个向量在方向上相似程度的度量,它的值范围在 -1 到 1 之间,1 表示完全相同的方向,-1 表示完全相反的方向,0 表示两者正交,即没有相似性。
计算余弦相似度的步骤如下:

  1. 获取词向量:首先,需要获取两个词的词向量。这些向量是在 Word2Vec 模型训练过程中学习到的。
  2. 计算点积:计算两个向量的点积(内积)。点积可以通过将两个向量的对应元素相乘然后求和得到。
  3. 计算向量长度:计算每个向量的长度(范数)。向量的长度是通过将向量中的每个元素平方后求和,然后取平方根得到的。
  4. 计算余弦相似度:余弦相似度是通过将两个向量的点积除以它们长度的乘积得到的。数学上表示为:
    [ \text{cosine similarity} = \frac{\vec{a} \cdot \vec{b}}{| \vec{a} | \times | \vec{b} |} ]
其中,( \vec{a} ) 和 ( \vec{b} ) 分别是两个词的词向量,( \cdot ) 表示点积,( | \vec{a} | ) 和 ( | \vec{b} | ) 分别是两个向量的长度。

在 Gensim 中,model.wv.similarity 方法会自动执行上述步骤,返回两个词向量之间的余弦相似度值。如果其中一个词不在词汇表中,该方法会抛出一个异常。

# 计算两个词的相似度
print(model.wv.similarity('沙瑞金','季昌明'))
print(model.wv.similarity('沙瑞金','田国富'))

0.9993937
0.999558

# 选出最相似的5个词
for e in model.wv.most_similar(positive=['沙瑞金'],topn=5):
    print(e[0], e[1])

学生 0.9996994137763977
老 0.9996634721755981
还是 0.9996193647384644
赵东来 0.999608039855957
又 0.9995825290679932

2.找出不匹配的词汇

model.wv.doesnt_match 是 Gensim 库中 Word2Vec 模型的一个方法,用于找出一个列表中与其他词最不相似的词。这个方法基于 Word2Vec 模型学习到的词向量,通过计算词向量之间的余弦相似度来确定最不相似的词。
该方法的工作原理如下:

  1. 获取词向量:首先,需要获取列表中所有词的词向量。这些向量是在 Word2Vec 模型训练过程中学习到的。
  2. 计算相似度:对于列表中的每个词,计算它与其他词的余弦相似度。这需要对列表中的每个词计算与其他词的点积,然后除以它们长度的乘积。
  3. 选择最不相似的词:对于列表中的每个词,找出它与其他词中最小的相似度值。这个最小值就是该词与其他词中最不相似的度量。
  4. 返回结果:最后,返回列表中与其他词最不相似的词。

在 Gensim 中,model.wv.doesnt_match 方法会自动执行上述步骤,返回一个列表,其中包含列表中与其他词最不相似的词。如果列表中的某个词不在词汇表中,该方法会抛出一个异常。

odd_word = model.wv.doesnt_match(["苹果","香蕉", "橙子", "书"])
print(f"在这组词汇中不匹配的词汇:{odd_word}")

在这组词汇中不匹配的词汇:书

3.计算词汇的词频

get_vecattr函数是Word2Vec模型中的一个方法,用于获取词向量的附加属性。它通常接收两个参数:单词和一个属性名称。

  1. 第一个参数:单词,即你想要查询的词汇。
  2. 第二个参数:属性名称,可以是以下几种:
    • 'count':该单词在训练时出现的次数。
    • 'mean':返回这个词向量的平均值。
    • 'norm':返回这个词向量的欧几里得范数(L2范数)。
    • 'total_count':这个单词及其所有上下文词对的总数。
    • 'total_bytes':存储向量所需的字节数。
    • 'total_words':训练集中的总词数。
    • 'state_size':在线训练期间的状态大小。

注意:使用get_vecattr函数前需要确保Word2Vec模型已经被正确训练,并且传入的单词是在模型训练时出现的词汇之一。

word_frequency = model.wv.get_vecattr("沙瑞金","count")
print(f"沙瑞金:{word_frequency}")

沙瑞金:353

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值