import numpy as np
import pandas as pd
#1准备工作
# graph LR
# 文本-->分词
# 分词-->训练词向量
# 训练词向量-->保存词向量
import gensim
#训练自己的词向量,并保存
def trainWord2Vec(filePath):
sentences = gensim.models.word2vec.LineSentence(filePath)#读取分词后的文本
model = gensim.models.Word2Vec(sentences, size=100, window=5, min_count=1, workers=4)#训练模型
model.save('./CarComment_vord2vec_100')
def testMyWord2Vec():
#读取自己的词向量,并简单测试一下效果
inp = './CarCommennt_vord2vec_100' #读取词向量
model = gensim.models.Word2Vec.load(inp)
print('空间的词向量(100维):', model['空间'])
print('打印与空间最相近的5个词语:', model.most_similar('空间', topn=5))
if __name__ == '__main__':
testMyWord2Vec()
pass
#通过上述,我们就拥有了预训练的词向量文件CarCommennt_vord2vec_100
# 转化词向量为keras所需格式
#keras中使用的embedding层,embedding层所需要的格式为一个巨大的“矩阵”:第i列表示词索引为i的词的词向量
#思路:embedding层,提供一个【word:word_vector]的词典来初始化embedding层中所需要的的大矩阵,并且标记为不可训练
# 获取所有词语word和词向量
#首先导入预训练的词向量
myPath = './CarCommennt_vord2vec_100' #本地词向量的位置
Word2VecModel = gensim.models.Word2Vec.load(myPath) # 读取词向量
vector = Word2VecModel.wv['空间'] #词语的向量,是numpy格式
#gensim的word2vec模型 把所有的单词和 词向量 都存储在了Word2VecModel.wv里面,讲道理直接使用这个.wv即可
print(type(Word2VecModel.wv)) #结果为Word2VecKeyedVectors
for i,j in Word2VecModel.wv.vocab.items():
print(i) #此时i 代表每个单词
print(j) #j代表封装了词频等信息的gensim“Vocab”对象,例子:Vocab(count:1481, index:38, sample_int:3701260191)
break
#2.2 构造“词语——词向量”字典
#构造一个list存储所有的单词:vocab——list存储所有词语
#构造一个字典word_index:{word:index}, key是每个词语,value是单词在字典中的序号。
#在后期tokenize(序号化)训练集的时候就是用该词典
#构造一个大向量矩阵embedding_matrix(按照embedding层的要求):行数为所有单词数,比如10000;列数为词向量维度,比如100.
#构造包含所有词语的list,以及初始化“词语-序号”字典和“词向量”矩阵
vocab_list = [word for word, Vocab in Word2VecModel.wv.vocab.items()]#存储所有的词语
word_index = {" ": 0}#初始化‘[word:token]',后期tokenize语料库就是用该词典
word_vector = {} #初始化’[word:vector]'字典
#初始化存储所有向量的大矩阵,留意其中多一位(首行),词向量全为0,用于padding补零
#行数为所有单词+1,比如10001;列数为词向量维度,比如100
embedding_matrix = np.zeros((len(vocab_list)+1),Word2VecModel.vector_size)
#2.3 填充字典和矩阵
#填充上述步骤中的字典和大矩阵
for i in range(len(vocab_list)):
word = vocab_list[i] #每个词语
word_index[word] = i+1 #词语:序号
word_vector[word] = Word2VecModel.wv[word]#词语:词向量
embedding_matrix[i+1] = Word2VecModel.wv[word] #词向量矩阵
#2.4在keras的embedding层中使用与驯良词向量
from keras.layers import Embedding
from keras.utils.np_utils import *
#from…import *:是把一个模块中所有函数都导入进来; 注:相当于:相当于导入的是一个文件夹中所有文件,所有函数都是绝对路径。
EMBEDDING_DIM = 100 #词向量维度
embedding_layer = Embedding(input_dim=len(embedding_matrix),#字典长度
EMBEDDING_DIM, #词向量长度100
weights= [embedding_matrix],#重点:预训练的词向量系数
input_length=MAX_SEQUENCE_LENGTH,#每句话的最大长度(必须padding
trainable=False) #是否在训练的过程中更新词向量
#此时输入EMbedding层的数据的维度是,形如(samples,sequence_length)的2D张量
#3D张量:(samples,sequence_length,embeding_matrix)
#*2.5不使用“预训练”而直接生成词向量模型
#我们也可以直接使用KERAS自带的Embedding层训练词向量,而不用预训练的word2vec词向量。
embedding_layer = Embedding(len(word_index)+1,#由于没有预训练,设置 +1
EMBEDDING_DIM,
input_length = MAX_SEQUENCE_LENGTH)
#一般来说,在自然语言处理任务中,当样本数量非常少时,使用预训练的词向量是可行的。(实际上,预训练的词向量引入了外部语义信息
# 3整体代码:在Keras模型中使用预训练的词向量
#文本数据预处理,将每个文本样本转换为一个数字矩阵,矩阵的每一行表示一个词向量。
# 3.1 读取数据
def load_file():
dataFrame_2016 = pd.read_csv('data\\nlpcc2016_traindata_zong_right.csv', encoding='utf-8')
print(dataFrame_2016.coloumns) #打印列的名称
texts = [] #存储读取的x
labels = [] #存储读取的y
#遍历获取数据
for i in range(len(dataFrame_2016)):
texts.append(dataFrame_2016.iloc[i].q_text)
##每个元素为一句话“《机械设计基础》这本书的作者是谁?”
labels.append(dataFrame_2016.iloc[i].q_type)
#每个元素为一个int 代表类别 # [2, 6, ... 3] 的形式
#把类别从int3转换为(0,0,0,1,0,0)的形式
labels = to_categorical(np.assarray(labels))## keras的处理方法,一定要学会# 此时为[[0. 0. 1. 0. 0. 0. 0.]....] 的形式
return texts,labels
#3.2句子分词
import jieba
#jieba.lcut生成为一个列表
def cut_sentence2word(texts):
texts = [jieba.lcut(Sentence.repalce('\n','')) for Sentence in texts]
#句子分词
return texts
#构造词向量字典
#获取word2vec模型,并构造,词语index字典,词向量字典
import os
## 3.获取word2vec模型, 并构造,词语index字典,词向量字典
def get_word2vec_dictionaries(texts):
def get_word2vec_model(texts=None): # 获取 预训练的词向量 模型,如果没有就重新训练一个。
if os.path.exists('data_word2vec/Word2vec_model_embedding_25'): # 如果训练好了 就加载一下不用反复训练
model = Word2Vec.load('data_word2vec/Word2vec_model_embedding_25')
# print(model['作者'])
return model
else:
model = Word2Vec(texts, size = EMBEDDING_DIM, window=7, min_count=10, workers=4)
model.save('data_word2vec/Word2vec_model_embedding_25') # 保存模型
return model
Word2VecModel = get_word2vec_model(texts) # 获取 预训练的词向量 模型,如果没有就重新训练一个。
vocab_list = [word for word, Vocab in Word2VecModel.wv.vocab.items()] # 存储 所有的 词语
word_index = {" ": 0}# 初始化 `[word : token]` ,后期 tokenize 语料库就是用该词典。
word_vector = {} # 初始化`[word : vector]`字典
# 初始化存储所有向量的大矩阵,留意其中多一位(首行),词向量全为 0,用于 padding补零。
# 行数 为 所有单词数+1 比如 10000+1 ; 列数为 词向量“维度”比如100。
embeddings_matrix = np.zeros((len(vocab_list) + 1, Word2VecModel.vector_size))
## 填充 上述 的字典 和 大矩阵
for i in range(len(vocab_list)):
word = vocab_list[i] # 每个词语
word_index[word] = i + 1 # 词语:序号
word_vector[word] = Word2VecModel.wv[word] # 词语:词向量
embeddings_matrix[i + 1] = Word2VecModel.wv[word] # 词向量矩阵
return word_index, word_vector, embeddings_matrix
#3.4文本序号化Tokenizer
#英文文本不用切词,因为默认会将空格将词切开,就需要切词,且每个词用空格隔开
from keras.preprocessing.text import Tokenizer
tokenizer = Tokenizer(num_words = 2000) #建一个2000个单词的字典
tokenizer.fit_on_texts(train_texts)
#当然我们也可以使用之前构建的word——index字典。手动构建tokenizer句子(推荐这种方法,这样序号下标与预训练词向量一致。
from keras.preprocessing import sequence
#序号化文本,tokenizer句子,并返回每个句子所对应的词语索引
def tokenizer(texts,word_index):
data = []
for sentence in texts:
new_txt = []
for word in sentence:
try:
new_txt.append(word_index[word]) #把句子中的词语转化为index
except:
new_txt.append(0)
data.append(new_txt)
texts = sequence
#3.5 切分数据
from sklearn.model_selection import train_test_split
def split_data(texts,labels):
x_train, x_test, y_train, y_test = train_test_split(texts,labels,test_size=0.2)
return x_train,x_test,y_train,y_test
embedding_layer = Embedding(input_dim=len(embeddings_matrix), # 字典长度
output_dim = EMBEDDING_LEN, # 词向量 长度(25)
weights=[embeddings_matrix], # 重点:预训练的词向量系数
input_length=MAX_SEQUENCE_LENGTH, # 每句话的 最大长度(必须padding) 10
trainable=False, # 是否在 训练的过程中 更新词向量
name= 'embedding_layer')
本文的部分工作、代码、数据共享到gethub网站《使用多层级注意力机制和keras实现问题分类》:https://github.com/xqtbox/question-classification-with-multi-level-attention-mechanism-and-keras
2 QA match/文本匹配/文本分类/文本embedding/文本聚类/文本检索:https://github.com/MachineLP/TextMatch
3 文本相似度计算/文本匹配
https://github.com/JepsonWong/Text_Matching