使用Tensorflow训练LSTM+Attention中文标题党分类

这里用Tensorflow中LSTM+Attention模型训练一个中文标题党的分类模型,并最后用Java调用训练好的模型。

数据预处理

首先根据语料和实验数据训练词向量word2vec模型,这个有很多教程,这么不再叙述。之后根据训练好的词向量生成我们需要的词典文件。保存的词典map为每行一个词和词的编号。

import gensim
import numpy as np

def load_words_embedding(model, embedding_dim, word_map_path):
    """
    获取word2vec词向量中的词表
    :param model: 训练好的word2vec模型
    :param embedding_dim: word2vec模型的维度
    :param word_map_path: word2vec中的词保存为词典编号
    :return:
     vocab_dict 词典编号
     vectors_array 词向量转成数组,索引为0的位置填充了一个随机初始化向量,表示未知词
    """
    # load word2vec
	w2v_model = gensim.models.KeyedVectors.load_word2vec_format(w2v_path, binary=True)
	
    vocab = model.wv.vocab
    word_keys = list(vocab.keys())
    vocab_dict = {
   "UNKNOW": 0} # 0表示未知词
    fw = open(word_map_path, "w", encoding="utf8")
    for i in range(len(word_keys)):
        vocab_dict[word_keys[i]] = i+1
        fw.write(word_keys[i] + " " + str(i+1) + "\n")
    fw.close()
    vector_list = list()
    vector_list.append(np.random.rand(embedding_dim))
    for word in word_keys:
        try:
            vector_list.append(model[word])
        except:
            vector_list.append(np.random.rand(embedding_dim).astype(np.float32))
    vectors_array = np.array(vector_list)
    print("dict_size:", len(vocab_dict))
    print("embedding_sizes:", len(vectors_array))
    return vocab_dict, vectors_array

处理实验数据集,我们的数据是中文已经分好词的标题党数据,每行一个标签(1为标题党,0为正常标题)和一条数据,中间制表符隔开("\t"),实例如下图所示:
标题党数据实例

我们需要根据上面的词典文件,把分词序列转成词典编号序列,并记录每个样本的长度。

def read_data(data_path, vocab_dict, sequence_length):
    """
    读取并处理实验数据集
    :param data_path: 数据集路径
    :param vocab_dict: 前面产生的词典
    :param sequence_length: 输入模型最大长度控制,多则阶段,少则填充
    :return:
        datas_index: 由词序列转成的编号序列
        datas_length:每条数据的长度
        labels:每条数据的标签
    """
    fo = open(data_path, "r", encoding='utf8')
    all_data = fo.readlines()
    fo.close()
    random.shuffle(all_data)  # 打乱顺序
    datas_index = []
    datas_length = []
    labels = []
    for line in all_data:
        line = line.strip().split("\t")
        label = int(line[0])
        title = line[1]
        data_index = []
        for word in title.split(" "):
            try:
                data_index.append(vocab_dict[word])
            except:
                data_index.append(0)

        length = len(title.split(" "))
        if length > sequence_length:
            length = sequence_length
            
        datas_index.append(data_index)
        datas_length.append(length)
        labels.append(label)

    return datas_index, datas_length, labels

对于长度不一致的情况,需要进行数据填充。还对标签进行one-hot编码。

def pad_sequences(data_index, maxlen):
    """
     数据填充
    :param data_index: 输入数据的词索引
    :param maxlen: 最大长度
    :return: 填充后的数据
    """
    data_pad_index = []
    for sentence in data_index:
        if len(sentence) >= maxlen:
            padded_seq = sentence[0: maxlen]
        else:
            padded_seq = sentence + [0] * (maxlen - len(sentence))
        data_pad_index.append(padded_seq)
    data_pad = np.array(data_pad_index)
    return data_pad
 
 def make_one_hot(label, n_label):
    """
    label表转成one-hot向量
    :param label: 输入标签值
    :param n_label: 标签及分类的总数
    :return: one-hot标签向量
    """
    values = np.array(label)
    label_vec = np.eye(n_label)[values]
    return label_vec
  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值