word2vec
1.近几年的机器学习和数据挖掘会议中,时常出现各种“嵌入”(embedding)的方法,这种方法的火爆是从Word2Vec算法开始的。
Word2Vec是一种将文本中的词进行嵌入的方法,而所谓嵌入,就是将各个词使用一个定长的向量来表示。
为什么要将词表示为向量呢?因为这极大方便了计算。例如,表示为向量以后,就可以方便的计算向量之间的距离,就可以知道对应的两个词之间有多么相近。
一个直接的想法是将词做one-hot编码,举例来说,假定总共有1000个词,那么就用1000维向量来表示每个词,对于第i个词,它对应的向量的第i个位置就是1,其他位置都是0。这种方法的缺点是浪费空间和不可扩展。如果总共有1万个词,就需要1万维的向量表示,而且,出现新词的时候也难以处理。
Word2Vec的思路是,将每个词嵌入到一个定长的向量里去,至于嵌入后的向量是什么,是模型自动学习的。
Word2Vec的实现有两种方式:skip-gram和CBOW(Continuous Bag-of-Words Model),它们的图示如下。
左边是CBOW模型,它的目标是:给定一串文本,使用某个词的上下文来预测这个词。例如,对于句子“The quick brown fox jumps over lazy dog”,预测fox这个词时,可以使用quick、brown、jumps、over这四个词,它们构成了fox的上下文。这样,从文本中就可以提取一系列的训练样本。
得到上下文以后,将这些词的one-hot编码累加起来,输入神经网络,然后神经网络进行一些变换,其目标为得到fox这个词的one-hot编码。训练好之后的神经网络中,隐藏层的权重矩阵就是词嵌入后的向量了。
右边的skip-gram是类似的,它输入当前词fox,目标是变换为上下文的词汇,此处上下文词汇的处理与CBOW一样,也是将这些词的one-hot编码相加,作为训练使用的真值。
上图展示了skip-gram的具体网络结构。从input vector到hidden layer这部分矩阵就是从one-hot编码到词向量的转换。输入一个词以后,所得到的隐藏层中各神经元的数值就组成了嵌入以后的向量。
2.code:
def sentence2list(sentence):
return sentence.strip().split()
df_train = pd.read_csv(data_path +'train_set1.csv',engine='python')
sentences_train = list(df_train.loc[:, 'word_seg'].apply(sentence2list))
model = gensim.models.Word2Vec(sentences=sentences_train , size=vector_size, window=5, min_count=5, workers=8, sg=0, iter=5)
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)#第0位置的vector为'unk'的vector
参考:
https://cloud.tencent.com/developer/news/121512
https://github.com/Heitao5200/DGB/blob/master/feature/feature_code/train_word2vec.py