lstm分类情感分析代码完整解析
⽂本情感分析(Sentiment Analysis)是⾃然语⾔处理(NLP)⽅法中常见的应⽤,也是⼀个有趣的基本任务,尤其是以提炼⽂本情绪内容为⽬的的分类。它是对带有情感⾊彩的主观性⽂本进⾏分析、处理、归纳和推理的过程。
  本⽂将介绍情感分析中的情感极性(倾向)分析。所谓情感极性分析,指的是对⽂本进⾏褒义、贬义、中性的判断。在⼤多应⽤场景下,只分为两类。例如对于“喜爱”和“厌恶”这两个词,就属于不同的情感倾向。
  本⽂将详细介绍如何使⽤深度学习模型中的LSTM模型来实现⽂本的情感分析。
⽂本介绍及语料分析
evaluation,label
⽤了⼀段时间,感觉还不错,可以,正⾯
电视⾮常好,已经是家⾥的第⼆台了。第⼀天下单,第⼆天就到本地了,可是物流的⼈说车坏了,⼀直催,客服也帮着催,到第三天下午5点才送过来。⽗母年纪⼤了,买个⼤电视画⾯清晰,趁着⽿朵还好使,享受⼏年。,正⾯
电视⽐想象中的⼤好多,画⾯也很清晰,系统很智能,更多功能还在摸索中,正⾯
不错,正⾯
⽤了这么多天了,感觉还不错。夏普的牌⼦还是⽐较可靠。希望以后⽐较耐⽤,现在是考量质量的时候。,正⾯
物流速度很快,⾮常棒,今天就看了电视,⾮常清晰,⾮常流畅,⼀次⾮常完美的购物体验,正⾯
⾮常好,客服还特意打电话做回访,正⾯
物流⼩哥不错,⾟苦了,东西还没⽤,正⾯
送货速度快,质量有保障,活动价格挺好的。希望⽤的久,不出问题。,正⾯
接着我们需要对语料做⼀个简单的分析:
数据集中的情感分布;
数据集中的评论句⼦长度分布。
  使⽤以下Python脚本,我们可以统计出数据集中的情感分布以及评论句⼦长度分布。
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager
from itertools import accumulate
# 设置matplotlib绘图时的字体
my_font = font_manager.FontProperties(fname="/home/george/Documents/项⽬/")
# 统计句⼦长度及长度出现的频数
df = pd.read_csv('./corpus.csv')
upby('label')['label'].count())
df['length'] = df['evaluation'].apply(lambda x: len(x)) # 评价那⼀列的评价长度
len_df = df.groupby('length').count()
sent_length =len_list()#把⾏序号即各种长度展开成⼀个list
sent_freq = len_df['evaluation'].tolist() # 每个长度有多少个
# 绘制句⼦长度及出现频数统计图
plt.bar(sent_length,sent_freq)#x轴,y轴数值
plt.title("句⼦长度及出现频数统计图", fontproperties=my_font)#标题
plt.xlabel("句⼦长度", fontproperties=my_font)#x轴标签
plt.ylabel("句⼦长度出现的频数", fontproperties=my_font)#y轴标签
plt.savefig("./句⼦长度及出现频数统计图.png")
plt.close()
# 绘制句⼦长度累积分布函数(CDF)
sent_pentage_list = [(count/sum(sent_freq)) for count in accumulate(sent_freq)]
#绘制CDF
plt.plot(sent_length,sent_pentage_list)
# 寻分位点为quantile的句⼦长度
quantile = 0.91
#print(list(sent_pentage_list))
for length, per in zip(sent_length,sent_pentage_list):
if round(per, 2) == quantile:
index = length
break
print("\n分位点为%s的句⼦长度:%d." % (quantile, index))
# 绘制句⼦长度累积分布函数图
plt.plot(sent_length,sent_pentage_list)
plt.hlines(quantile, 0, index, colors="c",linestyles="dashed")#加⼀条⽔平的线,指向(quantile, index) 这个点plt.vlines(index,0,quantile,colors="c",linestyles="dashed")#加⼀条垂直的线,指向(quantile, index) 这个点(0,quantile,str(quantile))
<(index,0,str(index))
plt.title("句⼦长度累积分布函数图", fontproperties=my_font)
plt.xlabel("句⼦长度", fontproperties=my_font)
plt.ylabel("句⼦长度累积频率", fontproperties=my_font)
plt.savefig("./句⼦长度累积分布函数图.png")
plt.close()
输出的结果如下:
label
正⾯    1908
负⾯    2375
Name: label, dtype: int64
分位点为0.91的句⼦长度:183.
可以看到,正反⾯两类情感的⽐例差不多。句⼦长度及出现频数统计图如下:
句⼦长度累积分布函数图如下:
使⽤LSTM模型
  接着我们使⽤深度学习中的LSTM模型来对上述数据集做情感分析,笔者实现的模型框架如下:
