1、数据集
提到负面评论,我们首先要了解“网络水军”,本章主要以IMDB数据集为例介绍负面评论的识别技术。测试的数据来自互联网电影资料库(Internet Movie Database , IMDB),IMDB是一个关于电影演员、电影、电视节目、电视明星和电影制作的在线数据库。整个数据集一共有10万条记录,5万做了标记,5万没有做标记。5万做了标记的数据集被随机分配成了训练数据集和测试数据集。
IMDB文件夹下一级目录主要包含训练数据集和测试数据集两个文件夹,
IMDB文件夹二级目录主要包含3个目录,分别为正面评论、负面评论和未标识。
IMDB数据的下载地址为:http://ai.stanford.edu/~amaas/data/sentiment/
2、特征提取
负面评论使用的特征提取方法有:词袋和TF-IDF模型、词汇表模型、Word2Vec和Doc2Vec模型。我们使用最常见的词袋模型提取文件特征。把一个评论文件作为一个完整的字符串处理,定义函数load_one_file加载文件到一个字符串变量中返回:
def load_one_file(filename):
x=""
with open(filename, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
line=line.strip('\n')
line = line.strip('\r')
x+=line
f.close()
return x
遍历目录,加载目录下全部文件,以字符串集合的形式返回:
def load_files_from_dir(rootdir):
x=[]
list = os.listdir(rootdir)
for i in range(0, len(list)):
path = os.path.join(rootdir, list[i])
if os.path.isfile(path):
v=load_one_file(path)
x.append(v)
return x
分别加载训练数据集目录下的正面评论和负面评论目录下所有文件,同时进行标记,正面评价0,负面评价1.
path="C:/Users/Administrator\PycharmProjects/tensortflow快速入门/tensorflow_study\MNIST_data_bak\负面评论acllmdb数据集/train/pos/"
print("Load %s" % path)
x_train=load_files_from_dir(path)
y_train=[0]*len(x_train)
path="C:/Users/Administrator\PycharmProjects/tensortflow快速入门/tensorflow_study\MNIST_data_bak\负面评论acllmdb数据集/train/neg/"
print("Load %s" % path)
tmp=load_files_from_dir(path)
y_train+=[1]*len(tmp)
x_train+=tmp
分别加载测试数据集目录下的正面评论和负面评论目录下所有文件,同时进行标记,正面评价0,负面评价1.
path="C:/Users/Administrator\PycharmProjects/tensortflow快速入门/tensorflow_study\MNIST_data_bak\负面评论acllmdb数据集/test/pos/"
print("Load %s" % path)
x_test=load_files_from_dir(path)
y_test=[0]*len(x_test)
path="C:/Users/Administrator\PycharmProjects/tensortflow快速入门/tensorflow_study\MNIST_data_bak\负面评论acllmdb数据集/test/neg/"
print("Load %s" % path)
tmp=load_files_from_dir(path)
y_test+=[1]*len(tmp)
x_test+=tmp
使用Scikit-Learn的CountVectorizer对象进行词袋化处理,同时将抽取的词汇表保存,用于词袋化测试数据集。词汇表保存在CountVectorizer对象的Vocabulary属性中,初始化CountVectorizer对象。
x_train, x_test, y_train, y_test=load_all_files()
vectorizer = CountVectorizer(
decode_error='ignore',
strip_accents='ascii',
max_features=max_features,
stop_words='english',
max_df=1.0,
min_df=1 )
print(vectorizer)
x_train=vectorizer.fit_transform(x_train)
x_train=x_train.toarray()
vocabulary=vectorizer.vocabulary_
复用Vocabulary对测试数据集进行词袋化处理,其中由于设置了Vocabulary,max_features的值会被忽略:
vectorizer = CountVectorizer(
decode_error='ignore',
strip_accents='ascii',
vocabulary=vocabulary,
stop_words='english',
max_df=1.0,
min_df=1 )
print(vectorizer)
x_test=vectorizer.fit_transform(x_test)
x_test=x_test.toarray()
3、朴素贝叶斯算法
完整的处理流程如下:
(1)将IMDB数据集的文件提取词袋。
(2)根据IMDB的训练数据文件和测试数据文件夹将词袋化的数据划分为测试集和训练集
(3)使用朴素贝叶斯算法在训练集上训练,获得模型数据。
(4)使用模型数据在测试集上进行预测。
(5)验证朴素贝叶斯算法,使用训练数据集训练,针对测试数据集预测。
实现代码:
from sklearn.feature_extraction.text import CountVectorizer
import os
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn import metrics
import numpy as np
import tensorflow as tf
import tflearn
max_features=400
max_document_length=1000
vocabulary=None
doc2ver_bin="doc2ver.bin"
word2ver_bin="word2ver.bin"
#LabeledSentence = gensim.models.doc2vec.LabeledSentence
SentimentDocument = namedtuple('SentimentDocument', 'words tags')
def load_one_file(filename):
x=""
with open(filename, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
line=line.strip('\n')
line = line.strip('\r')
x+=line
f.close()
return x
#遍历目录,加载目录下全部文件,以字符串集合的形式返回:
def load_files_from_dir(rootdir):
x=[]
list = os.listdir(rootdir)
for i in range(0, len(list)):
path = os.path.join(rootdir, list[i])
if os.path.isfile(path):
v=load_one_file(path)
x.append(v)
return x
#分别加载训练数据集目录下的正面评论和负面评论目录下所有文件,同时进行标记,正面评价0,负面评价1.
def load_all_files():
x_train=[]
y_train=[]
x_test=[]
y_test=[]
path="C:/Users/Administrator\PycharmProjects/tensortflow快速入门/tensorflow_study\MNIST_data_bak\负面评论acllmdb数据集/train/pos/"
print("Load %s" % path)
x_train=load_files_from_dir(path)
y_train=[0]*len(x_train)
path="C:/Users/Administrator\PycharmProjects/tensortflow快速入门/tensorflow_study\MNIST_data_bak\负面评论acllmdb数据集/train/neg/"
print("Load %s" % path)
tmp=load_files_from_dir(path)
y_train+=[1]*len(tmp)
x_train+=tmp
#分别加载测试数据集目录下的正面评论和负面评论目录下所有文件,同时进行标记,正面评价0,负面评价1.
path="C:/Users/Administrator\PycharmProjects/tensortflow快速入门/tensorflow_study\MNIST_data_bak\负面评论acllmdb数据集/test/pos/"
print("Load %s" % path)
x_test=load_files_from_dir(path)
y_test=[0]*len(x_test)
path="C:/Users/Administrator\PycharmProjects/tensortflow快速入门/tensorflow_study\MNIST_data_bak\负面评论acllmdb数据集/test/neg/"
print("Load %s" % path)
tmp=load_files_from_dir(path)
y_test+=[1]*len(tmp)
x_test+=tmp
return x_train, x_test, y_train, y_test
#使用Scikit-Learn的CountVectorizer对象进行词袋化处理,同时将抽取的词汇表保存,用于词袋化测试数据集。词汇表保存在CountVectorizer对象的Vocabulary属性中,初始化CountVectorizer对象。
def get_features_by_wordbag():
global max_features
x_train, x_test, y_train, y_test=load_all_files()
vectorizer = CountVectorizer(
decode_error='ignore',
strip_accents='ascii',
max_features=max_features,
stop_words='english',
max_df=1.0,
min_df=1 )
print(vectorizer)
x_train=vectorizer.fit_transform(x_train)
x_train=x_train.toarray()
vocabulary=vectorizer.vocabulary_
#复用Vocabulary对测试数据集进行词袋化处理,其中由于设置了Vocabulary,max_features的值会被忽略:
vectorizer = CountVectorizer(
decode_error='ignore',
strip_accents='ascii',
vocabulary=vocabulary,
stop_words='english',
max_df=1.0,
min_df=1 )
print(vectorizer)
x_test=vectorizer.fit_transform(x_test)
x_test=x_test.toarray()
return x_train, x_test, y_train, y_test
def do_nb_wordbag(x_train, x_test, y_train, y_test):
print("NB and wordbag")
gnb = GaussianNB()
gnb.fit(x_train,y_train)
y_pred=gnb.predict(x_test)
print(metrics.accuracy_score(y_test, y_pred))
print(metrics.confusion_matrix(y_test, y_pred))
if __name__ == "__main__":
print("Hello review")
print("get_features_by_wordbag_tfidf")
x_train, x_test, y_train, y_test=get_features_by_wordbag()
#NB
do_nb_wordbag(x_train, x_test, y_train, y_test)
运行结果:
评价结果的准确度和TP、FP、TN、FN4个值:
print(metrics.accuracy_score(y_test, y_pred))
print(metrics.confusion_matrix(y_test, y_pred))
在词袋最大特征数为5000的情况下,仅使用词袋模型时,着呢个系统准确度为79.16%,TP、FP、TN、FN矩阵见下表:
类型名称 | 相关 | 不相关 |
检索到 | 10175 | 2325 |
未检索到 | 2886 | 9614 |