【keras】4. IMDb网络电影数据集处理与LSTM情感分析

参考:《Tensorflow和keras-深度学习人工智能实践应用》
第13、14章
GitHub:点我

部分封装函数请看文章:【keras】1. MNIST手写数据集识别(重要)_myaijarvis notebook-CSDN博客

步骤

在这里插入图片描述

数据预处理

分析数据

import urllib.request # 下载文件
import os
import tarfile # 解压缩文件

# 下载数据集
url="http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz"
filepath=r"data/aclImdb_v1.tar.gz"
if not os.path.isfile(filepath): # 如果该路径下没有文件就下载
    result=urllib.request.urlretrieve(url,filepath)
    print('downloaded:',result)
# 解压文件
if not os.path.exists(r"data/aclImdb"):
    tfile=tarfile.open(filepath,'r:gz')
    result=tfile.extractall(r"data/")

读取数据

在这里插入图片描述


import re  # 正则

def rm_tags(text):
    re_tag=re.compile(r'<[^>]+>') # 剔除html标签
    return re_tag.sub('',text)
# 读取文件
import os

# filetype: train test
def read_file(filetype):
    path="data/aclImdb/"
    file_list=[]
    
    positive_path=path+filetype+'/pos/' # 正面评价的文件路径
    for f in os.listdir(positive_path):
        file_list+=[positive_path+f] # 加入所有文件
    
    negative_path=path+filetype+'/neg/'
    for f in os.listdir(negative_path):
        file_list+=[negative_path+f]
        
    print("read",filetype,"files:",len(file_list)) # 文件个数
    
    all_labels=([1]*12500 + [0]*12500) # 前12500 是正面 都为1 后面12500 是负面 都为0
    all_texts=[]
    
    # 读取所有文件
    for fi in file_list: 
        with open(fi,encoding="utf8") as file_input:
            # 先读取文件 使用join连接所有字符串 然后使用rm_tags剔除tag 最后加入all_texts
            all_texts.append(rm_tags("".join(file_input.readlines())))
    
    return all_labels,all_texts

在这里插入图片描述

y_train,train_text=read_file("train")
y_test,test_text=read_file("test")

y_train=np.array(y_train)
y_test=np.array(y_test)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
建立token字典

from tensorflow.python.keras.preprocessing.text import Tokenizer # 建立字典
# 建立 token
token=Tokenizer(num_words=2000) # 词典的单词数为2000
# 建立token词典
token.fit_on_texts(train_text) # 按单词出现次数排序 取前2000个

在这里插入图片描述
将影评文字转化为数字列表


# 将影评文字转化为数字列表(一条影评文字转化为一条数字列表)
x_train_seq=token.texts_to_sequences(train_text)
x_test_seq=token.texts_to_sequences(test_text)

在这里插入图片描述
对“数字列表”截长补短 ,全部弄成100位

from tensorflow.python.keras.preprocessing import sequence # 截长补短
# 截长补短
x_train=sequence.pad_sequences(x_train_seq,maxlen=100)
x_test=sequence.pad_sequences(x_test_seq,maxlen=100)

在这里插入图片描述

MLP

模型

# tf 2.0+   tensorflow.python  加个前缀
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras.layers.core import Dense,Dropout,Activation,Flatten
from tensorflow.python.keras.layers.embeddings import Embedding

model = Sequential([])
model.add(
    Embedding( # 将数字列表转换成词向量
        output_dim=32 # 将每一个数字列表里面的数字都转换成32维向量,即一个单词用32维词向量表示
        ,input_dim=2000 # 输入维数 字典词数2000
        ,input_length=100 # 每个数字列表有100个数字  相当于用100个数字去表示一条评论
    )
)
model.add(Dropout(0.35))
model.add(Flatten()) # 将输入“压平”,即把多维的输入一维化 共有32*100=3200个
model.add(Dense(
    units=256 # 神经元节点数
    ,activation="relu" # 激活函数
))# 隐藏层
model.add(Dropout(0.35))
model.add(Dense(
    units=1 # 输出 1表示正面评价 0表示负面评价
    ,activation='sigmoid'
))

model.summary() # 模型摘要
# 配置
model.compile(
    loss="binary_crossentropy" # 损失函数
    ,optimizer='adam' # 优化器
    ,metrics=['accuracy'] # 评估
)
# 训练
train_history=model.fit(
    x=x_train
    ,y=y_train
    ,validation_split=0.2 # 验证集占20%
    ,epochs=10 # 训练10个周期
    ,batch_size=100 # 每一批次训练100项数据 一个周期大概训练20000/100=200批次
    ,verbose=1
)
'''
verbose:日志显示
verbose = 0 为不在标准输出流输出日志信息
verbose = 1 为输出进度条记录
verbose = 2 为每个epoch输出一行记录
注意: 默认为 1
'''

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

评估

scores=model.evaluate(
    x_test
    ,y_test
    ,batch_size=100 # 一批次使用100个样本 共训练25000/100=250批次
    ,verbose=1) 
print(scores)

250/250 [==============================] - 2s 8ms/step - loss: 0.6740 - accuracy: 0.8614
[0.6740041375160217, 0.8614000082015991]

print('Test loss:', scores[0])
print('Test accuracy:', scores[1])

Test loss: 0.7183531522750854
Test accuracy: 0.8219599723815918

预测

predict=model.predict_classes(x_test) # 预测的是类别,打印出来的值就是类别号

在这里插入图片描述

predict_calsses_vector=predict.reshape(-1) # 转为一维数组
predict_calsses_vector[:10]

array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

SentimentDict={1:'正面的',0:'负面的'}

