中文情感分类(基于LSTM)

中文情感分类(基于LSTM)

基于LSTM实现中文情感分类,框架在开始的时候使用的是tensorflow,但是不知到为什么,最后网络总是收敛不了,损失几乎不降。但是同样的想法思路使用keras后,训练就十分顺畅。话不多说,总流程如下:

  • 准备数据集
  • 二分类数据集
  • 将数据集中的所有字映射为字典,即每个字都有唯一的标号对应,这里使用tensorflow中的模块很容易就实现了。
    if os.path.exists("processor"):
        processor = learn.preprocessing.VocabularyProcessor.restore("processor")
    else:
        processor = learn.preprocessing.VocabularyProcessor(max_document_length=MAX_DOCUMENT_LEN)
        processor.fit(all_word)
        processor.save("processor")
  • 实现Embedding层
    针对本文中Embedding层,其主要作用是将每个词的id映射为固定维度的数,每次相同的id映射为相同的数据,这个固定的数据是可以训练的。在不断的迭代中完成训练。如果针对词向量来说,到了最后Embedding层所得到的就是每个词的词向量,只要我们输入词的对应id就可以得到其对应的词向量。所以Embedding层可以使用预先训练好的词向量,这样在训练的过程中,收敛速度会加快。
    model.add(Embedding(input_dim=len(all_word), output_dim=EMBEDDING_SIZE))
  • *添加LSTM层进行特征抽取
    使用LSTM进行数据特征的抽取,我觉得tensorflow中就是这一块使用失误,导致网络不收敛。最后网路使用交叉熵损失,随机梯度下降法进行训练优化。所以直接看看keras的全部实现:
import pandas as pd
from tensorflow.contrib import learn
from keras.layers.embeddings import Embedding
from keras.layers.recurrent import LSTM
from keras.models import Sequential, load_model
from keras.layers import Dense
import numpy as np
import os

MAX_DOCUMENT_LEN = 30
EMBEDDING_SIZE = 100

def train():
    train = pd.read_csv("all.csv", encoding="utf-8")
    all_word = set([word for seq in train.content.values for word in list(seq)])

    if os.path.exists("processor"):
        processor = learn.preprocessing.VocabularyProcessor.restore("processor")
    else:
        processor = learn.preprocessing.VocabularyProcessor(max_document_length=MAX_DOCUMENT_LEN)
        processor.fit(all_word)
        processor.save("processor")

    # fit generate
    def get_generate(batch_size):
        while True:

            sample_data = train.sample(batch_size)
            labels = sample_data.label.values
            contents = sample_data.content.values

            contents = [list(seq) for seq in contents]
            x = []
            for seq in contents:
                item_str = ""
                for word in seq:
                    item_str += " " + str(word)
                x.append(item_str)

            x = np.array(list(processor.transform(x)))
            y = np.array([[1, 0] if int(item) == 0 else [0, 1] for item in labels])
            yield x, y

    # create embedding
    model = Sequential()
    model.add(Embedding(input_dim=len(all_word), output_dim=EMBEDDING_SIZE))
    model.add(LSTM(units=128, activation="relu"))
    model.add(Dense(2, activation="softmax", name="logit"))

    model.compile(loss='categorical_crossentropy', optimizer='sgd')

    model.fit_generator(get_generate(50), samples_per_epoch=10000, epochs=10)
    model.save("lstm.model")

def pre():
    text = input("请输入:")
    text = list(text)
    item_str = ""
    for item in text:
        item_str += " " + str(item)

    processor = learn.preprocessing.VocabularyProcessor.restore("processor")
    input_data = np.array(list(processor.transform([item_str])))
    print(input_data)
    model = load_model("lstm.model")
    target = model.predict(input_data)
    print(target)


猜你喜欢

转载自blog.csdn.net/qq_21157073/article/details/81584963