RNN学习:利用LSTM,GRU解决航空公司评论数据预测问题

文章目录

  • RNN学习:利用LSTM,GRU解决航空公司评论数据预测问题
    • 1.RNN的介绍
      • 1.1 LSTM的简单介绍
      • 1.2 GRU的简单介绍
    • 2.数据集的介绍
    • 3.读取数据并作预处理
    • 4.模型的搭建
    • 结语

1.RNN的介绍

​ RNN,即循环神经网络,即一般的神经网络同层节点与节点之间并无连接,比如CNN隐藏单元之间并没有连接,那么这相对于一些序列问题上的处理就会效果很差。如翻译单词,全文的意思必须是根据所有单词来进行判断。或判断说话人情绪,评论好坏,最终的输出要和前面所有的输入发生关系,所以这里学者们提出循环神经网络,让上一个节点会对下一个节点传递状态向量,每个节点之间输出两个值,一个是我们要的输出,还有一个就是状态向量,该向量输入下一个下一个节点,最终输出为二维数据(None,units)units为RNN的隐藏单元数。

1.1 LSTM的简单介绍

​ 刚才我们说明了RNN会不断的向下一个节点传递状态,但是经过长时间的多次传递,最终传递的状态可能会引起梯度爆炸或梯度消失等问题,为了解决这个问题,学者们又提出了LSTM层来解决这个问题,LSTM层的内部存在一些门,他会通过训练门的参数控制了上一状态我们需要遗忘多少,并且在这一层状态的更新。

可以看到在这一个单元中上一层的输出ht-1和状态Ct-1都传递了进来从而经过我们的门来控制该单元遗忘并更新状态。

1.2 GRU的简单介绍

GRU是LSTM结构的一种变体,他可以做到与LSTM性能相当的情况下,计算量会比LSTM减少,他的网络结构如下

可以看到他作为LSTM的变体,与LSTM的相似之处,他也会有前一次的状态(但是不会有前一层的输出传入)向他传入并且通过训练控制前一次状态在本单元的遗忘与更新。

2.数据集的介绍

