本篇主要记录Keras实现BiLSTM+Attention模型,其中Attention是自定义层。然后用该模型完成新闻标题文本分类任务。
详细代码和数据:https://github.com/huanghao128/zh-nlp-demo,如果不嫌弃,欢迎star和Fork~
数据预处理
这里使用的数据集只是用来演示文本分类任务,所以没有使用长篇的文章,而是使用的标题。原始数据集是在头条爬取的,在这里可以下载:https://github.com/fate233/toutiao-text-classfication-dataset
我在这个数据集上做了一些处理,只保留了类别和标题,去除了关键词,处理后的数据如下图“类别_!_标题”格式:
读取上面的数据,然后HanLP分词预处理,构建词典并保存词典的结果。
from pyhanlp import HanLP
import numpy as np
from tqdm import tqdm
# 读取原始数据集分词预处理 并保存词典
def read_toutiao_dataset(data_path, save_vocab_path):
with open(data_path, "r", encoding="utf8") as fo:
all_lines = fo.readlines()
datas, labels = [], []
word_vocabs = {
}
for line in tqdm(all_lines):
content_words = []
category, content = line.strip().split("_!_")
for term in HanLP.segment(content):
if term.word not in word_vocabs:
word_vocabs[term.word] = len(word_vocabs)+1
content_words.append(term.word)
datas.append(content_words)
labels.append(category)
with open(save_vocab_path, "w", encoding="utf8") as fw:
for word, index in word_vocabs.items():
fw.write(word+"\n")
return datas, labels
读取词典文件,生成词-索引对应关系,其中special_words是填充<PAD>和未知词<UNK>等。
def read_word_vocabs(save_vocab_path, special_words):
with open(save_vocab_path, "r", encoding="utf8") as fo:
word_vocabs = [word.strip() for word in fo]
word_vocabs = special_words + word_vocabs
idx2vocab = {
idx: char for idx, char in enumerate(word_vocabs)} # 索引-词对应
vocab2idx = {
char: idx for idx, char in idx2vocab.items()} # 词-索引对应
return idx2vocab, vocab2idx
把前面分词预处理过的数据索引化,即根据词典索引对应关系,把文本序列变成词编号序列。
def process_dataset(datas, labels, category2idx, vocab2idx):
new_datas, new_labels = [], []
for data, label in zip(datas