使用深度学习训练极性情感模型

一、数据的预处理
1、首先将从网上搜集已经标注好的数据集包含的领域有书籍、酒店、计算机、牛奶、手机、热水器,积极的评论10679条标注为1,消极的评论10428条标注为0,添加完标记后将其合并。这里使用Python来完成处理,用到的第三方库有numpypandas。处理的代码如下:

pos = pd.read_excel('./pos.xls',header=None)
pos['label'] = 1;

neg = pd.read_excel('./neg.xls',header=None)
neg['label'] = 0

all_ = pos.append(neg,ignore_index=True)

2、中文切词,采用开源库jieba把每条评论进行切词。注意这里使用深度学习的方法来训练模型,所以去除一些停用词。共计词汇数目1353755

all_['words'] = all_[0].apply(lambda s: list(jieba.cut(s)))

3、将词汇进行向量转化,比如有三个词汇"你","好","漂亮","风趣",'假如用数字来表示他们1,2,3,4。那么"你好风趣"整个句子的表示方式为[1,2,4],而"你好漂亮"的向量表示为[1,2,3]。基于上一步我们切词得到的词汇1353755条进行词频统计,统计完我们需要做一些处理:去除重复的词条,去重后剩余50921条词汇。为了加快我们训练的速度,我们这里对50921条词汇进一步处理:过滤掉频次少于5的词汇,处理后剩余词汇14321条。然后将每个词语从1-14321进行编号,另外空格符' '标号为0。

maxlen = 100 #截断词数
min_count = 5 #出现次数少于该值的词扔掉。这是最简单的降维方法

content = []
for i in all_['words']:
    content.extend(i)

# print(len(set(content)))
abc = pd.Series(content).value_counts()
abc = abc[abc >= min_count]
# print(len(abc))

abc[:] = list(range(1, len(abc)+1))
abc[''] = 0 #添加空字符串用来补全

word_set = set(abc.index)

4、将每条评论用向量来表示,为了统一X(X为训练的输入集合)的格式,我们这里将每条评论都是100个词汇组成,不够100的用空格的来补全,超过的则截取。

def doc2num(s, maxlen):
    s = [i for i in s if i in word_set]
    s = s[:maxlen] + ['']*max(0, maxlen-len(s))
    print(s)

    return list(abc[s])

all_['doc2num'] = all_['words'].apply(lambda s: doc2num(s, maxlen))

二、训练模型并保存
使用keras基于LSTM搭建一个深度模型,使用15000条评论进行训练,用剩下的评论的做验证集。验证的准确率有81.13%。

# #手动打乱数据
    idx = list(range(len(all_)))
    np.random.shuffle(idx)
    all_ = all_.loc[idx]
    #
    # #按keras的输入要求来生成数据
    x = np.array(list(all_['doc2num']))
    y = np.array(list(all_['label']))
    y = y.reshape((-1, 1))  # 调整标签形状

    # print(x)
    # print(x.shape)
    from keras.models import Sequential
    from keras.layers import Dense, Activation, Dropout, Embedding
    from keras.layers import LSTM

    # 建立模型

    model = Sequential()
    model.add(Embedding(len(abc), 256, input_length=maxlen))
    model.add(LSTM(128))
    model.add(Dropout(0.5))
    model.add(Dense(1))
    model.add(Activation('sigmoid'))
    model.compile(loss='binary_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])

    batch_size = 128
    train_num = 15000

    model.predict()
    model.fit(x[:train_num], y[:train_num], batch_size=batch_size, epochs=30)

    score = model.evaluate(x[train_num:], y[train_num:], batch_size=batch_size)

    model.save('./commemnt.h5')

三、使用衡山负面评论书籍来验证模型的准确率
使用衡山负面游记评论来验证,其验证结果正确率为59.6%,正确不太理想,出现的原因可能有:1、训练集合中没有包含旅游评论的数据。2、词频过滤设置为5和假设每条评论最多为100个词汇的假设存在问题。3、词向量的转化方式。4、算法和超参数需要调整

from keras.models import  load_model
import  jieba
import  numpy as np
import pandas as pd
import matplotlib.pyplot as plt

model = load_model('./commemnt.h5')
print(model)




def load_list(path):
    with open(path) as fp:
        arr = [ w.strip() for w in fp.readlines()]
        return arr



# 1.加载所有的评论
# comments = load_list('./neg_hengshan.txt')

comments = pd.read_excel('./neg.xls',header=None)[0].values


# 2.将所有评论进行切词
cut_words = []

for comment in comments:
    words = []
    for w in jieba.cut(comment[2:-2]):
        words.append(w)

    cut_words.append(words)




pos = pd.read_excel('./pos.xls',header=None)
pos['label'] = 1;

neg = pd.read_excel('./neg.xls',header=None)
neg['label'] = 0

all_ = pos.append(neg,ignore_index=True)

all_['words'] = all_[0].apply(lambda s: list(jieba.cut(s)))
#
#
#
maxlen = 100 #截断词数
min_count = 5 #出现次数少于该值的词扔掉。这是最简单的降维方法

content = []
for i in all_['words']:
    content.extend(i)

abc = pd.Series(content).value_counts()
abc = abc[abc >= min_count]

abc[:] = list(range(1, len(abc)+1))
abc[''] = 0 #添加空字符串用来补全

word_set = set(abc.index)
def doc2num(s, maxlen):
    s = [i for i in s if i in word_set]
    s = s[:maxlen] + ['']*max(0, maxlen-len(s))

    # print(abc[s])
    return list(abc[s])

print(cut_words[0])
arr  = [ doc2num(w,100) for w in cut_words]

# print(arr)
#
#
#
# # print(all_)
#
# # # #手动打乱数据
# # idx = list(range(len(all_)))
# # np.random.shuffle(idx)
# # all_ = all_.loc[idx]
# #
# # #按keras的输入要求来生成数据
x = np.array(arr)
#
# print(x)
#
#
#



arr = model.predict(x,steps=1)

correct_results = []
for w in arr:
    if w < 0.5:
        correct_results.append(correct_results)


print('负面评论的比例为:{}'.format(len(correct_results)/len(arr)))


# plt.scatter(arr,range(0,len(arr)),label='test')
# plt.xlabel('x')
# plt.ylabel('y')
# plt.title('test')
# plt.legend()
# plt.show()

你可能感兴趣的:(使用深度学习训练极性情感模型)