基于机器学习的情绪分析研究_第1页
基于机器学习的情绪分析研究_第2页
基于机器学习的情绪分析研究_第3页
基于机器学习的情绪分析研究_第4页
基于机器学习的情绪分析研究_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北京理工大学珠海学院2016届本科生毕业设计基于机器学习的情绪分析研究——智能模型设计和实现基于机器学习的情绪分析研究——智能模型设计和实现摘要互联网技术的迅速发展使得社交平台逐渐成为热点事件中社会情感的枢纽。社会热点事件的舆论监管的其中一个重要环节就是能够准确分析民众的社会情绪。本文旨在探索可以基于文本大数据彻底分析民众对热点事件的社会情绪的模型和方法。先是从社交平台上借助文本大数据、对数据进行提前处理以及用python自然语言处理包等方法建立能够分析社会情绪的模型,其次找到最佳的机器学习算法,再次用机器学习的方法对模型进行训练,获得一个情感分类器。最后用热点事件“冠状病毒”的真实数据在情感分类器上进行社会情绪分析验证,证明了模型和方法的有效性。

关键词:网络文本大数据;机器学习;情绪分类器;社会情绪分析;Researchonemotionanalysisbasedonmachinelearning——DesignandimplementationofintelligentmodelAbstractTherapiddevelopmentofInternettechnologymakessocialplatformsgraduallybecomethehubofsocialemotioninhotevents.Oneoftheimportantaspectsofpublicopinionsupervisionofsocialhoteventsistheabilitytoaccuratelyanalyzethepublic'ssocialsentiment.Thispaperaimstoexplorethemodelandmethodthatcanthoroughlyanalysethepeople’ssocialemotionsofhoteventsbasedontextbigdata.Firstly,thewriterbuiltupthemodelofsocialemotionsanalysisbyvirtueoftextbigdatafromthesocialplatforms,datapreprocessingandtheuseofPythonNaturalLangugeToolkitandsoon.Secondly,utilizedthebestmachinelearningalgorithmandthentrainedthemodelbymachinelearningmethodtoobtainanemotionclassifier.Finally,therealdataofthehotevent"coronavirus"wasusedtoanalyzethesocialemotionsontheemotionclassifier,whichprovedthevalidityofthemodelandmethod.Keywords:Webtextbigdata、machinelearning、sentimentclassifier、socialsentimentanalysis;目录TOC\o"1-3"\h\u10113诚信承诺书 前言:1.1设计目的及意义近来,社交媒体和电子商务平台发展迅速,Twitter、微博、MSN、微信等社交网络正逐渐地改变着人们的生活,越来越多的人习惯于通过网络平台表达自己的态度和情感,这些网络文本是客户流露的真实情感。对网络文本大数据热门事件的情绪进行分析可以使人们获得更多关于内心世界的知识,因此,从这些文本信息中自动准确的识别客户的情感类别,对政府舆情监控、企业管理与决策来说是一个很大的支持,它也成为学术界近来持续关注的研究热点,同时极大地促进了情绪分析技术的发展。1.2本课题国内外现状及存在问题文本情感分析也可以说是挖掘文本意见的方法。简而言之,它是分析,处理,总结和推断具有情感色彩的主观文本的过程[1]。目前海内外关于文本情绪分析研究的方向主要有两个:一个是判断主观信息的细粒度,另一个是判断文本的主客观性。前者强调将情感词作为中心去分析文本级的情绪倾向,而文本的情绪倾向是通过贬值情感词的线性加权值来实现的。熊德兰等人[2]基于HowNet语义词典中词汇语义相似度的计算方法。意在基于语义词典,充分想到词语组成在一起之后语义可能改变,直接影响到情感褒贬判断的偏向结果,于是用各个词语义进行权重计算结果来判断从而避免受影响。该方式基于语义词集,能很精确地预测情感倾向,但缺点是操作起来复杂且在很大程度上取决于词汇层次分类算法的精确度。则此方法显然对大量的文本数据处理是不合适。为了处理大量数据,研究人员介绍了用于情感分析的机器学习方法,例如K最近邻,最大熵模型,朴素贝叶斯和支持向量机(SVM)方法[3]。虽然以语义词集为基础的语义加权分类效果比机器学习方法较好,但胜在后者能够更轻易地去分析处理大量的文本数据。例如徐军等人[4]利用机器学习方法对新闻评论进行情感分类,在最理想的数据集上分类准确率可以达到90%,然而这种方法缺乏语义分析,容易产生向量空间模型数据稀疏问题,对于中文文本处理中普遍存在的一词多义和多词一义问题也不能解决。闻彬等人[5]在情感词识别中引人情感语义概念,基于语义理解来进行文本情感分类,可在一定程度上缓解一词多义和多词一义引起的分类准确率不高的问题,它的不足之处在于只考虑到词语语义层副词的出现规律对词语语义的作用,忽略了整个文本语境对词语语义的影响。一些研究者[6]通过已有文本规则,充分考虑用文本的语法结构去预测文本情绪倾向。但是不得不说该方式的实用性差、工艺复杂且难以推广。也有部分研究者尝试借助非标注样本不断训练分类器的方法来提高半监督学习方法的情感分类准确率,实验证明该方法是有效的[7]。还有谢丽星等[8]提出了一种基于SVM的层次结构多策略中文微博情感分析方法;刘宝芹等[9]在将情绪类别组织成三层树状结构后,采用朴素贝叶斯分类模型对中文微博进行多层次的情绪分析;欧阳纯萍等[10]提出多策略中文微博细粒度情绪分析方法,采用SVM和KNN算法对微博进行细粒度情绪分析;雷龙艳等[11]在对微博进行文本特征表示的基础上,采用SVN和KNN算法对微博进行细粒度情绪分析。等等这些国内外的文本情感分类方法研究,对本设计的方法选择与优化都提供了一定的帮助。1.3本设计应解决的主要问题接下来Twitter数据将作为我们今天的实战项目用于情绪分析。由于采用了机器学习,我们主要解决以下问题:从Twitter上获取适量文本数据;对文本数据进行必要的预处理;标住类标签,分割开发集和测试集数据;对预处理后的数据进行特征提取与向量加权;训练模型,调整参数,评估模型;用测试集进行测试验证情绪分析的准确率;2设计过程2.1设计简要流程训练文本集训练文本集测试文本集文本预处理选举特征词集情感词典向量空间表示SVM分类器情感分类结果训练SVM分类器文本预处理向量空间表示分类参数TF-IDF特征降维图2.1-1_设计简要流程图2.2文本数据获取2.2.1创建APP首先通过已有的twitter账号访问推特官方网站,想要抓取数据就要创建app去访问twitter的API。创建app时,必要填写信息为“name,Description,website”,其中name为APP的名称;description是对自己APP的描述;website自己有网站写自己的网站,没有就写一个符合格式的网站就行。并不需要进一步的验证,app中的AccessToken、Access、TokenSecretConsumerKey(APIKey)和ConsumerSecret(APISecret)这四个开发者身份认证令牌参数才是我们的目标,也是获取数据的基本条件。如果需要获取大量数据,可以申请多个app,因为单个的爬取次数和数量均有限制。2.2.2调配使用API之所以选择Twitter作为实战的文本数据是因为它提供很多类型的API,其中RestAPI与StreamingAPI是最为常见的。前者是经常被用到的类型,而StreamingAPI可以用于追踪想要了解的用户或事件。下面介绍一下RESTAPI中有爬取意义的几个API:GETstatuses/usertimeline:返回一个用户发的推文。注意twitter里回复也相当于发推文。GETfriends/ids:返回一个用户的followees。GETfollowers/ids:返回一个用户的followers。GETusers/show:返回一个用户的信息。接下来,通过使用twitterapi进行数据抓取,目前的twitterapi有很多python语言版本,本设计将会用到的是tweepy。安装tweepy库,只需要在cmd中输入pipinstalltweepy命令即可。2.2.3开始程序编辑Twitter平台不仅给以了我们爬取数据所用到的API接口,并且还携带了供我们写程序代码参考所用到的Tweepy库。最后将获取到的数据将保存到csv格式文件中,获取文本数据程序代码如下:2.3数据预处理2.3.1句柄的删除句柄(@user)携带是每个推特用户得以批准的一种方式,所以tweets文本数据中有的大量twitter句柄。而这个句柄其实没有什么信息含量,因此我们删除所有这些twitter句柄。为了省去不必要的麻烦,最好将测试集跟训练集都一齐处理掉。说到删除tweet中用不到的文本模式,首先我们需要定义一个函数,输入两个参数,一个是文本原始字符串,另一个是字符串中我们想要删除的文本模式。用该函数进行“@user”模式的删除。最后,创建一个新的列名为processed_tweet,用于存放经过清理和处理的tweet。程序代码如下:2.3.2删除标点、数字和特殊字符标点符号、数字和特殊字符对一般的文本处理没什么帮助。就像twitter句柄一样需要从文本中删除掉它们,用空格替换除字符和标签的全部内容。处理程序代码如下:2.3.3处理表情符号将表情符号转化为情绪表达,分别为Positive和negative。可以更加直观的判断文本的情绪倾向,转化代码如下:2.3.4词干提取由于英文表达中的单词大多带有后缀,如(“ing”、“ly”、“er”、“es”、“s”等)对单词没有情绪改变的后缀。举个例子,“fly”、“flyer”、“flying”,其中“flyer”和“flying”是单词“fly”的不同变体。我们需要从一个单词中剥离后缀,提取出对情绪分类有用的词干信息,提取程序代码如下:2.4标注类标签在经过预处理后的的数据,分别划分为训练以及测试文本集,训练集的数额要远大于测试集的数额。本设计总获取约一百万个文本数据,其中测试集数量约为百分之九十,然后按照文本的情感表达给它们分类为消极negative(标注为0)和积极Positive(标注为1)的标签,测试集用于后续的验证,不需要标注。标注后的效果图如下:图2.4-1_类标注效果图2.5分词由于在特征提取前,需要并将这些词用作向量来表示文本,即将所有训练文档进行分词。举个例子:在情感分类问题中,选择特征可以基于“词”这个层次,例如“Thistweetisexcellent”,我给他标注成“Positive”的类标签。里面有4个词,分别为“This”、“tweet”、“is”、“excellent”。意思是将这4个词全部作为了分类特征词,那么包含这个词的文本就会被分类为“积极”。同理,对上面提及的那句文本,还能选择双词组合(Bigrams)。这种方法就是将“Thistweet”,“tweetis”,“isexcellent”这种两两搭配作为分类特征。本设计将用到这两种特征选择作为分词方式进行选择,分词程序代码如下:2.6特征提取机器学习算法并不能直接使用原始数据,这就需要我们对分词后的的词语集合(原始数据)做一个特征提取处理,然后把原始数据转变为能够被机器学习算法认识的数量特征(固定长度的向量表示)。基于2.5提到的两种特征选择,可以用到N-Gram,一种基于概率去判别的模型的算法,该语言模型的根本原理就是将文本内容依据不同的字节大小N去截取想要大小的片段序列。进行过滤后对所有的字节片段(gram)所浮出的频度分别计算,最后合成向量特征空间(gram列表)。其中列表里面不同的gram代表着不同的特征向量维度。当n=1时,为一元模型(unigrammodel),对应公式如下:(式2.6-1)(式2.6-1)当n=2时,为二元模型(bigrammodel),对应公式如下:(式2.6-2)(式2.6-2))本设计在模型中分别创建了一元模型和二元模型特征向量列表,然后通过使用上面提到的两种特征提取方式对数据集中所有的单词在语料中出现的频率,对比这两种特征提取的测试效果,最终选择最佳的特征特征向量维度,将数据以这个字节长度添加到特征列向量表中。实践流程和程序设计如下:文档信息文档信息特征向量列表语段序列gram频度列表粗切分N-gram切分过滤图2.6-1实践流程图2.7特征降维与TF-IDF特征降维显然意味着减少特征维数。这有两个不同含义。一是可以减少特征数量以加快算法计算。另一个是,如果使用某种方法来选择信息丰富的特征,则可以减少噪声并有效地提高分类的准确性。何为信息量丰富?,可以回顾一下上面的例子:“Thistweetisexcellent”,很明显,其实不需要把“This”、“tweet”、“is”、“excellent”这4个都当做特征,因为“excellent”这一个词,或者“isexcellent”这样一个双词搭配就能够判定了这个文本属于“积极”的。这就足够说明了“excellent”是一个信息量非常丰富的词。下面将通过一定的统计方法找到信息量丰富的特征。TF-IDF(TermFrequency-InverseDocumentFrequency),是在分类问题中用于统计的一种方法。用于评估一个字词在文本集或语义库中的某个文本的影响度。字词在文本中出现的次数越多吗,其影响度越大。相反,字词在语义库中出现的频率越高,该词的影响度就越低。TF-IDF由TF和IDF这两部分组成。词频(TermFrequency,TF)是计算文本中某个特定词出现的多少次。同一个词不管它重不重要,在长文本较于短文本出现的次数可能偏高。为了防止它的偏向,这个数值通常需要除以文章总词数进行归一化,表达式如下:(式2.7-1)(式2.7-1)但是需要考虑的问题是:一些出现频率较高的词通常对于情绪判断没有啥作用,反而一些较少出现的词却能表达出文本基本情绪。例如在大多数文本都会用到的"to"的词频就很高,但是其对情绪分类的作用却比不上词频低的"Study"和“Sing”等词。因此权重的计算不能只用到TF,必须考虑到:一个词要跟其分类情绪的的能力成正比,能力越强,权重越大,反之则权重越小。要找到一些词只是很少地出现在所有统计文本中的其中几个,那么这些词对文本情绪表达作用就很大。因此需要用到IDF来完成此工作,将这些词的权重设计的更大去反映出这些词的重要性,进而改正单纯使用词频表示的特征值。逆向文件频率(InverseDocumentFrequency,IDF)可用于去寻找具有优秀分类能力的词条,根据词条出现在的文档数较少,其逆向文件频率就越大来判别。以下公式就可计算出某一特定词语的IDF:(式2.7-2)(式2.7-2)为了使每一个IDF值都有意义,应该避免一个极端的情况,就是某个词在全部的文本中都出现,其IDF值为0就失去了意义。因此我们在使用IDF时需要做一些平滑,如对上式的分母加1,就是为了防止分母等于0,使得没有出现在语料库中的词也得到一个合理的IDF值。TF-IDF重在过滤掉常见的词,留下信息量丰富的词。想要输出权重的TF-IDF,这个词就需要满足较多的出现在一个特定文本,较少的出现在文本集的文本中。理解了IDF的定义,接下来就可以推出计算某一个词的TF-IDF值的公式了:(式2.7-3)(式2.7-3)即:(式2.7-4(式2.7-4)式中的表示某字词在句子中出现的概率,其中N为训练集文本数量,表示训练集中包含特征词的文本数。根据TF-IDF公式表示,某特征词出现在一个文本集的次数越多,其其辨别能力越小,权重值越低;而在一个文本中出现的概率越高,可区分性就越大,权重也就越大。2.8搭建模型2.8.1以机器学习为基础的文本情感分析方法首先对已经标注好的文本数据进行特征处理,然后对模型进行训练以进行监督学习。训练完好的模型最后用于预测新文本测试集信息的情感极性。简要操作流程如下图所示:已经标住的文本数据已经标住的文本数据特征提取模型训练极性标签机器学习训练未标住的句子特征提取取情感极性预测图2.8-1_简要操作流程图机器学习依照分类算法的不同,分为国内外研究现状中使用的三种方法:朴素贝叶斯、最大熵和支持向量机(SVM)。相对于前两者,由vapnik提出的支持向量机(SVM),被认为是最好的情绪分析方法,该方法通过寻找最小的结构化风险,降低泛化错误率和计算开销,并且实现了经验危险和置信面积的最小化,最重要的是对于训练集较小的文本也可以获得良好的统计规律和情感分析效果。高维数据使用支持向量机(SVM)的处理效果很不错,想要很好的使用该方法,就要做好参数调节和核函数的挑选。2.8.2支持向量机SVM支持向量机(SupportVectorMachine,SVM)算法用于文本分类经常被称赞。该机器学习方法主要基于统计学习。该算法将数据集进行压缩,转化为向量集合,以降低结构风险,学习得到决策函数的分类技术。该技术能实现文本向量化,仅需要一定的文本数据就能被抽象得到训练集,解决了过去需要无限大样本的问题,提高了分类的准确性。使用支持向量机(SVM)算法,就能用有限的文本数据获得最好的推广能力,是因为它在模型的复杂性与学习能力之间寻找最好折中点实现的。下面说说支持向量机算法的赞点:(1)能匹配现有数额的的文本数据,找到最好值点,充分照顾到有限数据的情况。(2)支持向量机算法在特征向量稀少的空间和特征向量密集的空间都能很好的执行任务,这是其他一些分类算法不能做到的。(3)支持向量机算法能帮你找到权重的特征向量,该工具的优秀学习能力体现了它在文本分类中的巨大潜能。支持向量机(SVM)是一种二向线性分类器,线性可分和线性不可分,用于监督学习。线性可分相对简单,而线性不可分离则想到SVM,它能把原始数据映射到线性可分新界面,经过投影,可在原始界面获得划分边界。SVM是一种经常用于分类问题的数学模型。它的主要思想是构造一个多维超平面,对要分类的特征值进行分类,使用训练示例数据向量将其划分为相对应的类别,然后找到该平面的边界最大化。wwyx图2.8-2_SVM超平面分隔图上文说到SVM针对非线性的情况,那它是怎么做到的呢?而核函数(Kernel)正是它解决这个问题的秘方,核函数通过在较于原本数据空间更高维的特征空间去看线性不可分的分类问题,从而得到了很好的分界面。核函数的精髓如下:在我们的学习研究过程中,经常碰到各种线性不可分的情况。而我们常用的方法就是将原始数据特征映射到高维的象征空间里,(如上图2.8-2_SVM超平面分割图所示)这样是为了使相关特征被分开达到分类的目的。以此类推,我们将所有碰到的线性不可分样例,都像上面所说的一律映射到高维空间。那该维度岂不是高到吓人,那改如何呢?接下来,核函数的出现意义不仅在于它实现特征从低到高的空间维度变换,还能将数据在低维空间上计算效果展现在高维空间中,防止了②中说到的复杂高维计算。接下来讨论核函数的选择,LinearSVC和使用SVC且在kerne中引入linear是本设计需要考虑的使用结果一样的两种选择。其中SVC在任意核中可用,而LinearSVC只能运用于线性核,因此SVC的计算较复杂。这使得如果你决定使用线性SVM时,选择用LinearSVC会比另一个的操作速度快很多。本设计就是用到了LinearSVC,程序片段如下:SVC属于本设计所用到的sklearn中用于分类的SVM模型,SVR是另外提供的回归模型用于预测。调用这两种模型时的参数设置相似,简单介绍一下SVC如何设置参数。上面提及到的SVC()参数,其中的C是惩罚系数,可以解释为准许分类出错的权重(C越大,越不准许出错),越小,则准许少量划分出错。2.9模型评估在使用人工智能算法时,经过算法实现和模型训练后,可以对训练模型进行评估从而检查算法的性能好不好,以便进行优化得到想要的准确率。下面我们将用涉及到精确率(Precision)、召回率(Recall)和准确率(Accuracy)这几个判断标准的F1-score来进行模型评估:F1-score的定义:F1分数(F1-score)经常被用于衡量一些基于机器学习的两个以上分类问题比赛结果的判定标准。它是召回率和精确率的倒数平均数,值最大时等于1,最小时等于0。其表达式如下:(式2.8-1)(式2.8-1)F1-score的计算:1.首先给以下变量定义概念:TruePositive(TP):推测结果标准;FalsePositive(FP):错将别的标签为推测本类;TrueNegative(TN):推测结果标准;FalseNegative(FN):错将本类归类为别类标签;2.通过步骤1中的值算出的精准度和召回率。精准度(precision):指被分类器推测为正样本占正例总数的比值。(式2.8-2)(式2.8-2)召回率(recall):代表被推测为正样本占总正样本的比值。(式2.8-3)(式2.8-3)准确率(accuracy):指的是分类器对总样本推测正确的比值。(式2.8-4))(式2.8-4))3.通过步骤2计算结果得出各个类别下的f1-score,下面为计算公式:(式2.8-5)(式2.8-5)各个类别下的F1-score可通过步骤3计算得的值,从而测评出分类器各个指标结果,公式如下:(式2.8-6)(式2.8-6)f1_score函数在程序中的运用为了便捷使用f1_score函数可以直接在程序中加载sklearn包。分类器推段获取average

