Project 3

  • 在Project 2中,我们构建并训练了一个两层的神经网络用于情感的分析,但是准确率不尽人意
  • 在这个Project中,我们将对问题进行分析,思考如何提高准确率

到底出了什么问题?

  • 总结来说,就是输入数据噪声太大了。这里的噪声是指那些对于输出没有任何价值的单词,比如the, an, of, on等等。这些单词属于中性词,对于判断Positive或者Negative没有任何帮助,并且这些词出现频率非常高,在统计个数时,这些词肯定比带有情绪的词个数要多。
  • 当这些中性的词占据了大部分的输入时,神经网络在训练的时候就会感到疑惑。它会这么想:label=1(positive)的时候,这些词出现了很多次,label=0(negative)的时候,这些词也出现了很多次,那这些词到底是正向词还是负向词呢?
  • 我们举一个例子来感受一下这些噪声的出现频率有多高
import numpy as np
import sys
import time
import pandas as pd
# 读取数据
reviews = pd.read_csv('reviews.txt', header=None)
labels = pd.read_csv('labels.txt', header=None)
from collections import Counter
positive_counter = Counter()
negative_counter = Counter()
total_counter = Counter()
for review, label in zip( reviews.values, labels.values ):word = review[0].split(' ')if label == 'positive':positive_counter.update(word)elif label == 'negative':negative_counter.update(word)total_counter.update(word)
positive_counter.most_common()
negative_counter.most_common()
  • 从positive_counter和negative_counter的统计结果来看,那些出现最多次的词都是噪声。真正有用词,例如happy,funny,horrible等出现次数并不多,但是却是非常重要的

如何解决

  • 一个直观的想法就是对训练数据进行预处理,将那些中性的词,无用的词进行剔除,只保留真正有用的词。
  • 嗯,想法不错,我们之后的Project也会这么做,但是在这里,我们给出另一种解决方法:降低中性词的权重
  • 回忆我们将文本数字化的步骤:
    1. 将输入的文本划分成一个一个的单词
    2. 统计每个单词出现的个数 count,
    3. 从word2idx中找到这个单词的位置,将count作为输入
  • 这么做确实将文本进行数字化,但是,中性单词,例如the,在一个review中出现次数是很多的,导致神经网络认为the这个单词很重要,因此我们需要降低中性单词的权重
  • 一种最简单的方法就是,我们不再以出现次数作为输入,而是只输入0或者1,0表示这个单词在review中没有出现,1表示出现。
  • 那么修改就非常简单了,将update_input_layer()中+=修改为=
