Gensim训练词向量与Embedding相关知识

在进行文本分类的时候,预处理我们可以自己做一个词向量模型,也可以采用预训练的模型。采用预训练的模型比如谷歌基于goole news训练的Word2vec模型,由于在大量文本数据中训练过,所以词的概率分布会比较准确,当自己的数据集比较小的时候,用预训练数据有利于提升模型的准确度。 以下内容使用了tensorflow。 训练文本生成word2vec模型 自己训练模型一般有以下几步: 处理数据集,首先gensim的Word2Vec()方法需要的输入是句子顺序的单词,比如 我 爱 你 而不是我爱你,所以要将文本数据分词处理,在这个过程中,我们可以去除停用词,英文全部小写,语法统一等处理,可能对词向量的训练比较有帮助。 完成文本的处理以后,我们得到一个分词后的文本数据集,比如一个列表[‘she’, ‘is’, ‘beautiful’],在gensim模块中可以简单的使用model=gensim.models.word2vec.Word2Vec()得到训练的模型。 该方法有一些参数: sentences-即数据集;sg-设置训练算法,0代表CBOW,1代表skip-gram算法; size-指特征向量的维度,默认为100,大的size需要更多数据,效果更好,但是过大则浪费资源,效果提升不明显; window-当前词与预测词在一个句子中的最大距离,默认是5,比如 我 今天 成功 完成 工作,对于 成功,如果设置窗口为2,可能去预测的词就是我 今天 完成 和 工作,注意是最大值而不是一定选取四个词。最后模型输出的是一个概率分布,即一个词出现在其他词边的概率是多少,我们也就可以据此去发现相似的词。 min_count-去除词频小于min_count的词; hs-1采用hierarchy softmax,0采用negative sample; iter-迭代次数 workers-参数控制训练的并行数¨C9C 更多参考: //www.cnblogs.com/kjkj/p/9825418.html 其他训练词向量有相似的方法和思路,网上有很多资料。 使用预训练词向量 首先加载获取到准备好的模型,然后我们的目标是得到一个embedding_metrics即词向量矩阵,词向量矩阵的shape为(vocab_size, embedding_dim),它是我们要用于训练的数据的每个词(更具体的说是词表中的词)在训练好的模型中的词向量组成的矩阵。 接下来处理训练数据,即用tokenizer处理训练后的数据得到词表,然后将每条文本数据转变为用词表索引数字代替各单词表示的列表,这里给词编码的顺序是词频由高到低,再进行padding使句子输入变为定长,最后我们利用word_index和模型生成embedding_metrics,数据的准备就基本完成了。这些步骤使用tensorflow提供的api可以很简单的实现。 生成代码及相关解释如下: embedding_matrix = np.zeros((len(word_index) + 1, word2vec.vector_size)) # len(word_index) + 1,加1是因为word_index的标记是从1开始而非0,这样词索引与词向量刚好对应,并且对于padding后为 # 0的填充位置可以有对应的映射。 for word, index in word_index.items(): try: embedding_vector = word2vec.wv.getitem(str(word)) embedding_matrix[int(index)] = embedding_vector except KeyError: print("vector not found for word - %s" % word) Embedding层做了什么? Embedding层就是以one hot为输入、中间层节点为词向量维数的全连接层!而这个全连接层的参数,就是一个“词向量表”即我们的embedding_metrics,也就是说,其实onehot的作用就是查表,选择onehot表示的词对应的词向量,然后输出到下一层去。如果我们不用预处理的词向量,就是放一个空矩阵在embedding层(或者说是随机初始化参数),然后在训练网络过程中更新参数。 ...

May 22, 2020 · Xiangtao XIAO

Natural Language Processing相关概念理解

