一、原理
与其他大多数的分类算法不同,如:决策树、KNN、逻辑回归等,它们都是判别方法,直接学习出类别y和特征x之间的关系。朴素贝叶斯属于生成方法,它的理论基础是贝叶斯公式: ,其中P(Y)是先验知识,P(X’|Y)是已知果,求因出现的概率。而“朴素”一词指的是假设特征X之间相互独立。与频率学派的不同点在于,贝叶斯加入了先验知识的影响。贝叶斯算法计算量不大,在文本分类中有很好的效果。
下面说一下朴素贝叶斯的推导过程:
我们的目标是对给定的样本特征X,计算其所属分类,即求
,设
为第k个类别,根据贝叶斯公式,也就是:
把所有的类别都计算一遍,最后概率最大的那个就是我们要找的类别了。
对于不同的类别来说,上面公式中的分母P(X)是相同的,所以我们只需要计算分子然后比较概率就可以了。
对分子的第二项 ,可以看做所有样本中,类别 出现的频率,这个很好求。
对分子的第一项
,要看特征X是离散还是连续的。
1、若
为离散值,那么我们只需计算每个属性取值占该类别样本的数量比例就行了:
表示训练集D中第c类样本组成的集合,
表示的是第c类样本组成的集合中在第i个属性值上取值为
的样本组成的集合。
2、若
是连续值,就要用概率密度函数,假定X服从高斯分布:
其中
和
分别是第c类样本在第i个属性上取值的均值和方差。
推导过程就是这样,在实际用的时候,需要注意:
1、防止概率连乘之后太小,以至于为0,往往把连乘取对数。
2、为了防止某个离散类型的属性值在训练集的某个类别中没有出现过,会导致
,这样是不合理的,因此我们一般会做平滑处理:
这样我们在分母上加上取值的可能性个数,分子上都加1,这就保证了即使是存在某个属性i的取值
未曾与类别c同时出现过,我们也不会把其概率
算成0。
二、sklearn调用
在scikit-learn中,一共有3个朴素贝叶斯的分类算法类。分别是GaussianNB,MultinomialNB和BernoulliNB。它们的样本特征先验分布不同,其中GaussianNB的先验为高斯分布,MultinomialNB的先验为多项式分布,而BernoulliNB的先验为伯努利分布。
1、GaussianNB
GaussianNB类的主要参数仅有一个,即类别先验概率priors ,对应Y的各个类别的先验概率
,默认是
。其中m为训练集样本总数量,
为输出为第
类别的训练集样本数。
模型训练:
fit()
partial_fit(),这个方法的一般用在训练集数据量非常大,一次不能全部载入内存的时候。这时我们可以把训练集分成若干等分,重复调用partial_fit增量式地学习训练集。
样本预测:
predict():给出测试集的预测类别输出。
predict_proba:给出测试集样本在各个类别上预测的概率。
predict_log_proba:给出测试集样本在各个类别上预测的概率的对数。
2、MultinomialNB
MultinomialNB假设特征的先验概率为多项式分布:
MultinomialNB参数共有3个。
(1)参数alpha即为上面的常数λ,默认为1,如果发现拟合的不好,需要调优时,可以选择稍大于1或者稍小于1的数。
(2)布尔参数fit_prior表示是否要考虑类别先验概率,默认是true;如果输入false,则所有的样本类别输出都有相同的类别先验概率;
(3)class_prior类别先验概率:默认是
;如果指定为class_prior,则指定的这个作为先验概率;
模型训练和样本预测同GaussianNB。在做文本分类时用的就是这个。
3、BernoulliNB
这个没有用到过,以后再总结。
总结:如果用朴素贝叶斯做分类,效果不是很好,可能有下面几个原因:
1、特征之间关联度太高。
2、类别先验概率不合适。