:string,[None,‘binary’(default),

‘macro’,

‘weighted’]类别,挑选好参数可事半功倍。当在意类别不稳定时,使用‘binary’参数来解决二分类问题;在考虑类别的不平衡性前提下,用‘weighted’参数能够算出类别的权重值;相反在不在意类别不稳定时,使用‘macro’参数,可以计算宏平均。相关代码如下: 3设计总结SVM之所以被广泛运用于处理分类问题,是因为它具备了较强的泛化和分类能力。一般有关SVM的分类方法很看重情感词,并将权重的情感词提取用作特征向量。而且存在的问题可分为以下三方面:(1)样本数据稀少问题。情感词集不能覆盖全部文档;(2)一词多种含义问题。由于一个情感词有时可以理解为多个语义,而造成的不同程度的情感偏差;(3)多个不同词表达的是一个语义问题。相同的的情感可以用许多的情感词去描述。当传统SVM方法遇到以上提及的3种情况时,其分类性能就会下降。由上述可知情感词与文档语义关系在这3个方面完全得以体现了。因此想要提高分类的精度,就需要考虑基于语义特征去分类,从而壮大情感词的分类规模。为了解决传统分类算法存在的上述问题,想到采用挖掘语义分类的方法,把情感词典和将要处理的文本结合起来,通过测量词与文本的语义差距用作特征向量。通过结合尚未发现的语义分析和SVM避开上文那3个问题。实验展示本文用到的方法在分类精确度真的有所提升。本文采用基于支持向量机(SVM)分类的机器学习方法,首先选择特征向量,将twitter的信息量丰富的情感词、表情符号等当做其特征向量,通过使用训练数据训练分类模型,得到一个情感分类器,最后对测试文本集进行划分。本设计用到了依照民众在twitter上的语言表达特色和语言表情规则,同时结合支持向量机(SVM)方法并完善SVM方法中的缺点,更大程度地优化其分类效果,提高分类结果的可靠性。从分类器对测试数据进行情绪预测的结果可知,最后的实验数据不错,其准确率和召回率都偏小,这更表明文本情绪分析在未来的研究中还可以走的更远。最后总结一下文本分类的特殊性,不管是使用SVM还是其他工具分类时,都要记得考虑以下几方面:在文本预处理过程中执行的很多步骤对最终使用分类工具时都会产生一定影响。文本特征向量的选择极其重要,因为即使你使用的分类器很强大,你的文本特征选择的不好,最后也未必能训练得到效果好的分类结果。不好的文本特征向量,给你多好的参数你都很难去训练提升优化你的分类器,一个不好的分类器,很容易在实际测试中出现错误分类的情况。在文本预处理和使用分类工具进行训练时,你所选择的训练集本和测试集数据文本都会对其效果产生影响。本设计的后续提升感想:在自然语言处理方面很难深度学习的优势更为凸显,深度学习的方法能够自动进行特征提取、自主学习修正输出、能很好地处理非线性复等杂数据。正成为众多学者对于情绪分类的热点研究对象,深度学习的方法将使文本情感分析研究走上更高的阶层,实现更好的分类的效果。4参考文献SubasicP,HuettnerA.Affectanalysisoftextusingfuzzysemantictyping[J].IEEETransactionsonFuzzySystems,2001,9(4):483-496熊德兰,程菊明,田胜利.基于HowNet的句子褒贬倾向性研究[J].计算机工程与应用,2008,44(22):143—145唐慧丰,谭松波,程学旗.基于监督学习的中文情感分类技术比较研究[J].中文信息学报,2007,21(6):88—94徐军,丁宇新,王晓龙.使用机器学习方法进行新闻的情感自动分类[J].中文信息学报,2007,21(6):95—100闻彬,何婷婷,罗乐,等.基于语义理解的文本情感分类方法研究[J].计算机科学,2010,37(6):261—264段建勇,谢宇超,张梅.基于句法语义的网络舆论情感倾向性评价技术研究IJ].情报杂志,2012,31(1):147—150高伟,王中卿,李寿山.基于集成学习的半监督情感分类方法研究[J].中文信息学报,2013,27(3):120—126谢丽星,周明,孙茂松.基于层次结构的多策略中文微博情感分析和特征抽取[J].中文信息学报,2012,26(1):73—83刘宝芹,牛耘.多层次中文微博情绪分析[J].计算机技术与发展2015,25(11):23—26欧阳纯萍,阳小华,雷龙艳,等.多策略中文微博细粒度情绪分析研究[J].北京大学学报(自然科学版),2014,50(1):67—72雷龙艳.中文微博细粒度情绪识别研究[D].衡阳:南华大学,20146附录6.1数据预处理程序代码#

