机器学习实战-朴素贝叶斯
2017-08-21 21:02
260 查看
使用python进行文本分类
# -*- coding: utf-8 -*- """ Created on Mon Aug 21 17:17:19 2017 @author: rocky """ #机器学习实战第四章 #朴素bayes #使用python进行文本分类 #从文本中构建词向量 from numpy import * def loadDataSet():#创建一个实验样本 postingList=[['my','dog','has','flea','problem','help','please'], ['maybe','not','take','him','to','dog','park','stupid'], ['my','dalmation','is','so','cute','I','love','him'], ['stop','posting','stupid','worthless','garbage'], ['mr','licks','ate','my','steak','how','to','stop','him'], ['quit','buying','worthless','dog','food','stupid']] classVec=[0,1,0,1,0,1]#1代表侮辱性文字,0代表正常言论 return postingList,classVec def createVocalList(dataSet): vocabSet=set([])#set返回一个不含重复词的列表 for document in dataSet: vocabSet=vocabSet|set(document)#创建两个集合的并集 return list(vocabSet) def setOfWord2Vec(vocabList,inputSet):#输入为经上个函数的结果以及 returnVec=[0]*len(vocabList)#创建一个全零向量 for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)]=1 else: print("the word: %s is not in my Vocabulary!" % word) return returnVec #以上的三个程序的作用: #程序1返回几篇文档和文本类别,程序2对程序1进行非重复处理并拼接,返回一篇文档 #程序3的输入分别对应程序2的结果和程序1中的第i篇文档,返回的结果是2的结果的每一个词 #是否出现在第i篇文章中。出现则是1,没出现则是0. #这样我们就把一篇文章(在第i篇文档环境下)转换成了一组数字
我们可以做这样的实验,在命令窗口输入以下:
listOPosts,listClasses=loadDataSet() data=[['my','dog'],['is','rain']] lis=createVocalList(data) lis Out[22]: ['rain', 'my', 'is', 'dog'] setOfWord2Vec(lis,listOPosts[5]) the word: quit is not in my Vocabulary! the word: buying is not in my Vocabulary! the word: worthless is not in my Vocabulary! the word: food is not in my Vocabulary! the word: stupid is not in my Vocabulary! Out[23]: [0, 0, 0, 1]
我们可以判断第六行的每个词是否出现在data中,从而得到data的数字表示,为后面对data进行概率计算(好坏属性判断)准备。
训练算法:从词向量计算概率
#训练算法:从词向量计算概率(假设二类分布,即只有两个属性) def trainNB0(trainMatrix,trainCategory): numTrainDocs=len(trainMatrix)#统计矩阵行数,即文档数 numWords=len(trainMatrix[0])#统计列数,即每个文档的字数 pAbusive=sum(trainCategory)/float(numTrainDocs)#计算文档属性的概率(P1,另一个就是P0) p0Num=zeros(numWords)#建立零向量,长度为文档字数 p1Num=zeros(numWords) p0Denom=0.0 p1Denom=0.0#以上是对概率的初始化 for i in range(numTrainDocs):#循环每个文档 if trainCategory[i]==1:#如果这个文档的属性是1 p1Num+=trainMatrix[i]#把第i行数据(或者第i个文档)赋给p1Num p1Denom+=sum(trainMatrix[i])#求该文档中1的和,赋给。。。 else: p0Num+=trainMatrix[i] p0Denom+=sum(trainMatrix[i]) p1Vect=p1Num/p1Denom p0Vect=p0Num/p0Denom return p0Vect,p1Vect,pAbusive
在命令行输入以下命令检验:
#建立自己的数据集和类别,不使用上面的。 data=[['to','my','worthless'],['dog','take','ate'],['stop','to','him']] listclass=[1,1,0] mylist=createVocalList(data) #mylist就是待检验的文档 mylist Out[17]: ['to', 'worthless', 'take', 'ate', 'my', 'him', 'dog', 'stop'] trainmat=[] #生成一个文本矩阵,代表着这个待检验文本在每个样本下的存在与否 for postindoc in data: trainmat.append(setOfWord2Vec(mylist,postindoc)) trainmat Out[21]: [[1, 1, 0, 0, 1, 0, 0, 0], [0, 0, 1, 1, 0, 0, 1, 0], [1, 0, 0, 0, 0, 1, 0, 1]] #计算各个概率 p0V,p1V,pAb=trainNB0(trainmat,listclass) pAb Out[23]: 0.66666666666666663 p0V Out[24]: array([ 0.33333333, 0. , 0. , 0. , 0. , 0.33333333, 0. , 0.33333333]) p1V Out[25]: array([ 0.16666667, 0.16666667, 0.16666667, 0.16666667, 0.16666667, 0. , 0.16666667, 0. ])
在trainNB0的循环中,循环参数是行数,也就是类别数,也就是3,而不是列数(8),这一点要注意。在上面自己的数据中,前两行类别都是1,那么经过i=0和i=1后,p1Num=(11111010)(两个向量相加),p1Denom=6(即3+3),经i=2后,p0Num=(10000101)(第三个向量),p0Denom=3。这样就可以计算概率了。
以上计算的是文本中每个词在各个类别下出现的概率。
测试算法,修改分类器
上面计算了各个词在每个类别下的概率,下面就要计算多个概率的乘积来获得文档属于某个类别的概率。那么如果一个词的概率为0,总结果就是0,这显然不行。所以进行简单处理,所有词的初始出现数为1,分母初始化2,修改上述程序。修改p0Num\p0Denom\p1Num\p1Denom的初值,以及最后的概率计算,改为对数运算。def trainNB0(trainMatrix,trainCategory): numTrainDocs=len(trainMatrix)#统计矩阵行数,即文档数 numWords=len(trainMatrix[0])#统计列数,即每个文档的字数 pAbusive=sum(trainCategory)/float(numTrainDocs)#计算文档属性的概率(P1,另一个就是P0) p0Num=ones(numWords)#建立o向量,长度为文档字数 p1Num=ones(numWords) p0Denom=2.0 p1Denom=2.0#以上是对概率的初始化 for i in range(numTrainDocs):#循环每个文档 if trainCategory[i]==1:#如果这个文档的属性是1 p1Num+=trainMatrix[i]#把第i行数据(或者第i个文档)赋给p1Num p1Denom+=sum(trainMatrix[i])#求该文档中1的和,赋给。。。 else: p0Num+=trainMatrix[i] p0Denom+=sum(trainMatrix[i]) p1Vect=log(p1Num/p1Denom) p0Vect=log(p0Num/p0Denom) return p0Vect,p1Vect,pAbusive
下面构建完整的分类器。
#创建朴素贝叶斯分类函数 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): p1=sum(vec2Classify*p1Vec)+log(pClass1) p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1) if p1>p0: return 1 else: return 0 #以下的命令其实是将一些命令窗口中的操作封装为一个函数,叫便利函数。节省输入时间。 def testingNB(): listOPosts,listClasses=loadDataSet() myVocabList=createVocalList(listOPosts) trainMat=[] for postinDoc in listOPosts: trainMat.append(setOfWord2Vec(myVocabList,postinDoc)) p0V,p1V,pAb=trainNB0(array(trainMat),array(listClasses)) testEntry=['love','my','dalmation'] thisDoc1=array(setOfWord2Vec(myVocabList,testEntry)) #上面这一句的意思是检查myVocabList中的文字是否出现在testEntry中 print(testEntry,'classified as: ',classifyNB(thisDoc1,p0V,p1V,pAb)) testEntry=['stupid','garbage'] thisDoc2=array(setOfWord2Vec(myVocabList,testEntry)) print(testEntry,'classified as: ',classifyNB(thisDoc2,p0V,p1V,pAb)) return thisDoc1,thisDoc2
最后的return thisDoc1,thisDoc2是自己加的,检查结果。后一个函数是封装了一些操作。命令窗口输入以下:
testingNB() ['love', 'my', 'dalmation'] classified as: 0 ['stupid', 'garbage'] classified as: 1 Out[31]: (array([0, 0, 0, ..., 1, 0, 0]), array([0, 0, 0, ..., 0, 1, 0]))
我们可以看到,thisDoc1结果是([0, 0, 0, …, 1, 0, 0]),中间有一些省略号,看不到中间是什么数据,这时我们可以在开头定义numpy的下面,输入一行’np.set_printoptions(threshold=np.inf)’,可以保证数据全部显示,另外我也将myVocabList输出(return稍作修改即可):
testingNB() ['love', 'my', 'dalmation'] classified as: 0 ['stupid', 'garbage'] classified as: 1 Out[42]: (array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0]), ['to', 'worthless', 'ate', 'quit', 'stop', 'steak', 'take', 'has', 'I', 'problem', 'park', 'dog', 'so', 'love', 'is', 'posting', 'flea', 'not', 'help', 'maybe', 'my', 'licks', 'food', 'cute', 'buying', 'stupid', 'how', 'please', 'him', 'dalmation', 'garbage', 'mr'])
以上我们可以看到[‘love’, ‘my’, ‘dalmation’]的出现,用1表示,而之前我们得到了一个概率分布,这样thisDoc1(thisDoc2)表示待测文本在当前环境下的表示(仍保持thisDoc1的意义),这样再利用函数classifyNB就可以计算thisDoc1是否属于侮辱性文档的概率。
注:处理垃圾邮件尚未学习,等回顾上述思路待后续。
相关文章推荐
- [机器学习实战] 基于概率论的分类方法:朴素贝叶斯
- 机器学习实战第四章-朴素贝叶斯
- 机器学习实战--朴素贝叶斯
- 机器学习理论与实战(三)朴素贝叶斯
- 机器学习实战python版 朴素贝叶斯示例 垃圾邮件分类 从个人广告中获取趋于趋向
- 机器学习实战笔记-朴素贝叶斯
- 机器学习理论与实战(三)朴素贝叶斯
- 机器学习实战(3)--(基于概率论的分类方法)朴素贝叶斯
- 机器学习实战---读书笔记: 第4章 基于概率论的分类而方法:朴素贝叶斯
- 机器学习实战 - 读书笔记(04) - 朴素贝叶斯
- 机器学习实战-朴素贝叶斯
- 机器学习实战之朴素贝叶斯
- 机器学习理论与实战(三)朴素贝叶斯
- 机器学习理论与实战(三)朴素贝叶斯
- 机器学习实战笔记(3.3)-朴素贝叶斯算法(多项式模型的朴素贝叶斯实现)
- 【读书笔记】机器学习实战-4.5节 贝叶斯文本分类
- 机器学习笔记:朴素贝叶斯
- [机器学习][源码]机器学习实战ch4 朴素贝叶斯
- 机器学习入门03-朴素贝叶斯
- 机器学习经典算法3-朴素贝叶斯