基于TensorFlow的词向量算法

什么是Word2Vec

Word2Vec是从大量文本语料中以无监督的方式学习语义知识的一种模型,它被大量地用在自然语言处理(NLP)中。
Word2Vec其实就是通过学习文本来用词向量的方式表征词的语义信息,即通过一个嵌入空间使得语义上相似的单词在该空间内距离很近。我们从直观角度上来理解一下,cat这个单词和kitten属于语义上很相近的词,而dog和kitten则不是那么相近,iphone这个单词和kitten的语义就差的更远了。

Word2Vec模型实际上分为了两个部分,第一部分为建立模型,第二部分是通过模型获取嵌入词向量。Word2Vec的整个建模过程实际上与自编码器(auto-encoder)的思想很相似,即先基于训练数据构建一个神经网络,当这个模型训练好以后,我们并不会用这个训练好的模型处理新的任务,我们真正需要的是这个模型通过训练数据所学得的参数,例如隐层的权重矩阵。

数据预处理

数据预处理部分主要包括:

  • 剔除低频词汇
  • 替换特殊字符
  • 构建单词映射表

为了使模型高效的计算,我们知道神经网络的输入数据都为数值型,首先需要对输入词进行热编码(one-hot),生成的输入向量是一个稀疏矩阵,为避免消耗过大的资源,将出现频率较低的词汇剔除,并对高频词汇进行抽样。
Word2Vec通过“抽样”模式来解决这种高频词问题。它的基本思想如下:对于我们在训练原始文本中遇到的每一个单词,它们都有一定概率被我们从文本中删掉,而这个被删除的概率与单词的频率有关。

from __future__ import division,print_function,absolute_import

import collections
import os
import random
import urllib.request
import zipfile

import numpy as np
import tensorflow as tf


max_vocabulary_size = 50000 #词汇表中非重复单词个数
min_occurrence = 10 #剔除所有出现次数小于该值的单词


data_path = 'text8.zip'
#解压该文件,数据已被处理
with zipfile.ZipFile(data_path) as f:
    text_words = f.read(f.namelist()[0]).lower().split() 
    
#构建单词映射表并使用UNK代替特殊字符
count = [('UNK', -1)]
#寻找高频词汇
count.extend(collections.Counter(text_words).most_common(max_vocabulary_size - 1))
for i in range(len(count) - 1, -1):
    if count[i][1] < min_occurrence:
        count.pop(i)
    else:
        break
#计算单词的规模大小
vocabulary_size = len(count)
#为每个单词指定id
word2id = dict()
for i, (word, _)in enumerate(count): 
    word2id[word] = i

data = list()
unk_count = 0
for word in text_words:
    #如果该单词不存在字典中,使用UNK代替
    index = word2id.get(word, 0)
    if index == 0:
        unk_count += 1
    data.append(index)
count[0] = ('UNK', unk_count)
id2word = dict(zip(word2id.values(), word2id.keys()))

print("Words count:", len(text_words))
print("Unique words:", len(set(text_words)))
print("Vocabulary size:", vocabulary_size)
print("Most common words:", count[:10])

输出的结果:

Words count: 17005207
Unique words: 253854
Vocabulary size: 50000
Most common words: [('UNK', 418391), (b'the', 1061396), (b'of', 593677), (b'and', 416629), (b'one', 411764), (b'in', 372201), (b'a', 325873), (b'to', 316376), (b'zero', 264975), (b'nine', 250430)]

接下来对这部分代码进行更详细的讲解:
1 division,print_function,absolute_import这三个函数的功能就是python2 为了适配python3格式做的补充,所有如果是python3的话,是不需要导入的。
参考链接:from future import absolute_import,division,print_function的作用

from __future__ import division,print_function,absolute_import

2 从压缩包里解压缩出一个文件的方法是使用ZipFile的read方法:f.read(f.namelist()[0])读取出f.namelist()中的第一个文件。lower()返回将字符串中所有大写字符转换为小写后生成的字符串。split()返回分割后的字符串列表,以空格为分隔符,包括\n。
参考链接:
python模块 zipfile
split()函数介绍

with zipfile.ZipFile(data_path) as f:
    text_words = f.read(f.namelist()[0]).lower().split() 

3 enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
参考链接:Pytho

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值