class SentimentNetwork(object):def __init__(self, reviews, labels, hidden_nodes=10, learning_rate = 0.1):"""参数:reviews(dataFrame), 用于训练labels(dataFrame), 用于训练hidden_nodes(int), 隐层的个数learning_rate(double),学习步长"""np.random.seed(1)self.pre_process_data(reviews, labels)self.init_network(len(self.review_vocab), hidden_nodes, 1, learning_rate)def pre_process_data(self, reviews, labels):"""预处理数据,统计reviews中出现的所有单词,并且生成word2index"""# 统计reviews中出现的所有单词,review_vocab = set()for review in reviews.values:word = review[0].split(' ')review_vocab.update(word)self.review_vocab = list(review_vocab)# 统计labels中所有出现的label(其实在这里,就+1和-1两种)label_vocab = set()for label in labels.values:label_vocab.add(label[0])self.label_vocab = list(label_vocab)# 构建word2idx,给每个单词安排一个"门牌号"self.word2idx = dict()for idx, word in enumerate(self.review_vocab):self.word2idx[word] = idxdef init_network(self, input_nodes, hidden_nodes, output_nodes, learning_rate):"""初始化网络的参数"""self.learning_rate = learning_rateself.input_nodes = input_nodesself.hidden_nodes = hidden_nodesself.output_nodes = output_nodesself.weights_0_1 = np.random.normal( 0.0, self.input_nodes**-0.5, (self.input_nodes, self.hidden_nodes) )self.weights_1_2 = np.random.normal( 0.0, self.hidden_nodes**-0.5, (self.hidden_nodes, self.output_nodes) )self.layer_0 = np.zeros((1, self.input_nodes))def update_input_layer(self, review):"""对review进行数字化处理,并将结果存放到self.layer_0中,也就是输入层"""self.layer_0 *= 0for word in review.split(' '):if word.lower() in self.word2idx:idx = self.word2idx[word.lower()]# 在出现的单词位置设置为1,不再使用出现次数作为输入self.layer_0[0,idx] = 1# self.layer_0[0,idx] += 1def sigmoid(self, x):return 1 / (1 + np.exp(-x))def sigmoid_output_2_derivative(self, output):return output * (1 - output)def get_target_for_label(self,label):if label == 'positive':return 1else:return 0def train(self, training_reviews, training_label):assert(len(training_reviews) == len(training_label))correct_so_far = 0start = time.time()# 进行训练for i in range(len(training_reviews)):review = training_reviews.iloc[i,0]label = training_label.iloc[i,0]self.update_input_layer(review)layer_1_i = np.dot( self.layer_0, self.weights_0_1 )layer_1_o = layer_1_ilayer_2_i = np.dot( layer_1_o, self.weights_1_2 )layer_2_o = self.sigmoid( layer_2_i )layer_2_error = layer_2_o - self.get_target_for_label(label)layer_2_delta = layer_2_error * self.sigmoid_output_2_derivative(layer_2_o)layer_1_error = np.dot( layer_2_delta, self.weights_1_2.T )layer_1_delta = layer_1_error# 权重更新self.weights_1_2 -= np.dot(layer_1_o.T, layer_2_delta) * self.learning_rateself.weights_0_1 -= np.dot(self.layer_0.T, layer_1_delta) * self.learning_rateif(layer_2_o >= 0.5 and label=='positive'):correct_so_far += 1elif(layer_2_o < 0.5 and label=='negative'):correct_so_far += 1elapsed_time = float(time.time() - start)reviews_per_second = i / elapsed_time if elapsed_time > 0 else 0sys.stdout.write("\rProgress:" + str(100 * i/float(len(training_reviews)))[:4] \+ "% Speed(reviews/sec):" + str(reviews_per_second)[0:5] \+ " #Correct:" + str(correct_so_far) + " #Trained:" + str(i+1) \+ " Training Accuracy:" + str(correct_so_far * 100 / float(i+1))[:4] + "%")if(i % 2500 == 0):print("")def test(self, testing_reviews, testing_labels):assert(len(testing_reviews) == len(testing_labels))correct = 0start = time.time()for i in range(len(testing_reviews)):review = testing_reviews.iloc[i,0]label = testing_labels.iloc[i,0]pred = self.run(review)if pred == label:correct += 1elapsed_time = float(time.time() - start)reviews_per_second = i / elapsed_time if elapsed_time > 0 else 0sys.stdout.write("\rProgress:" + str(100 * i/float(len(testing_reviews)))[:4] \+ "% Speed(reviews/sec):" + str(reviews_per_second)[0:5] \+ " #Correct:" + str(correct) + " #Tested:" + str(i+1) \+ " Testing Accuracy:" + str(correct * 100 / float(i+1))[:4] + "%")def run(self, review):self.update_input_layer(review)layer_1_i = np.dot( self.layer_0, self.weights_0_1 )layer_1_o = layer_1_ilayer_2_i = np.dot( layer_1_o, self.weights_1_2 )layer_2_o = self.sigmoid( layer_2_i )            if layer_2_o >= 0.5:return 'positive'else:return 'negative'

训练

mlp = SentimentNetwork(reviews, labels, learning_rate=0.1)
mlp.train(reviews[:-1000], labels[:-1000])

Progress:0.0% Speed(reviews/sec):0.0 #Correct:1 #Trained:1 Training Accuracy:100.%
Progress:10.4% Speed(reviews/sec):103.6 #Correct:1952 #Trained:2501 Training Accuracy:78.0%
Progress:20.8% Speed(reviews/sec):104.3 #Correct:3999 #Trained:5001 Training Accuracy:79.9%
Progress:31.2% Speed(reviews/sec):104.4 #Correct:6119 #Trained:7501 Training Accuracy:81.5%
Progress:41.6% Speed(reviews/sec):103.3 #Correct:8277 #Trained:10001 Training Accuracy:82.7%
Progress:52.0% Speed(reviews/sec):102.9 #Correct:10435 #Trained:12501 Training Accuracy:83.4%
Progress:62.5% Speed(reviews/sec):102.9 #Correct:12574 #Trained:15001 Training Accuracy:83.8%
Progress:72.9% Speed(reviews/sec):102.8 #Correct:14689 #Trained:17501 Training Accuracy:83.9%
Progress:83.3% Speed(reviews/sec):102.1 #Correct:16861 #Trained:20001 Training Accuracy:84.3%
Progress:93.7% Speed(reviews/sec):102.0 #Correct:19051 #Trained:22501 Training Accuracy:84.6%
Progress:99.9% Speed(reviews/sec):101.9 #Correct:20371 #Trained:24000 Training Accuracy:84.8%

测试

mlp.test(reviews[-1000:], labels[-1000:])

Progress:99.9% Speed(reviews/sec):942.9 #Correct:858 #Tested:1000 Testing Accuracy:85.8%

End Project 3

  • 哇!准确率上80了!看来我们一个很简单的方法就能让效果提升非常多
  • 在下一个Project,我们将对现在这个网络进行加速,使得训练的速度能够大大加快