本次使用的是Twitter 美国航空公司情绪:2015年2月美国航空公司的Twitter数据,分类为正面,负面和中性推文(https://www.kaggle.com/crowdflower/twitter-airline-sentiment)

整个数据集使用CSV格式存储,这种文件格式是一种经常用来数据科学存储数据的纯文本文件,可以用EXCEL直接打开。

可以看到该数据集上有该评价的好坏有neural,positive,negative三种,关于评价的具体 文本是text下的,我们在此次任务中只会用到评价文本(作为数据),情绪好坏作为我们的标签,也就是真值。

3.读取数据并作预处理

​ 首先先清楚我们的目标在预处理过程,是想要提取一个序列(这个序列是由我们的评论转换的),和一个标签(标签也要数字化),那么我们接下来就开始从CSV格式文件中提取文本和标签并分别将他们转化成序列和数字。

import tensorflow as tf
keras=tf.keras
layers=keras.layers
import numpy as np
import pandas as pd
import re
data=pd.read_csv('../input/twitter-airline-sentiment/Tweets.csv')
data.head()#文件内部数据太多使用这个默认查看前五行

然后我们此次只需要提取每个人评论的text,和评论观点的倾向,所以我们提取以下两列

data=data[['airline_sentiment','text']]
data.head()

我们成功提取每个评论的情绪,和文本,接下来我们先将情绪用数字表示,可以先查看有多少种情绪

data.airline_sentiment.value_counts()#使用该方法可以查看每个值的个数
negative    9178
neutral     3099
positive    2363
Name: airline_sentiment, dtype: int64

可以看到这里有三个倾向的情绪,消极,中立,积极,那么也就是说这是一个多分类单标签问题,那么我们直接对每个情绪进行编码然后转化即可

sentiment_to_index={'positive':0,'neutral':1,'negative':2}
def to_index(sentiment):#写函数来转化return sentiment_to_index.get(sentiment)
data['sentiment']=data.airline_sentiment.apply(to_index)
del data['airline_sentiment'] #删除原有的一列
data.head()

可以看到我们的标签被成功的转化成对应的数字标签。

并且我们还要注意一点,消极的评论远远多余积极的评论,我们在训练分类问题上最好是将每个类别上的数据的数量都保持一致,防止模型对于某些分类的特征过分学习。也就是说我们在这里使用消极和中立的数量都必须被降为和积极一样,那么这里我们就直接使用切片,对于series数据切片使用iloc函数

data_positive=data[data.airline_sentiment=='positive']
data_negative=data[data.airline_sentiment=='negative']
data_neutral=data[data.airline_sentiment=='neutral']
data_negative=data_negative.iloc[:len(data_positive)]
data_neutral=data_neutral.iloc[:len(data_positive)]
len(data_negative),len(data_neutral),len(data_positive)(2363, 2363, 2363) #可以看到我们将三个数据全部转化为相同个数

那么接下来我们合并我们的这些数据并且使用sample方法随机打乱(sample的用法是从原有数据随机抽出一部分数据,但是如果我们把抽出数据的规模等于所有数据,就相当于打乱)

data=pd.concat([data_negative,data_positive,data_neutral])
data=data.sample(len(data))  #smaple的意思是从dataframe中随机抽取指定数量的数据
data.head()

那么接下来我们就将每个文本转化为一个序列,怎么转化呢,其实很简单,那就是将每个句子里的单词映射成一个数字,那么整个句子就成为了一个数字序列,那么如何来完成了,接下来我们开始贴代码

token=re.compile('[A-Za-z]+|[!?,.()]')
#我们设置匹配的时候不要特殊字符,只要标点符号和字母,并且大小写不会影响单词原意,我这里也直接将所有大写转化成小写
def constractor_text(text):res_text=token.findall(text)res_text=[word.lower() for word in res_text]return res_text
#上面是使用re库提供的一个正则匹配方法在除去特殊符号其他均匹配情况下效果显著
new_data=data.text.apply(constractor_text)
data['text']=new_data
data.head()

那么接下里我们将单词全部映射成一个个数字其实想法很简单,先做一个集合将所有单词添加进集合吗,由于集合本身的特性,会自动删除重复的,然后我们将该集合中的单词转化成字典,就可以将单词转化成序列了,这里也简单的贴代码

word_list=list(word_set) #因为集合并没有下标这个概念,所以为了后面的方便我们转化成列表
word_dict=dict((k,v+1) for v,k in enumerate(word_list))
word_dict#同时为了防止填充单词之后填充0影响结果我们将所有数据,转化
{'win': 1,'DEFINITELY': 2,'gfc': 3,'OI': 4,'pearl': 5,'briughy': 6,'necessity': 7,'flyingwithUS': 8,'agreement': 9,...

这里需要非常注意的一点就是,每个评论的数据都是有一定长度的,但最后为了规范化我们一定是要将所有评论长度都处理到相同长度,那么我们填充的数字一般用0来填充,所以我们在字典里不能对0进行赋值,防止影响结果,所以我这里将所有单词对应的编号加一。可以看到我们单词编号从一开始。

好的有了单词的转换表,那么我们接下来编写函数将句子转换成序列

def word_to_vector(text):vector=[word_dict.get(word,0) for word in text]return vector
data['text']=data.text.apply(word_to_vector)
data_text=data['text']
data_text.head()8263    [3228, 11239, 9075, 694, 1133, 4364, 10324, 10...
4953    [1721, 11079, 870, 10, 11285, 9390, 10642, 724...
5489    [1721, 443, 6165, 4999, 4859, 4806, 7367, 7013...
2452    [3436, 10200, 6758, 10, 310, 1660, 8275, 10324...
8219    [3228, 11460, 10774, 10324, 1291, 6804, 516, 7...
Name: text, dtype: object

这里我们可以看到每个句子就都被转换为对应的序列,那么我们接下里将所有向量处理成完全一样的长度,

maxlen=max(len(x) for x in data_text)
max_word=len(word_set)+1
data_text=keras.preprocessing.sequence.pad_sequences(data_text.values,maxlen=maxlen)
data_text.shape
(7089, 40)

可以看到每个序列都被填充到了长度为40,那么我们接下来提取标签然后制作dataset,划分测试集与训练集

label=data.sentiment.values
test_count=int(7089*0.2)
train_count=7089-test_count
test_data=train_data.take(test_count)
train_data=train_data.skip(test_count)
train_data=train_data.shuffle(train_count).repeat().batch(64)
test_data=test_data.batch(64)

划分完毕后我们总算是完成了我们数据的预处理,接下来开始我们模型的搭建。

4.模型的搭建

我们输入的是一个长度为40的序列,但这样并不适合我们模型对他的处理,对此已经有提出词嵌入方法,WORD2VEC的方法,即将每个单词转化成固定维度的向量,向量之间差的大小,表示每个单词之间关系的大小(我理解为单词之间的相似性),这里我们可以用RGB表示颜色的方式来理解,每个颜色的值都可以用一个三维向量来表示,对于单词就是我们设置一个几十个维度的词向量,假设所有词都可以用这个高维向量来表示,那么具体怎么转换,有多种方法,我们这里使用keras提供的embelding层来将所有单词转换成我们设定维度的向量

model=keras.Sequential()
#Embedding层可以吧文本映射为一个密集向量
model.add(layers.Embedding(max_word,50,input_length=maxlen))
#然后我们多次未见的主角GRU登场,用它来处理这种序列数据效果是十分好的
model.add(layers.GRU(64))#LSTM的参数是一个隐藏单元数
model.add(layers.Dense(3,activation='softmax'))
#最后输出这是一个三分类的问题,所以我们激活函数用softmax
model.compile(optimizer=keras.optimizers.Adam(0.0001),loss='sparse_categorical_crossentropy',metrics=['acc'])
#设置模型的优化器这里没什么好说的

5.训练结果分析与网络调整

model.fit(train_data,steps_per_epoch=train_count//64,epochs=10,validation_data=test_data,validation_steps=test_count//64)

这里我们开始训练查看结果却发现

网络已经达到严重过拟合,测试集准确率极高,但验证集却非常低,两者相差达到20%,那么为了抑制过拟合我这里采取两种方法一是增加网络深度,添加Dropout层抑制过拟合

model=keras.Sequential()
#Embedding层可以吧文本映射为一个密集向量
model.add(layers.Embedding(max_word,50,input_length=maxlen))
model.add(layers.GRU(64))#LSTM的参数是一个隐藏单元数
model.add(layers.Dropout(0.2))
model.add(layers.Dense(32,activation='relu'))
model.add(layers.Dropout(0.2))
model.add(layers.Dense(16,activation='relu'))
model.add(layers.Dense(3,activation='softmax'))

,二是我将数据增加一倍,(等于是复制了一遍数据再,打乱),最终数据翻倍达到14000多条那么我们再次开始训练,查看结果

Epoch 15/15
177/177 [==============================] - 6s 34ms/step - loss: 0.0542 - acc: 0.9852 - val_loss: 0.1551 - val_acc: 0.9592

可以看到在训练最后,过拟合被抑制了,模型无论在训练集,测试集都达到了极高的正确率

结语

本篇博客简单介绍了RNN网络,并且非常具体的展示了如何从CSV文件读取数据,预处理并制作成模型可以接收的数据,在最后利用GRU搭建模型,并且对于训练结果产生过拟合如何去抑制方面做了处理,如果有任何建议或者问题欢迎评论区指出,谢谢!

RNN学习:利用LSTM,GRU层解决航空公司评论数据预测问题相关推荐

  1. DL之LSTM之MvP:基于TF利用LSTM基于DIY时间训练csv文件数据预测后100个数据(多值预测)状态

    DL之LSTM之MvP:基于TF利用LSTM基于DIY时间训练csv文件数据预测后100个数据(多值预测)状态 目录 数据集csv文件内容 输出结果 设计思路 训练记录全过程 数据集csv文件内容 输 ...

  2. DL之LSTM之UvP:基于TF利用LSTM基于DIY时间训练1200个数据预测后200个数据状态

    DL之LSTM之UvP:基于TF利用LSTM基于DIY时间训练1200个数据预测后200个数据状态 目录 输出结果 设计思路 训练记录全过程 输出结果 设计思路 训练记录全过程 INFO:tensor ...

  3. DL之LSTM:基于《wonderland爱丽丝梦游仙境记》小说数据集利用LSTM算法(层加深,基于keras)对单个character字符预测

    DL之LSTM:基于<wonderland爱丽丝梦游仙境记>小说数据集利用LSTM算法(层加深,基于keras)对单个character字符预测 目录 基于<wonderland爱丽 ...

  4. DL之LSTM/GRU/CNN:基于tensorflow框架分别利用LSTM/GRU、CNN算法对上海最高气温(数据归一化+构造有监督数据集)实现回归预测案例

    DL之LSTM/GRU/CNN:基于tensorflow框架分别利用LSTM/GRU.CNN算法对上海最高气温(构造有监督数据集)实现回归预测案例 目录 基于tensorflow框架分别利用LSTM/ ...

  5. 航空公司大数据的“钱景”猜想

    目前,在国内航空市场上,绝大部分服务是免费的,航企正在逐步寻求服务收费的方法.然而,现阶段的付费服务还不"叫座",只有找到旅客最想要的服务,才是诉求. 正视数据,运用数据,航企大数 ...

  6. RNN及其变种LSTM/GRU/SRU

    1. RNN ht=σ(W(hh)ht−1+W(hx)x[t])(5)h_t=\sigma(W^{(hh)}h_{t-1}+W^{(hx)}x_{[t]}) \tag{5} ht​=σ(W(hh)ht ...

  7. 航空公司大数据建设的思考

    ZDNET至顶网CIO与应用频道 10月13日 北京消息:主题为"科技整合·智汇航行"的2014年航空用户大会在青岛召开,文思海辉首席架构师李飞介绍了目前大数据的趋势以及航空领域的 ...

  8. requests 可以 scrapy 不行_python学习教程,B站博人传评论数据抓取 scrapy

    点击蓝字"python教程"关注我们哟! 1. B站博人传评论数据爬取简介 今天想了半天不知道抓啥,去B站看跳舞的小姐姐,忽然看到了评论,那就抓取一下B站的评论数据,视频动画那么多 ...

  9. 爬虫学习笔记:天猫(淘宝)评论数据爬虫

    目录 1.杂语 2.目的和方法 2.1 目的 2.2 爬虫方法 step1:获取cookie信息与评论url地址 step2:获取请求头信息user-agent step3:查看评论数据 step4: ...

  10. 【一起入门NLP】中科院自然语言处理第5课-循环神经网络RNN(BPTT+LSTM+GRU)

    专栏介绍:本栏目为 "2021秋季中国科学院大学胡玥老师的自然语言处理" 课程记录,不仅仅是课程笔记噢- 如果感兴趣的话,就和我一起入门NLP吧

最新文章

  1. OD调试9—实例:深入分析代码完成软件破解
  2. Objective-C中@property的所有属性详解
  3. 谷歌浏览器有哪些好看的主题_Kibou 简洁的Typecho主题
  4. 比特币中的密码学知识汇总
  5. 释放广域网潜能的“简单”之道
  6. 外媒:欧盟针对谷歌语音助手展开反垄断调查
  7. 《网络工程师考试 考前冲刺预测卷及考点解析》复习重点
  8. android日历便签,安卓手机上有日历与便签结合的app吗?
  9. 高接低挡,Isilon三款新品铺开战线
  10. el-table样式美化
  11. 我的第一个博客:爬取豆瓣top250电影名
  12. c语言中calloc是什么意思,calloc(c语言calloc是什么意思)
  13. 跨考计算机要选择408吗,408难度比较大,对于跨考更是如此,应从以下三个方面做准备...
  14. Java不同字符使用下划线分隔_004_Java语言基础(a-变量)
  15. kindle中html笔记,大神教你用Kindle做笔记,事半功倍的方法来了!
  16. [SHOI2008]小约翰的游戏John(博弈+SJ定理)
  17. Spark累加器的作用和使用
  18. 【简易搭建个人博客】------- 基于BT面板的个人博客搭建
  19. 两种经过验证的设计相结合:带有低温探针台的 8425 型直流霍尔系统
  20. 安装和使用所见即所得WYSIWYG的 Web 创作软件 BlueGriffon

热门文章

  1. C语言之for循环应用之断案篇----找凶手
  2. Hive实战之Youtube数据集
  3. Spring事务(Transaction)
  4. aes ccm模式 java_AES_GCM和AES_CCM的选择
  5. u盘插上电脑显示计算机无响应,为什么u盘连接电脑没反应,u盘在电脑上显示不出来...
  6. Python之字体反爬详细操作
  7. excel面板,快捷键,一些实用技巧,最多多少行数据?
  8. grid lightbox gallery
  9. @SpringBootApplication(exclude={DataSourceAutoConfiguration.class})的应用场景
  10. webpack ——css兼容性处理