达观杯”文本智能处理挑战赛

回顾
任务1-----对数据进行初步的预处理:
https://blog.csdn.net/weixin_38966454/article/details/89046445
任务2----F-IDF算法实现
https://blog.csdn.net/weixin_38966454/article/details/89058683

Now
任务3—word2vec算法实现

1.什么是word2vec
Word2vec,是一群用来产生词向量的相关模型。这些模型为浅而双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系,该向量为神经网络之隐藏层。

2.适用场景
word2vec适合用作序列数据的分类,聚类和相似度计算。有用作app下载推荐系统中的,也有用在推荐系统和广告系统上的,也可以用在机器人对话类别判决系统上。

3.word2vec原理

word2vec也叫word embeddings,中文名“词向量”,作用就是将自然语言中的字词转为计算机可以理解的稠密向量(Dense Vector)。在word2vec出现之前,自然语言处理经常把字词转为离散的单独的符号,也就是One-Hot Encoder。

在这里插入图片描述
如上图所示:One hot representation用来表示词向量非常简单,但是却有很多问题。最大的问题是我们的词汇表一般都非常大,比如达到百万级别,这样每个词都用百万维的向量来表示简直是内存的灾难。

Distributed representation可以解决One hot representation的问题,它的思路是通过训练,将每个词都映射到一个较短的词向量上来。所有的这些词向量就构成了向量空间,进而可以用普通的统计学的方法来研究词与词之间的关系。这个较短的词向量维度是多大呢?这个一般需要我们在训练时自己来指定。

在这里插入图片描述

有了用Distributed Representation表示的较短的词向量,我们就可以较容易的分析词之间的关系了,比如我们将词的维度降维到2维,有一个有趣的研究表明,用下图的词向量表示我们的词时,我们可以发现:
King→−Man→+Woman→=Queen→

在这里插入图片描述
4. CBOW与Skip-Gram用于神经网络语言模型
Skip-gram把一个词从词窗剔除。在skip-grams下给定n词围绕着词w,word2vec预测一个句子中其中一个缺漏的词c,即以机率来表示。相反地,CBOW给定词窗中的文本,预测当前的词。
CBOW

CBOW(Continuous Bag-of-Word Model)又称连续词袋模型,是一个三层神经网络。如下图所示,该模型的特点是输入已知上下文,输出对当前单词的预测。

在这里插入图片描述
其学习目标是最大化对数似然函数:

在这里插入图片描述
其中,w表示语料库C中任意一个词。
首先输入的是one-hot向量,第一层是一个全连接层,然后没有激活函数,输出层是一个softmax层,输出一个概率分布,表示词典中每个词出现的概率。
我们并不关心输出的内容,训练完成后第一个全连接层的参数就是word embedding。

Skip-Gram

Skip-gram只是逆转了CBOW的因果关系而已,即已知当前词语,预测上下文.

在这里插入图片描述
5.用gensim实现word2vec

a、API参数
在gensim中,word2vec 相关的API都在包gensim.models.word2vec中。
和算法有关的参数都在类gensim.models.word2vec.Word2Vec中。

b、参数
sentences: 我们要分析的语料,可以是一个列表,或者从文件中遍历读出。后面我们会有从文件读出的例子。

size: 词向量的维度,默认值是100。这个维度的取值一般与我们的语料的大小相关,如果是不大的语料,比如小于100M的文本语料,则使用默认值一般就可以了。如果是超大的语料,建议增大维度。

window:即词向量上下文最大距离,这个参数在我们的算法原理篇中标记为c,window越大,则和某一词较远的词也会产生上下文关系。默认值为5。在实际使用中,可以根据实际的需求来动态调整这个window的大小。如果是小语料则这个值可以设的更小。对于一般的语料这个值推荐在[5,10]之间。

sg: 即我们的word2vec两个模型的选择了。如果是0, 则是CBOW模型,是1则是Skip-Gram模型,默认是0即CBOW模型。

