朴素贝叶斯中文情感分类

1、写在前面

朴素贝叶斯算法理论在很多博客上已经解释的很详细了,本文就不再叙述,本文注重于算法的应用以及编程实现,在读取前人的博客以及他们的项目应用,本人结合书本《机器学习算法原理与编程实践_郑捷》中的贝叶斯算法介绍,将其运用于中文情感分类中,书本中的代码运用了矢量编程,代码块简练易懂,这样也能提高对算法的理解。

本人对贝叶斯分类的理解,简单的概括就是:要想由什么特征属性来判定属于哪种分类,即求,可以由在这种分类中具有这些特征属性的概率求得,而可以通过训练集得到。算法针对中文文本分析,情感分类区别在于特征属性的选择,前者是将所有文本内容的分词去除重复后,得到词典,后者是将情感词作为特征属性,情感词由各大学教授,权威人士在各自研究领域内公布了各自的情感分词库,免费公开(真诚感谢)。中文文本分析的编程实现已在上面提到的书本内完成,因它采取的是Scikit-Learn模块的朴素贝叶斯分类模块,可以进Scikit-Learn官方网站下载朴素贝叶斯分类模块源码学习,也可以自己编写贝叶斯算法类,本人觉得自己编写贝叶斯算法类有利于对算法的理解,在理解后,再采取Scikit-Learn模块进行相应的项目开发。故本人将书本中编写的贝叶斯算法类运用在中文情感分类中,增加对算法的理解。

2、项目实践

本人实现的中文情感分类过程,分为两个部分:(1)训练集数据的准备过程,(2)文本情感分类;

训练集数据的准备过程分为:

