❝
🤵♂️ 个人主页:@艾派森的个人主页
✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+
目录
[3.1 数据说明](#3.1 数据说明 "#3.1%20%E6%95%B0%E6%8D%AE%E8%AF%B4%E6%98%8E")
[5.1 SVM模型评估结果](#5.1 SVM模型评估结果 "#5.1%20SVM%E6%A8%A1%E5%9E%8B%E8%AF%84%E4%BC%B0%E7%BB%93%E6%9E%9C")
一、实验背景
当前,随着社交媒体的迅猛发展,人们也越来越习惯于在论坛、博客、微博等社交网络中发表主观性的言论,用于表达自己对周围所见所闻的观点和看法,从而形成了大量带有主观情感倾向性的文本。这些海量的主观性文本对人们的行为会产生重要影响,因而人们渴望对其进行自动挖掘和处理。然而,这些文本大多表现为非结构化的或半结构化的形式,使得自动地分析和抽取其中蕴含的情感倾向性成为一项极具挑战性的课题。如果仅仅通过人工获取并分析这些评论中的情感信息,效率将会十分低下,无法满足实际的需求.自然语言处理领域存在一种可行的方法---------情感分析(sentiment analysis),情感分析大致兴起于世纪年代末,在进入本世纪后,人们开始普遍认识到情感分析的巨大研究价值和潜能,经过二十年的发展,情感分析已经成为数据挖掘、机器学习、自然语言处理等领域的研究热点之一。
情感分析,又叫作观点挖掘,倾向性分析等,简单而言,是对带有情感色彩的主观性文本进行分析、处理、归纳和推理的过程。目的是理解文本中作者对于某个实体(包括产品、服务、人、组织机构、事件、话题)的评判态度(支持或反对、喜欢或厌恶等)或情感状态(高兴、愤怒、悲伤、恐惧等)。在研究工作中,人们往往把情感分析看作是一种分类问题,并将文本的情感标签划分为两类(正倾向、负倾向)或三类(正倾向、负倾向、中立正倾向情感(是指主题中持有积极的、支持的、健康的态度和立场;负倾向情感(是指文本中持有消极的、反对的、不健康的态度和立场;中立类别(是指文本中持中立态度和立场。虽然文本情感分析的实质是分类问题,但它与传统的文本分类任务有着很大的不同。传统的文本分类通常基于文本主题(例如:体育、经济、政治等)进行分类,对文本内容的分析与理解都处于比较浅的层次。而情感分析关注的是文本内容所体现的情感、观点或态度,并非文本本身的内容。它是对传统的文本分类研究的深入和拓展,可以满足人们更深层次获取和利用信息的需求。
文本情感分析涉及到人工智能、机器学习、数据挖掘、信息抽取、信息检索、自然语言处理、计算语言学、统计学等多个研究领域,不仅需要应用这些领域的前沿技术,而且反过来又对这些技术提出了新的挑战,推动了其发展。因此,情感分析在科学研究方面具有重要意义。同时,情感分析又具有广泛的应用前景,主要包括:
1.舆情分析。舆情是指在一定社会空间内,围绕社会事件的发生、发展和变化,民众对事件和当事各方的社会政治态度,是人们对于社会中各种现象、问题所表现的信念、态度、意见和情绪等的总和。近年来,随着社交媒体的迅速发展,我们已经感受到网络舆论对于政策改革、企业重塑、经济调控等发挥的巨大影响。利用文本情感分析技术,可以实时、准确地收集、把握群众意见,使政府和商家能够及时做出相应调整。
2.市场情报。在购买商品时,消费者希望通过其他用户发表的评论来决定自己的购买意向。同时,许多商家也希望通过用户评论来及时了解产品的优缺点及用户满意度。文本情感分析技术可自动地从海量评论语料中挖掘有用信息,并对这些信息进行组织和分类,直观地展示给用户和商家。
3.其他相关系统。情感分析技术可推动其他系统的发展。例如:推荐系统中可利用情感分析技术拒绝推荐收到大量负面反馈的项目;情感分析技术有利于一些在线网站根据正、负情感信息的数量排列广告;自动问答系统中需要将主观情感型问题与客观事实型问题区别对待;自动摘要系统中需要考虑文档的多角度主观观点从而丰富摘要的信息量和多样性;人机交互系统中利用情感分析技术判断人的情绪,提高系统的智能水平。
目前,文本情感分析方法主要分为3类:基于情感词典的方法、基于传统机器学习的方法以及基于深度学习的方法.基于情感词典的方法主要依赖人工构建的情感词典,该方法实现简单,但构建情感词典困难,需要耗费大量的人力物力;基于传统机器学习的方法依赖人工设计的特征,该方法计算量小容易实现,但需要专业领域的专业人士分析并提取相关特征,且泛化能力不足;基于深度学习的方法通过构建网络模型模拟人脑神经系统对文本进行学习,自动提取特征进行文本分类。
二、相关算法
2.1Word2vec
Word2vec 是 Word Embedding 的方法之一。他是 2013 年由谷歌的 Mikolov 提出的一套新的词嵌入方法,是一种神经网络概率语言模型,可以用于计算单词的词向量。与传统的高维词向量 one-hot representation 相比,Word2vec 词向量的维度通常在 100~300 维之间,减少了计算的复杂度,也不会造成向量维数灾难。除此之外,Word2vec词向量是根据词汇所在上下文计算出的,充分捕获了上下文的语义信息,很容易通过它计算两个词汇的相似程度。
Word2vec是一个用于处理文本的双层神经网络。它的输入是文本语料,输出则是一组向量:该语料中词语的特征向量。虽然Word2vec并不是深度神经网络,但它可以将文本转换为深度神经网络能够理解的数值形式。
Word2vec的应用不止于解析自然语句。它还可以用于基因组、代码、点赞、播放列表、社交媒体图像等其他语言或符号序列,同样能够有效识别其中存在的模式。为什么呢?因为这些数据都是与词语相似的离散状态,而我们的目的只是求取这些状态之间的转移概率,即它们共同出现的可能性。所以gene2vec、like2vec和follower2vec都是可行的。Word2vec的目的和功用是在向量空间内将词的向量按相似性进行分组。它能够识别出数学上的相似性。
Word2vec能生成向量,以分布式的数值形式来表示词的上下文等特征。而这一过程无需人工干预。给出足够的数据、用法和上下文,Word2vec就能根据过去经验对词的意义进行高度准确的预测。这样的预测结果可以用于建立一个词与其他词之间的联系(例如,"男人"和"男孩"的关系与"女人"和"女孩"的关系相同),或者可以将文档聚类并按主题分类。而这些聚类结果是搜索、情感分析和推荐算法的基础,广泛应用于科研、调查取证、电子商务、客户关系管理等领域。Word2vec神经网络的输出是一个词汇表,其中每个词都有一个对应的向量,可以将这些向量输入深度学习网络,也可以只是通过查询这些向量来识别词之间的关系。Word2vec衡量词的余弦相似性,无相似性表示为90度角,而相似度为1的完全相似则表示为0度角,即完全重合。
Word2vec包含了两种训练模型,分别是CBOW(Continuous Bag-of-words Model)和 Skip_gram(Continuous Skip-gram Model)。CBOW的意思就是用上下文来预测当前词,而Skip-gram就是用当前词来预测上下文,如图所示:
优点:
(1)由于 Word2vec 会考虑上下文,跟之前的 Embedding 方法相比效果更好。
(2)比之前的 Embedding方 法维度更少,所以速度更快。
(3)通用性很强,可以用在各种 NLP 任务中。
缺点:
(1)由于词和向量是一对一的关系,所以多义词的问题无法解决。
(2)Word2vec 是一种静态的方式,虽然通用性强,但是无法针对特定任务做动态优化。
2.2支持向量机
支持向量机(support vector machine),故一般简称SVM,通俗来讲,它是一种二分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,这族分类器的特点是他们能够同时最小化经验误差与最大化几何边缘区,因此支持向量机也被称为最大边缘区分类器。其学习策略便是间隔最大化,最终可转化为一个凸二次规划问题的求解。SVM在很多诸如文本分类,图像分类,生物序列分析和生物数据挖掘,手写字符识别等领域有很多的应用。
支持向量机将向量映射到一个更高维的空间里,在这个空间里建立有一个最大间隔超平面。在分开数据的超平面的两边建有两个互相平行的超平面,分隔超平面使两个平行超平面的距离最大化。假定平行超平面间的距离或差距越大,分类器的总误差越小。
如图所示,我们希望找到如图中粗线所示的边界函数(分类超平面),因为粗线有更大的几何间距,对于离群点有更好的兼容性,鲁棒性更好,即泛化能力更好。
优点:
(1)非线性映射是SVM方法的理论基础,SVM利用内积核函数代替向高维空间的非线性映射;
(2)对特征空间划分的最优超平面是SVM的目标,最大化分类边际的思想是SVM方法的核心;
(3)支持向量是SVM的训练结果,在SVM分类决策中起决定作用的是支持向量。
(4)SVM 是一种有坚实理论基础的新颖的小样本学习方法。它基本上不涉及概率测度及大数定律等,因此不同于现有的统计方法。从本质上看,它避开了从归纳到演绎的传统过程,实现了高效的从训练样本到预报样本的"转导推理",大大简化了通常的分类和回归等问题。
(5)SVM 的最终决策函数只由少数的支持向量所确定,计算的复杂性取决于支持向量的数目,而不是样本空间的维数,这在某种意义上避免了"维数灾难"。
(6)少数支持向量决定了最终结果,这不但可以帮助我们抓住关键样本、"剔除"大量冗余样本,而且注定了该方法不但算法简单,而且具有较好的"鲁棒"性。
SVM的限制包括:
(1)SVM算法不适用于大型数据集。
(2)当数据集的噪声较大时,支持向量机不能很好地工作。
(3)如果每个数据点的实体数量超过了训练数据样本的数量,SVM将会表现不佳。
(4)由于支持向量分类器通过在分类超平面的上方和下方放置数据点来工作,因此没有概率解释。
2.3随机森林
随机森林(Random Forest)是一种基于分类树(classification tree)的算法(Breiman,2001)。这个算法需要模拟和迭代,被归类为机器学习中的一种方法。经典的机器学习模型是神经网络(Hopfield,1982),有半个多世纪的历史了。神经网络预测精确,但是计算量很大。上世纪八十年代Breiman等人发明了分类和回归树(Classification and Regression Tree,简称CART)的算法,通过反复二分数据进行分类或回归,计算量大大降低。
2001年Breiman和Cutler借鉴贝尔实验室的Ho所提出的随机决策森林(random decision forests)的方法,把分类树组合成随机森林,即在变量(列)的使用和数据(行)的使用上进行随机化,生成很多分类树,再汇总分类树的结果。后来Breiman在机器学习杂志上发表了他和Cutler设计的随机森林的算法。这篇文章被大量引用(根据Google Scholar,该文章至2013年被引用9000多次),成为机器学习领域的一个里程碑。
随机森林在运算量没有显著提高的前提下提高了预测精度。随机森林对多元公线性不敏感,结果对缺失数据和非平衡的数据比较稳健,可以很好地预测多达几千个解释变量的作用,被誉为当前最好的算法之一。在机器学习的诸多算法中,随机森林因高效而准确而备受关注,在各行各业得到越来越多的应用。
同其他模型一样,随机森林可以解释若干自变量(X1、X2、...、Xk)对因变量Y的作用。如果因变量Y有n个观测值,有k个自变量与之相关;在构建分类树的时候,随机森林会随机地在原数据中重新选择n个观测值,其中有的观测值被选择多次,有的没有被选到,这是Bootstrap重新抽样的方法。同时,随机森林随机地从k个自变量选择部分变量进行分类树节点的确定。这样,每次构建的分类树都可能不一样。一般情况下,随机森林随机地生成几百个至几千个分类树,然后选择重复程度最高的树作为最终结果。
随机森林通过产生大量的分类树,建立若干自变量X和一个因变量Y的关系。随机森林的优点是:它的学习过程很快。在处理很大的数据时,它依旧非常高效。随机森林可以处理大量的多达几千个的自变量。现有的随机森林算法评估所有变量的重要性,而不需要顾虑一般回归问题面临的多元共线性的问题。它包含估计缺失值的算法,如果有一部分的资料遗失,仍可以维持一定的准确度。随机森林中分类树的算法自然地包括了变量的交互作用(interaction),即X1的变化导致X2对Y的作用发生改变。交互作用在其他模型中(如逻辑斯蒂回归)因其复杂性经常被忽略。随机森林对离群值不敏感,在随机干扰较多的情况下表现稳健。随机森林不易产生对数据的过度拟合(overfit),然而这点尚有争议。
随机森林通过袋外误差(out-of-bag error)估计模型的误差。对于分类问题,误差是分类的错误率;对于回归问题,误差是残差的方差。随机森林的每棵分类树,都是对原始记录进行有放回的重抽样后生成的。每次重抽样大约1/3的记录没有被抽取。没有被抽取的自然形成一个对照数据集。所以随机森林不需要另外预留部分数据做交叉验证,其本身的算法类似交叉验证,而且袋外误差是对预测误差的无偏估计随机森林的缺点是它的算法倾向于观测值较多的类别(如果昆虫B的记录较多,而且昆虫A、B和C间的差距不大,预测值会倾向于B)。另外,随机森林中水平较多的分类属性的自变量(如土地利用类型 > 20个类别)比水平较少的分类属性的自变量(气候区类型<10个类别)对模型的影响大。总之,随机森林功能强大而又简单易用,相信它会对各行各业的数据分析产生积极的推动作用。
三、实验数据
3.1 数据说明
实验训练 word2vec 模型的语料爬虫采集自当当图书评论,京东商品评论,携程用户评论以及豆瓣电影评论,去重后保留 20 000 条数据,包括 10000条积极评论和10000条消极评论。为了进行实验,将积极和消极的数据集各分为两份,其中 80%作为训练集,余下20%作为测试集,数据样例如表所示。
| 实验数据 | |
|-------------------------------------------------------------|---|-------------------------------------------|
| 积 极 | | 感觉手写识别能力强26TFT屏幕效果很好,64的YMAHA声音也不错,很好听 |
| --------------------------------------------------------- | |
| 信号好!闹铃中有一星期中具体某几日响铃,很方便了!显示屏在强光下,比以前那个明显清晰! | |
| 听音乐和相片拍摄及编辑功能非常强。 | |
| 1.相片拍摄及编辑功能实为超强。2.所拍影像整体色彩以及清晰度都比较理想。 | |
| 外观很独特,给人耳目一新的感觉,而且导航键很方便平常的操作。按键手感也不错。16和弦铃声效果还可以,声音也比较大。 | |
| 这本书我想应该大部分人都看过,感觉挺好的 | |
| 交通很方便,房间小了一点,但是干净整洁,很有香港的特色,性价比较高。 | |
| 笑得开心,那就够了。 | |
| 笑到不行,喜剧就要有喜剧的样子,笑中带泪很想二刷的一部电影,不错! | |
| 五星好评!必须支持! | |
| 前笑后泪,非常动人,非常真实的电影 | |
| 走在去二刷的路上,能够大家一起坐下来笑笑,不容易了。 | |
| 消 极 | | 机子没发现什么缺点,就是京东的服务好像不怎么的,5号就完成了付款,订单到今天才完成 |
| ----------------------------------------------------------- | |
| 很后悔买这本书,觉得并非作者自己的观点体会,而是东拼西凑来的。想吐的感觉。(心情指数为什么没"气愤"可选?) | |
| 2.现在为什么订单要等货物审核才可以支付,我要老等的。我就直接网上支付不行的。 3.电话服务老让人等的,请增加服务人数 | |
| 感觉内容很虚,泛泛而谈,没有介绍的那么吸引我有点失望 | |
| 质量和速度是不错啦,就是圆通快递太差啦,单上注明是本人签收的,可快递员随便一个人就给签啦,一点责任感都没有! | |
| 毫无疑问,是烂片。 | |
| 故事老套,强行煽情,后边真的太拖拉了 | |
| 笑料还算有点意思,但觉得价值观问题很大,直导致该片完全是无意义的扯淡 | |
| 完全get不到笑点...但看的确实特烦 | |
| 不喜欢就是不喜欢 | |
3.2评价标准
本文情感分类的评价指标采用精度(Precision)、召回率(Recall)、F-score。下表是两分类分类器的 混 淆 矩 阵(Confusion Matrix), 其 中 TP(True Positive)表示实际为正类、预测也为正类的文本数量;FN 表示实际为正类、预测为反类的文本数量;FP 表示实际为反类、预测为正类的文本数量;TN表示实际为反类、预测也为反类的文本数量。
数据类别 | 预测正例 | 预测反例 |
---|---|---|
实际正例 | TP | FN |
实际反例 | FP | TN |
四、实验步骤
1 .首先导入本次实验用到的第三方库
javascript
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
import jieba as jb
from sklearn.externals import joblib
from sklearn.svm import SVC
from gensim.models.word2vec import Word2Vec
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics
2. 加载数据,使用jieba将数据进行分词,将正反样本拼接,然后创建全是0和全是1的向量拼接起来作为标签
css
#读取数据文件
neg = pd.read_excel("data/neg.xlsx", header=None)
pos = pd.read_excel("data/pos.xlsx", header=None)
# 这两类数据都是x值
neg['words'] = neg[0].apply(lambda x: jieba.lcut(x))
pos['words'] = pos[0].apply(lambda x: jieba.lcut(x))
#需要y值 0 代表neg ,1代表是pos
x = np.concatenate((pos['words'],neg['words']))
y = np.concatenate((np.ones(len(pos)),np.zeros(len(neg))))
#拆分训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=3)
#保存数据
np.save("dataset/y_train.npy",y_train)
np.save("dataset/y_test.npy",y_test)
3.定义生成每一个句子vec的函数
arduino
def build_vector(text,size,w2v):
#创建一个指定大小的数据空间
vec = np.zeros(size).reshape((1,size))
#count是统计有多少词向量
count = 0
#循环所有的词向量进行求和
for w in text:
try:
vec += w2v[w].reshape((1,size))
count +=1
except:
continue
#循环完成后求均值
if count!=0:
vec/=count
return vec
4 .计算词向量
ini
#初始化模型和词表
w2v = Word2Vec(size=300,min_count=10)
w2v.build_vocab(x_train)
# 训练并建模
w2v.train(x_train,total_examples=w2v.corpus_count, epochs=w2v.iter)
#获取train_vecs
train_vecs = np.concatenate([ build_vector(z,300,w2v) for z in x_train])
#保存处理后的词向量
np.save('dataset/train_vecs.npy',train_vecs)
#保存模型
w2v.save("dataset/w2v_model.pkl")
w2v.train(x_test,total_examples=w2v.corpus_count, epochs=w2v.iter)
test_vecs = np.concatenate([build_vector(z,300,w2v) for z in x_test])
np.save('dataset/test_vecs.npy',test_vecs)
5.训练SVM/RF模型
ini
#创建SVC模型/RF模型
cls = SVC(kernel="rbf",verbose=True)
cls = RandomForestClassifier()
#训练模型
cls.fit(train_vecs,y_train)
#保存模型
joblib.dump(cls,"dataset/svm_model.pkl")
joblib.dump(cls,"dataset/RF_model.pkl")
6.对训练得出的模型进行评估
ini
y_pred = cls.predict(test_vecs)
#模型评估
print('准确率:', metrics.accuracy_score(y_test, y_pred)) #预测准确率输出
#计算宏平均、微平均、加权平均精确率输出
print('宏平均精确率:',metrics.precision_score(y_test,y_pred,average='macro'))
print('微平均精确率:', metrics.precision_score(y_test, y_pred, average='micro'))
print('加权平均精确率:', metrics.precision_score(y_test, y_pred, average='weighted'))
#计算宏平均、微平均、加权平均召回率输出
print('宏平均召回率:',metrics.recall_score(y_test,y_pred,average='macro'))
print('微平均召回率:',metrics.recall_score(y_test,y_pred,average='micro'))
print('加权平均召回率:',metrics.recall_score(y_test,y_pred,average='weighted'))
#计算宏平均、微平均、加权平均f1-score输出
print('宏平均F1-score:',metrics.f1_score(y_test,y_pred,labels=[0,1],average='macro'))
print('微平均F1-score:',metrics.f1_score(y_test,y_pred,labels=[0,1],average='micro'))
print('加权平均F1-score:',metrics.f1_score(y_test,y_pred,labels=[0,1],average='weighted'))
print('混淆矩阵输出:\n',metrics.confusion_matrix(y_test,y_pred))#混淆矩阵输出
print('分类报告:\n', metrics.classification_report(y_test, y_pred))#分类报告
五、实验结果与分析
5.1 SVM模型评估结果
5.2随机森林模型评估结果
通过对同一评论数据集采用word2vec生成词向量,然后分别采用支持向量机和随机森林两种算法训练并建立模型,然后用测试集对两个模型进行评估。分别得出如上图所示结果。通过对两组数据进行对比,可以得出,支持向量机模型的精确率,召回率以及F1值均大于随机森林模型的评估结果。因此,可得出支持向量机训练所建立的模型取得的效果更好。
通过网络爬虫采集了电影《你好,李焕英》的豆瓣短评483条,采用支持向量机所训练得出的分类模型进行判断。部分典型结果如下表所示:
评论内容 | 判断结果 | 判断正误 |
---|---|---|
"你以为自己已经很爱很爱妈妈了,妈妈却远比想象中更爱更爱你。你以为自己是在为妈妈圆梦,没成想只是她陪你做了一场好梦。" | [积极] | 正确 |
"观众已经笑得不行了" | [消极] | 错误 |
说实话吧,这要都算电影,电影的门槛是太低了点。 | [消极] | 正确 |
在夏洛特烦恼的穿越梗用得已经烂大街的时候,贾玲用亲情再次焕发了生机 | [积极] | 正确 |
什么电影手法,在真挚感人面前不重要 | [消极] | 错误 |
不知道有多尴尬 全程尬笑 | [消极] | 正确 |
"我宝"那一句真的泪奔了,五星好评,前面笑点不尬,后面反转真的流泪了... | [消极] | 错误 |
没有刻意的笑点,没有刻意的煽情,淳朴自然。最后的反转锦上添花!我哭的一塌糊涂😭😭😭😭 好喜欢贾玲张小斐!我宝! | [消极] | 错误 |
看懂的人是幸福的。 | [积极] | 正确 |
任何时候真心都是最打动人的。 | [消极] | 错误 |
根据上表分析,该模型对大部分评论可以很好的进行情感分类,尤其是采用了比较明显的表达积极或者消极情绪的词汇的评论,可以做到很好的分类。而对一部分评论,比如"看哭了","笑得不行"等出现了分类错误。另外对于一些不是很明显,偏向于中性的评论以及过长的评论,容易出现分类错误。根据分析,认为存在数据集中此类表述不够多的原因,导致模型对此类评论不能做到很准确的分类。总的来说,该模型对大部分评论能够做到较好的分类,基本上达到了实验目标。
六、实验总结
通过做本次情感分析的项目实战,学习并了解了word2vec生成词向量的相关原理,同时学习了支持向量机与随机森林算法在解决文本分类问题中的应用。虽然在通过python编程进行实现的过程中也遇到过一些困难和疑惑,最终都通过自己查阅相关资料并在老师的悉心指导下,以及和同学的交流过程中得以解决。本次项目虽然经过了不懈得努力得以完成,但仍有不足之处,在之后得学习中,我会继续学习与文本情感分析相关的算法,并将其加以应用以期更好的解决文本情感分析相关问题。
源代码
css
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
import jieba as jb
from sklearn.externals import joblib
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from gensim.models.word2vec import Word2Vec
from sklearn.model_selection import cross_val_score
from sklearn import metrics
neg =pd.read_excel("dataset/800neg.xlsx",header=None,index=None)
pos =pd.read_excel("dataset/800pos.xlsx",header=None,index=None)
# 这是两类数据都是x值
pos['words'] = pos[0].apply(lambda x:list(jb.cut(x)))
neg['words'] = neg[0].apply(lambda x:list(jb.cut(x)))
#需要y值 0 代表neg 1代表是pos
y = np.concatenate((np.ones(len(pos)),np.zeros(len(neg))))
x = np.concatenate((pos['words'],neg['words']))
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=3)
#保存数据
np.save("dataset/y_train.npy",y_train)
np.save("dataset/y_test.npy",y_test)
def build_vector(text,size,w2v):
#创建一个指定大小的数据空间
vec = np.zeros(size).reshape((1,size))
#count是统计有多少词向量
count = 0
#循环所有的词向量进行求和
for w in text:
try:
vec += w2v[w].reshape((1,size))
count +=1
except:
continue
#循环完成后求均值
if count!=0:
vec/=count
return vec
#初始化模型和词表
w2v = Word2Vec(size=300,min_count=10)
w2v.build_vocab(x_train)
# 训练并建模
w2v.train(x_train,total_examples=w2v.corpus_count, epochs=w2v.iter)
#获取train_vecs
train_vecs = np.concatenate([ build_vector(z,300,w2v) for z in x_train])
#保存处理后的词向量
np.save('dataset/train_vecs.npy',train_vecs)
#保存模型
w2v.save("dataset/w2v_model.pkl")
w2v.train(x_test,total_examples=w2v.corpus_count, epochs=w2v.iter)
test_vecs = np.concatenate([build_vector(z,300,w2v) for z in x_test])
np.save('dataset/test_vecs.npy',test_vecs)
#创建SVC模型
cls = SVC(kernel="rbf",verbose=True)
cls = RandomForestClassifier()
#训练模型
cls.fit(train_vecs,y_train)
#保存模型
joblib.dump(cls,"dataset/svm_model.pkl")
joblib.dump(cls,"dataset/RF_model.pkl")
y_pred = cls.predict(test_vecs)
#模型评估
print('准确率:', metrics.accuracy_score(y_test, y_pred)) #计算准确率输出
print('宏平均精确率:',metrics.precision_score(y_test,y_pred,average='macro')) #计算宏平均精确率输出
print('微平均精确率:', metrics.precision_score(y_test, y_pred, average='micro')) #计算微平均精确率输出
print('加权平均精确率:', metrics.precision_score(y_test, y_pred, average='weighted')) #计算加权平均精确率输出
print('宏平均召回率:',metrics.recall_score(y_test,y_pred,average='macro'))#计算宏平均召回率输出
print('微平均召回率:',metrics.recall_score(y_test,y_pred,average='micro'))#计算微平均召回率输出
print('加权平均召回率:',metrics.recall_score(y_test,y_pred,average='weighted'))#计算加权平均召回率输出
print('宏平均F1-score:',metrics.f1_score(y_test,y_pred,labels=[0,1],average='macro'))#计算宏平均f1-score输出
print('微平均F1-score:',metrics.f1_score(y_test,y_pred,labels=[0,1],average='micro'))#计算微平均f1-score输出
print('加权平均F1-score:',metrics.f1_score(y_test,y_pred,labels=[0,1],average='weighted'))#计算加权平均f1-score输出
print('混淆矩阵输出:\n',metrics.confusion_matrix(y_test,y_pred))#混淆矩阵输出
print('分类报告:\n', metrics.classification_report(y_test, y_pred))#分类报告
python
import jieba
import numpy as np
import pandas as pd
from gensim.models.word2vec import Word2Vec
from sklearn.externals import joblib
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
model = joblib.load('dataset/svm_model.pkl')
#model = joblib.load('dataset/RF_model.pkl')
def total_vec(words):
w2v = joblib.load('dataset/w2v_model.pkl')
vec = np.zeros(300).reshape((1,300))
count = 0
for word in words:
try:
vec += w2v.wv[word].reshape((1,300))
count +=1
except KeyError:
continue
#循环完成后求均值
if count!=0:
vec/=count
return vec
def svm_predict():
#读取数据
df = pd.read_excel("dataset/comments.xlsx")
#读取支持向量机模型
comment_sentiment = []
for string in df['评论内容']:
#对评论分词
words = jieba.lcut(str(string))
words_vec = total_vec(words)
result = model.predict(words_vec)
comment_sentiment.append('积极' if int(result[0]) else '消极')
if int(result[0]) == 1:
print(string,'[积极]')
else:
print(string,'[消极]')
comment_sentiment = []
svm_predict()