朴素贝叶斯文本分类(python代码实现)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

朴素贝叶斯⽂本分类(python代码实现)
朴素贝叶斯(naive bayes)法是基于贝叶斯定理与特征条件独⽴假设的分类⽅法。

优点:在数据较少的情况下仍然有效,可以处理多分类问题。

缺点:对⼊输⼊数据的准备⽅式较为敏感。

使⽤数据类型:标称型数据。

下⾯从⼀个简单问题出发,介绍怎么使⽤朴素贝叶斯解决分类问题。

⼀天,⽼师问了个问题,只根据头发和声⾳怎么判断⼀位同学的性别。

为了解决这个问题,同学们马上简单的统计了7位同学的相关特征,数据如下:
头发声⾳性别
长粗男
短粗男
短粗男
长细⼥
短细⼥
短粗⼥
长粗⼥
长粗⼥
这个问题之前⽤做过了,这⾥我们换⼀种思路。

要是知道男⽣和⼥⽣头发长短的概率以及声⾳粗细的概率,我们就可以计算出各种情况的概率,然后⽐较概率⼤⼩,来判断性别。

假设抽样样本⾜够⼤,我们可以近似认为可以代表所有数据,假设上位7位同学能代表所有数据,这⾥⽅便计算~
由这7位同学,我们马上得出下⾯表格概率分布。

性别头发长声⾳粗
男1/31
⼥3/53/5
假设头发和声⾳都是独⽴特征,于是
男⽣头发长声⾳粗的概率=3/8*1/3*1=1/8
⼥⽣头发长声⾳粗的概率=5/8*3/5*3/5=9/40
因为1/8<9/40所以如果⼀个⼈,头发长,声⾳粗,那么这个⼈更可能是⼥⽣,于是出现这些特征就是⼥⽣。

其他特征依次类推。

这就是朴素贝叶斯分类⽅法。

是的,就是这么简单。

下⾯来解释原理,先看贝叶斯公式:
公式中,事件Bi的概率为P(Bi),事件Bi已发⽣条件下事件A的概率为P(A│Bi),事件A发⽣条件下事件Bi的概率为P(Bi│A)。

带⼊我们的例⼦中,判断头发长的⼈性别:
P(男|头发长)=P(头发长|男)*P(男)/P(头发长)
P(⼥|头发长)=P(头发长|⼥)*P(⼥)/P(头发长)
判断头发长、声⾳粗的⼈性别:
P(男|头发长声⾳粗)=P(头发长|男)P(声⾳粗|男)*P(男)/P(头发长声⾳粗)
P(⼥|头发长声⾳粗)=P(头发长|⼥)P(声⾳粗|⼥)*P(⼥)/P(头发长声⾳粗)
可以看到,⽐较最后⽐较概率,只⽤⽐较分⼦即可。

也就是前⾯计算头发长声⾳粗的⼈是男⽣⼥⽣的概率。

下⾯应⽤于⽂本分类,⽂本分类不想上⾯例⼦有具体的特征,需先建⽴⽂本特征。

以下为⽂本分类的⼀个简单例⼦。

1# _*_ coding:utf-8 _*_
2from numpy import *
3import re
4import random
5
6def loadDataSet(): #创建样例数据
7 postingList = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
8 ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
9 ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
10 ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
11 ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
12 ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
13 classVec = [0, 1, 0, 1, 0, 1] #1代表脏话
14return postingList, classVec
15
16def createVocabList(dataSet): #创建词库这⾥就是直接把所有词去重后,当作词库
17 vocabSet = set([])
18for document in dataSet:
19 vocabSet = vocabSet | set(document)
20return list(vocabSet)
21
22def setOfWords2Vec(vocabList, inputSet): #⽂本词向量。

词库中每个词当作⼀个特征,⽂本中就该词,该词特征就是1,没有就是0 23 returnVec = [0] * len(vocabList)
24for word in inputSet:
25if word in vocabList:
26 returnVec[vocabList.index(word)] = 1
27else:
28print("the word: %s is not in my Vocabulary!" % word)
29return returnVec
30
31
32def trainNB0(trainMatrix, trainCategory):
33 numTrainDocs = len(trainMatrix)
34 numWords = len(trainMatrix[0])
35 pAbusive = sum(trainCategory) / float(numTrainDocs)
36 p0Num = ones(numWords) #防⽌某个类别计算出的概率为0,导致最后相乘都为0,所以初始词都赋值1,分母赋值为2.
37 p1Num = ones(numWords)
38 p0Denom = 2
39 p1Denom = 2
40for i in range(numTrainDocs):
41if trainCategory[i] == 1:
42 p1Num += trainMatrix[i]
43 p1Denom += sum(trainMatrix[i])
44else:
45 p0Num += trainMatrix[i]
46 p0Denom += sum(trainMatrix[i])
47 p1Vect = log(p1Num / p1Denom) #这⾥使⽤了Log函数,⽅便计算,因为最后是⽐较⼤⼩,所有对结果没有影响。

48 p0Vect = log(p0Num / p0Denom)
49return p0Vect, p1Vect, pAbusive
50
51def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): #⽐较概率⼤⼩进⾏判断,
52 p1 = sum(vec2Classify*p1Vec)+log(pClass1)
53 p0 = sum(vec2Classify*p0Vec)+log(1-pClass1)
54if p1>p0:
55return 1
56else:
57return 0
58
59def testingNB():
60 listOPosts,listClasses = loadDataSet()
61 myVocabList = createVocabList(listOPosts)
62 trainMat=[]
63for postinDoc in listOPosts:
64 trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
65 p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
66 testEntry = ['love', 'my', 'dalmation'] # 测试数据
67 thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
68print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
69 testEntry = ['stupid', 'garbage'] # 测试数据
70 thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
71print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
72
73if__name__=='__main__':
74 testingNB()
1#输出结果
2 ['love', 'my', 'dalmation'] classified as: 0
3 ['stupid', 'garbage'] classified as: 1
参考:
- Machine Learning in Action
- 统计学习⽅法。

相关文档
最新文档