word2vec是google在2013年推出的一个NLP工具,,它的特点是将所有的词向量化,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词之间的联系。一时间无word2vec,不文本分析。本文主要介绍了如何利用 gensim来进行训练 。
'''
1.数据导入
'''
从网上下载imdb50000数据压缩包,解压后发现里面存在train,test两个文件夹。每个文件夹中还存在两个neg,pos两个文件夹。文件夹中全为txt格式的评论数据,每个文件夹下有12500个文件,共计50000。我们使用glob库,用来读取全部的文件。然后使用pandas将其保存为csv格式的文件,存在本地,以便于以后的使用。
import pandas as pd
import glob
import gensim
import logging
import nltk
'''
1.data_getting
'''
path='./imdb50000'
test_path_neg=path+'/test/neg/'
test_path_pos=path+'/test/pos/'
train_path_neg=path+'/train/neg/'
train_path_pos=path+'/train/pos/'
file_test_neg=glob.glob(test_path_neg+'*.txt')
file_test_pos=glob.glob(test_path_pos+'*.txt')
file_train_neg=glob.glob(train_path_neg+'*.txt')
file_train_pos=glob.glob(train_path_pos+'*.txt')
data=[]
files=[file_test_neg,file_test_pos,file_train_neg,file_train_pos]
for i in range(len(files)):
for file in files[i]:
f=open(file,encoding='ISO-8859-1')
temp=[f.read(),i%2]
data.append(temp)
movie_review=pd.DataFrame(data,columns=["review",'label'])
movie_review.to_csv('movie_review.csv')
texts=movie_review['review']
'''
2.数据预处理
'''
因为 使用gensim训练要求输入的数据为词list的形式,即[['I','am','ok'],['you','are','beautiful']]。我们对文本数据进行稍作处理,利用NLTK对文本进行分析即可。
sentences=[]
for text in texts:
tokens = nltk.word_tokenize(text)
sentences.append(tokens)
'''
3.开始训练
'''
训练完后,保存为bin格式,以便于以后加载使用,
# 设置输出日志
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
# 直接用gemsim提供的API去读取txt文件,读取文件的API有LineSentence 和 Text8Corpus, PathLineSentences等。
# 训练模型,词向量的长度设置为200, 迭代次数为8,采用CBOW模型,模型保存为bin格式
model = gensim.models.Word2Vec(sentences, size=200, sg=0, iter=8,negative=10)
model.wv.save_word2vec_format("./word2Vec" + ".bin", binary=True)
# 加载bin格式的模型
wordVec = gensim.models.KeyedVectors.load_word2vec_format("word2Vec.bin", binary=True)
wordVec['man']
主要参数介绍如下:
1) sentences:我们要分析的语料,可以是一个列表。
2) size:训练出来词向量的维度,本文使用的是200。当数据量大的时候建议提升维度,300在工业界用的多。
3) window:即词向量上下文最大距离,window越大,则和某一词较远的词也会产生上下文关系。默认值为5,在实际使用中,可以 根据实际的需求来动态调整这个window的大小,如果是小语料则这个值可以设的更小。
4) sg:即我们的word2vec两个模型的选择了。如果是0, 则是CBOW模型;是1则是Skip-Gram模型;默认是0即CBOW模型。
数据量小的情况下,CBOW效果更为理想,反之则反。
5) hs:即我们的word2vec两个解法的选择了。如果是0, 则是Negative Sampling;是1的话并且负采样个数negative大于0, 则是Hierarchical Softmax。默认是0即Negative Sampling。
6) negative:即使用Negative Sampling时负采样的个数,默认是5。推荐在[3,10]之间。这个参数在我们的算法原理篇中标记为neg。
7) cbow_mean:仅用于CBOW在做投影的时候,为0,则算法中的xw为上下文的词向量之和,为1则为上下文的词向量的平均值。在我们的原理篇中,是按照词向量的平均值来描述的。个人比较喜欢用平均值来表示xw,默认值也是1,不推荐修改默认值。
8) min_count:需要计算词向量的最小词频。这个值可以去掉一些很生僻的低频词,默认是5。如果是小语料,可以调低这个值。
9) iter:随机梯度下降法中迭代的最大次数,默认是5。对于大语料,可以增大这个值。
10) alpha:在随机梯度下降法中迭代的初始步长。算法原理篇中标记为η,默认是0.025。
11) min_alpha: 由于算法支持在迭代的过程中逐渐减小步长,min_alpha给出了最小的迭代步。
以下为全部代码
import pandas as pd
import glob
import gensim
import logging
import nltk
'''
1.data_getting
'''
path='./imdb50000'
test_path_neg=path+'/test/neg/'
test_path_pos=path+'/test/pos/'
train_path_neg=path+'/train/neg/'
train_path_pos=path+'/train/pos/'
file_test_neg=glob.glob(test_path_neg+'*.txt')
file_test_pos=glob.glob(test_path_pos+'*.txt')
file_train_neg=glob.glob(train_path_neg+'*.txt')
file_train_pos=glob.glob(train_path_pos+'*.txt')
data=[]
files=[file_test_neg,file_test_pos,file_train_neg,file_train_pos]
for i in range(len(files)):
for file in files[i]:
f=open(file,encoding='ISO-8859-1')
temp=[f.read(),i%2]
data.append(temp)
movie_review=pd.DataFrame(data,columns=["review",'label'])
movie_review.to_csv('movie_review.csv')
texts=movie_review['review']
'''
2.预处理,分词
'''
#给与训练的应该是分词过后的, 分词链表
sentences=[]
for text in texts:
tokens = nltk.word_tokenize(text)
sentences.append(tokens)
'''
3.word2vec
'''
# 设置输出日志
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
# 直接用gemsim提供的API去读取txt文件,读取文件的API有LineSentence 和 Text8Corpus, PathLineSentences等。
# 训练模型,词向量的长度设置为200, 迭代次数为8,采用CBOW模型,模型保存为bin格式
model = gensim.models.Word2Vec(sentences, size=200, sg=0, iter=8,negative=10)
model.wv.save_word2vec_format("./word2Vec" + ".bin", binary=True)
# 加载bin格式的模型
wordVec = gensim.models.KeyedVectors.load_word2vec_format("word2Vec.bin", binary=True)
wordVec['man']
插入一条 Word2vec 公式推导的blog :