hs: 即我们的word2vec两个解法的选择了,如果是0, 则是Negative Sampling,是1的话并且负采样个数negative大于0, 则是Hierarchical Softmax。默认是0即Negative Sampling。

negative:即使用Negative Sampling时负采样的个数,默认是5。推荐在[3,10]之间。这个参数在我们的算法原理篇中标记为neg。

cbow_mean: 仅用于CBOW在做投影的时候,为0,则算法中的xw为上下文的词向量之和,为1则为上下文的词向量的平均值。在我们的原理篇中,是按照词向量的平均值来描述的。个人比较喜欢用平均值来表示xw,默认值也是1,不推荐修改默认值。

min_count:需要计算词向量的最小词频。这个值可以去掉一些很生僻的低频词,默认是5。如果是小语料,可以调低这个值。

iter: 随机梯度下降法中迭代的最大次数,默认是5。对于大语料,可以增大这个值。

alpha: 在随机梯度下降法中迭代的初始步长。算法原理篇中标记为η,默认是0.025。

min_alpha: 由于算法支持在迭代的过程中逐渐减小步长,min_alpha给出了最小的迭代步长值。随机梯度下降中每轮的迭代步长可以由iter,alpha, min_alpha一起得出。这部分由于不是word2vec算法的核心内容,因此在原理篇我们没有提到。对于大语料,需要对alpha, min_alpha,iter一起调参,来选择合适的三个值。

c.Python实现

#导入必要的库
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

#读取数据
test_path=r"D:\Desktop\new_data\test_set.csv"
train_path=r"D:\Desktop\new_data\train_set.csv"
train_data=pd.read_csv(train_path,nrows=5000,index_col='id')
test_data=pd.read_csv(test_path,nrows=5000,index_col='id')
#划分训练集&测试集 9:1
from sklearn.model_selection import train_test_split
X_train,X_valid,y_train,y_valid=train_test_split(train_data[['article','word_seg']],train_data['class'],test_size=0.3,random_state=2019)

print(X_train.shape,X_valid.shape,y_train.shape,y_valid.shape)
(3500, 2) (1500, 2) (3500,) (1500,)
#Word2vec训练

from  gensim.models import Word2Vec
vector_size=100

def sentence2list(sentence):
    return sentence.strip().split()

print('=============准备数据==========')
sentence_train=list(X_train.loc[:,'word_seg'].apply(sentence2list))
sentence_valid=list(X_valid.loc[:,'word_seg'].apply(sentence2list))
sentences=sentence_train+sentence_valid

print("========数据准备完成!===========")

#开始训练
print("========开始训练===========")
model=Word2Vec(sentences=sentences,size=vector_size,window=5,min_count=5,workers=8,sg=1,iter=5)
print("====训练完成======")


#提取词汇表及vectors并保存
import pickle
import numpy as np
print("=========保存训练结果==========")

wv=model.wv
vocab_list=wv.index2word
word_idx_dict={}

for idx,word in enumerate(vocab_list):
    word_idx_dict[word]=idx
    
vectors_arr=wv.vectors
vectors_arr=np.concatenate((np.zeros(vector_size)[np.newaxis,:],vectors_arr),axis=0)

feature_path=r"D:\Desktop\new_data"

f_wordidx = open(feature_path+'word_seg_idx_dict.pkl','wb')
f_vectors=open(feature_path+'word_seg_vectors_arr.pkl','wb')

pickle.dump(word_idx_dict,f_wordidx)
pickle.dump(vectors_arr,f_vectors)
f_wordidx.close()
f_vectors.close()

print("======训练结果已保存======")

=============准备数据==========
========数据准备完成!===========
========开始训练===========
=======训练完成==========
=========保存训练结果==========
======训练结果已保存======

参考文献:
1.http://www.cnblogs.com/pinard/p/7160330.html

猜你喜欢

转载自blog.csdn.net/weixin_38966454/article/details/89150133