词向量 订阅
词向量(Word embedding),又叫Word嵌入式自然语言处理(NLP)中的一组语言建模和特征学习技术的统称,其中来自词汇表的单词或短语被映射到实数的向量。 从概念上讲,它涉及从每个单词一维的空间到具有更低维度的连续向量空间的数学嵌入。生成这种映射的方法包括神经网络,单词共生矩阵的降维,概率模型,可解释的知识库方法,和术语的显式表示 单词出现的背景。当用作底层输入表示时,单词和短语嵌入已经被证明可以提高NLP任务的性能,例如语法分析和情感分析。 展开全文
词向量(Word embedding),又叫Word嵌入式自然语言处理(NLP)中的一组语言建模和特征学习技术的统称,其中来自词汇表的单词或短语被映射到实数的向量。 从概念上讲,它涉及从每个单词一维的空间到具有更低维度的连续向量空间的数学嵌入。生成这种映射的方法包括神经网络,单词共生矩阵的降维,概率模型,可解释的知识库方法,和术语的显式表示 单词出现的背景。当用作底层输入表示时,单词和短语嵌入已经被证明可以提高NLP任务的性能,例如语法分析和情感分析。
信息
外文名
Word embedding
中文名
词向量
词向量技术的发展
在语言学中,在分布语义学的研究领域中讨论了词嵌入。它旨在基于语言数据的大样本中的分布属性来量化和分类语言项之间的语义相似性。 Firth普及了“一个词以其所保持的特征为特征”的基本观点。将词语表示为向量的技术起源于20世纪60年代随着用于信息检索的向量空间模型的发展。使用奇异值分解减少维数,然后导致在20世纪80年代后期引入潜在语义分析。2000年Bengio等人。在一系列论文中提供了“神经概率语言模型”,通过“学习单词的分布式表示”来减少语境中单词表示的高维度。 (Bengio等,2003)。单词嵌入有两种不同的风格,一种是将单词表示为共同出现的单词的向量,另一种是将单词表示为单词出现的语言上下文的向量;研究了这些不同的风格(Lavelli等,2004)。Roweis和Saul在“科学”杂志上发表了如何使用“局部线性嵌入”(LLE)来发现高维数据结构的表示。该区域在2010年后逐渐发展并真正起飞,部分原因是此后在向量质量和模型训练速度方面取得了重要进展。有许多分支机构和许多研究小组从事字嵌入工作。 2013年,由Tomas Mikolov领导的Google团队创建了word2vec,这是一个嵌入式工具包,可以比以前的方法更快地训练向量空间模型。大多数新词嵌入技术依赖于神经网络架构而不是更传统的n-gram模型和无监督学习。
收起全文
精华内容
下载资源
问答
  • 词向量

    千次阅读 2019-03-07 12:49:31
    词向量是自然语言处理中重要的基础,有利于我们对文本、情感、词义等等方向进行分析,主要是将词转化为稠密向量,从而使得相似的词,其词向量也相近。 一、词向量的表示 词向量的表示通常有两种方式,一种是离散...

      词向量是自然语言处理中重要的基础,有利于我们对文本、情感、词义等等方向进行分析,主要是将词转化为稠密向量,从而使得相似的词,其词向量也相近。

    一、词向量的表示

      词向量的表示通常有两种方式,一种是离散的,另一种是分布式的;其离散方式通常称为one-hot representation,其缺点是不能显示词与词之间的关系,但优点是在高维空间中,很多任务线性可分。

      其分布式的方式通常称为 distribution representation,是将词转化为一种分布式的、连续的、定长的稠密向量,其优点是可以表示词与词之间的距离关系,每一维度都有其特定的含义;

      两者的区别是用one-hot特征时,可以对特征向量进行删减,而分布式的则不可以。

    二、词向量的训练

    2.1 基于统计的方法

    2.1.1 共现矩阵

      统计一个窗口内word共现次数,以word周边的共现词的次数做为当前word的vector。该矩阵一定程度上缓解了one-hot向量相似度为0问题,但并没有解决数据的稀疏性和高维性问题。

    2.1.2 奇异值分解

      针对共现矩阵存在的问题,提出了对原始词向量进行降维,从而得到一个稠密的连续词向量。利用SVD的方法,最终可以得到一个正交矩阵,进行归一化后即为词向量。

      该方法的有点是可以一定程度上反映语义相近的词,以及word间的线性关系;但由于很多词没有出线,导致矩阵及其稀疏,需要对词频做额外处理才能达到好的结果,并且其矩阵也是非常大,维度高。

      基于共现矩阵的词向量代码如下:

      

    # 基于词与词构造共现矩阵,提取词向量
    import collections
    file_path = "D:\workspace\project\\NLPcase\\word2vec\\data\\data.txt"
    model_path = "D:\workspace\project\\NLPcase\\word2vec\\model\\skipgram_word2vec.txt"
    min_count = 5 #最低词频
    word_demension = 200
    window_size = 5 # 窗口大小
    
    def load_data(file_path = file_path):
        dataset = []
        for line in open(file_path,encoding='utf-8'):
            line = line.strip().split(',')
            dataset.append([word for word in line[1].split(' ') if 'nbsp' not in word and len(word)<1])
        return dataset
    dataset = load_data()
    
    # 统计总词数
    def build_wrod_dict():
        words = []
        for data in dataset:
            words.extend(data)
        reserved_words = [item for item in collections.Counter(words).most_common() if item[1]>min_count]
        word_dict = {item[0]:item[1] for item in reserved_words}
        return word_dict
    # 构造上下文窗口
    def build_word2word_dict():
        word2word_dict = {}
        for data_idx, data in enumerate(dataset):
            contexts = []
            for index in range(len(data)):
                if index < window_size:
                    left = data[:index]
                else:
                    left = data[index-window_size:index]
                if index + window_size > len(data):
                    right = data[index + 1:]
                else:
                    right = data[index + 1: index + window_size + 1]
                context = left + [data[index]] + right# 得到了一句话中的上下文的窗口
                for word in context:
                    if word not in word2word_dict:
                        word2word_dict[word] = {}
                    else:
                        for co_word in context:
                            if co_word !=word:
                                word2word_dict[word][co_word] =1
                            else:
                                word2word_dict[word][co_word] += 1
        return word2word_dict
    # 构造共现矩阵
    def build_word2word_matrix():
        word2word_dict = build_word2word_dict()
        word_dict =build_wrod_dict()
        word_list = list(word_dict)# 这个只会构造出一个word的key
        word2word_matrix = []
        count = 0
        for word1 in word_list:
            count +=1
            temp = []
            sumtf = sum(word2word_dict[word1].values())
            for word2 in word_list:
                weight = word2word_dict[word2].get(word2, 0) / sumtf
                temp.append(weight)
            word2word_matrix.append(temp)
        return word2word_matrix

    2.2 基于语言模型

      语言模型生成词向量是通过训练神经网络模型附带产出的,一般是采用三层神经网络结构,分别为输入层、隐藏层以及输出层。常见的就是word2vect方法,该方法主要有两种方式,CBOW和skip-gram;

      Word2vect的改进方法有两种,一种是基于Hierarchical softmax,另一种是基于负采样。

      word2vect最先优化使用的结构是霍夫曼树,来代替隐藏层和输出层的神经元,但其问题就在隐藏层和输出层的softmax计算量很大(因为要计算所有词的softmax概率,再去找最大概率),因此霍夫曼树可以解决这个问题。霍夫曼树的叶子节点起到输出神经元的作用。一般霍夫曼树后会对叶子节点进行编码,由于权重高的叶子节点靠近根节点,而权重低的叶子节点远离根节点,这样权重高的节点编码段短,权重低的编码较长,符合信息论,也就是越是常用的词拥有更短的编码。霍夫曼树当中定义左节点还是右节点里面有个主意的sigmoid函数,因此最后变成了求解Hierarchical Softmax的参数的问题,求解梯度并进行计算。

      基于负采样求解word2vect模型的方法摒弃了霍夫曼树,因为霍夫曼树针对样本中心词是一个生僻词时,就得在霍夫曼树中路径寻找很久。比如训练一个样本,中心词是w,他的周围上下文共有2c个词,则记为context(w)。由于这个中心词w和context(w)相关,则它是一个真实的正例;现在通过负采样技术,得到neg个和w不同的中心词wi,i=1,2,…,neg,则context(w)和这个wi组成一个负例子;利用这个正例和neg负例,我们进行二元逻辑回归,得到负采样对应每个词wi对应的模型参数theta,以及每个词的词向量。

      简单的对负采样进行总结:

      还是假设词库有10000个词,词向量300维,那么每一层神经网络的参数是300万个,输出层相当于有一万个可能类的多分类问题。可以想象,这样的计算量非常非常非常大。采样的思想非常简单,简单地令人发指:我们知道最终神经网络经过softmax输出一个向量,只有一个概率最大的对应正确的单词,其余的称为negative sample。现在只选择5个negative sample,所以输出向量就只是一个6维的向量。要考虑的参数不是300万个,而减少到了1800个! 这样做看上去很偷懒,实际效果却很好,大大提升了运算效率。

    2.2.1 CBOW(连续词袋模型)

      该模型是预测上下文已知的情况下,当前词出现的概率。上下文的选取采用窗口方式。本文基于负采样的TensorFlow下训练cbow的词向量代码如下:

    # 连续词袋模型,根据上下文预测当前单词
    import math
    import numpy as np
    import tensorflow as tf
    import  collections
    file_path = "D:\workspace\project\\NLPcase\\word2vec\\data\\data.txt"
    model_path = "D:\workspace\project\\NLPcase\\word2vec\\model\\skipgram_word2vec.txt"
    min_count = 5 #最低词频
    batch_size = 200 # 每次迭代的数量
    embedding_size = 200 # 生成词向量的维度
    window_size = 5 # 窗口大小
    num_sampled = 100 # 负采样的样本
    num_steps = 10000# 最大的迭代次数
    def load_data(file_path = file_path):
        dataset = []
        for line in open(file_path,encoding='utf-8'):
            line = line.strip().split(',')
            dataset.append([word for word in line[1].split(' ') if 'nbsp' not in word and len(word)<1])
        return dataset
    dataset = load_data()
    # 获得所有的单词组
    def read_data(dataset):
        words = []
        for data in dataset:
            words.extend(data)
        return words
    # 创建数据集合
    def build_dataset(words,min_count):
        count = [['unk',-1]]
        reserved_words = [item for item in collections.Counter(words).most_common() if item[1]>min_count]
        count.extend(reserved_words)
        dictionary = dict()
        for word,_ in count:
            dictionary[word] = len(dictionary)
        data = list()
        unk_count = 0
        for word in words:
            if word in dictionary:
                index = dictionary[word]
            else:
                index = 0
                unk_count += 1
            data.append(index)
        count[0][1] = unk_count
        reverse_dictionary = dict(zip(dictionary.values(),dictionary.keys()))
        return data,count,dictionary,reverse_dictionary
    # 生成训练的样本
    data_index = 0
    def generate_batch(batch_size, window_size,data):
        # data的格式为编号
        span = 2*window_size+1
        batch = np.ndarray(shape=(batch_size,span-1),dtype=np.int32)
        labels = np.ndarray(shape=(batch_size,1),dtype=np.int32)
        buffer = collections.deque(maxlen=span)
    
        for _ in range(span):
            buffer.append(data[data_index])
            data_index = (data_index+1)/len(data)# data中每个元素的下标
        for i in range(batch_size):
            target=window_size
            target2avoid = [window_size]
            col_idx = 0
            for j in range(span):
                if j ==span//2:
                    continue
                batch[i,col_idx] = buffer[j]
                col_idx += 1
            labels[i,0] = buffer[target]
            buffer.append(data[data_index])
            data_index = (data_index+1)/len(data)
        return batch,labels
    # 进行训练
    def train_word2vec(vocabulary_size,batch_size,embedding_size,window_size,num_sampled,num_steps,data):
        graph = tf.Graph()
        with graph.as_default(),tf.device('/cpu:0'):
            train_dataset = tf.placeholder(tf.int32,shape=[batch_size,2*window_size])
            train_labels = tf.placeholder(tf.int32,shape=[batch_size,1])
            embedding = tf.Variable(tf.random_uniform([vocabulary_size,embedding_size],-1.0,1.0))
            # 这儿与skip-gram不同的是,cbow的输入是上下文向量的均值
            #embed = tf.reshape(embedding,window_size*2,batch_size//(window_size*2),embedding_size)这个方法也可以
            context_embedding = []
            for i in range(2 * window_size):#对每列进行相加,然后取平均值
                context_embedding.append(tf.nn.embedding_lookup(embedding,train_dataset[:,i]))
            ave_embed = tf.reduce_mean(tf.stack(axis=0,values=context_embedding),0,keep_dims=False)
            softmax_weights = tf.Variable(tf.truncated_normal([vocabulary_size,embedding_size],stddev=1.0/math.sqrt(embedding_size)))
            softmax_biases = tf.Variable(tf.zeros([vocabulary_size]))
            # 定义损失函数
            loss = tf.reduce_mean(tf.nn.sampled_softmax_loss(
                weights=softmax_weights,
                biases=softmax_biases,
                inputs=ave_embed,
                labels=train_labels,
                num_sampled = num_sampled,
                num_classes=vocabulary_size
            ))
            opt = tf.train.AdamOptimizer(1.0).minimize(loss)
            norm = tf.sqrt(tf.reduce_mean(tf.square(embedding),1,keep_dims=True))
            normalized_embeddings = embedding/norm
        with tf.Session(graph) as session:
            tf.global_variables_initializer()
            average_loss = 0
            for step in range(num_steps):
                batch_data,batch_labels = generate_batch(batch_size,window_size,data)
                feed_dict = {train_labels:batch_data,train_labels:batch_labels}
                _,l = session.run([opt,loss],feed_dict=feed_dict)
                average_loss += l
                if step % 200 ==0:
                    if step>0:
                        average_loss = average_loss/200
                    print('average loss at step',step,':',average_loss)
                    average_loss = 0
            final_embedding = normalized_embeddings.eval()
        return final_embedding

    2.2.2 skip-gram(跳字模型)

      原理和CBOW大致相同,只是输入是中心词,输出是周围词词向量。

      基于负采样的TensorFlow训练skipgram的词向量代码如下:

    # 利用skip-gram进行词向量的训练,是当前单词预测上下文
    import collections
    import math
    import random
    import numpy as np
    import tensorflow as tf
    file_path = "D:\workspace\project\\NLPcase\\word2vec\\data\\data.txt"
    model_path = "D:\workspace\project\\NLPcase\\word2vec\\model\\skipgram_word2vec.txt"
    min_count = 5 #最低词频
    batch_size = 200 # 每次迭代的数量
    embedding_size = 200 # 生成词向量的维度
    window_size = 5 # 窗口大小
    num_sampled = 100 # 负采样的样本
    num_steps = 10000# 最大的迭代次数
    def load_data(file_path = file_path):
        dataset = []
        for line in open(file_path,encoding='utf-8'):
            line = line.strip().split(',')
            dataset.append([word for word in line[1].split(' ') if 'nbsp' not in word and len(word)<1])
        return dataset
    dataset = load_data()
    # 获得所有的单词组
    def read_data(dataset):
        words = []
        for data in dataset:
            words.extend(data)
        return words
    # 创建数据集合
    def build_dataset(words,min_count):
        # 把那些低频的词过滤掉,并根据出现频次的大小进行相关的编号
        count = [['UNK',-1]] # 对不统计或者没有出现的进行计数
        count.extend([item for item in collections.Counter(words).most_common() if item[1]>min_count])
        dictionary = dict()
        for word,_ in count:
            dictionary[word] = len(dictionary)# 进行编号
        data = list()
        unk_count = 0
        for word in words:
            if word in dictionary:
                index = dictionary[word]
            else:
                index = 0
                unk_count += 1
            data.append(index)
        count[0][1] = unk_count
        reverse_dictionary = dict(zip(dictionary.values(),dictionary.keys()))# 形成id:单词,的形式
        return data,dictionary,reverse_dictionary
    
    # 生成训练样本
    data_index = 0
    def generate_bath(batch_size,window_size,data):
        # 其中data的格式为进行编号的id格式
        # num_skips: 表示为每个单词生成多少个样本,本实验设置的是2个,其中batch_size必须是num_skips的整数倍
        # window_size:一般2*window_size>=num_skips
        batch = np.ndarray(shape=(batch_size),dtype=np.int32)# 建立一个batch大小的一维数组,保存任意单词
        # 建立一个(batch,1)大小的二维数组,保存打次前一个或者后一个从而形成pair,其中1表示预测周围的词的数目
        labels = np.ndarray(shape=(batch_size,1),dtype=np.int32)
        # Sample data [0, 5241, 3082, 12, 6, 195, 2, 3137, 46, 59] ['UNK', 'anarchism', 'originated', 'as', 'a', 'term', 'of', 'abuse', 'first', 'used']
        # 假设取num_steps为2, window_size为1, batchsize为8
        # batch:[5242, 3084, 12, 6]
        # labels[0, 3082, 5241, 12, 3082, 6, 12, 195]
        #print(batch)[5242    5242    3084    3084    12    12    6    6],共8维
        #print(labels)[[0][3082][12][5242][6][3082][12][195]],共8维
        span = 2*window_size+1 # 得到一个窗口的大小
        buffer = collections.deque(maxlen=span)
        for _ in range(span):
            buffer.append(data[data_index])
            data_index = (data_index+1)%len(data)
        # batch_size一定是num-skips的倍数,从而保证每个batch-size都能够用完num-skips
        for i in range(batch_size//(window_size*2)):#保证每个词产生的上下文组合用完
            target = window_size#中心词
            target2avoid = [window_size]#中心词首先被排除
            for j in range(window_size*2):#一个窗口的数据
                while target in target2avoid:
                    target = random.randint(0,span-1)
                target2avoid.append(target2avoid)
                batch[i*window_size*2+j] = buffer[window_size]
                labels[i*window_size*2+j,0] = buffer[target]
            buffer.append(data[data_index])
            data_index = (data_index + 1) % len(data)
        return batch,labels
    # 然后构建网络进行训练
    def train_wordvec(vocabulary_size,batch_size,embeddingsize,window_size,num_sample,num_steps,data):
        gragh = tf.Graph()
        with gragh.as_default():
            # 输入数据
            train_inputs = tf.placeholder(tf.int32,shape=[batch_size])
            train_labels = tf.placeholder(tf.int32,shape=[batch_size,1])
            # 使用cpu进行训练
            with tf.device('/cpu:0'):
                # 初始化一个embedding
                embedding = tf.Variable(tf.random_uniform([vocabulary_size,embedding_size],-1.0,1.0))
                # 查找对应的embedding
                embed = tf.nn.embedding_lookup(embedding_size,train_inputs)
                # 全连接参数定义
                nce_weights = tf.Variable(tf.truncated_normal([vocabulary_size,embedding_size],stddev=1.0/math.sqrt(embedding_size)))
                nce_bias = tf.Variable(tf.zeros([vocabulary_size]))
                # 定义一个loss
                loss = tf.reduce_mean(tf.nn.nce_loss(weights=nce_weights,
                                                     biases=nce_bias,
                                                     inputs=embed,
                                                     num_classes=vocabulary_size,
                                                     num_sampled=num_sampled))
                # 优化方法
                opt = tf.train.GradientDescentOptimizer(1.0).minimize(loss)
                # 计算每个词的模,用于归一化
                norm = tf.sqrt(tf.reduce_sum(tf.square(embedding),1,keep_dims=True))
                normalized = embedding/norm
                # 初始化模型的变量
                init = tf.global_variables_initializer()
    
            # 基于构造的网络进行训练
            with tf.Session(gragh) as session:
                # 初始化运行
                init.run()
                # 定义平均损失
                average_loss = 0
                for step in range(num_steps):
                    batch_inputs,batch_labels = generate_bath(batch_size,window_size,data)
                    feed_dict = {train_inputs:batch_inputs,train_labels:batch_labels}
                    # 计算每一次迭代的loss
                    _,loss = session.run([opt,loss],feed_dict=feed_dict)
                    average_loss += loss
                    # 每个一段时间将其打印出来
                    if step%200 == 0:
                        if step>0:
                            average_loss /=200
                        print('average loss at step',step,":",average_loss)
                        average_loss =0
                final_embedding = normalized.eval()
        return final_embedding

    参考文献:

      https://blog.csdn.net/mawenqi0729/article/details/80698350

      http://www.cnblogs.com/pinard/p/7160330.html

      https://blog.csdn.net/u014595019/article/details/54093161

      http://www.cnblogs.com/pinard/p/7249903.html

      https://blog.csdn.net/rxt2012kc/article/details/71123052

    https://blog.csdn.net/leadai/article/details/80249999

    https://github.com/liuhuanyong/Word2Vector

     

    展开全文
  • 词向量:如何评价词向量的好坏

    千次阅读 2018-07-10 11:51:32
    词向量、词嵌入或者称为词的分布式表示,区别于以往的独热表示,已经成为自然语言任务中的一个重要工具,对于词向量并没有直接的方法可以评价其质量,下面介绍几种间接的方法。 二、评价方法 对于词向量的评价更多...

    一、前言

    词向量、词嵌入或者称为词的分布式表示,区别于以往的独热表示,已经成为自然语言任务中的一个重要工具,对于词向量并没有直接的方法可以评价其质量,下面介绍几种间接的方法。

    二、评价方法

    对于词向量的评价更多还是应该考虑对实际任务的收益,脱离的实际任务很难确定A模型就一定比B好,毕竟词向量方法更多是一种工具。

    1、语义相关性任务

    这个任务用来评价词向量模型在两个词之间的语义相关性,如:学生与作业,中国与北京等。
    具体方法由监督模式实现,首先需要一份如下的标记文件,一般可以由人工标注:

    学生 上课 0.78
    教师 备课 0.8
    ...
    

    上述文件代表了词语之间的语义相关性,我们利用标注文件与训练出来的词向量相似度进行比较,如:词向量之间的cos距离等,确定损失函数,便可以得到一个评价指标。
    但这种方法首先需要人力标注,且标注的准确性对评价指标影响非常大。

    2、语义类比任务

    这个任务词向量来考察不同单词间的语义关系能力,一般给定三个词,如a、b、c,要求寻找a+b = c + ?任务中最相似的词,一般使用向量间距离来进行寻找,如:

    queen-king+man=women
    

    同样需要准备标记文件,根据寻找出来的词的正确率判断词向量的质量。

    3、文本分类任务

    这个任务利用词向量构成文本向量,一般采用求和平均的方式,之后利用构成的文本向量进行文本分类,根据分类的准备率等指标衡量词向量的质量。

    三、模型优化

    1、模型

    对于自然语言处理任务,在模型效果相差不大的情况下,选用简单的模型。
    同样,复杂的模型对于大规模的语料效果更为明显,小语料尽量用简单模型。

    2、语料

    选用与自然语言任务同领域的语料,提升效果会非常明显,在一定语料规模范围内,语料越大,效果越好;如果使用不同领域的语料,甚至会有反面效果。
    在语料的选择上,同领域的语料比大规模的其他领域语料重要。

    3、向量维度

    向量维度太小难以表现出语义的复杂度,一般更大的维度的向量表现能力更强,综合之下,50维的向量可以胜任很多任务。

    展开全文
  • 深入理解词向量-词向量的可视化

    千次阅读 热门讨论 2018-08-16 17:47:49
    词向量是自然语言分词在词空间中的表示,词之间的距离代表了分词之间的相似性,我们可以使用gensim,tensorflow等框架非常方便的来实现词向量。但词向量在词空间的分布到底是什么样的,如何更好的理解词向量是一个...

    1、概述

    词向量是自然语言分词在词空间中的表示,词之间的距离代表了分词之间的相似性,我们可以使用gensim,tensorflow等框架非常方便的来实现词向量。但词向量在词空间的分布到底是什么样的,如何更好的理解词向量是一个非常重要的问题。本文将使用tensorbord以及相关的降维技术在三维空间中模拟词向量在高维空间的分布。

    2、训练词向量

    词向量的训练是一个无监督的学习过程,这并不是本文讨论的重点。这里只是简单描述一下基本理论。词的表述有两种基本方法:

    • one-hot表示方法
    • 词向量表示方法

    One hot 用来表示词向量非常简单,但是却有很多问题。1、任意两个词之间都是孤立的,根本无法表示出在语义层面上词语词之间的相关信息,而这一点是致命的。2、我们的词汇表一般都非常大,比如达到百万级别,这样每个词都用百万维的向量来表示简直是内存的灾难。能不能把词向量的维度变小呢?

    Dristributed representation可以解决One hot representation的问题,它的思路是通过训练,将每个词都映射到一个较短的词向量上来。所有的这些词向量就构成了向量空间,进而可以用普通的统计学的方法来研究词与词之间的关系。这个较短的词向量维度是多大呢?这个一般需要我们在训练时自己来指定。 
    词的分布式表示主要可以分为三类:基于矩阵的分布表示、基于聚类的分布表示和基于神经网络的分布表示

    词向量的训练有两种方法:

    • cbow
    • skip-gram

    2.1 cbow模型

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

    2.1 skip-gram模型

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

    3、词向量的可视化

    这里我们使用一组已经训练好的词向量,直接在三维空间中进行可视化操作。主要使用到的语料是北师大训练好的一个300维的语料库,如下图所示:

    可以使用此链接下载相关语料:https://github.com/embedding/chinese-word-vectors

    3.1 语料结构

    这是一个非常庞大的语料,由于语料已经丢失了上下文环境,所以无法进行迁移学习。下面主要分析语料的主要结构,以便于后续读取相关数据。这个语料大小接近3.5G,如下图所示:

    语料的基本结构如下:

    语料的第一行说明了整个语料包含的单词数量,以及每个单词表示的维度。在这里每一个单词都是由一个300为的向量来表示的。一共有1292607个单词。从第二行开始每一行代表一个单词,用空格隔开,上图中第二行代表单词“,”,后边是他的向量表示。整个语料的整体结构就是这样。这是一个标准的词向量表示文本,可以使用gensim等第三方类库直接读取,但由于本文的目的是为了充分理解词向量所以后面会采用,手动读取词向量的方式来处理语料。

    3.2 读取语料

    这里采用传统的读取文件的形式读取语料,为了降低计算机处理的数据量,这里我们只读取2000个单词,而不是整个语料。具体代码如下所示:

    from tqdm import tqdm # progression bars
    import numpy as np
    with open('sgns.merge.word','r') as f:
        header = f.readline()
        vocab_size, vector_size = map(int, header.split())
        words, embeddings = [], []
        for line in tqdm(range(2000)):
            word_list = f.readline().split(' ')
            word = word_list[0]
            vector = word_list[1:-1]
            words.append(word)
            embeddings.append(np.array(vector))
    print(words[9:10])
    print(embeddings[9:10])

    输出结果如下图所示:

    3.3 为tensorboard生成数据

    下面将这些变量保存到到tensorflow的variable中并保存模型,请参照下面代码:

    import tensorflow as tf
    from tensorflow.contrib.tensorboard.plugins import projector
    import os
    log_path = 'logs'
    with tf.Session() as sess:
        # tf.assign():这里是一个将具体数值(即,词向量矩阵)赋值给tf Variable的例子:
        X = tf.Variable([0.0], name='embedding')
        place = tf.placeholder(tf.float32, shape=[len(words), vector_size])
        set_x = tf.assign(X, place, validate_shape=False)
        sess.run(tf.global_variables_initializer())
        sess.run(set_x, feed_dict={place: embeddings})
    
        # 需要保存一个metadata文件,给词典里每一个词分配一个身份
        with open(log_path + '/metadata.tsv', 'w') as f:
            for word in tqdm(words):
                f.write(word + '\n')
        
        # 写 TensorFlow summary
        summary_writer = tf.summary.FileWriter(log_path, sess.graph)
        config = projector.ProjectorConfig()
        embedding_conf = config.embeddings.add()
        embedding_conf.tensor_name = 'embedding:0'
        embedding_conf.metadata_path = os.path.join(log_path, 'metadata.tsv')
        projector.visualize_embeddings(summary_writer, config)
        
        # 保存模型
        # word2vec参数的单词和词向量部分分别保存到了metadata和ckpt文件里面
        saver = tf.train.Saver()
        saver.save(sess, os.path.join(log_path, "model.ckpt"))

    生成文件如下图所示:

    3.4 使用tensorboard观察数据

    使用下面命令开启tensorboard,观察效果

     

    展开全文
  • gensim生成词向量并获取词向量矩阵

    千次阅读 2020-07-07 17:16:55
    word2vec是目前比较通用的训练词向量的工具,使用Gensim模块,可以使词向量的训练变的简单,但是调用gensim.models的word2vec模块使用skip-gram或CBOW完成词向量训练之后,如何获取词向量中的词汇表以及对应的词向量...

    gensim生成词向量并获取词向量矩阵

    word2vec是目前比较通用的训练词向量的工具,使用Gensim模块,可以使词向量的训练变的简单,但是调用gensim.models的word2vec模块使用skip-gram或CBOW完成词向量训练之后,如何获取词向量中的词汇表以及对应的词向量矩阵呢。本文以一个小例子进行演示。

    1. 导入相关包

    主要用到了jieba和gensim包,可以使用命令行pip3 install gensim或下载gensim包的方式,具体不述。

    import jieba
    from gensim.models import Word2Vec
    

    1. 加载语料并清洗

    为了方便演示,本文直接定义了一个语料,并使用jieba进行分词操作。

    #  停用词
    stopword_list = []
    with open('./stopwords.txt', 'r+', encoding='utf8') as f:
        for word in f.readlines():
            if len(word)>0 and word != '\n\t':
                stopword_list.append(word)
                
    # 语料
    content = [
    "长江是中国第一大河,干流全长6397公里(以沱沱河为源),一般称6300公里。流域总面积一百八十余万平方公里,年平均入海水量约九千六百余亿立方米。以干流长度和入海水量论,长江均居世界第三位。",
    "黄河,中国古代也称河,发源于中华人民共和国青海省巴颜喀拉山脉,流经青海、四川、甘肃、宁夏、内蒙古、陕西、山西、河南、山东9个省区,最后于山东省东营垦利县注入渤海。干流河道全长5464千米,仅次于长江,为中国第二长河。黄河还是世界第五长河。",
    "黄河,是中华民族的母亲河。作为中华文明的发祥地,维系炎黄子孙的血脉.是中华民族民族精神与民族情感的象征。",
    "黄河被称为中华文明的母亲河。公元前2000多年华夏族在黄河领域的中原地区形成、繁衍。",
    "在兰州的“黄河第一桥”内蒙古托克托县河口镇以上的黄河河段为黄河上游。",
    "黄河上游根据河道特性的不同,又可分为河源段、峡谷段和冲积平原三部分。 ",
    "黄河,是中华民族的母亲河。"
    ]
    
    # 分词
    seg = [jieba.lcut(text) for text in content]
    
    # 清洗
    content_clean = []
    for t in seg:
        text_clean = []
        for i in t:
            if len(i)>1 and i != '\t\n': 
                if not i.isdigit():
                    if i.strip() not in stopword_list:
                        text_clean.append(i.strip())
        content_clean.append(text_clean)
    

    最后的content_clean为一个list,具体为:

    在这里插入图片描述

    3. 使用gensim训练词向量

    ## 用gensim训练词向量模型
    
    model = Word2Vec(content_clean, sg=1, size=100, window=5, min_count=2, negative=1, 
                     sample=0.001, workers=4)
    '''
    sg=1 是 skip-gram 算法,对低频词敏感;默认 sg=0 为 CBOW 算法。
    size 是输出词向量的维数,值太小会导致词映射因为冲突而影响结果,值太大则会耗内存并使算法计算变慢,一般值取为100到200之间。
    window 是句子中当前词与目标词之间的最大距离,3表示在目标词前看3-b 个词,后面看 b 个词(b 在0-3之间随机)。
    min_count 是对词进行过滤,频率小于 min-count 的单词则会被忽视,默认值为5。
    negative 和 sample 可根据训练结果进行微调,sample 表示更高频率的词被随机下采样到所设置的阈值,默认值为 1e-3。
    hs=1 表示层级 softmax 将会被使用,默认 hs=0 且 negative 不为0,则负采样将会被选择使用。
    '''
    
    
    # 训练后的模型model可以保存,备用
    model.save('./word2vec')   #保存
    model = Word2Vec.load('word2vec')   #加载model
    

    代码中model是一个训练好的词向量模型,里面包含许多内容,可以获取词汇表和对应的词向量。

    ## 获取词汇
    words = model.wv.index2word
    print(words)                 # 长度18
    
    # ['黄河', '长江', '中国', '干流', '中华民族', '母亲河', '第一', '全长',
    #    '公里', '入海', '水量', '世界', '内蒙古', '河道', '长河', '中华文明', '民族', '上游']
    
    
    ## 获取对应词向量
    vectors = model.wv.vectors
    print(vectors)    # 18*100   100为设置的size,即词向量维度
    
    #[[ 1.2898202e-03 -3.4580764e-03  3.4779524e-03 ... -3.6768757e-03
    #   2.6582647e-03 -3.7408734e-03]
    # [ 2.9404070e-03  3.9611240e-03 -2.1796243e-03 ...  2.3843886e-03
    #  -4.3357350e-03 -3.3540600e-03]
    # [ 4.9255025e-03  1.4151304e-03 -8.7503344e-04 ...  4.2551141e-03
    #  -2.9053804e-03  3.6766860e-03]
    # ...
    # [ 1.9452259e-03  4.8658932e-03 -2.3852135e-03 ... -2.7566685e-03
    #   4.9943980e-03 -3.9313175e-03]
    # [ 5.2972522e-04  4.8273476e-03 -3.0694890e-03 ...  4.2261067e-03
    #   9.7657423e-05  4.4411011e-03]
    # [-2.2659900e-03  1.5058877e-03 -4.7887382e-03 ...  2.4552434e-03
    #   4.4189487e-04  5.9008709e-04]]
    
    
    ## 根据指定词获取该词的向量
    vec = model.wv['长江']
    print(vec)
    
    #[ 2.9404070e-03  3.9611240e-03 -2.1796243e-03  3.5846021e-03
    # -8.5443829e-04 -1.5641276e-03 -1.6966875e-03 -4.6902820e-03
    # -4.3645203e-03 -1.8363699e-03 -3.9727231e-03  4.7817207e-03
    # -1.3380363e-03 -2.6813489e-03  4.1867769e-03  3.4822649e-03
    # -3.9391480e-03 -2.3266519e-03  1.4906399e-03 -7.4510416e-04
    # ...
    
    
    ## 判断词之间的相似度
    print(model.similarity('黄河','黄河'))   #1.0
    print(model.similarity('黄河','长江'))   #-0.08
    print(model.similarity('黄河','中国'))   #0.14
    
    
    ## 预测与'黄河'和'母亲河'最相似,而与长江不接近的词
    print(model.most_similar(positive=['黄河','母亲河'], negative=['长江']))
    
    #[('长河', 0.10036612302064896), ('世界', 0.065335713326931), 
    # ('民族', 0.05369586870074272), ('中华民族', 0.03456304967403412), 
    # ('入海', 0.00084715336561203), ('公里', -0.007249757647514343), 
    # ('第一', -0.0175853930413723), ('内蒙古', -0.0281079038977623), 
    # ('干流', -0.02939787693321705), ('上游', -0.029546111822128296)]
    #__main__:1: DeprecationWarning: Call to deprecated `most_similar` 
    #(Method will be removed in 4.0.0, use self.wv.most_similar() instead).
    
    
    展开全文
  • PyTorch 词向量模型简介

    千次阅读 多人点赞 2021-03-07 00:36:02
    词向量模型简介概述词向量维度Word2VecCBOW 模型Skip-Gram 模型负采样模型词向量的训练过程1. 初始化词向量矩阵2. 神经网络反向传播 概述 我们先来说说词向量究竟是什么. 当我们把文本交给算法来处理的时候, 计算机...
  • 跨语言词向量笔记2. 跨语言词向量表示简史使用双语词典的跨语言词向量表示跨语言词嵌入与词对齐基于隐式/显式跨语言概念的表示结语 尽管原书讨论的是跨语言词向量的获得方法,但是在使用神经网络获得词向量的时代...
  • 词向量总结

    2018-12-03 13:21:27
    词向量 词向量是自然语言理解的重要工具,它的核心思想是把词映射到一个向量空间,并且这个向量空间很大程度上保留了原本的语义。词向量既可以作为对语料进行数据挖掘的基础,也可以作为更复杂的模型的输入,是现在 ...
  • 中文预训练词向量——基于中文维基百科语料训练 英文预训练词向量——斯坦福glove预训练的词向量 百度云分享:https://pan.baidu.com/s/1UpZeuqlNMl6XtTB5la53Xw 提取码: afhh 维基百科词向量 sgns.wiki....
  • 词向量算法

    千次阅读 2019-06-05 22:31:07
    https://www.cnblogs.com/the-wolf-sky/articles/10192363.html...基于神经网络的表示一般称为词向量、词嵌入(word embdding)或分布式表示。 神经网络的词向量和其他分布式类似,都基于分布式表达方式,核心依然是上...
  • 词向量简介

    千次阅读 2020-06-29 22:35:23
    词向量简介 ** 1.什么是词向量? 每一个词典(里面存着一堆单词,例如{one on the and of 。。。。}) 用nn.embedding模块进行词嵌入 输出的就是对应的词向量。 2.什么是 nn.embedding ? torch.nn.Embedding理解 看这...
  • 概述 在深度学习中,Embedding技术对于深度学习非常重要,甚至可以说是深度学习的“基本核心操作”。深度学习网络中作为Embedding层,...常用的获取词向量的方法 利用网络embedding层训练词向量, FastText工具快速生
  • 词向量one hot编码词向量编码思想Word2VecEmbeddingSkip-gram的原理负采样 前言:深度学习网络rnn能解决有序的问题,我们就生活在这样一个有序的世界。比如时间,音乐,说话的句子,甚至一场比赛,比如最近正在举办...
  • 利用gensim包的word2vec模块构建CBOW或Skip-Gram模型来进行词向量化比较方便。 ''' 根据训练语料库,自己训练语言模型得到词向量 ''' # 对分词后的文本训练Word2vec模型 from gensim.models import word2vec import ...
  • 词向量,空间向量模型,源码,word2vec,ngram2vec
  • 1.Word2Vec 怎么将得到的词向量变成句子向量 1)平均词向量: 平均词向量就是将句子中所有词的word embedding相加取平均,得到的向量就当做最终的sentence embedding。这种方法的缺点是认为句子中的所有词对于表达...
  • 词向量与句向量概述

    千次阅读 2019-01-22 11:05:07
    比较常见的词向量表示方式:glove、fasttext、wordRank、tfidf-BOW、word2vec 词向量一般看作是文档特征,不同词向量有不同用法,主要有四类词向量:1.hash算法及衍生;2.BOW算法延伸;3.word2vec延伸;4.LDA主题...
  • 词向量表示

    2019-07-05 14:11:38
    N-gram词向量表示和语言模型 Co-currence矩阵的行(列)向量作为词向量 ❖ 分布式连续表示 Co-currence矩阵的SVD降维的低维词向量表示 Word2Vec: Continuous Bag of Words Model Word2Vec: Skip-Gr...
  • 向量化是使用一套统一的标准打分,比如填写表格...词向量 同理,词也可以向量化word2vec(word to vector),可以从词性、感情色彩、程度等等方面量度,用一套分值代表一个词,从而词之间可以替换,比较。词与向量...
  • word2vec训练中文词向量

    万次阅读 多人点赞 2018-09-26 16:27:45
    良好的词向量可以达到语义相近的词在词向量空间里聚集在一起,这对后续的文本分类,文本聚类等等操作提供了便利,这里简单介绍词向量的训练,主要是记录学习模型和词向量的保存及一些函数用法。 一、搜狐新闻 1. ...
  • 漫谈词向量

    千次阅读 2016-10-31 10:04:35
    原文: On word embeddings 作者: Sebastian Ruder 译者: KK4SBB 审校:王艺 ...词向量的来历 词向量模型 语言建模概述 经典的神经语言模型 C&amp;W模型 Word2Vec CBOW Skip-gram 非监督式学习得到...
  • EMLO词向量

    千次阅读 2019-03-06 08:57:25
    本文提出了一种提取深层次语义特征的词向量的方法,该方法是通过一个在大规模语料库上预训练得到的模型来提取词向量。通过本文方法提取到的词向量效果较好,可用于多种类型的NLP任务。 文中采用了一种名为biLM...
  • Word2Vec、WordEmbedding及预训练词向量的一文总结
  • 本篇为资源汇总,一些NLP的比赛在抽取文本特征的时候会使用非常多的方式。...文章目录@[toc]1 之前的几款词向量介绍与训练帖子2 极简训练glove/word2vec/fasttext2.1 word2vec的训练与简易使用2.2 glove...
  • 中文词向量大全

    千次阅读 2019-09-20 10:28:03
    # 中文词向量大全 https://github.com/Embedding/Chinese-Word-Vectors 里面有词向量下载(很多的类型) # 使用方法 下载后加载方式: unicode 字符哦! import gensim from gensim.models import KeyedVectors ...
  • 词向量综述

    千次阅读 2017-03-30 09:20:21
    词向量综述

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 87,590
精华内容 35,036
关键字:

词向量