词向量说明如下:

词向量模型表征的是词语与词语之间的距离和联系,词向量也叫词嵌入 word embedding
CBOW 模型: 根据某个词的上下文,计算中间词出现的概率,预测的是中心词
Skip-Gram 模型: 跟据中间词,分别计算它的上下文概率,与 CBOW 模型相反,预测的是上下文比如 "我喜欢你" 在Skip-Gram 中,取出其中的一个字当做输入,将其前面和后面的子分别当做标签,拆分如下:
"喜 我"
"喜 欢"
"欢 喜"
"欢 你"
每一行代表一个样本,第一列代表输入,第二列代表标签。即中间词取它的上下文为标签而 CBOW 模型恰恰相反,上下文取它的中间词为标签
"我 喜"
"欢 喜"
"喜 欢"
"你 欢"tf.nn.nce_loss 计算NCE 的损失值,主要说明如下
def nce_loss(weights, biases, inputs, labels, num_sampled, num_classes,num_true=1,sampled_values=None,remove_accidental_hits=False,partition_strategy="mod",name="nce_loss")
'''
假设nce_loss之前的输入数据是 K 维(也就是词向量的维度) 的,一共有 N 个类(也就是N个词),那么
weight.shape = (N, K)
bias.shape = (N)
inputs.shape = (batch_size, K)
labels.shape = (batch_size, num_true) num_true 就是对应的样本标签,也就是词id
num_true : 实际的正样本个数
num_sampled: 采样出多少个负样本
num_classes = N
sampled_values: 采样出的负样本,如果是None,就会用不同的sampler去采样。
remove_accidental_hits: 如果采样时不小心采样到的负样本刚好是正样本,要不要干掉
'''nce_loss的实现逻辑如下:
_compute_sampled_logits: 通过这个函数计算出正样本和采样出的负样本对应的output和label
sigmoid_cross_entropy_with_logits: 通过 sigmoid cross entropy来计算output和label的loss,从而进行反向传播。
这个函数把最后的问题转化为了num_sampled+num_real个两类分类问题,然后每个分类问题用了交叉熵的损伤函数,也就是logistic regression常用的损失函数。
TF里还提供了一个softmax_cross_entropy_with_logits的函数,和这个有所区别默认情况下,他会用log_uniform_candidate_sampler去采样。那么log_uniform_candidate_sampler是怎么采样的呢?他的实现在这里:
1、会在[0, range_max)中采样出一个整数k
2、P(k) = (log(k + 2) - log(k + 1)) / log(range_max + 1)
可以看到,k越大,被采样到的概率越小。
TF的word2vec实现里,词频越大,词的类别编号也就越小。因此,在TF的word2vec里,负采样的过程其实就是优先采词频高的词作为负样本。

batch 数据生成文件 datas.py 如下

# -*- coding:utf-8 -*-
import numpy as np
import tensorflow as tf
import random
import collections
from collections import Counter
import jiebafrom sklearn.manifold import TSNE
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['font.family'] = 'STSong'
mpl.rcParams['font.size'] = 20training_file = "人体阴阳与电能.txt"# 中文字
def get_ch_label(text_file):labels = ""with open(text_file,"rb") as f:for label in f :labels += label.decode("gb2312")return labels# 分词
def fenci(training_data):seg_list = jieba.cut(training_data)training_ci = " ".join(seg_list)training_ci = training_ci.split()# 用空格将字符串分开training_ci = np.array(training_ci)training_ci = np.reshape(training_ci,[-1,])return training_cidef build_dataset(words,n_words):count = [['UNK',-1]]# Counter 是计数器,统计词频,这里也就是统计前 n_words - 1 个最高的频率词count.extend(collections.Counter(words).most_common(n_words - 1))dictionary = dict()# 建立词典idfor word,_ in count:dictionary[word] = len(dictionary)data = list()unk_count = 0for word in words:if word in dictionary:index = dictionary[word]else:index = 0unk_count += 1data.append(index)count[0][1] = unk_countreversed_dictionary = dict(zip(dictionary.values(),dictionary.keys()))return data,count,dictionary,reversed_dictionarydata_index = 0
def generate_batch(data,batch_size,num_skips,skip_window):global data_indexassert batch_size % num_skips == 0assert num_skips <= 2 * skip_windowbatch = np.ndarray(shape = (batch_size),dtype = np.int32)labels = np.ndarray(shape = (batch_size,1),dtype = np.int32)# 每一个样本由 skip_window + 当前 target + 后 skip_window 组成span = 2 * skip_window + 1buffer = collections.deque(maxlen = span)if data_index + span > len(data):data_index = 0buffer.extend(data[data_index:data_index + span])data_index +=  spanfor i in range(batch_size // num_skips ):target = skip_window #target 在 buffer 中的索引为 skip_windowtargets_to_avoid = [skip_window]for j in range(num_skips):while target in targets_to_avoid:target = random.randint(0,span - 1)targets_to_avoid.append(target)batch[i*num_skips + j] = buffer[skip_window]labels[i*num_skips + j,0] = buffer[target]if data_index == len(data):buffer = data[:span]data_index = spanelse:buffer.append(data[data_index])data_index += 1data_index = (data_index + len(data) - span) % len(data)return batch,labelsdef get_batch(batch_size,num_skips = 2,skip_window = 1):# print (collections.Counter(['a','a','b','b','b','c']).most_common(1))training_data = get_ch_label(training_file)print "总字数",len(training_data)# 分词后的一维词表training_ci = fenci(training_data)training_label,count,dictionary,words = build_dataset(training_ci,350)words_size = len(dictionary)print "字典词数",words_size# print('Sample data',training_label[:10],[words[i] for i in training_label[:10]])# 获取batch,labelsbatch,labels = generate_batch(training_label,batch_size = batch_size,num_skips = num_skips,skip_window = skip_window)return batch,labels,words,words_size