思想就是:
1.数据处理:
⾸先将 评价(evaluation) 和 正负⾯(value) 取出来放到list, 然后去重(unique),然后分词放到词典vocabulary中,然后做出两个词典映射
#字典列表
#就是给每个词编号形成两个映射 word_dictionary 词:编号  inverse_word_dictionary 编号:词⾃⼰编的号
word_dictionary = {word: i + 1 for i, word in enumerate(vocabulary)}
inverse_word_dictionary = {i + 1: word for i, word in enumerate(vocabulary)}
正反⾯:
output_dictionary = {i : labels for i, labels in enumerate(labels)}
然后根据词汇表,将所有的评价⾥⾯的分词变成序号,然后利⽤padding 补齐成⼀样的长度.
2 构建
# 创建深度学习模型, Embedding + LSTM + Softmax.
# 通过语义库(训练的或者现成的wprd2Vec),利⽤embedding 实现将字词⽤⾼维向量表⽰,可以训练后得到前后⽂的意义的向量Embedding层:将序号[1234,2324,...] 变成20维的向量,然后进⾏训练,训练出来的 20维向量数值是互相有关系的然后再训练LSTM,保存模型就⾏了
import pickle
import numpy as np
import pandas as pd
from keras.utils import np_utils, plot_model
dels import Sequential
from keras.preprocessing.sequence import pad_sequences
from keras.layers import LSTM, Dense, Embedding, Dropout
del_selection import train_test_split
ics import accuracy_score
# 导⼊数据
# ⽂件的数据中,特征为evaluation, 类别为label.
def load_data(filepath, input_shape = 20):
df = pd.read_csv(filepath)
# 标签及词汇表
labels, vocabulary =  list(df['label'].unique()), list(df['evaluation'].unique())
# 构造字符级别的特征
string = ''
for word in vocabulary:
string += word # ⼀句话⼀句话加进去
vocabulary = set(string)
#字典列表
#就是给每个词编号形成两个映射 word_dictionary 词:编号  inverse_word_dictionary 编号:词⾃⼰编的号
word_dictionary = {word: i + 1 for i, word in enumerate(vocabulary)}
with open('word_dict.pk','wb') as f:
pickle.dump(word_dictionary,f)
inverse_word_dictionary = {i + 1: word for i, word in enumerate(vocabulary)}
label_dictionary = {label: i for i, label in enumerate(labels)}
with open('label_dict.pk','wb') as f:
pickle.dump(label_dictionary, f)
output_dictionary = {i : labels for i, labels in enumerate(labels)}
vocab_size = len(word_dictionary.keys())# 词汇表⼤⼩
label_size = len(label_dictionary.keys()) # 标签类别数量
# 序列填充,按input_shape填充,长度不⾜的按0补充
x = [[word_dictionary[word]for word in sent] for sent in df['evaluation']]
x = pad_sequences(maxlen = input_shape,sequences=x,padding = 'post',value = 0)#blog.csdn/wcy23580/article/details/84957471
#为了实现的简便,keras只能接受长度相同的序列输⼊。因此如果⽬前序列长度参差不齐,这时需要使⽤pad_sequences()。该函数是将序列转化为经过填充以后的    y = [[label_dictionary[sent]]for sent in df['label']]#sent 因为是 for迭代过去的,所以需要⼀个列表(容器)来吸收
y = [_categorical(label,num_classes = label_size) for label in y]
y = np.array([list(_[0]) for _ in y])
return x,y,output_dictionary,vocab_size,label_size,inverse_word_dictionary
# 创建深度学习模型, Embedding + LSTM + Softmax.
# 通过语义库(训练的或者现成的wprd2Vec),利⽤embedding 实现将字词⽤⾼维向量表⽰,可以得到前后⽂的关系,进⾏训练
# 具体看 www.jianshu/p/158c3f02a15b
def create_LSTM(n_units,input_shape, output_dim,filepath):
x, y,output_dictionary, vocab_size,label_size,inverse_word_dictionary = load_data(filepath)
model = Sequential()
model.add(Embedding(input_dim = vocab_size+1, output_dim= output_dim,
input_length = input_shape, mask_zero = True))
# input_dim:这是⽂本数据中词汇的取值可能数。例如,如果您的数据是整数编码为0-9之间的值,那么词汇的⼤⼩就是10个单词;也就是one-hot
#从one-hot变20维的 180是多少个词也就是长度,也就是得到180*20 然后再进⾏训练
# output_dim:这是嵌⼊单词的向量空间的⼤⼩,这⾥是20。它为每个单词定义了这个层的输出向量的⼤⼩。例如,它可能是32或100甚⾄更⼤,可以视为具体问题的超# input_length:这是输⼊序列的长度,就像您为Keras模型的任何输⼊层所定义的⼀样,也就是⼀次输⼊带有的词汇个数。例如,如果您的所有输⼊⽂档都由1000个字# juejin.im/entry/6844903589299634183
import pickle
# 如果是普通神经⽹络那么 embedding 后⾯需要 flatten 平铺, 但是当数量过⼤平铺的参数就会过⼤, 所以⽤ LSTM 保留了前⾯的优化信息,就不⽤平铺.
model.add(LSTM(n_units, input_shape = (x.shape[0],x.shape[1])))#xshape = (4283,20)
model.add(Dropout(0.2))
model.add(Dense(label_size,activation='softmax'))
modelpile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics=['accuracy'])
plot_model(model, to_file='./model_lstm.png', show_shapes = True) #⾃动给你⽣成⼀个每层的维数的图特别好
model.summary()
#预计到达时间: (ETA: Estimated Time of Arrival)
return model
# 模型训练

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。