神经网络之文本情感分析(三)相关推荐

  1. 神经网络之文本情感分析(一)

    情感分析 Sentiment Analysis 本文主要是对优达学城 深度学习 第二部分卷积神经网络中Lesson2的一个总结,主要在代码层面 目标:利用BP神经网络判断一段影评是正面评价(Posit ...

  2. 神经网络之文本情感分析(二)

    Projet 2 在Project 1 中,我们学习了如何处理和统计reviews 基于上一个Project"一个萝卜一个坑"的思想,我们将文本进行了数字化,使得文本可以作为输入进 ...

  3. 神经网络之文本情感分析(四)

    Project 4 在Project 3中,我们对神经网络做了一丢丢的改变就使得准率上升了一大截 在这个Project中,我们将对神经网络进行改进,使得训练的速度更快. 如何实现呢?我们的网络存在很多 ...

  4. 基于LSTM三分类的文本情感分析,采用LSTM模型,训练一个能够识别文本postive, neutral, negative三种

    基于LSTM三分类的文本情感分析,采用LSTM模型,训练一个能够识别文本postive, neutral, negative三种 ,含数据集可直接运行 完整代码下载地址:基于LSTM三分类的文本情感分 ...

  5. NLP学习(十三)-NLP实战之LSTM三分类文本情感分析-tensorflow2+Python3

    背景介绍 文本情感分析作为NLP的常见任务,具有很高的实际应用价值.本文将采用LSTM模型,训练一个能够识别文本postive, neutral, negative三种情感的分类器. 本文的目的是快速 ...

  6. TensorFlow-RNN循环神经网络 Example 2:文本情感分析

    TensorFlow-RNN文本情感分析 之前用全连接神经网络写过一个文本情感分析 http://blog.csdn.net/weiwei9363/article/details/78357670 现 ...

  7. 文本情感分析-机器学习实验三

    情感分析-机器学习实验三 实验目的: 通过实验,掌握文本分析的整体流程,了解文本分类.情感分析.自动摘要等内容 通过给定的文本内容,完成分词.文本向量化.文本分类.情感分析等相关实验 实验可从文本分类 ...

  8. [深度学习TF2][RNN-LSTM]文本情感分析包含(数据预处理-训练-预测)

    基于LSTM的文本情感分析 0. 前言 1. 数据下载 2. 训练数据介绍 3. 用到Word2Vector介绍 wordsList.npy介绍 wordVectors.npy介绍 4 数据预处理 4 ...

  9. 让机器有温度:带你了解文本情感分析的两种模型

    摘要:本篇博文从模型和算法的视角,分别介绍了基于统计方法的情感分析模型和基于深度学习的情感分析模型. 文本情感分析(Sentiment Analysis)是指利用自然语言处理和文本挖掘技术,对带有情感 ...

最新文章

  1. Node搭建多人聊天室
  2. JavaScript设计模式系列四之外观模式(附案例源码)
  3. 标准C++的类型转换符:static_cast、dynamic_cast、reinterpret_cast和const_cast(转载)
  4. 【软件开发底层知识修炼】十 链接器-main函数不是第一个被执行的函数
  5. Python: 使用装饰器“@”取得函数执行时间
  6. volatile 和 atomic 原子性的区别和联系
  7. 翻译连载 | JavaScript轻量级函数式编程-第5章:减少副作用 |《你不知道的JS》姊妹篇...
  8. 【转】Intellij IDEA 14中使用MyBatis-generator 自动生成MyBatis代码
  9. 简单说说JAVA的String和byte[]的关系
  10. 实例变量,局部变量,全局变量,静态全局变量。
  11. Atitit 局部图查找大图 方法 与 说明
  12. 好用的小工具系列之---fastJson
  13. 详细设计的工具——程序流程图
  14. matlab交通标志神经网络识别,一种应用于交通标志识别的深度卷积神经网络方法与流程...
  15. 过采样之SMOTE算法
  16. preparedstatement mysql 数据_使用PreparedStatement对象操作数据库
  17. 正态性检验中的统计量D值和统计量W值如何计算?
  18. bzoj1127 洛谷3474 题解
  19. 时序分析模型——MMMC
  20. 基于字典爆破的子域名脚本

热门文章

  1. docker用gpu的参数_ZStack实践汇 | ZStack+Docker支撑GPU业务实践
  2. Java基础05 break和continue比较区别
  3. ROS中阶笔记(六):机器人感知—机器语音
  4. python彩票36选7_彩票开奖查询-极速数据【最新版】_API_金融_生活服务-云市场-阿里云...
  5. python协同过滤调用包_简单的python协同过滤程序实例代码
  6. 相同布局在不同手机上显示不同_React Native布局详细指南
  7. YApi--使用YApi的目的
  8. react 流程图框架_【赠书】Preact(React)核心原理详解Preact(React) 核心原理解析...
  9. 在JSP页面中,对同名的CHECKBOX的处理
  10. 报错,o.h.engine.jdbc.spi.SqlExceptionHelper : Data truncation: Data too long for column ‘verify_msg‘