def display_test_Sentiment(i):
    print('影评:',test_text[i])
    print(f'真实值:{SentimentDict[y_test[i]]} \n预测值:{SentimentDict[predict_calsses_vector[i]]}')

在这里插入图片描述

预测其他评论 ***

# 封装函数

def predict_review(input_text):
	# 将影评文字转换为数字列表
    input_seq=token.texts_to_sequences([input_text])
    # 截断或者填充至100
    pad_input_seq=sequence.pad_sequences(input_seq,maxlen=100)
    predict_result=model.predict_classes(pad_input_seq) # predict_result是二维的
    print(SentimentDict[predict_result[0][0]])
    
# 差评
# 将近300元买的杜比首映场,是真的不值。除了花里胡哨的特效外,一无是处,没有插科打诨和反高潮冷笑话,漫威就不会拍电影啦?花了十年塑造的人物形象性格在本作随意全部推翻,每个人所做的决策都不计后果,意气用事,幼稚且儿戏。巨作难逃烂尾,或许真的是个定律。 
bad_text='''
Nearly 300 yuan for a Dolby premiere is really not worth it. Nothing but fancy special effects, and without gags and anti-climax dry jokes, marvel wouldn't make a movie? The characters that took ten years to build are overthrown at will, and everyone's decisions are reckless, emotional, childish and playful. It may be the rule that a blockbuster ends badly.
'''
predict_review(bad_text)

负面的

加大词典

加大词典,增加预测准确度

这里只放修改的地方


token=Tokenizer(num_words=3800) # 词典的大小改为3800
token.fit_on_texts(train_text)
...
x_train=sequence.pad_sequences(x_train_seq,maxlen=380) # 长度改为380
x_test=sequence.pad_sequences(x_test_seq,maxlen=380)
...
model = Sequential()
model.add(Embedding(
    output_dim=32
    ,input_dim=3800 # 修改
    ,input_length=380 # 修改
))

RNN

模型

from tensorflow.python.keras.layers.recurrent import SimpleRNN

model=Sequential()
model.add(Embedding(output_dim=32,input_dim=3800,input_length=380))
model.add(Dropout(0.35))

model.add(SimpleRNN(16)) # RNN

model.add(Dense(units=256,activation='relu'))
model.add(Dropout(0.35))
model.add(Dense(units=1,activation='sigmoid'))
model.summary()

model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
train_history=model.fit(
    x=x_train
    ,y=y_train
    ,validation_split=0.2
    ,epochs=10
    ,batch_size=100 # 每一批次训练100项数据 一个周期大概训练20000/100=200批次
    ,verbose=1
)

在这里插入图片描述

评估


scores=model.evaluate(x_test,y_test) # 默认batch_size=32  25000/32=782

print('accuracy=',scores[1])

782/782 [==============================] - 4s 5ms/step - loss: 0.8148 - accuracy: 0.8408
accuracy= 0.8407999873161316

可以自己用评论去预测一下

LSTM

在这里插入图片描述
在这里插入图片描述

模型

from tensorflow.python.keras.layers.recurrent import LSTM

model=Sequential()
model.add(Embedding(output_dim=32,input_dim=3800,input_length=380))
model.add(Dropout(0.35))
model.add(LSTM(32))
model.add(Dense(units=256,activation='relu'))
model.add(Dropout(0.35))
model.add(Dense(units=1,activation='sigmoid'))
model.summary()

# 这里训练比较慢 可以要花几分钟
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
train_history=model.fit(x=x_train,y=y_train,validation_split=0.2,epochs=10,batch_size=100,verbose=1)
scores=model.evaluate(x_test,y_test)
print('accuracy=',scores[1])

782/782 [==============================] - 22s 28ms/step - loss: 0.4828 - accuracy: 0.8532
accuracy= 0.8532400131225586

可以自己用评论去预测一下

  • 8
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用循环神经网络(RNN)对IMDB电影评论数据集进行文本情感分类的代码: ```python import tensorflow as tf from tensorflow.keras.datasets import imdb from tensorflow.keras.layers import Embedding, LSTM, Dense from tensorflow.keras.models import Sequential from tensorflow.keras.preprocessing import sequence # 设置超参数 max_features = 20000 # 只考虑最常见的20,000个单词 max_len = 80 # 每个评论最多包含80个单词 embedding_size = 128 # 词向量的维度 # 加载IMDB电影评论数据集 (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) # 对数据进行预处理 x_train = sequence.pad_sequences(x_train, maxlen=max_len) x_test = sequence.pad_sequences(x_test, maxlen=max_len) # 构建模型 model = Sequential() model.add(Embedding(max_features, embedding_size, input_length=max_len)) model.add(LSTM(units=128)) model.add(Dense(units=1, activation='sigmoid')) # 编译模型 model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # 训练模型 model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test)) ``` 这个代码中,我们首先导入了所需的库和类。然后,我们设置了一些超参数,包括每个评论最多包含的单词数、词向量的维度和我们要考虑的最常见的单词数。 接下来,我们使用 `imdb.load_data()` 函数从Keras中加载IMDB电影评论数据集,并将其分成训练集和测试集。 然后,我们对数据进行了预处理,使用 `sequence.pad_sequences()` 函数将每个评论的长度统一设置为 `max_len`,并使用零值填充序列。 接着,我们构建了一个简单的RNN模型,包括一个嵌入层、一个LSTM层和一个全连接层。我们使用 `model.compile()` 函数来编译模型,指定了损失函数、优化器和评价指标。 最后,我们使用 `model.fit()` 函数来训练模型,并在测试集上进行了验证。在这个例子中,我们将模型训练了5个epoch,使用批大小为32。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值