词向量训练和可视化如下:

# -*- coding:utf-8 -*-
from __future__ import unicode_literals
import sys
reload(sys)
sys.setdefaultencoding("utf-8")from datas import get_batch,np,tf,plt,TSNE
batch_inputs,batch_labels,words,words_size =  get_batch(batch_size = 200)batch_size = 128
embedding_size = 128
skip_window = 1
num_skips =2valid_size = 16
valid_window = words_size / 2
valid_examples = np.random.choice(valid_window,valid_size,replace = False) # 0-valid_window 中的数据取 16 个,不能重复
num_sampled = 64 # 负采样个数tf.reset_default_graph()
train_inputs = tf.placeholder(tf.int32,shape = [None])
train_labels = tf.placeholder(tf.int32,shape = [None,1])
valid_dataset = tf.constant(valid_examples,dtype = tf.int32)with tf.device('/cpu:0'):embeddings = tf.Variable(tf.random_uniform([words_size,embedding_size],-1.0,1.0))embed = tf.nn.embedding_lookup(embeddings,train_inputs)# 计算 NCE 的loss 值nce_weights = tf.Variable(tf.truncated_normal([words_size,embedding_size],stddev = 1.0 /tf.sqrt(np.float32(embedding_size))))nce_biases = tf.Variable(tf.zeros([words_size]))loss = tf.reduce_mean(tf.nn.nce_loss(weights = nce_weights,biases = nce_biases,labels = train_labels,inputs = embed,num_sampled = num_sampled,num_classes = words_size))optimizer = tf.train.GradientDescentOptimizer(1.0).minimize(loss)# 计算 minibach examples 和所有 embeddings 的 cosine 相似度norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings),axis = 1,keep_dims = True)) # 按行单位化normalized_embeddings = embeddings / norm # 单位化 embeddingsvalidate_embeddings = tf.nn.embedding_lookup(normalized_embeddings,valid_dataset)# 就算出的余弦相似度,是一个矩阵,每一行代表某个 valid example 与每个词典的相似度similarity = tf.matmul(validate_embeddings,normalized_embeddings,transpose_b = True) # 余弦相似度矩阵if __name__ == "__main__":num_steps = 100001with tf.Session(graph = tf.get_default_graph()) as sess:tf.initialize_all_variables().run()print ('Initialized')average_loss = 0for step in range(num_steps):feed_dict = {train_inputs:batch_inputs,train_labels:batch_labels}_,loss_val = sess.run([optimizer,loss],feed_dict = feed_dict)average_loss += loss_valemv = sess.run(embed,feed_dict = {train_inputs:[37,18]})#print "emv----------------------------------",emv[0]if step % 1000 ==0:average_loss /= 1000print 'Average loss at step ',step,':',average_lossaverage_loss = 0sim = similarity.eval(session = sess)for i in range(valid_size):valid_word = words[valid_examples[i]]top_k = 8nearest = (-sim[i,:]).argsort()[1:top_k + 1] # argsort 返回的是数组值从小到大的索引值log_str = 'Nearest to %s:' % valid_wordfor k in range(top_k):close_word = words[nearest[k]]log_str = '%s,%s' %(log_str,close_word)print log_strfinal_embeddings = sess.run(normalized_embeddings)# 将词向量可视化 def plot_with_labels(low_dim_embs,labels,filename = 'tsne.png'):assert low_dim_embs.shape[0] >= len(labels),'More labels than embeddings'plt.figure(figsize = (18,18))for i,label in enumerate(labels):x,y = low_dim_embs[i,:]plt.scatter(x,y)plt.annotate(label.decode("utf-8"),xy = (x,y),xytext = (5,2),textcoords ='offset points',ha = 'right',va = 'bottom')plt.savefig(filename)try:tsne = TSNE(perplexity = 30,n_components = 2,init = 'pca',n_iter = 5000)plot_only = 80 # 输出 100 个词low_dim_embs = tsne.fit_transform(final_embeddings[:plot_only,:])labels = [unicode(words[i]) for i in range(plot_only)]plot_with_labels(low_dim_embs,labels)except:print "Save png Error"

运行结果如下:因为只有一篇 1700 字左右,所以效果不是很理想

生成的词向量模型可视化结果:其中距离越近代表词语之间的相关性越高

