30.5.4 使用增加嵌入维度的深度学习模型
还有继续提升模型性能的空间,特别是因为我们拥有一个相对较大的数据集,并且数据是由专家进行标注的。嵌入层似乎是构建优秀模型的关键,因此我们将尝试一种使用嵌入层的深度学习方法。
我们的深度学习模型将使用20,000的词汇表,并将最大文档长度限制为50个单词以进行填充。我们将采用LSTM层和嵌入层,其中嵌入层将是一个可训练的100维嵌入层。对于二分类问题,我们将使用二元交叉熵损失函数和Adam优化器。深度学习模型将在训练集上进行训练,并在测试集(90/10)上进行评估。此外,训练数据将进一步分割为训练和验证子集(60/40)。
(1)下面代码定义了一个使用Keras构建的深度学习模型类nlp_evals_keras,用于对文本数据进行情感分析。该类通过将文本转换为数字表示并进行填充,分割训练和测试数据集,然后训练LSTM模型,并在训练集和测试集上评估模型的性能。最后,模型可以对新的文本数据进行推断。
from keras.wrappers.scikit_learn import KerasClassifier
import warnings; warnings.filterwarnings('ignore')
class nlp_evals_keras:
def __init__(self,
df,
corpus,
label,
title='accuracy evaluation'
):
# 初始化参数
self.df = deepcopy(df) # 深拷贝数据框
self.corpus = corpus # 定义语料库列
self.label = label # 定义标签列
self.title = title # 定义标题
# 将语料分割为训练和测试子集
def tts(self, ratio=0.1):
# 分割出用于验证的数据集
Y = self.df[self.label]
X = self.paddings
# 使用train_test_split进行数据分割
X_train, X_test, y_train, y_test = train_test_split(X, Y,
test_size=ratio,
random_state=32)
self.X_train = X_train # 训练集特征
self.X_test = X_test # 测试集特征
self.y_train = y_train # 训练集标签
self.y_test = y_test # 测试集标签
print('train/test split!')
# 创建分词器、词汇表,生成数值表示并填充文本
def get_paddings(self):
### 创建序列
vocabulary_size = 20000
self.tokenizer = Tokenizer(num_words=vocabulary_size) # 创建分词器
self.tokenizer.fit_on_texts(self.df[self.corpus]) # 拟合分词器
sequences = self.tokenizer.texts_to_sequences(self.df[self.corpus]) # 将文本转换为序列
self.paddings = pad_sequences(sequences, maxlen=50) # 填充序列
# 训练和测试评估
def eval_tts(self):
def create_model(input_length=50):
model = Sequential()
model.add(Embedding(20000, 100, input_length=50)) # 嵌入层
model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2)) # LSTM层
model.add(Dense(1, activation='sigmoid')) # 输出层
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model
clf = KerasClassifier(build_fn=create_model,
epochs=10,
verbose=1,
validation_split=0.4)
clf.fit(self.X_train, self.y_train) # 训练模型
# 进行预测
ytrain_res = clf.predict(self.X_train)
ytest_res = clf.predict(self.X_test)
self.clf = clf # 保存模型
# 计算训练和测试的准确率
lstm_train_res = accuracy_score(ytrain_res, self.y_train)
lstm_test_res = accuracy_score(ytest_res, self.y_test)
print(lstm_train_res, lstm_test_res)
# 将预测结果添加到数据框中
self.y_train.to_frame()['lstm_res'] = ytrain_res
self.y_test.to_frame()['lstm_res'] = ytest_res
# 对新语料进行推断
def inference(self, df, corpus: str):
sequences = self.tokenizer.texts_to_sequences(df[corpus]) # 将新数据转换为序列
paddings = pad_sequences(sequences, maxlen=50) # 填充序列
y_pred = self.clf.predict(paddings) # 进行预测
df['lstm'] = y_pred # 将预测结果添加到数据框
return df
#%% 实例化新的评估类
evals_nlp = nlp_evals_keras(df=labelled_data, # 定义语料库数据框
corpus='headline', # 定义语料库列
label='sentiment') # 定义标签列
evals_nlp.get_paddings() # 准备填充后的数值数据
evals_nlp.tts() # 将数据分割为训练和测试子集
evals_nlp.eval_tts() # 进行训练和测试评估
(2)下面代码的功能是实例化一个使用Keras构建的文本情感分析评估类nlp_evals_keras,并对文本数据进行预处理和模型评估。具体步骤包括准备填充后的数值数据、将数据分割为训练和测试子集,以及对模型进行训练和测试评估。
# 实例化新的评估类
evals_nlp = nlp_evals_keras(df=labelled_data, # 定义语料库数据框
corpus='headline', # 定义语料库列
label='sentiment') # 定义标签列
evals_nlp.get_paddings() # 准备填充后的数值数据
evals_nlp.tts() # 将数据分割为训练和测试子集
evals_nlp.eval_tts() # 进行训练和测试评估
执行后会输出:
train/test split!
Epoch 1/10
160/160 [==============================] - 19s 98ms/step - loss: 0.4008 - accuracy: 0.8058 - val_loss: 0.1556 - val_accuracy: 0.9449
Epoch 2/10
160/160 [==============================] - 16s 100ms/step - loss: 0.0604 - accuracy: 0.9824 - val_loss: 0.0942 - val_accuracy: 0.9716
Epoch 3/10
160/160 [==============================] - 15s 96ms/step - loss: 0.0194 - accuracy: 0.9951 - val_loss: 0.0975 - val_accuracy: 0.9689
Epoch 4/10
160/160 [==============================] - 16s 100ms/step - loss: 0.0099 - accuracy: 0.9973 - val_loss: 0.0949 - val_accuracy: 0.9716
Epoch 5/10
160/160 [==============================] - 15s 96ms/step - loss: 0.0053 - accuracy: 0.9988 - val_loss: 0.0978 - val_accuracy: 0.9716
Epoch 6/10
160/160 [==============================] - 16s 99ms/step - loss: 0.0033 - accuracy: 0.9990 - val_loss: 0.1091 - val_accuracy: 0.9701
Epoch 7/10
160/160 [==============================] - 15s 96ms/step - loss: 0.0067 - accuracy: 0.9984 - val_loss: 0.1013 - val_accuracy: 0.9701
Epoch 8/10
160/160 [==============================] - 16s 98ms/step - loss: 0.0023 - accuracy: 0.9996 - val_loss: 0.1251 - val_accuracy: 0.9695
Epoch 9/10
160/160 [==============================] - 16s 98ms/step - loss: 0.0023 - accuracy: 0.9994 - val_loss: 0.1187 - val_accuracy: 0.9692
Epoch 10/10
160/160 [==============================] - 15s 96ms/step - loss: 0.0033 - accuracy: 0.9992 - val_loss: 0.1278 - val_accuracy: 0.9698
267/267 [==============================] - 4s 15ms/step
30/30 [==============================] - 0s 13ms/step
0.9876803942273847 0.9725448785638859
通过上面的输出可知,我们基于LSTM的深度学习模型能够达到0.97的验证准确率。我们还要确保保存我们的嵌入数据,并尝试用更快速的机器学习模型来利用它。现在,让我们使用推断方法为我们的数据集创建情感标签,基于我们刚刚构建的深度学习模型。
(3)下面代码的功能是利用之前训练好的深度学习模型对数据集 ldf 中的 headline 列进行推断,生成情感标签,并展示结果的前几行。
# 使用深度学习模型对数据进行推断,生成情感标签
ldf = evals_nlp.inference(ldf, 'headline')
# 显示结果的前几行
ldf.head()
执行后会输出:
68/68 [==============================] - 1s 13ms/step
ticker headline date eventRet perc_sent lstm
0 AMZN Whole Foods (WFMI) -5.2% following a downgrade... 2011-05-02 0.031269 0 0
1 NFLX Netflix (NFLX +1.1%) shares post early gains a... 2011-05-02 0.012173 1 1
2 MSFT The likely winners in Microsoft's (MSFT -1.4%)... 2011-05-10 -0.007741 1 1
3 MSFT Microsoft (MSFT -1.2%) and Skype signed their ... 2011-05-10 -0.007741 0 0
5 AMZN Amazon.com (AMZN -1.7%) shares slip as comment... 2011-05-12 0.010426 0 1
标签:NLP,val,loss,self,30,train,维度,160,accuracy
From: https://blog.csdn.net/asd343442/article/details/143371304