使用lstm对IMDB的电影评论数据进行情感分析(pytorch代码)
接下来让我们看看如何使用pytorch实现一个基于长短时记忆网络的情感分析模型。在飞桨中,不同深度学习模型的训练过程基本一致,流程如下:
数据处理:选择需要使用的数据,并做好必要的预处理工作。
网络定义:使用飞桨定义好网络结构,包括输入层,中间层,输出层,损失函数和优化算法。
网络训练:将准备好的训练集数据送入神经网络进行学习,并观察学习的过程是否正常,如损失函数值是否在降低,也可以打印一些中间步骤的结果出来等。
网络评估:使用测试集数据测试训练好的神经网络,看看训练效果如何。
import numpy as np
import torch
import pandas as pd
import torch.nn as nn
import torch.nn.functional as F
import re#正则表达式
import string#字符串处理
import seaborn as sns#绘制热力图
from nltk.corpus import stopwords#停用词
from collections import Counter#词频统计
from sklearn.model_selection import train_test_split#数据集划分
from tqdm import tqdm#进度条
import matplotlib.pyplot as plt
from torch.utils.data import TensorDataset, DataLoader
is_cuda=torch.cuda.is_available()
if is_cuda:
device=torch.device("cuda")
print("GPU is available")
else:
device=torch.device("cpu")
print("CPU is available")
CPU is available
首先,需要下载语料用于模型训练和评估效果。我们使用的是IMDB的电影评论数据,这个数据集是一个开源的英文数据集,由训练数据和测试数据组成。每个数据都分别由若干小文件组成,每个小文件内部都是一段用户关于某个电影的真实评价,以及观众对这个电影的情感倾向(是正向还是负向)
base_csv=r'E:\kaggle\情感分析\archive (1)\IMDB Dataset.csv'
df=pd.read_csv(base_csv)
df.head()#查看前五行数据
review | sentiment | |
---|---|---|
0 | One of the other reviewers has mentioned that ... | positive |
1 | A wonderful little production. <br /><br />The... | positive |
2 | I thought this was a wonderful way to spend ti... | positive |
3 | Basically there's a family where a little boy ... | negative |
4 | Petter Mattei's "Love in the Time of Money" is... | positive |
X,y=df['review'].values,df['sentiment'].values#数据集划分,review为内容,sentiment为标签
x_train,x_test,y_train,y_test=train_test_split(X,y,stratify=y)#数据集划分,按照y的比例进行划分
print('train size:{},test size:{}'.format(len(x_train),len(x_test)))#查看数据集划分情况
train size:37500,test size:12500
dd = pd.Series(y_train).value_counts()#统计每个类别的数量
sns.barplot(x=np.array(['negative','positive']),y=dd.values)#绘制条形图
plt.show()
def preprocess_string(s):
# 删除所有非单词字符(除数字和字母外的所有字符)
s = re.sub(r"[^\w\s]", '', s)
# 将所有空格替换为无空格
s = re.sub(r"\s+", '', s)
# 用无空格的数字代替
s = re.sub(r"\d", '', s)
return s
def tockenize(x_train,y_train,x_val,y_val):
word_list=[]#初始化词汇表
stop_words=set(stopwords.words('english'))#获取停用词
for sent in tqdm(x_train):#遍历训练集
for word in sent.lower().split():#遍历单词
word=preprocess_string(word)#预处理
if word not in stop_words and word !='' and word !=' ':#去除停用词
word_list.append(word)#将单词存储在word_list中
corpus=Counter(word_list)#统计词频
corpus_=sorted(corpus,key=corpus.get,reverse=True)[:1000]#取前1000个词频最高的词,进行排序
onehot_dict= {
w:i for i,w in enumerate(corpus_)}#建立词到数字的映射{词:数字}的字典
final_list_train,final_list_test=[],[]#初始化训练集和测试集
for sent in x_train:
final_list_train.append([onehot_dict[preprocess_string(word)] for word in sent.lower().split()
if preprocess_string(word) in onehot_dict.keys()])
'''
再次遍历训练集的每个句子,使用 onehot_dict 将句子中的每个单词转换为对应的整数索引,
并创建一个标记化列表,同理遍历测试集
'''
for sent in x_val:
final_list_test.append([onehot_dict[preprocess_string(word)] for word in sent.lower().split()
if preprocess_string(word) in