在结束模型训练之后,一般使用$W_0$作为最终要使用的词向量 , 可以用$W_0$提供的向量表示 。通过向量点乘的方式,计算两个不同词之间的相似度 。
3. 实现Skip-gram接下来我们将学习使用飞桨实现Skip-gram模型的方法 。在飞桨中,不同深度学习模型的训练过程基本一致,流程如下:
- 数据处理:选择需要使用的数据,并做好必要的预处理工作 。
- 网络定义:使用飞桨定义好网络结构,包括输入层,中间层,输出层,损失函数和优化算法 。
- 网络训练:将准备好的数据送入神经网络进行学习,并观察学习的过程是否正常,如损失函数值是否在降低,也可以打印一些中间步骤的结果出来等 。
- 网络评估:使用测试集合测试训练好的神经网络,看看训练效果如何 。
import osimport sysimport requestsfrom collections import OrderedDictimport mathimport randomimport numpy as npimport paddleimport paddle.fluid as fluidfrom paddle.fluid.dygraph.nn import Embedding
3.1数据处理首先,找到一个合适的语料用于训练word2vec模型 。使用text8数据集,这个数据集里包含了大量从维基百科收集到的英文语料,我们可以通过如下代码下载数据集,下载后的文件被保存在当前目录的“text8.txt”文件内 。def download():#可以从百度云服务器下载一些开源数据集(dataset.bj.bcebos.com)corpus_url = "https://dataset.bj.bcebos.com/word2vec/text8.txt"#使用python的requests包下载数据集到本地web_request = requests.get(corpus_url)corpus = web_request.content#把下载后的文件存储在当前目录的text8.txt文件内with open("./text8.txt", "wb") as f:f.write(corpus)f.close()download()
接下来,把下载的语料读取到程序里,并打印前500个字符查看语料的格式 , 代码如下:def load_text8():with open("./text8.txt", "r") as f:corpus = f.read().strip("\n")f.close()return corpuscorpus = load_text8()#打印前500个字符,简要看一下这个语料的样子print(corpus[:500])
def data_preprocess(corpus):#由于英文单词出现在句首的时候经常要大写,所以我们把所有英文字符都转换为小写 , #以便对语料进行归一化处理(Apple vs apple等)corpus = corpus.strip().lower()corpus = corpus.split(" ")return corpuscorpus = data_preprocess(corpus)print(corpus[:50])
在经过切词后,需要对语料进行统计 , 为每个词构造ID 。一般来说,可以根据每个词在语料中出现的频次构造ID,频次越高,ID越?。?便于对词典进行管理 。代码如下:def build_dict(corpus):#首先统计每个不同词的频率(出现的次数),使用一个词典记录word_freq_dict = dict()for word in corpus:if word not in word_freq_dict:word_freq_dict[word] = 0word_freq_dict[word] += 1#将这个词典中的词,按照出现次数排序,出现次数越高,排序越靠前#一般来说,出现频率高的高频词往往是:I,the,you这种代词,而出现频率低的词,往往是一些名词 , 如:nlpword_freq_dict = sorted(word_freq_dict.items(), key = lambda x:x[1], reverse = True)#构造3个不同的词典,分别存储,#每个词到id的映射关系:word2id_dict#每个id出现的频率:word2id_freq#每个id到词的映射关系:id2word_dictword2id_dict = dict()word2id_freq = dict()id2word_dict = dict()#按照频率,从高到低,开始遍历每个单词,并为这个单词构造一个独一无二的idfor word, freq in word_freq_dict:curr_id = len(word2id_dict)word2id_dict[word] = curr_idword2id_freq[word2id_dict[word]] = freqid2word_dict[curr_id] = wordreturn word2id_freq, word2id_dict, id2word_dictword2id_freq, word2id_dict, id2word_dict = build_dict(corpus)vocab_size = len(word2id_freq)print("there are totoally %d different words in the corpus" % vocab_size)for _, (word, word_id) in zip(range(50), word2id_dict.items()):print("word %s, its id %d, its word freq %d" % (word, word_id, word2id_freq[word_id]))
得到word2id词典后,还需要进一步处理原始语料,把每个词替换成对应的ID , 便于神经网络进行处理,代码如下:def convert_corpus_to_id(corpus, word2id_dict):#使用一个循环,将语料中的每个词替换成对应的id,以便于神经网络进行处理corpus = [word2id_dict[word] for word in corpus]return corpuscorpus = convert_corpus_to_id(corpus, word2id_dict)print("%d tokens in the corpus" % len(corpus))print(corpus[:50])
接下来,需要使用二次采样法处理原始文本 。二次采样法的主要思想是降低高频词在语料中出现的频次 。方法是将随机将高频的词抛弃 , 频率越高,被抛弃的概率就越大;频率越低,被抛弃的概率就越小 。标点符号或冠词这样的高频词就会被抛弃,从而优化整个词表的词向量训练效果 , 代码如下:
推荐阅读
- 超人怎么死的(超人怎么复活)
- 米游社上传图片水印怎么关
- 苹果se3参数与图片_苹果se3参数详细配置
- 双叶h-单叶双曲面与双叶双曲面的图像区别
- dc超人咋死的
- 许褚怎么牺牲的(三国名将许褚之死)
- CSS处理器-Less/Scss
- JUC学习笔记——进程与线程
- 红警尤里怎么玩(红警2共和国之辉尤里怎么玩)
- 斗地主怎么玩(斗地主怎么记牌最轻松)