使用 rnn 训练词向量模型相关推荐

  1. 基于Keras预训练词向量模型的文本分类方法

    本文语料仍然是上篇所用的搜狗新闻语料,采用中文预训练词向量模型对词进行向量表示.上篇文章将文本分词之后,采用了TF-IDF的特征提取方式对文本进行向量化表示,所产生的文本表示矩阵是一个稀疏矩阵,本篇采 ...

  2. 从零开始构建基于textcnn的文本分类模型(上),word2vec向量训练,预训练词向量模型加载,pytorch Dataset、collete_fn、Dataloader转换数据集并行加载

    伴随着bert.transformer模型的提出,文本预训练模型应用于各项NLP任务.文本分类任务是最基础的NLP任务,本文回顾最先采用CNN用于文本分类之一的textcnn模型,意在巩固分词.词向量 ...

  3. ELMo预训练词向量模型

    引言 Word Embedding:词嵌入.最简单的理解就是:将词进行向量化表示,抽象成为数学描述,然后可以进行建模,应用到很多自然语言处理的下游任务中.之前用语言模型做 Word Embedding ...

  4. Ubuntu下GloVe中文词向量模型训练

    开启美好的九月 最近在学习textCNN进行文本分类,然后随机生成向量构建embedding网络的分类效果不是很佳,便考虑训练Glove词向量来进行训练,整个过程还是有遇到一些问题,希望懂的旁友能来指 ...

  5. 【NLP】word2vec词向量模型训练——基于tensorflow

    前言   维基百科中文数据训练word2vec词向量模型--基于gensim库   上文我们使用了 gensim 库中的 Word2vec 模块训练词向量模型,本篇我们通过 tensorflow 自己 ...

  6. 《自然语言处理学习之路》02 词向量模型Word2Vec,CBOW,Skip Gram

    本文主要是学习参考莫烦老师的教学,对老师课程的学习,记忆笔记. 原文链接 文章目录 书山有路勤为径,学海无涯苦作舟. 零.吃水不忘挖井人 一.计算机如何实现对于词语的理解 1.1 万物数字化 1.2 ...

  7. Python Djang 搭建自动词性标注网站(基于Keras框架和维基百科中文预训练词向量Word2vec模型,分别实现由GRU、LSTM、RNN神经网络组成的词性标注模型)

    引言 本文基于Keras框架和维基百科中文预训练词向量Word2vec模型,分别实现由GRU.LSTM.RNN神经网络组成的词性标注模型,并且将模型封装,使用python Django web框架搭建 ...

  8. DNN模型训练词向量原理

    转自:https://blog.csdn.net/fendouaini/article/details/79821852 1 词向量 在NLP里,最细的粒度是词语,由词语再组成句子,段落,文章.所以处 ...

  9. 使用Google word2vec训练我们自己的词向量模型

    主要内容 这篇文章主要内容是介绍从初始语料(文本)到生成词向量模型的过程. 词向量模型 词向量模型是一种表征词在整个文档中定位的模型.它的基本内容是词以及它们的向量表示,即将词映射为对应的向量,这样就 ...

最新文章

  1. python arm64_PyTorch-aarch64
  2. python连接linux获取日志_Python 日志记录模块logging的使用
  3. leetcode 95. Unique Binary Search Trees II | 96. Unique Binary Search Trees
  4. windows 获取系统CPU和进程CPU 内存等信息
  5. python执行一段代码_我发现了个 Python 黑魔法,执行任意代码都会自动念上一段 『平安经』...
  6. 最新性能测试:Kafka、Pulsar 和 Pravega 哪个最强?
  7. ASP网页中 制作连续无缝滚动文字
  8. 一篇介绍OpenJDK字体的文章
  9. 前端书籍推荐之《精通JavaScript+jQuery》
  10. 【WinHex篇】WinHex磁盘克隆教程
  11. IDL实现TM遥感影像直方图统计(中值、均值、方差、众数及峰度系数计算)
  12. awgn信道matlab建模,正交幅度调制信号在AWGN信道中传输的MATLAB仿真
  13. 网页yy语音(歪歪语音) 网页版
  14. 【Notepad++】Notepad++格式化JSON数据
  15. 解决黑苹果无法自动更新的问题,
  16. 【Origin】Origin准确标注某点
  17. SQL 查询某个字段某个字符串内容出现次数实现
  18. 铰链、弹簧,特殊的物理关节
  19. htb_Escape (mssql渗透,winrm)
  20. 【多元统计分析】08.协方差阵的假设检验

热门文章

  1. 网易内部邮箱coremail smtp pop设置
  2. linux 的基本命令格式,Linux学习之路(一)命令基本格式
  3. 双向带头循环链表-实现思路+图解
  4. 中国今年包揽前三,KDD Cup 20年全回顾
  5. Mac下的快速回到桌面快捷方式
  6. mysql alter table add foreign key_mysql alter table add foreign (errno: 150)添加外键150错误
  7. python算法工程师书籍_算法工程师路线图(经验浓缩,纯干货!)
  8. 选择一幅灰度图像,用Matlab编程计算该图像的灰度均值、方差和熵。
  9. mysql 自增字段、属性
  10. 用C++写“生日快乐”祝福