import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers import numpy as np import pandas as pd import re ``import matplotlib.pyplot as plt %matplotlib inline
读取csv文件 1 data = pd.read_csv('Tweets.csv')
获取目标列:’airline_sentiment’,’text’ 1 data = data[['airline_sentiment','text']]
统计’airline_sentiment’列 1 2 3 4 5 6 data.airline_sentiment.value_counts() negative 9178 neutral 3099 positive 2363 Name: airline_sentiment, dtype: int64
正面评价、负面评价归类 1 2 data_p = data[data.airline_sentiment == 'positive'] data_n = data[data.airline_sentiment == 'neutral']
正面评价、负面评价数据量相同 1 data_n = data_n.iloc[:len(data_p)]
数据拼接 1 data = pd.concat([data_n,data_p])
数据乱序 1 data = data.sample(len(data))
从所选的数据的指定 axis 上返回随机抽样结果,类似于random.sample()函数。
positive->0 , neutral->1 1 data['review'] = (data.airline_sentiment == 'positive').astype('int')
删除’airline_sentiment’列 1 del data['airline_sentiment']
正则匹配评论数据(去除表情和无关数据) 1 token = re.compile('[A-Za-z]+|[!?,.()]')
1 2 3 4 def reg_text(text): new_text = token.findall(text) new_text = [word.lower() for word in new_text] return new_text
加载reg_text函数 1 data['text'] = data.text.apply(reg_text)
443 [virginamerica, congrats, vx, on, the, new, ro... 2823 [united, if, i, had, a, ticket, refunded, whic... 14194 [americanair, bershawnjackson, big, ups, to, n... 3981 [united, big, up, the, pilot, of, for, turning... 7781 [jetblue, you, can, t, beat, jetblue, in, spac... ... 7086 [please, explain, ., ., jetblue, our, fleet, s... 3601 [united, vusa, australia, i, m, just, an, auss... 6466 [despite, mother, nature, s, best, efforts, ,,... 5823 [southwestair, good, to, know, ., perhaps, it,... 2563 [united, we, are, trying, to, go, as, far, awa... Name: text, Length: 4726, dtype: object
设置单词字典 1 2 3 4 word_set = set() for text in data.text: for word in text: word_set.add(word)
1 2 word_list = list(word_set) word_index = dict((word,word_list.index(word)+1) for word in word_list)#将每个单词设置index
将评论单词转化成index 1 data_ok = data.text.apply(lambda x:[word_index.get(word,0) for word in x])
记录最长评论单词数 1 2 maxlen = max(len(x) for x in data_ok) maxlen
记录单词字典数+1 1 2 max_word = len(word_set) +1 max_word
对数据进行填充 1 data_ok = keras.preprocessing.sequence.pad_sequences(data_ok.values,maxlen=maxlen)#对数据进行填充 根据最长评论长度进行填充
data_ok[0],data_ok.shape(array([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 570, 1321, 1106, 4425, 1443, 1359, 6269, 7359]), (4726, 40))
创建模型 1 2 3 4 model = keras.Sequential() model.add(layers.Embedding(max_word,50,input_length=maxlen))#输入文本个数,映射成的密集向量长度,输入的文本长度 model.add(layers.LSTM(64)) model.add(layers.Dense(1,activation='sigmoid',use_bias=False))
tf.keras.layers.Embedding 把文本向量化
Embeding:把文本映射为一个密集向量
模型配置 1 2 3 4 model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'] )
模型训练 1 history = model.fit(data_ok, data.review.values, epochs=10, batch_size=128, validation_split=0.2)#validation_split 将数据进行切分 切分20%去做测试数据
绘制训练数据变化 1 2 3 plt.plot(history.epoch, history.history.get('val_acc'), c='r', label='val_acc') plt.plot(history.epoch, history.history.get('acc'), c='b', label='acc') plt.legend()
1 2 3 plt.plot(history.epoch, history.history.get('val_loss'), c='r', label='val_loss') plt.plot(history.epoch, history.history.get('loss'), c='b', label='loss') plt.legend()
模型优化(添加Dropout) 1 2 3 4 5 6 7 8 9 10 11 12 def train_model(): model = keras.Sequential() model.add(layers.Embedding(max_word, 16, input_length=maxlen)) model.add(layers.LSTM(64, dropout=0.2, recurrent_dropout=0.5)) model.add(layers.Dropout(0.5)) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer=keras.optimizers.RMSprop(), loss='binary_crossentropy', metrics=['acc']) return model
dropout:0~1之间的浮点数,控制输入线性变换的神经元断开比例
recurrent_dropout:0~1之间的浮点数,控制循环状态的线性变换的神经元断开比例
1 2 model2 = train_model() history = model2.fit(data_ok, data.review.values, epochs=10, batch_size=128, validation_split=0.2)#validation_split 数据切分20%的出去作为测试
绘制添加Dropout模型数据变化 1 2 3 plt.plot(history.epoch, history.history.get('val_acc'), c='r', label='val_acc') plt.plot(history.epoch, history.history.get('acc'), c='b', label='acc') plt.legend()
1 2 3 plt.plot(history.epoch, history.history.get('val_loss'), c='r', label='val_loss') plt.plot(history.epoch, history.history.get('loss'), c='b', label='loss') plt.legend()
模型优化( 使用双向 RNN) 1 2 3 4 5 6 7 8 9 10 11 12 def train_model(): model = keras.Sequential() model.add(layers.Embedding(max_word, 16, input_length=maxlen)) model.add(layers.Bidirectional(layers.LSTM(64, dropout=0.2, recurrent_dropout=0.5))) model.add(layers.Dropout(0.5)) model.add(layers.Dense(1, activation='sigmoid')) model.compile(optimizer=keras.optimizers.RMSprop(), loss='binary_crossentropy', metrics=['acc']) return model
设置学习速率回调函数 1 learning_rate_reduction = keras.callbacks.ReduceLROnPlateau(monitor='val_loss', patience=3, factor=0.3, min_lr=0.00001)
模型( 双向 RNN)训练 1 2 3 4 5 6 7 model3 = train_model() history = model3.fit(data_ok, data.review.values, epochs=30, batch_size=128, validation_split=0.2, callbacks=[learning_rate_reduction])
绘制训练数据变化 1 2 3 plt.plot(history.epoch, history.history.get('val_acc'), c='r', label='val_acc') plt.plot(history.epoch, history.history.get('acc'), c='b', label='acc') plt.legend()
1 2 3 plt.plot(history.epoch, history.history.get('val_loss'), c='r', label='val_loss') plt.plot(history.epoch, history.history.get('loss'), c='b', label='loss') plt.legend()