NLP一般流程 文本预处理->词向量与文本表示->特征选择与特征抽取->分类算法 词向量与文本表示 词袋模型(BOW) 将所有词汇放进一个袋子里,假设有n个词,则每个句子表示为一个长度为n的词频向量,词频即对应词在句子里出现的次数,如果没有出现就是0。这种方法句子里的语义信息被完全遗失了。 word based encodings 另一种思路是表示句子,这样就可以把词在句子中的位置关系考虑进去,例如 “我 喜欢 猫”和 “我 喜欢 狗”分别表示为(0 1 2)和(0 1 3),这里的数字不再是词频,而是对应单词被分配的编码,如果词重复了,显然在数组中对应的数字也会重复。 padding 句子长度不同时,需要将他们转化为统一长度的向量输入到神经网络中训练,这时就要padding,设置一个长度n,如果句子长度小于n,就在数组左侧或右侧填充0,如果句子长了,就把左侧或右侧多余的部分忽略,具体方位由自己选择。 词向量模型(word embedding) 考虑词与词之间的位置关系。原本用随机分配的数字代表每一个词,词与词之间是完全独立的,而embedding使得每一个词成为了一个n维空间中的向量,如果两个词的含义相近,那么相应的向量距离也就进,这样就考虑到了词的含义。 word2Vec : 底层采用基于CBOW和Skip-Gram算法的神经网络模型。 CBOW模型: CBOW模型的训练输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。由于CBOW使用的是词袋模型,因此上下文的几个词都是平等的,也就是不考虑他们和我们关注的词之间的距离大小,只要在我们上下文之内即可。 这样我们这个CBOW的例子里,我们的输入是上下文选定的词向量,输出是所有词的softmax概率(训练的目标是期望训练样本特定词对应的softmax概率最大),对应的CBOW神经网络模型输入层有4个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某4个词对应的最可能的输出中心词时,我们可以通过一次DNN前向传播算法并通过softmax激活函数找到概率最大的词对应的神经元即可。 Skip-Gram模型: Skip-Gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。 这样我们这个Skip-Gram的例子里,我们的输入是特定词, 输出是softmax概率排前几的词,对应的Skip-Gram神经网络模型输入层有1个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某1个词对应的最可能的4个上下文词时,我们可以通过一次DNN前向传播算法得到概率大小排前4的softmax概率对应的神经元所对应的词即可。 词向量模型突出特点: 在词向量模型中,词向量与词向量之间有这非常特殊的特性。例如现在存在国王、男生、女人、皇后四个词向量,那么一个完善的词向量模型,就存在“国王-男人+女人=皇后”这样的关系。 参考: 词袋模型(BOW,bag of words)和词向量模型(Word Embedding)概念介绍

May 21, 2020 · Xiangtao XIAO

NLP数据准备相关代码记录

csv文件 什么是csv文件 csv既逗号分隔符文件,行数据用’,‘分隔,列数据用换行符’\n’分隔 读取与写入csv文件 with open(filename, 'r', encoding='gbk') as rf: reader = csv.reader(rf, dialect=csv.excel) # 按行读取,读取的是存储为excel可读格式的csv文件,这个文件可以用excel打开查看 with open(r'clean_data\clean_data_0.5_no_repeat.csv', 'w', encoding='gbk', newline='') as f: writer = csv.writer(f, dialect=csv.excel, delimiter=',') for data in final_dataset: writer.writerow(data) # 按行写入,写入格式也是csv.excel,会把一个二维列表自动存储为表格,行列对应,存储的内容是原封不动的 csv文件存储格式与换行问题 用以上方法读取的csv文件每一行每一列取出的都是字符串’str’格式,对于字典要用eval()函数自动转回原本对应的格式,而int等也要用对应函数转换 newline=’’“设置存储的行与行之间没有空行,否则会隔行存储。 json格式 json格式文件特点 json格式文本对{对象:值},例如: {“name”: “John Doe”, “age”: 18, “address”: {“country” : “china”, “zip-code”: “10000”}},和字典有些相似,存储的值可以是字符串,数组,字典等,这个格式好处在于可以存储结构相对复杂的数据并且易于存取。 json与str,json的读取 在实际操作中似乎直接把json放在列表里就可以和其他数据一样存储到csv文件中,在使用csv.writer方法时,双引号的问题被自动解决了,取出以后和其他数据一样都是str,使用json.loads()方法即可转换为json格式数据,写入的时候可以用同样的方法转换。 转换后的json格式数据按对象取值的方法与字典相似,即data[‘对象名’]->值 python集合、列表、字典 在处理重复数据时(这里指字符串或数值的数据),可以采用集合进行存储,因为集合中元素不能重复,可以很简单的使用set()或list()方法将集合和列表相互转换,因此可以利用集合去重后在转换为list存储。 要注意的是,创建空的集合要使用a = set()方法,如果是a={}则是一个空的字典。 当存储集合时如果集合为空会存储一个空集,内容为set()。 集合增加元素要用add()方法,集合没有列表的append()方法。 在处理数据时,字典一个很大的用处在于给出的key是有语义的,这提高了代码的可读性,list[1]中的数据是什么我们是不知道的,而dict[‘key’]则很好懂。 tensorflow输入数据格式转化 constant方法生成张量,tensorflow搭建的算法输入数据都是相应格式的张量,而不是列表,因此如果采用csv.reader读取csv文件而不是tensorflow自带的方法读取csv文件的话,要用对应的tensorflow或者numpy方法将数据转化为张量,通常为[None,*]None为数据量比如有2000条训练文本,None就是2000,后面的就是处理后的数据格式,比如设置的padding,maxlen=500的embedding size=12后的文本数据,格式就是[None,500,12],label数据格式也要与之相对应。 tensorflow自带的读取csv文件的方法可以直接得到tensor格式的数据,但是由于我要处理的csv文件是文本文件并且包含json,这个时候还是先用csv的方法处理完比较好。

May 21, 2020 · Xiangtao XIAO