码迷,mamicode.com
首页 > 其他好文 > 详细

贝叶斯分类

时间:2017-04-21 22:41:37      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:独立   排序   color   add   append   ase   存在   决策   需要   

贝叶斯分类

  • 原理

  贝叶斯最基本的思想就是条件概率公式+条件独立假设。

  它的思想有点类似于奥卡姆剃刀原理,举个例子,当前眼前走过一个黑人的时候,为你他是那里人,你第一眼想到的是他是个非洲人。因为非洲人普遍皮肤黑。

  贝叶斯分类思想与此类似,当问你某个数据实例属于某个类别时候,会先去求各个类别下出现该数据实例的概率是多少,那个类别下概率越大,就分为哪个类别。

  条件概率公式:

P(xy) = P(y|x)*P(x) = P(x|y)*P(y)

=>     P(y|x) = P(x|y)*P(y) / P(x)

  而贝叶斯公式:当X是由一组完备的事件组成的时候,P(X) = P(x1)*...*P(xn)

  对于给定特征向量X,它的类别为Yc:

 Yc = max i P(Yi|X) = max i { P(X|Yi)*P(Yi)/P(X) }

  即求在X条件下yi概率最大的类别 i 作为分类类别,由于等式右边的分母P(X),所以只用计算max i { P(X|Yi)*P(Yi) }

  其中P(Yi)是每个类别的概率,即每个类别的在训练集中的频率

  P(X|Yi)可以根据贝叶斯公式和条件独立假设展开,P(X|Yi) = P(x1|Yi) * P(x2|Yi) *...*P(xn|Yi)

  其中P(xi|Yi)为当前类别yi下(所有类别为yi的数据实例),特征x取值为xi的概率(取值为xi的数据实例的频率)。

  

  所以贝叶斯分类模型的训练只要计算好以下两个概率:

  • 各个类别yi的概率P(Yi)
  • 各个类型yi下每个特征取各个值的概率P(xi|Yi)

 

  • Python实现

  在Python中可以用嵌套字典这样表示模型训练要求的概率P(xi=val|Yi):

技术分享

  其中yi是各个类别,fi是当前类别yi下每一个特征,val是当前特征fi下的取值,pi是fi取值为pi的频率。有点绕口。。。

  可以按照上面的数据结构,依次按yi、fi划分数据集,其实就是按行在按列切分数据集,然后求fi取各个值的概率。

技术分享

  上图中收入是预测的类别变量,后面三个是特征变量,对应求解过程就是,先按类别变量收入排序(划分数据),然后求收入yi=高(低)的时候,特征变量fi=能力(学历、性别)时候,取值val=高(中、低)的概率。概率用频率来估计。

#coding=uft-8
import
os, sys from math import * import time #load dataSet def loadData(filePath): dataSet = [] with open(filePath) as fin: for line in fin: label_feats = line.strip().split(\t) #print label_feats dataSet.append(label_feats) labelList = [i[0] for i in dataSet] uniqLabel = list(set(labelList)) featuresNum = len(dataSet[0][1:]) features = [] for i in range(featuresNum): features.append(f+str(i+1)) #print uniqLabel #print features return dataSet,uniqLabel,features def calcPOfLabels(dataSet, labels): pOfLabels = [] total = len(dataSet) labelList = [example[0] for example in dataSet] labelsKinds = len(labels) for i in range(labelsKinds): pOfLabels.append(labelList.count(labels[i])) #pOfLabels[i] /= float(total) #laplacian correction pOfLabels[i] = (pOfLabels[i] + 1) / (float(total) + labelsKinds) print pOfLabels[i] return pOfLabels def getYi_Fi_ConditionP(subColumn, colIndex): yi_fi = {} uniqCol = set(subColumn) total = len(subColumn) for val in uniqCol: pinlv = 0 for d in subColumn: if(d == val): pinlv += 1 #yi_fi[val] = float(pinlv) / total #‘192‘:p if(colIndex != 10): yi_fi[val] = (float(pinlv) + 1)/ (total + 256) #laplacian correction else: yi_fi[val] = (float(pinlv) + 1)/ (total + 15672) #laplacian correction return yi_fi def getYi_Fs_ConditionP(subSet, features): yi_fs = {} for f in features: col = features.index(f) + 1 #subSet first col is label subColumn = [d[col] for d in subSet] #split subSet with feature yi_fs[f] = getYi_Fi_ConditionP(subColumn, col) #fi:{‘192‘:0.2, ‘202‘:0.4} return yi_fs def getYs_Fs_ConditionP(dataSet, labels, features): conditionP = {} for yi in labels: subSet = [] #split dataSet with yi for d in dataSet: if(d[0] == yi): subSet.append(d) conditionP[yi] = getYi_Fs_ConditionP(subSet, features) #yi:{‘f1‘:{}, ‘f2‘:{}},依次构建字典 return conditionP if(len(sys.argv) < 2): print Usage xxx.py trainDataFile sys.exit() t1 = time.time() dataSet, labels, features = loadData(sys.argv[1]) pOfLabels = calcPOfLabels(dataSet, labels) ys_fs_conditionP = getYs_Fs_ConditionP(dataSet, labels, features) print pOfLabels print ys_fs_conditionP t2 = time.time() print t2 - t1

  得到P(xi|Yi)就可以求解当前数据实例条件下各个类别的条件概率,以此来预测分类。

  ps:

  1、代码实现过程中要注意拉普拉斯平滑。因为按照yi划分数据集后,可能某个特征的取值val不在当前类别的划分中;

     虽然不在,但是我们不能不去求P(xi=val|Yi)的概率啊(测试集中可能会出现),而且也不能直接让P(xi=val|Yi)=0,需要用拉普拉斯平滑。

     即让每个取值val都+1,那么分母也要加N,N是val的取值个数,这样可以保证概率和还是为1

     上面的代码val取值不存在我就没有计算它的概率,我是在预测的时候计算了拉普拉斯平滑后的概率。

  2、写了决策树和贝叶斯分类模型,感觉都是对数据集划分,然后用频率估计概率。重要的是怎么构建求解结果的数据结构。

贝叶斯分类

标签:独立   排序   color   add   append   ase   存在   决策   需要   

原文地址:http://www.cnblogs.com/vincent-vg/p/6746256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!