-*-

coding:

utf-8

-*

import

re

import

sys

from

utils

import

write_status

from

nltk.stem.porter

import

PorterStemmer

#处理单词句子

def

preprocess_word(word):

word

=

word.strip('\'"?!,.():;')

word

=

re.sub(r'(.)\1+',

r'\1\1',

word)

word

=

re.sub(r'(-|\')',

'',

word)

return

word

def

is_valid_word(word):

return

(re.search(r'^[a-zA-Z][a-z0-9A-Z\._]*$',

word)

is

not

None)

def

handle_emojis(tweet):

tweet

=

re.sub(r'(:\s?\)|:-\)|\(\s?:|\(-:|:\'\))',

'

EMO_POS

',

tweet)

tweet

=

re.sub(r'(:\s?D|:-D|x-?D|X-?D)',

'

EMO_POS

',

tweet)

tweet

=

re.sub(r'(<3|:\*)',

'

EMO_POS

',

tweet)

tweet

=

re.sub(r'(;-?\)|;-?D|\(-?;)',

'

EMO_POS

',

tweet)

tweet

=

re.sub(r'(:\s?\(|:-\(|\)\s?:|\)-:)',

'

EMO_NEG

',

tweet)

tweet

=

re.sub(r'(:,\(|:\'\(|:"\()',

'

EMO_NEG

',

tweet)

