前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >中文NLP笔记:8. 基于LSTM的文本分类

中文NLP笔记:8. 基于LSTM的文本分类

作者头像
杨熹
发布2019-02-20 16:32:51
3.4K0
发布2019-02-20 16:32:51
举报

图片发自简书App

序列模型

语言模型 N-gram

  前面的词袋模型(Bag-of-Words,BoW),没有考虑每个词的顺序

  有些句子即使把词的顺序打乱,还是可以看懂这句话在说什么,有时候词的顺序打乱,句子意思就变得面目全非

  N-gram 是一种考虑句子中词与词之间的顺序的模型

  它是一种语言模型(Language Model,LM),一个基于概率的判别模型,输入是一句话(词的顺序序列),输出是这句话中所有词的联合概率(Joint Probability)

  N-gram 模型知道的信息越多,得到的结果也越准确

  主要应用在如词性标注、垃圾短信分类、分词器、机器翻译和语音识别、语音识别等领域。

  优缺点

  优点:包含了前 N-1 个词所能提供的全部信息

  缺点:需要很大规模的训练文本来确定模型的参数

根据 N-gram 的优缺点,它的进化版 NNLM(Neural Network based Language Model)诞生了

  由 Bengio 在2003年提出

  由四层组成,输入层、嵌入层、隐层和输出层

  NNLM 的输入是长度为 N 的词序列的 index 序列,输出是下一个词的类别。

  “我是小明”的 index 序列就是 10、 23、65

  然后经过嵌入层(Embedding),是一个大小为 |V|×K 的矩阵,从中取出第10、23、65行向量拼成 3×K 的矩阵

  再经过 tanh 为激活函数,最后送入带 softmax 的输出层,输出概率

  最大的缺点就是参数多,训练慢,要求输入定长 N 很不灵活,不能利用完整的历史信息。

针对 NNLM 存在的问题,Mikolov 在2010年提出了 RNNLM

  结构实际上是用 RNN 代替 NNLM 里的隐层

  减少模型参数、提高训练速度、接受任意长度输入、利用完整的历史信息

基于 Keras 的 LSTM 文本分类

  引入数据处理库,停用词和语料加载

      #引入包     import random     import jieba     import pandas as pd     #加载停用词     stopwords=pd.read_csv('stopwords.txt',index_col=False,quoting=3,sep="\t",names=['stopword'], encoding='utf-8')     stopwords=stopwords['stopword'].values     #加载语料     laogong_df = pd.read_csv('beilaogongda.csv', encoding='utf-8', sep=',')     laopo_df = pd.read_csv('beilaogongda.csv', encoding='utf-8', sep=',')     erzi_df = pd.read_csv('beierzida.csv', encoding='utf-8', sep=',')     nver_df = pd.read_csv('beinverda.csv', encoding='utf-8', sep=',')     #删除语料的nan行     laogong_df.dropna(inplace=True)     laopo_df.dropna(inplace=True)     erzi_df.dropna(inplace=True)     nver_df.dropna(inplace=True)     #转换     laogong = laogong_df.segment.values.tolist()     laopo = laopo_df.segment.values.tolist()     erzi = erzi_df.segment.values.tolist()     nver = nver_df.segment.values.tolist()

  分词和去停用词

      #定义分词和打标签函数preprocess_text     #参数content_lines即为上面转换的list     #参数sentences是定义的空list,用来储存打标签之后的数据     #参数category 是类型标签     def preprocess_text(content_lines, sentences, category):         for line in content_lines:             try:                 segs=jieba.lcut(line)                 segs = [v for v in segs if not str(v).isdigit()]#去数字                 segs = list(filter(lambda x:x.strip(), segs)) #去左右空格                 segs = list(filter(lambda x:len(x)>1, segs))#长度为1的字符                 segs = list(filter(lambda x:x not in stopwords, segs)) #去掉停用词                 sentences.append((" ".join(segs), category))# 打标签             except Exception:                 print(line)                 continue     #调用函数、生成训练数据     sentences = []     preprocess_text(laogong, sentences,0)     preprocess_text(laopo, sentences, 1)     preprocess_text(erzi, sentences, 2)     preprocess_text(nver, sentences, 3)

  打散数据,使数据分布均匀,然后获取特征和标签列表

      #打散数据,生成更可靠的训练集     random.shuffle(sentences)     #控制台输出前10条数据,观察一下     for sentence in sentences[:10]:         print(sentence[0], sentence[1])     #所有特征和对应标签     all_texts = [ sentence[0] for sentence in sentences]     all_labels = [ sentence[1] for sentence in sentences]

  使用 LSTM 对数据进行分类

      #引入需要的模块     from keras.preprocessing.text import Tokenizer     from keras.preprocessing.sequence import pad_sequences     from keras.utils import to_categorical     from keras.layers import Dense, Input, Flatten, Dropout     from keras.layers import LSTM, Embedding,GRU     from keras.models import Sequential     #预定义变量     MAX_SEQUENCE_LENGTH = 100    #最大序列长度     EMBEDDING_DIM = 200    #embdding 维度     VALIDATION_SPLIT = 0.16    #验证集比例     TEST_SPLIT = 0.2    #测试集比例     #keras的sequence模块文本序列填充     tokenizer = Tokenizer()     tokenizer.fit_on_texts(all_texts)     sequences = tokenizer.texts_to_sequences(all_texts)     word_index = tokenizer.word_index     print('Found %s unique tokens.' % len(word_index))     data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)     labels = to_categorical(np.asarray(all_labels))     print('Shape of data tensor:', data.shape)     print('Shape of label tensor:', labels.shape)     #数据切分     p1 = int(len(data)*(1-VALIDATION_SPLIT-TEST_SPLIT))     p2 = int(len(data)*(1-TEST_SPLIT))     x_train = data[:p1]     y_train = labels[:p1]     x_val = data[p1:p2]     y_val = labels[p1:p2]     x_test = data[p2:]     y_test = labels[p2:]     #LSTM训练模型     model = Sequential()     model.add(Embedding(len(word_index) + 1, EMBEDDING_DIM, input_length=MAX_SEQUENCE_LENGTH))     model.add(LSTM(200, dropout=0.2, recurrent_dropout=0.2))     model.add(Dropout(0.2))     model.add(Dense(64, activation='relu'))     model.add(Dense(labels.shape[1], activation='softmax'))     model.summary()     #模型编译     model.compile(loss='categorical_crossentropy',                   optimizer='rmsprop',                   metrics=['acc'])     print(model.metrics_names)     model.fit(x_train, y_train, validation_data=(x_val, y_val), epochs=10, batch_size=128)     model.save('lstm.h5')     #模型评估     print(model.evaluate(x_test, y_test))


学习资料:

《中文自然语言处理入门实战》

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.02.05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
NLP 服务
NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档