LSTM中文评论情感分析(粗糙版)

import pandas as pd #导入Pandas
import numpy as np #导入Numpy
import jieba #导入结巴分词
from keras.callbacks import EarlyStopping
from keras.preprocessing import sequence
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 import regularizers
from keras.layers.recurrent import LSTM, GRU
neg=pd.read_excel('neg.xls',header=None,index=None)
'''该函数主要的参数为io、sheetname、header、names、encoding.
 io:excel文件,可以是文件路径、文件网址、file-like对象、xlrd workbook;
 sheetname:返回指定的sheet,参数可以是字符串(sheet名)、整型(sheet索引)、list(元素为字符串和整型,返回字典{'key':'sheet'})、none(返回字典,全部sheet);
 header:指定数据表的表头,参数可以是int、list of ints,即为索引行数为表头;
 names:返回指定name的列,参数为array-like对象。
 encoding:关键字参数,指定以何种编码读取。
 该函数返回pandas中的DataFrame或dict of DataFrame对象,利用DataFrame的相关操作即可读取相应的数据。
 '''
pos=pd.read_excel('pos.xls',header=None,index=None) #读取训练语料完毕
pos['mark']=1
neg['mark']=0 #给训练语料贴上标签
#print(pos)
#print(neg)
pn=pd.concat([pos,neg],ignore_index=True) #合并语料
#pn.rename(columns={0:'text'}, inplace = True)更改列名
#print(pn.columns.values)获取列名
#print(pn.head(2))查看前两行
neglen=len(neg)
poslen=len(pos) #计算语料数目
cw = lambda x: list(jieba.cut(x)) #定义分词函数
#  冒号:之前的x表示它们是这个函数的参数。
# 匿名函数不需要return来返回值,表达式本身结果就是返回值。
pn['words'] = pn[0].apply(cw)
#print(pn[['words','mark']])查看列
comment = pd.read_excel('sum.xls') #读入评论内容
#comment = pd.read_csv('a.csv', encoding='utf-8')
comment = comment[comment['rateContent'].notnull()] #仅读取非空评论
comment['words'] = comment['rateContent'].apply(cw) #评论分词
'''concat函数是在pandas底下的方法,可以将数据根据不同的轴作简单的融合
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
       keys=None, levels=None, names=None, verify_integrity=False)
参数说明 
objs: series,dataframe或者是panel构成的序列lsit 
axis: 需要合并链接的轴,0是行,1是列 
join:连接的方式 inner,或者outer
如果两个表的index都没有实际含义,使用ignore_index参数,置true,合并的两个表就睡根据列字段对齐,然后合并。最后再重新整理一个新的index'''
d2v_train = pd.concat([pn['words'], comment['words']], ignore_index = True)
w = [] #将所有词语整合在一起
for i in d2v_train:
  w.extend(i)
dict = pd.DataFrame(pd.Series(w).value_counts()) #统计词的出现次数
del w,d2v_train
dict['id']=list(range(1,len(dict)+1))
'''更改列顺序
df_id = dict.id
dict = dict.drop('id',axis=1)
dict.insert(0,'id',df_id)
'''
get_sent = lambda x: list(dict['id'][x])
pn['sent'] = pn['words'].apply(get_sent) #速度太慢
maxlen = 50
print("Pad sequences (samples x time)")
pn['sent'] = list(sequence.pad_sequences(pn['sent'], maxlen=maxlen))#为训练词向量做准备
x = np.array(list(pn['sent']))[::2] #训练集,从第一个开始每两个取一个
y = np.array(list(pn['mark']))[::2]
xt = np.array(list(pn['sent']))[1::2] #测试集,从第二个开始每两个取一个
yt = np.array(list(pn['mark']))[1::2]
xa = np.array(list(pn['sent'])) #全集
ya = np.array(list(pn['mark']))
print('Build model...')
model = Sequential()#序列化
model.add(Embedding(len(dict)+1, 256))
model.add(LSTM(128, dropout=0.2, recurrent_dropout=0.2,kernel_regularizer=regularizers.l2(0.01),
                activity_regularizer=regularizers.l1(0.01)))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid',kernel_regularizer=regularizers.l2(0.01),
                activity_regularizer=regularizers.l1(0.01)))#激活函数

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
early_stopping = EarlyStopping(monitor='loss', patience=2)#定义EarlyStopping来提前终止训练
model.fit(x, y, batch_size=16, epochs=10 ,verbose=0,callbacks = [early_stopping]) #训练时间为若干个小时
score, acc = model.evaluate(xt, yt,batch_size=16,verbose=0)#本函数按batch计算在某些输入数据上模型的误差本函数返回一个测试误差的标量值(如果模型没有其他评价指标),或一个标量的list(如果模型还有其他的评价指标)
print('Test score:', score)
print('Test accuracy:', acc)

你可能感兴趣的:(算法)