return

tweet

def

preprocess_tweet(tweet):

processed_tweet

=

[]

tweet

=

tweet.lower()

tweet

=

re.sub(r'((www\.[\S]+)|(https?://[\S]+))',

'

URL

',

tweet)

tweet

=

re.sub(r'@[\S]+',

'USER_MENTION',

tweet)

tweet

=

re.sub(r'#(\S+)',

r'

\1

',

tweet)

tweet

=

re.sub(r'\brt\b',

'',

tweet)

tweet

=

re.sub(r'\.{2,}',

'

',

tweet)

tweet

=

tweet.strip('

"\'')

tweet

=

handle_emojis(tweet)

tweet

=

re.sub(r'\s+',

'

',

tweet)

words

=

tweet.split()

for

word

in

words:

word

=

preprocess_word(word)

if

is_valid_word(word):

if

use_stemmer:

word

=

str(porter_stemmer.stem(word))

processed_tweet.append(word)

return

'

'.join(processed_tweet)

def

preprocess_csv(csv_file_name,

processed_file_name,

test_file=True):

save_to_file

=

open(processed_file_name,

'w'

,

encoding='UTF-8')

with

open(csv_file_name,

'r'

,

encoding='UTF-8')

as

csv:

lines

=

csv.readlines()

total

=

len(lines)

for

i,

line

in

enumerate(lines):

tweet_id

=

line[:line.find(',')]

if

not

test_file:

line

=

line[1

+

line.find(','):]

positive

=

int(line[:line.find(',')])

line

=

line[1

+

line.find(','):]

tweet

=

line

processed_tweet

=

preprocess_tweet(tweet)

if

not

test_file:

save_to_file.write('%s,%d,%s\n'

%

(tweet_id,

positive,

processed_tweet))

else:

save_to_file.write('%s,%s\n'

%

(tweet_id,

processed_tweet))

write_status(i

+

1,

total)

save_to_file.close()

print

('\nSaved

processed

tweets

to(将已处理的推文保存到):

%s'

%

processed_file_name)

return

processed_file_name

if

__name__

==

'__main__':

if

len(sys.argv)

!=

2:

print

('请按这样的格式输入:

python3

preprocess.py

train.csv

')

exit()

use_stemmer

=

False

csv_file_name

=

sys.argv[1]

processed_file_name

=

sys.argv[1][:-4]

+

'-processed.csv'

if

use_stemmer:

porter_stemmer

=

PorterStemmer()

processed_file_name

=

sys.argv[1][:-4]

+

'-processed-stemmed.csv'

preprocess_csv(csv_file_name,

processed_file_name,

test_file=True,)

6.2模型程序代码from

sklearn

import

svm

import

utils

import

random

import

numpy

as

np

from

scipy.sparse

import

lil_matrix

from

sklearn.feature_extraction.text

import

TfidfTransformer

from

sklearn.metrics

import

accuracy_score

#调用准确率

from

sklearn.metrics

import

recall_score

#调用召回率

from

sklearn.metrics

import

f1_score

#调用F1度量

from

sklearn.metrics

import

confusion_matrix

#调用误差矩阵

#

Performs

classification

using

SVM.

FREQ_DIST_FILE

=

'train-processed-freqdist.pkl'

BI_FREQ_DIST_FILE

=

'train-processed-freqdist-bi.pkl'

TRAIN_PROCESSED_FILE

=

'train-processed.csv'

TEST_PROCESSED_FILE

=

'test-processed.csv'

TRAIN

=

True

UNIGRAM_SIZE

=

15000

VOCAB_SIZE

=

UNIGRAM_SIZE

USE_BIGRAMS

=

True

if

USE_BIGRAMS:

BIGRAM_SIZE

=

10000

VOCAB_SIZE

=

UNIGRAM_SIZE

+

BIGRAM_SIZE

FEAT_TYPE

=

'frequency'

def

get_feature_vector(tweet):

uni_feature_vector

=

[]

bi_feature_vector

=

[]

words

=

tweet.split()

for

i

in

range(len(words)

-

1):

word

=

words[i]

next_word

=

words[i

+

1]

if

unigrams.get(word):

uni_feature_vector.append(word)

if

USE_BIGRAMS:

if

bigrams.get((word,

next_word)):

bi_feature_vector.append((word,

next_word))

if

len(words)

>=

1:

if

unigrams.get(words[-1]):

uni_feature_vector.append(words[-1])

return

uni_feature_vector,

bi_feature_vector

def

extract_features(tweets,

batch_size=500,

test_file=True,

feat_type='presence'):

num_batches

=

int(np.ceil(len(tweets)

/

float(batch_size)))

for

i

in

range(num_batches):

batch

=

tweets[i

*

batch_size:

(i

+

1)

*

batch_size]

features

=

lil_matrix((batch_size,

VOCAB_SIZE))

labels

=

np.zeros(batch_size)

for

j,

tweet

in

enumerate(batch):

if

test_file:

tweet_words

=

tweet[1][0]

tweet_bigrams

=

tweet[1][1]

else:

tweet_words

=

tweet[2][0]

tweet_bigrams

=

tweet[2][1]

labels[j]

=

tweet[1]

if

feat_type

==

'presence':

tweet_words

=

set(tweet_words)

tweet_bigrams

=

set(tweet_bigrams)

for

word

in

tweet_words:

idx

=

unigrams.get(word)

if

idx:

features[j,

idx]

+=

1

if

USE_BIGRAMS:

for

bigram

in

tweet_bigrams:

idx

=

bigrams.get(bigram)

if

idx:

features[j,

UNIGRAM_SIZE

+

idx]

+=

1

yield

features,

labels

def

apply_tf_idf(X):

transformer

=

TfidfTransformer(smooth_idf=True,

sublinear_tf=True,

use_idf=True)

transformer.fit(X)

return

transformer

def

process_tweets(csv_file,

test_file=True):

"""Returns

a

list

of

tuples

of

type

(tweet_id,

feature_vector)

or

(tweet_id,

sentiment,

feature_vector)

Args:

csv_file

(str):

Name

of

processed

csv

file

generated

by

preprocess.py

test_file

(bool,

optional):

If

processing

test

file

Returns:

list:

Of

tuples

"""

tweets

=

[]

print

('Generating

feature

vectors')

with

open(csv_file,

'r')

as

csv:

lines

=

csv.readlines()

total

=

len(lines)

for

i,

line

in

enumerate(lines):

if

test_file:

tweet_id,

tweet

=

line.split(',')

else:

tweet_id,

sentiment,

tweet

=

line.split(',')

feature_vector

=

get_feature_vector(tweet)

if

test_file:

tweets.append((tweet_id,

feature_vector))

else:

tweets.append((tweet_id,

int(sentiment),

feature_vector))

utils.write_status(i

+

1,

total)

print

('\n')

return

tweets

if

__name__

==

'__main__':

np.random.seed(1337)

unigrams

=

utils.top_n_words(FREQ_DIST_FILE,

UNIGRAM_SIZE)

if

USE_BIGRAMS:

bigrams

=

utils.top_n_bigrams(BI_FREQ_DIST_FILE,

BIGRAM_SIZE)

tweets

=

process_tweets(TRAIN_PROCESSED_FILE,

test_file=False)

if

TRAIN:

train_tweets,

val_tweets

=

utils.split_data(tweets)

else:

random.shuffle(tweets)

train_tweets

=

tweets

del

tweets

print

('Extracting

features

&

training

batches')

clf

=

svm.LinearSVC(C=0.1)

batch_size

=

len(train_tweets)

i

=

1

n_train_batches

=

int(np.ceil(len(train_tweets)

/

float(batch_size)))

for

training_set_X,

training_set_y

in

extract_features(train_tweets,

test_file=False,

feat_type=FEAT_TYPE,

batch_size=batch_size):

utils.write_status(i,

n

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论