(1)文本下载:文本下载的方式有很多,其中高效的方法就是从文本网站上下载各个文章,下载可采取网络爬虫方法,可采取python+scrapy框架的方法对文本网页进行文章自动爬取(链接:https://pan.baidu.com/s/1EJ2QLjw_bEUza5JG9jDSLQ 密码:czuo),共下载文本(497)然后对文本进行分类,语料包括:积极文本(150),消极文本(266),其他的因情感倾向不明显,就不加入训练集。

(2)中文分词,本人将(1)中的文本采取jieba模块进行中文分词(代码在后面贴上)

(3)下载情感词典,链接: http://pan.baidu.com/s/1u12m0 ,来自台湾大学教授免费公布(再次感谢)

将爬虫到的xml文本进行解析以及中文分词,得到语料结构为list[[文本1],[文本2],[文本3]...[文本n]],代码如下:

#xml文件解析
# -*- coding: utf-8 -*-
import sys
import os
import jieba
from lxml import etreeclass GetCorpus(object):def savefile(self,path,content):fp=open(path,"w")jiebacontent=[]for word in content.split():if (word !='[' and word!=']' and word!="'" and word!="'"):jiebacontent.append(word)fp.write(str(jiebacontent))fp.close()def readfile(self,path):fp=open(path,"rb")content=fp.read()fp.close()return content#获取未分词语料#list xml文件路径,parse_list语料路径#xml文件内容def wordparse(self,html):page_source = etree.HTML(html)title = page_source.xpath("//tok[@type='group']/tok[@type='atom']/text()")words=[]for word in title:#str(word).replace()words.append(word)wordsString=[]string=""for word in words:string+=wordstring = string.replace("\n", "")string = string.replace("\t", "")wordsString.append(string)return wordsString
#中文文本解析
 
import sys
import os
import jieba
from lxml import etree
from xmlParse import *
import pickle
#dunp 写入
def writedumpobj(path,obj):file=open(path,"wb")pickle.dump(obj,file)file.close()#dump 读取
def readdumpobj(path):file=open(path,"rb")bunch=pickle.load(file)file.close()return bunchdef _jieba():postingList=[]os.chdir('D:/linguistic-corpus/')xml_path=r"500trainblogxml/"#parse_path=r"train_corpus_small/"#parse xml语句解析目录parse_path = r"train_corpus_seg/"catelist=os.listdir(xml_path)#xml文件目录路径cr=GetCorpus()#导入xml文件解析的类classVec=[]i=0for mydir in catelist:i += 1class_path=xml_path+mydir+"/"# 分类子目录路径seg_dir=parse_path+mydir+"/"if not os.path.exists(seg_dir):os.makedirs(seg_dir)file_list=os.listdir(class_path)for file_path in file_list:if i==1:classVec.append(1)#建立类别标签if i==2:classVec.append(0)#建立类别标签fullname=class_path+file_pathcontent=cr.readfile(fullname)contentpurse=cr.wordparse(content.decode("utf-8"))seg_list=jieba.cut(str(contentpurse))replase_seg_list=" ".join(seg_list).replace("[ '","").replace("' ]","")#删除一些无用字符串split_seg_list = replase_seg_list.split()postingList.append(split_seg_list)writedumpobj("D:\linguistic-corpus\postingList\postingList.dat",postingList)  # 写入分词,持久化保存writedumpobj("D:\linguistic-corpus\postingList\classVec.dat",classVec)#写入分类print(i)return postingListif __name__=="__main__":postingList=_jieba()
 
 
 

训练集准备就绪,以下进行文本分类

import pickle
import numpy as npdef readdumpobj(path):file=open(path,"rb")bunch=pickle.load(file)file.close()return bunchdef outemotionword(path):emotionset=[]with open(path,"rb") as fp:for word in fp:if not word.isspace():word=word.decode("utf-8")emotionset.append(word.strip())return emotionsetdef loadDataSet(path):#path是为了读入将情感词典postingList=readdumpobj("D:\linguistic-corpus\postingList\postingList.dat")classVec=readdumpobj("D:\linguistic-corpus\postingList\classVec.dat")emotionset=outemotionword(path)return postingList, classVec,emotionsetclass NBayes(object):def __init__(self):self.vocabulary = [] # 词典,文本set表self.idf=0           # 词典的idf权值向量self.tf=0            # 训练集的权值矩阵self.tdm=0           # P(x|yi)self.Pcates = {}     # P(yi)--是个类别字典self.labels=[]       # 对应每个文本的分类,是个外部导入的列表[0,1,0,1,0,1]self.doclength = 0   # 训练集文本数,训练文本长度self.vocablen = 0    # 词典词长,self.vocabulary长度self.testset = 0     # 测试集#   加载训练集并生成词典,以及tf, idf值def train_set(self,trainset,classVec,emotionset):self.cate_prob(classVec)   # 计算每个分类在数据集中的概率:P(yi)self.doclength = len(trainset)tempset = set()[tempset.add(word) for word in emotionset ] # 生成词典self.vocabulary = list(tempset)self.vocablen = len(self.vocabulary)#self.calc_wordfreq(trainset)self.calc_tfidf(trainset)  # 生成tf-idf权值self.build_tdm()           # 按分类累计向量空间的每维值:P(x|yi)# 生成 tf-idfdef calc_tfidf(self,trainset):self.idf = np.zeros([1,self.vocablen])self.tf = np.zeros([self.doclength,self.vocablen])for indx in range(self.doclength):for word in trainset[indx]:if word in self.vocabulary:self.tf[indx,self.vocabulary.index(word)] +=1# 消除不同句长导致的偏差self.tf[indx] = self.tf[indx]/float(len(trainset[indx]))for signleword in set(trainset[indx]):if signleword in self.vocabulary:self.idf[0,self.vocabulary.index(signleword)] +=1self.idf = np.log(float(self.doclength)/(self.idf+1))#防止该词语不在语料中,就会导致分母为零self.tf = np.multiply(self.tf,self.idf) # 矩阵与向量的点乘# 生成普通的词频向量def calc_wordfreq(self,trainset):self.idf = np.zeros([1,self.vocablen]) # 1*词典数self.tf = np.zeros([self.doclength,self.vocablen]) # 训练集文件数*词典数for indx in range(self.doclength):    # 遍历所有的文本for word in trainset[indx]:          # 遍历文本中的每个词if word in self.vocabulary:self.tf[indx,self.vocabulary.index(word)] +=1  # 找到文本的词在字典中的位置+1for signleword in set(trainset[indx]):if signleword in self.vocabulary:self.idf[0,self.vocabulary.index(signleword)] +=1# 计算每个分类在数据集中的概率:P(yi)def cate_prob(self,classVec):self.labels = classVeclabeltemps = set(self.labels) # 获取全部分类for labeltemp in labeltemps:# 统计列表中重复的值:self.labels.count(labeltemp)self.Pcates[labeltemp] = float(self.labels.count(labeltemp))/float(len(self.labels))#按分类累计向量空间的每维值:P(x|yi)def build_tdm(self):self.tdm = np.zeros([len(self.Pcates),self.vocablen]) #类别行*词典列sumlist = np.zeros([len(self.Pcates),1])  # 统计每个分类的总值for indx in range(self.doclength):self.tdm[self.labels[indx]] += self.tf[indx]  # 将同一类别的词向量空间值加总sumlist[self.labels[indx]]= np.sum(self.tdm[self.labels[indx]])  # 统计每个分类的总值--是个标量self.tdm = self.tdm/sumlist   # P(x|yi)# 测试集映射到当前词典def map2vocab(self,testdata):self.testset = np.zeros([1,self.vocablen])#删除测试集中词不在训练集中for word in testdata:if word  in self.vocabulary:self.testset[0,self.vocabulary.index(word)] +=1# 输出分类类别def predict(self,testset):if np.shape(testset)[1] != self.vocablen:print ("输入错误")exit(0)predvalue = 0predclass = ""for tdm_vect,keyclass in zip(self.tdm,self.Pcates):# P(x|yi)P(yi)temp = np.sum(testset*tdm_vect*self.Pcates[keyclass])if temp > predvalue:predvalue = temppredclass = keyclassreturn predclassif __name__=="__main__":postingList,classVec,emotionset=loadDataSet("D:\sentiment-word\emotionword.txt")testset=postingList[119]nb = NBayes()  # 类的实例化nb.train_set(postingList,classVec,emotionset)  # 训练数据集nb.map2vocab(testset)  # 随机选择一个测试句,这里2表示文本中的第三句话,不是脏话,应输出0。print(nb.predict(nb.testset))  # 输出分类结果0表示消极,1表示积极print("分类结束")

结合代码,文本情感分类这一部分是算法核心,具体解析过程如下:

重点:文本情感分类有两种加权方法,一种是词频加权,一种是TF-IDF策略,这里重点分析下tf-idf策略以及怎么通过训练集求出,即代码中 def calc_tfidf(self,trainset),def cate_prob(self,classVec)函数的解析

首先了解下如下几个数据结构:

a、idf矩阵:

 n为情感词典词的总数,元素表示情感词编号m在所有文本中出现的次数,注意:如果在一文本中情感词 m 出现了多次,也只算一次。接着将上面的idf数组转化为逆向文件频率。

self.idf = np.log(float(self.doclength)/(self.idf+1))#防止该词语不在语料中,就会导致分母为零。

b、tf矩阵:

其中,n表示情感词典词的总数,m表示所有文本个数,即创建了一个二维矩阵,矩阵元素表示在文本标号m中,出现标号为n的情感词的词频,接着再将tf消除不同句长导致的偏差。

self.tf[indx] = self.tf[indx]/float(len(trainset[indx]))

即将矩阵元素除以标号为m文本的所有单词数

这样tf,idf数组向量求出后再相乘,就得到了TF-IDF权重,将权重再赋予tf矩阵

不得不说,这个策略对文本分类的重要性。

c、tdm矩阵

既然权重得到了,接下来就是求,即

这个概率,本人在捉摸多次后理解如下:

首先,建立tdm矩阵,矩阵行为分类数,在本项目中,行数就为2,列为情感词典个数,为11086,而将tf中属于同一类的行相加,即得到tdm矩阵。

其次,建立sunlist矩阵,行数为分类数,列数为1,其元素是一标量,将tdm的属于同一类的行数元素累加,比如具体点的就是将tdm中是积极类的行数累加,

那么tdm=tdm/sumlista就是,即tdm最终保存的是在一分类中具有这些特征属性的概率。

得到tdm矩阵后,就可以对测试文本进行分类了,首先,必须要将测试文本进行分词,本代码是输入的是直接分词好的。然后将测试集映射到当前词典,得到测试向量testset即情感词典,就是求在测试文本中,各个情感词出现的频数,然后将testset与tdm矩阵相乘,将结果最大的值对应的分类作为这个测试文本的分类。

3、写在后面

一起学习,真诚感谢!

机器学习:朴素贝叶斯算法+中文情感分类+python相关推荐

  1. 机器学习朴素贝叶斯算法+tkinter库界面实现好瓜坏西瓜分类

    机器学习朴素贝叶斯算法+tkinter库界面实现好瓜坏西瓜分类 一.界面实现 from tkinter import * from tkinter import ttk import NBdef ma ...

  2. Python微调文本顺序对抗朴素贝叶斯算法垃圾邮件分类机制

    封面图片:<Python可以这样学>,ISBN:9787302456469,董付国,清华大学出版社 图书详情(京东): ================= 关于朴素贝叶斯算法中文垃圾邮件分 ...

  3. 机器学习朴素贝叶斯算法_机器学习中的朴素贝叶斯算法

    机器学习朴素贝叶斯算法 朴素贝叶斯算法 (Naive Bayes Algorithm) Naive Bayes is basically used for text learning. Using t ...

  4. 机器学习——朴素贝叶斯算法(垃圾邮件分类)

    朴素贝叶斯算法介绍以及垃圾邮件分类实现 1.一些数学知识 2.贝叶斯公式 3.朴素贝叶斯算法 (1)介绍 (2)核心思想 (3)朴素贝叶斯算法 (4)拉普拉斯修正 (5)防溢出策略 (6)一般过程 ( ...

  5. 5 机器学习 朴素贝叶斯算法 高斯模型 多项式模型 伯努利模型 拉普拉普平滑系数 TfidfVectorizer

    机器学习 1 朴素贝叶斯算法 1.1 朴素贝叶斯算法介绍 朴素贝叶斯算法是一种衡量标签和特征之间概率关系的监督学习算法,是一种专注于分类的算法."朴素"二字表示这个算法基于一个朴素 ...

  6. 朴素贝叶斯算法----评论情感分析系统

    文章目录 前言 Step1: 爬取京东评论,作为模型数据集 测试爬虫 爬取6000条好评信息作为数据集,并存储为CSV文件 爬取4000条差评信息作为数据集,并存储为CSV文件 Step2: 读取数据 ...

  7. 贝叶斯文本分类python_scikit_learn 中朴素贝叶斯算法做文本分类的 实践总结

    朴素贝叶斯算法对于分类非常高效 想了解的可以参考这篇博文:贝叶斯从浅入深详细解析,详细例子解释 - zwan0518的专栏 - 博客频道 - CSDN.NET贝叶斯从浅入深 先来做个小小总结说明 在这 ...

  8. 机器学习——朴素贝叶斯算法

    朴素贝叶斯算法 1.引言 2.朴素贝叶斯分类方法 3.概率基础 4.朴素贝叶斯特征提取 5.朴素贝叶斯分类的sklearn实现 6.垃圾短息分类 补充 1.引言 贝叶斯方法是一个历史悠久,有着坚实的理 ...

  9. 机器学习-朴素贝叶斯算法

    简介 NaïveBayes算法,又叫朴素贝叶斯算法,朴素:特征条件独立:贝叶斯:基于贝叶斯定理.属于监督学习的生成模型,实现简单,没有迭代,并有坚实的数学理论(即贝叶斯定理)作为支撑.在大量样本下会有 ...

最新文章

  1. PHP回收机制性能方面考虑的因素
  2. SAP ABAP 客户退出
  3. 数据交互智能终端设想
  4. Scala学习笔记(1)-环境搭建
  5. weblogic IllegalArgumentException 解决办法
  6. spring的前后台数据传输。
  7. Google 推荐和鼓励的 13 条代码审查标准,建议收藏!
  8. 《JSP实用教程(第2版)/耿祥义》错误之tomcat虚拟服务目录
  9. 打印机无法打印测试页是什么原因
  10. git difftool 使用 p4merge,DiffMerge 或者 Beyond Compare 4
  11. linux支持hd610显卡吗,奔腾G4560核显怎么样且HD610相当于什么级别的显卡?
  12. 惠普笔记本触摸板失灵
  13. css的div纵向居中
  14. MATLAB周边第三期-坤坤的唱跳rap
  15. 知乎热门:找工作时单位普遍要求 35 岁以下,那 35 岁以上的人都干嘛去了?
  16. 基于django的图书商城管理系统毕业设计源码110938
  17. 构造函数创造对象--创建四大天王的对象
  18. Google Play上架App设置隐私政策声明问题
  19. 英文论文写作注意事项整理
  20. Pytorch 实现全连接神经网络/卷积神经网络训练MNIST数据集,并将训练好的模型在制作自己的手写图片数据集上测试

热门文章

  1. 微信小程序开发学习文档(万字总结,一篇搞定前端开发)
  2. HDU 4382 【矩阵快速幂】【欧拉降幂】
  3. qfn封装怎么焊接_qfn封装焊接教程
  4. 重力加速度陀螺仪传感器MPU-…
  5. 使用word批量将.docx(或者.doc)转成.pdf
  6. android的今日头条软件怎么删除,如何把今日头条账号注销 退出账号的方法教程[多图]...
  7. 安卓So(C代码)MD5算法
  8. 思科devnet_CCNA、CCNP、CCIE及Devnet认证
  9. 智驾科技招聘|SLAM算法总监、感知定位、高精地图等岗位(20~50K)
  10. 中国命理学史论-第一章传统命理学的现代诠释