找回密码
 会员注册
查看: 22|回复: 0

PythonSkip-Gram代码实战,Skip-Gram代码超简单讲解和步骤拆解,Word2vec代码构建思路,Skip-Gram代码实例,模板套用

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
70610
发表于 2024-9-5 14:42:50 | 显示全部楼层 |阅读模式
1. Skip-Gram介绍        Skip-gram模型是Word2Vec模型的一种训练方法,它的目标是通过目标词预测上下文词。Skip-gram模型通过神经网络结构来学习每个单词的向量表示。        在Skip-gram模型中,每个单词被表示为一个固定维度的向量,该向量称为嵌入向量或词向量。模型通过对训练语料中的每个中心词进行预测,来学习得到这些词向量。        训练过程中,Skip-gram模型的输入是一个中心词,目标是预测该词周围窗口内的上下文词。例如,给定一个句子"thecatsatonthemat"和窗口大小为1,中心词"sat"会被输入到模型中,而目标是预测"the"和"on"这两个上下文词。为了完成这个预测任务,模型通过调整词向量的参数来优化预测结果。        Skip-gram模型的训练目标是最大化预测上下文词的概率。具体而言,模型通过在中心词和上下文词之间计算余弦相似度,将预测问题转化为一个二分类问题。通过多次迭代训练,模型会学习到每个单词的向量表示,使得上下文语境相似的单词在向量空间中的距离更近。        Skip-gram模型具有以下优势:能够处理大规模的语料库、能捕捉到词之间的语义关系、词向量具有相对较低的维度、可以处理生僻词等。因此,Skip-gram模型被广泛应用于自然语言处理领域的词嵌入任务中。2. Skip-Gram代码实战2.1 定义一个句子列表,后面会用这些句子来训练CBOW和Skip-Gram模型这个其实和CBOW的处理过程一样的#定义一个句子列表,后面会用这些句子来训练CBOW和Skip-Gram模型sentences=["KageisTeacher","MazongisBoss","NiuzongisBoss","XiaobingisStudent","XiaoxueisStudent",]#将所有句子连接在一起,然后用空格分隔成多个单词words=''.join(sentences).split()#构建词汇表,去除重复的词word_list=list(set(words))#创建一个字典,将每个词映射到一个唯一的索引word_to_idx={word:idxforidx,wordinenumerate(word_list)}#创建一个字典,将每个索引映射到对应的词idx_to_word={idx:wordforidx,wordinenumerate(word_list)}voc_size=len(word_list)#计算词汇表的大小print("词汇表:",word_list)#输出词汇表print("词汇到索引的字典:",word_to_idx)#输出词汇到索引的字典print("索引到词汇的字典:",idx_to_word)#输出索引到词汇的字典print("词汇表大小:",voc_size)#输出词汇表大小'运行运行2.2 生成Skip-Gram训练数据#生成Skip-Gram训练数据defcreate_skipgram_dataset(sentences,window_size=2):data=[]#初始化数据forsentenceinsentences:#遍历句子sentence=sentence.split()#将句子分割成单词列表foridx,wordinenumerate(sentence):#遍历单词及其索引#获取相邻的单词,将当前单词前后各N个单词作为相邻单词forneighborinsentence[max(idx-window_size,0):min(idx+window_size+1,len(sentence))]:ifneighbor!=word:#排除当前单词本身#将相邻单词与当前单词作为一组训练数据data.append((neighbor,word))returndata#使用函数创建Skip-Gram训练数据skipgram_data=create_skipgram_dataset(sentences)#打印未编码的Skip-Gram数据样例(前3个)print("Skip-Gram数据样例(未编码):",skipgram_data[:3])2.3 定义One-Hot编码函数#定义One-Hot编码函数importtorch#导入torch库defone_hot_encoding(word,word_to_idx):tensor=torch.zeros(len(word_to_idx))#创建一个长度与词汇表相同的全0张量tensor[word_to_idx[word]]=1#将对应词的索引设为1returntensor#返回生成的One-Hot向量#展示One-Hot编码前后的数据word_example="Teacher"print("One-Hot编码前的单词:",word_example)print("One-Hot编码后的向量:",one_hot_encoding(word_example,word_to_idx))#展示编码后的Skip-Gram训练数据样例print("Skip-Gram数据样例(已编码):",[(one_hot_encoding(context,word_to_idx),word_to_idx[target])forcontext,targetinskipgram_data[:3]])2.4 定义Skip-Gram类#定义Skip-Gram类importtorch.nnasnn#导入neuralnetworkclassSkipGram(nn.Module):def__init__(self,voc_size,embedding_size):super(SkipGram,self).__init__()#从词汇表大小到嵌入层大小(维度)的线性层(权重矩阵)self.input_to_hidden=nn.Linear(voc_size,embedding_size,bias=False)#从嵌入层大小(维度)到词汇表大小的线性层(权重矩阵)self.hidden_to_output=nn.Linear(embedding_size,voc_size,bias=False)defforward(self,X):#前向传播的方式,X形状为(batch_size,voc_size)#通过隐藏层,hidden形状为(batch_size,embedding_size)hidden=self.input_to_hidden(X)#通过输出层,output_layer形状为(batch_size,voc_size)output=self.hidden_to_output(hidden)returnoutputembedding_size=2#设定嵌入层的大小,这里选择2是为了方便展示skipgram_model=SkipGram(voc_size,embedding_size)#实例化Skip-Gram模型print("Skip-Gram模型:",skipgram_model)2.5 训练Skip-Gram类#训练Skip-Gram类learning_rate=0.001#设置学习速率epochs=1000#设置训练轮次criterion=nn.CrossEntropyLoss()#定义交叉熵损失函数importtorch.optimasoptim#导入随机梯度下降优化器optimizer=optim.SGD(skipgram_model.parameters(),lr=learning_rate)#开始训练循环loss_values=[]#用于存储每轮的平均损失值forepochinrange(epochs):loss_sum=0#初始化损失值forcontext,targetinskipgram_data:X=one_hot_encoding(target,word_to_idx).float().unsqueeze(0)#将中心词转换为One-Hot向量y_true=torch.tensor([word_to_idx[context]],dtype=torch.long)#将周围词转换为索引值y_pred=skipgram_model(X)#计算预测值loss=criterion(y_pred,y_true)#计算损失loss_sum+=loss.item()#累积损失optimizer.zero_grad()#清空梯度loss.backward()#反向传播optimizer.step()#更新参数if(epoch+1)%100==0:#输出每100轮的损失,并记录损失print(f"Epoch:{epoch+1},Loss:{loss_sum/len(skipgram_data)}")loss_values.append(loss_sum/len(skipgram_data))#绘制训练损失曲线importmatplotlib.pyplotasplt#导入matplotlib#绘制二维词向量图plt.rcParams["font.family"]=['SimHei']#用来设定字体样式plt.rcParams['font.sans-serif']=['SimHei']#用来设定无衬线字体样式plt.rcParams['axes.unicode_minus']=False#用来正常显示负号plt.plot(range(1,epochs//100+1),loss_values)#绘图plt.title('训练损失曲线')#图题plt.xlabel('轮次')#X轴Labelplt.ylabel('损失')#Y轴Labelplt.show()#显示图2.6 输出Skip-Gram习得的词嵌入 #输出Skip-Gram习得的词嵌入print("Skip-Gram词嵌入:")forword,idxinword_to_idx.items():#输出每个词的嵌入向量print(f"{word}:{skipgram_model.input_to_hidden.weight[:,idx].detach().numpy()}") 2.7向量可视化fig,ax=plt.subplots()forword,idxinword_to_idx.items():#获取每个单词的嵌入向量vec=skipgram_model.input_to_hidden.weight[:,idx].detach().numpy()ax.scatter(vec[0],vec[1])#在图中绘制嵌入向量的点ax.annotate(word,(vec[0],vec[1]),fontsize=12)#点旁添加单词标签plt.title('二维词嵌入')#图题plt.xlabel('向量维度1')#X轴Labelplt.ylabel('向量维度2')#Y轴Labelplt.show()#显示图3.总结Word2Vec是一种用于学习词向量的算法模型,它能够将单词转换为密集的向量表示,并捕捉单词之间的语义关系。Word2Vec模型由Google于2013年提出,是一种基于神经网络的词嵌入技术。Word2Vec模型包括两种主要的训练方法:Skip-gram和CBOW。Skip-gram模型的目标是通过目标词预测上下文词,而CBOW模型的目标是通过上下文词预测目标词。这两种模型均采用神经网络结构,在大规模文本语料上进行训练,学习得到每个单词的向量表示。Word2Vec的核心思想是通过单词在上下文中的分布来学习单词的语义信息。具体而言,相似上下文中的单词会拥有相似的词向量表示,这样就能够捕捉到单词之间的语义关系。通过将单词表示为稠密的向量,Word2Vec模型可以表示单词之间的相似度,进而应用于词义相似度计算、文本分类、语言建模等多个自然语言处理任务中。Word2Vec模型的训练速度快、效果好,因此在自然语言处理领域得到了广泛的应用。它为计算机更好地理解和处理自然语言提供了有效的工具,被认为是自然语言处理领域的重要突破之一。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-8 12:46 , Processed in 0.645526 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表