您的位置:首页 > 其它

深度学习项目实战--对于评论的情感分析

2018-03-06 03:58 483 查看
标签: 机器学习

该项目通过分析影评进行判断该评价的情感方向

项目准备:

实现思想

实现效果

现在开始我们的项目代码
1.首先我们要读入影评与情感标签

2.引入需要使用的库

3.实现神经网络

最后开始对数据进行学习

通过测试对学习效果进行评定

将以上代码复制粘贴即可运行,可以看到学习效果,准确率高达85%

并且该代码对数据进行了清洗与筛选,对神经网络的结构做了结构优化

将100条每秒的数据处理提高到了7000条每秒

该项目通过分析影评进行判断该评价的情感方向

项目准备:

1. 关于影评的数据集

2. 关于影评的情感标签

3. python的各种运算库

关于影评的数据集与情感标签点击此处下载

运算库请自行下载



(好吧,图文无关)

实现思想

对影评的每一个单词进行提取,通过神经网络找到单词之间与情绪的联系,进而进行预测

实现效果

准确率达85%以上,运算速率可达7000条影评/秒



现在开始我们的项目代码

4000

1.首先我们要读入影评与情感标签

g = open('reviews.txt','r') # What we know!
reviews = list(map(lambda x:x[:-1],g.readlines()))
g.close()

g = open('labels.txt','r') # What we WANT to know!
labels = list(map(lambda x:x[:-1].upper(),g.readlines()))
g.close()


2.引入需要使用的库

from collections import Counter
import numpy as np
import time
import sys
import numpy as np


3.实现神经网络

class SentimentNetwork:
def __init__(self, reviews,labels,min_count = 10,polarity_cutoff = 0.1,hidden_nodes = 10, learning_rate = 0.1):

np.random.seed(1)

################神经网络的数据预处理#################
self.pre_process_data(reviews, labels, polarity_cutoff, min_count)

##########神经网络的数据初始化###########
self.init_network(len(self.review_vocab),hidden_nodes, 1, learning_rate)

###################################################
#############神经网络的数据预处理函数实现#############
###################################################

def pre_process_data(self, reviews, labels, polarity_cutoff, min_count):

###建立三个计数器分别对正面,负面,所有,进行计数
positive_counts = Counter()
negative_counts = Counter()
total_counts = Counter()

#对正面评论的单词进行计数
for i in range(len(reviews)):
if(labels[i] == 'POSITIVE'):
for word in reviews[i].split(" "):
positive_counts[word] += 1
total_counts[word] += 1
#对负面评价的单词进行计数
else:
for word in reviews[i].split(" "):
negative_counts[word] += 1
total_counts[word] += 1

###建立一个比率计数器
pos_neg_ratios = Counter()

###对正面与反面的评论单词的比率进行计数
###正面比率大则为正数,反面比率大则为负数
for term,cnt in list(total_counts.most_common()):
if(cnt >= 50):
pos_neg_ratio = positive_counts[term] / float(negative_counts[term]+1)
pos_neg_ratios[term] = pos_neg_ratio

for word,ratio in pos_neg_ratios.most_common():
if(ratio > 1):
pos_neg_ratios[word] = np.log(ratio)
else:
pos_neg_ratios[word] = -np.log((1 / (ratio + 0.01)))

###只对出现总次数大于min_count以及比率介于±polarity_cutoff之间的单词进行统计
review_vocab = set()
for review in reviews:
for word in review.split(" "):
if(total_counts[word] > min_count):
if(word in pos_neg_ratios.keys()):
if((pos_neg_ratios[word] >= polarity_cutoff) or (pos_neg_ratios[word] <= -polarity_cutoff)):
review_vocab.add(word)
else:
review_vocab.add(word)

#将词汇表转换为一个列表,这样我们就可以通过索引访问单词。
self.review_vocab = list(review_vocab)

# 对单词所对应的标签进行填充
label_vocab = set()
for label in labels:
label_vocab.add(label)

# 将标签词汇表转换为一个列表,这样我们就可以通过索引访问标签。
self.label_vocab = list(label_vocab)

#存储影评和标签词汇数组的大小。
self.review_vocab_size = len(self.review_vocab)
self.label_vocab_size = len(self.label_vocab)

#对索引的影评与标签重新编写字典
self.word2index = {}
for i, word in enumerate(self.review_vocab):
self.word2index[word] = i

self.label2index = {}
for i, label in enumerate(self.label_vocab):
self.label2index[label] = i

