完整代码和数据下载地址:https://download.csdn.net/download/qq475225253/87881171

一、背景

现在手头上有一份11万条关于微博留言的数据,下图列举了部分数据

其实数据非常简单,只包含两个字段,label 和review  

label是用来分类情感的,1是积极,0是消极 。review是具体的评价内容。

我们待会要实现的内容其实本质就是根据评价中的关键词字,进行情感分类。如果使用支持向量机或其他常见的通用分类算法进行分类,预计效果可能不太好。因为词字的前后顺序不同,所表达出来的感情是不一样的。所以我们这里待会采用专门处理时序有关的神经网络算法(LSTM)来进行建模。建模后测试,发现它的准确率能达到95%

二、数据处理

在构造模型前,我们首先要对数据进行处理,毕竟计算机没办法直接对文本进行机器学习。那要做那些数据处理呢?分词,去停用词,词向量。

在处理数据前,我们首先要把数据读取进来

#加载必要的模块
import pandas as pd
# 读取文本数据

data = pd.read_csv('weibo_senti_100k.csv')
data = data.dropna()   #去掉数据集的空值

接下来我们就依次来处理数据

1、分词

顾名思义,把评论分成一个一个的单词

import jieba
data['data_cut'] = data['review'].apply(lambda x: list(jieba.cut(x)))  #内嵌自定义函数来分词
data.head()

这里我们用到了一个第三方库jieba,需要使用pip单独安装。jieba是一个常用于中文分词的工具

2、去停用词

在分词后,我们得到了很多单词,但是这些单词中,有很多一部分与我们情感分析无关,是无效的单词,所以我们就要去掉它,防止它对我们机器学习带来干扰。具体的,我们首先定义了一个文件,加入叫“stopword.txt",这里面存放了常见的无效单词,只要在这里面的,我们就从分词得到的数据中去掉他们。

# ##  去停用词

# 读取停用词
with open('stopword.txt','r',encoding = 'utf-8') as f:  #读取停用词
    stop = f.readlines()
# 对停用词处理
import re
stop = [re.sub(' |\n|\ufeff','',r) for r in stop]   #替换停用词表的空格等

# 去除停用词
#把分词之后的文本根据停用词表去掉停用词
data['data_after'] = [[i for i in s if i not in stop] for s in data['data_cut']]
data.head()

3、词向量

至此,我们已经得到了有效的单词库了,但这些单词还不能直接用于机器学习,我们机器学习用到的特征一般都是用数值表达的。所以我们需要把上面处理好的单词,编码成数值,并放置到tensorflow能够处理的向量中。

# 构建词向量矩阵
w = [] 
for i in data['data_after']:  
    w.extend(i)  #将所有词语整合在一起  
num_data = pd.DataFrame(pd.Series(w).value_counts()) # 计算出所有单词的个数

num_data['id'] = list(range(1,len(num_data)+1))   #把这些数据增加序号

#  转化成数字
a = lambda x:list(num_data['id'][x])    #以序号为序定义实现函数
data['vec'] = data['data_after'].apply(a)  #apply()方法实现
data.head()

三、训练模型

# ##  数据集划分
from sklearn.model_selection import train_test_split
from keras.preprocessing import sequence  

maxlen = 128   #句子长度
vec_data = list(sequence.pad_sequences(data['vec'],maxlen=maxlen))   #把文本数据都统一长度
x,xt,y,yt = train_test_split(vec_data,data['label'],test_size = 0.2,random_state = 123)   #分割训练集--2-8原则

# 转换数据类型
import numpy as np
x = np.array(list(x))
y = np.array(list(y))
xt = np.array(list(xt))
yt = np.array(list(yt))

###由于数据量较大,运行时间太长,可选择其中的2000条训练,500条测试来验证模型
x=x[:2000,:]
y=y[:2000]
xt=xt[:500,:]
yt=yt[:500]



#模型构建

from keras.optimizers import SGD, RMSprop, Adagrad  
from keras.utils import np_utils  

from keras.models import Sequential  
from keras.layers.core import Dense, Dropout, Activation  
from keras.layers.embeddings import Embedding  
from keras.layers.recurrent import LSTM, GRU  



model = Sequential()  
model.add(Embedding(len(num_data['id'])+1,256))   # 输入层,词向量表示层
model.add(Dense(32, activation='sigmoid', input_dim=100))  # 全连接层,32层
model.add(LSTM(128))   # LSTM网络层
model.add(Dense(1))  # 全连接层--输出层
model.add(Activation('sigmoid'))    # 输出层的激活函数
model.summary()  #输出模型结构


#模型的画图表示
import matplotlib.pyplot as plt
import matplotlib.image as mpimg 
from keras.utils import plot_model
plot_model(model,to_file='Lstm2.png',show_shapes=True)
ls = mpimg.imread('Lstm2.png') # 读取和代码处于同一目录下的Lstm.png
plt.imshow(ls) # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()


model.compile(loss='binary_crossentropy',optimizer='Adam',metrics=["accuracy"])  #模型融合

#训练模型
model.fit(x,y,validation_data=(x,y),epochs=15)


#模型验证
loss,accuracy=model.evaluate(xt,yt,batch_size=12)  # 测试集评估
print('Test loss:',loss)
print('Test accuracy:', accuracy)

更多推荐