朴素贝叶斯学习笔记

本文为学习《统计学习方法》、《机器学习实战》朴素贝叶斯相关的笔记。

朴素贝叶斯,是基于贝叶斯定理特征条件独立假设的分类方法。

特征条件独立假设是指:给定一个实例的类标签,实例中的每个属性的出现都独立于实例中其他属性的出现。这也是算法被称为朴素贝叶斯的原因。

公式推导

我们有数据集T = \left \{ (x_1,y_1),(x_2,y_2),...(x_N,y_N) \right \},其中输入为特征向量 x,输出为类标记 y。朴素贝叶斯要通过数据集学习先验概率和条件概率。

先验概率:P(y=y_k),k=1,2...K    这里代表数据集中的每个类别的概率

条件概率:P(X=x|Y=y_k) = P(X^{(1)}=x^{(1)},...X^{(n)}=x^{(n)}|Y=y_k),k=1,2...K    这里代表在类别为 y_k时,输入的特征向量中的每一个特征值为对应的 x^{(n)}的概率。

对条件概率分布作条件独立性的假设,即特征之间不相关,可以得出P(X=x|Y=y_k) = P(X^{(1)}=x^{(1)},...X^{(n)}=x^{(n)}|Y=y_k) =\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=y_k)

在分类时,对于给定的 x,通过学习到的模型计算得到后验概率 P(Y=y_k|X=x),将后验概率最大的类作为 x 的类输出。后验概率计算根据贝叶斯定理进行 :

P(Y=y_k|X=x) = \frac{P(X=x|Y=y_k)P(Y=y_k)}{\sum_{k=1}^{K}P(X=x|Y=y_k)P(Y=y_k)}    

将 上上式代入上式,可得 y = argmaxP(Y=y_k)\prod P(X^{(j)}=x^{(j)}|Y=y_k),代表在后验概率最大时对应的 y 值。

一个例子

这个例子来自于《机器学习实战》,是根据词条中词汇的出现判断其是否是侮辱性词条。

我们构造以下数据:

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代表侮辱性
    return postingList,classVec

       在计算先验概率和条件概率之前我们需要将输入向量统一化,即对于每个词条进行处理,将其用具有相同的特征数量的特征向量来表示。以下第一个函数创建一个词汇列表 vocablist,包含所有词条中所有词汇;第二个函数创建一个长度为词汇列表长度的向量,对于词条中的每个词汇,若出现在词汇列表中,则将向量中对应位置置为1。相当于我们的输入向量 x 为一个有len(vocablist)个特征的向量,每个特征可取 0 和 1,代表出现或不出现。

#创建词汇列表
def createVocabList(dataSet):
	vocabSet = set([])
	for document in dataSet:
		vocabSet = vocabSet | set(document)
	return list(vocabSet)

#将词条转换为输入向量
def setOfWords2Vect(vocabList,inputSet):
	returnVec = [0]*len(vocabList)
	for word in inputSet:
		if word in inputSet:
			returnVec[vocabList.index(word)] = 1
		else: 
			print('This word:',word,' is not in my Vocalbulary')
	return returnVec

接着计算先验概率和条件概率:

def trainNB0(trainMatrix,trainCategory):
	numDocs = len(trainMatrix)
	numWords = len(trainMatrix[0])
	#在所有样本中是某种类别的概率
	pAbusive = sum(trainCategory)/float(numWords) 
	p0Num = np.ones(numWords)
	p1Num = np.ones(numWords)
	p0Sum = 2; p1Sum = 2
	for i in range(numDocs):
		if(trainCategory[i]==1):
			p1Num += trainMatrix[i]
			p1Sum += sum(trainMatrix[i])
		else:
			p0Num += trainMatrix[i]
			p0Sum += sum(trainMatrix[i])
	p0Vect = np.log(p0Num/p0Sum)
	p1Vect = np.log(p1Num/p1Sum)
	return p0Vect,p1Vect,pAbusive

以上pAbusive相当于我们的 P(y=1),而 P(y=0) = 1-pAbusice。至此得出先验概率。

条件概率 P(X=x|y=1) = p1Vect ,P(X=x|y=0) = p0Vect。 

p0Vect,p1Vect均为长为 len(vocablist) 的向量,分别表示类别为非侮辱性和侮辱性时词条向量中各词汇的出现概率。

最后对给定的向量 x 进行判断:

def classifyNB(vec2classify,p0V,p1V,pClass1):
	p1 = np.sum(vec2classify*p1V)+np.log(pClass1)
	p0 = np.sum(vec2classify*p0V)+np.log(1-pClass1)
	if p1>p0:
		return 1
	else:
		return 0 

至此,用朴素贝叶斯进行简单的判断词条是否是侮辱性词条的例子结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值