一、基于条件概率的分类
1.基于贝叶斯决策理论的分类方法
在机器学习中,概率论也是一个总要的基础知识,下面我们就学习一些使用概率论进行分类的方法。叫朴素贝叶斯分类器。之所以称之为朴素,是因为整个形式化的过程只做最原始、最简单的假设。从最简单的概率开始说起,假设我们有两类数据,p1(x,y)表示我们的数据点(x,y)属于类别1的概率,p2(x,y)表示数据点(x,y)属于类别2的概率。对于一个新的数据点(x,y)可以用下面的规则来判断他的类别:
- 如果p1(x,y) > p2(x,y),那么属于类别1
- 如果p2(x,y) > p1(x,y),那么属于类别2
简单的说就是选择概率高所对应的类别,这就是贝叶斯决策理论的核心思想,选择最高概率的决策。
2.条件概率
什么是条件概率呢?简单的理解就是当一件事情发生时,另一件事情发生的概率。接下来就简单的讨论一下条件概率。
图中一共七个小球,我们很容易得到灰色石头的概率为p(gray)=3/7,黑色石头的概率p(black)=4/7。但是,将这七个球放入不同的桶中,又应该怎么求概率呢?
要想计算p(gray)和p(black),需要考虑到石头所在桶的信息,要计算从B桶中取到灰色石头的概率的方法。这就是条件概率,假定计算的是从B桶中取到灰色石头的概率的,可以记作p(gray|bucketB),称之为在已知石头出自B桶的条件下,取出灰色石头的概率。可以得到p(gray|bucketA)=2/4,p(gray|bucketB)=1/3。条件概率的计算公式如下:p(gray|bucketB)=p(gray and bucketB) / p(bucketB)。我们来验证一下这个公式。首先,用B桶中灰色石头的个数除以两个桶中总的石头数,得到p(gray and BucketB) = 1/7。其次,由于B桶中有3块石头,总石头数为7,于是选择B桶的概率为p(bucketB)=3/7。于是有p(gray|bucketB)=p(gray and bucketB) / p(bucketB)=(1/7)/(3/7)= 1/3。计算条件概率还有另外一种方法,就是贝叶斯准则。贝叶斯准则告诉我们如何交换条件概率中的条件与结果。即已知p(x|c), 要求p(c|x)。可以使用贝叶斯公式:
3.使用条件概率来分类
上边我们使用贝叶斯决策理论来计算概率进行分类,但是,那不是贝叶斯决策理论的全部内容,真正需要计算的是和,意义是给定某个数据点,该数据点来自的概率是多少。我们可以通过贝叶斯准则计算:。最后分类的准则就为:
贝叶斯准则,可以通过已知的三个概率来计算未知的概率值。下面,我们就要使用贝叶斯准则计算概率并对数据进行分类。
- 如果 > ,那么属于类别1
- 如果 > ,那么属于类别2
二、使用朴素贝叶斯进行文档分类
在文档分类中,整个文档是一个实例,而文档中的某些元素构成特征。我们观察文档中出现的词,并把每个词出现与不出现作为一个特征。这样得到的特征数目就会跟词汇表中的词目一样多。朴素贝叶斯中朴素的含义就是假设数据特征是相互独立的,即一个特征或者单词出现的可能性与它和其他单词相邻没有关系。另一个假设是每个特征是同等重要的。
1.从文本中构建词向量
我们把文本看成单词向量或者词条向量,也就是将句子转换为向量,然后将出现的单词纳入词汇表或者说所要的词汇集合。最后在转换为词汇表上的向量。
def loadDataSet():
""" 创建测试数据 """
postingList = [['my', 'dog', 'has', 'flea', 'problems', '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 createVocabList(dataSet):
""" 创建词汇表 """
vocabSet = set([])
for document in dataSet:
vocabSet = vocabSet | set(document) # 合并两个集合,求并集
return list(vocabSet)
def setOfWords2Vec(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
2. 从词向量计算概率
根据贝叶斯公式计算条件概率,我们用w表示词向量,则计算条件概率的贝叶斯公式为:,我们需要计算和。我们利用矩阵来实现计算过程。
def trainNB0(trainMatrix, trainCategory):
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory) / float(numTrainDocs) # 属于侮辱性文档的概率
p0Num = ones(numWords)
p1Num = ones(numWords)
p0Denom = 2.0
p1Denom = 2.0
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = log(p1Num / p1Denom) # 侮辱性文档中每个词出现的概率
p0Vect = log(p0Num / p0Denom) # 正常言论每个词出现的概率
return p0Vect, p1Vect, pAbusive
我们首先计算侮辱性文档的概率,然后初始化计算单词个数的全为1的矩阵p0Num和p1Num,并初始化词的总数p0Denom和p1Denom。分别计算不同类别下每个词出现的概率,最后的概率做对数运算是因为方式小数相乘值溢出的情况。
3. 测试算法
我们根据计算好的概率,计算最后的条件概率并进行分类。最后,定义一个测试函数,测试我们的朴素贝叶斯分类器的效果
def classifyNB(vec2Classigy, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classigy * p1Vec) + log(pClass1)
p0 = sum(vec2Classigy * p0Vec) + log(1.0 - pClass1)
if p1 > p0:
return 1
else:
return 0
def testingNB():
listOPosts, listClasses = loadDataSet()
myVocabList = createVocabList(listOPosts)
trainMat = []
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
testEntry = ['love', 'my', 'dalmation']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print(testEntry, 'classified as:', classifyNB(thisDoc, p0V, p1V, pAb))
testEntry = ['stupid', 'garbage']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print(testEntry, 'classified as:', classifyNB(thisDoc, p0V, p1V, pAb))
testingNB()
结果:
['love', 'my', 'dalmation'] classified as: 0
['stupid', 'garbage'] classified as: 1
三、使用朴素贝叶斯过滤垃圾邮件
使用朴素贝叶斯进行电子邮件的过滤是一个经典的应用。我们实现这个示例,从文本的切分开始,然后利用上边的相关函数实现。
代码链接:https://github.com/guoyuantao/MachineLearning/tree/master/Naive_Bayes
注意:此文章的内容参考《机器学习实战》。博客的主要目的为记录个人所学的知识。