###################################################
##########神经网络的数据初始化的函数实现###############
###################################################

def init_network(self, input_nodes, hidden_nodes, output_nodes, learning_rate):
#输入层、隐藏层、输出层的节点数量
self.input_nodes = input_nodes
self.hidden_nodes = hidden_nodes
self.output_nodes = output_nodes

#学习速率
self.learning_rate = learning_rate

#权重初始化
self.weights_0_1 = np.zeros((self.input_nodes,self.hidden_nodes))
self.weights_1_2 = np.random.normal(0.0, self.output_nodes**-0.5,
(self.hidden_nodes, self.output_nodes))

#初始化隐藏层数据
self.layer_1 = np.zeros((1,hidden_nodes))

#############标签数字化##############
def get_target_for_label(self,label):
if(label == 'POSITIVE'):
return 1
else:
return 0

###############激活函数:sigmoid函数################
def sigmoid(self,x):
return 1 / (1 + np.exp(-x))

###############sigmoid函数的倒数################
def sigmoid_output_2_derivative(self,output):
return output * (1 - output)

###########################################################
###################训练函数代码实现########################
###########################################################

def train(self, training_reviews_raw, training_labels):

#标记条影评中每个出现的单词,对应在字典中记录下来作为输入层
training_reviews = list()
for review in training_reviews_raw:
indices = set()
for word in review.split(" "):
if(word in self.word2index.keys()):
indices.add(self.word2index[word])
training_reviews.append(list(indices))

# 确保每个影评都有且仅有一个标签与其对应
assert(len(training_reviews) == len(training_labels))

#记录预测正确的数量
correct_so_far = 0

# 记录时间
start = time.time()

#对每条影评学习的循环
for i in range(len(training_reviews)):

review = training_reviews[i]
label = training_labels[i]

#### 实现前向传播 ####

# 隐藏层的计算
self.layer_1 *= 0
for index in review:
self.layer_1 += self.weights_0_1[index]

# 输出层的计算
layer_2 = self.sigmoid(self.layer_1.dot(self.weights_1_2))

### 反向传播的实现 ###

# 输出误差计算
layer_2_error = layer_2 - self.get_target_for_label(label)
layer_2_delta = layer_2_error * self.sigmoid_output_2_derivative(layer_2)

# 反向传播误差计算
layer_1_error = layer_2_delta.dot(self.weights_1_2.T)
layer_1_delta = layer_1_error

# 更新权重
self.weights_1_2 -= self.layer_1.T.dot(layer_2_delta) * self.learning_rate

for index in review:
self.weights_0_1[index] -= layer_1_delta[0] * self.learning_rate # update input-to-hidden weights with gradient descent step

# 对预测情况进行判断
if(layer_2 >= 0.5 and label == 'POSITIVE'):
correct_so_far += 1
elif(layer_2 < 0.5 and label == 'NEGATIVE'):
correct_so_far += 1

# 对预测以及学习情况进行即时输出
elapsed_time = float(time.time() - start)
reviews_per_second = i / elapsed_time if elapsed_time > 0 else 0

sys.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):

#用于直接测试的函数,没有train函数的权重更新
correct = 0
start = time.time()
for i in ra
a84f
nge(len(testing_reviews)):
pred = self.run(testing_reviews[i])
if(pred == testing_labels[i]):
correct += 1

elapsed_time = float(time.time() - start)
reviews_per_second = i / elapsed_time if elapsed_time > 0 else 0

sys.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] + "%")
#################################################
####################run函数的实现################
#################################################
def run(self, review):

#该函数通过数据的前向传播直接输出预测结果

self.layer_1 *= 0
unique_indices = set()
for word in review.lower().split(" "):
if word in self.word2index.keys():
unique_indices.add(self.word2index[word])
for index in unique_indices:
self.layer_1 += self.weights_0_1[index]
layer_2 = self.sigmoid(self.layer_1.dot(self.weights_1_2))
if(layer_2[0] >= 0.5):
return "POSITIVE"
else:
return "NEGATIVE"


最后开始对数据进行学习

mlp = SentimentNetwork(reviews[:-1000],labels[:-1000],min_count=20,polarity_cutoff=0.8,learning_rate=0.01)
mlp.train(reviews[:-1000],labels[:-1000])


通过测试对学习效果进行评定

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


将以上代码复制粘贴即可运行,可以看到学习效果,准确率高达85%

并且该代码对数据进行了清洗与筛选,对神经网络的结构做了结构优化

将100条每秒的数据处理提高到了7000条每秒

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