机器学习笔记(十二)朴素贝叶斯算法及实践(NB算法的产生及参数估计)

来源:互联网 发布:成都u盘数据恢复 编辑:程序博客网 时间:2024/05/22 02:10

前面几周确实忙的有点头疼,实验室里的活儿很多,然后又参加那个京东的算法比赛,所以博客的更新就耽误了,又到周末了赶紧写点东西,不能放纵自己,因为下周又放假了呀,哈哈哈O(∩_∩)O~

今天想和大家聊一聊朴素贝叶斯以及贝叶斯网络的相关内容,既然这个名字里都带贝叶斯,那么肯定和贝叶斯公式十分相关了,我们先来回忆一下贝叶斯公式


贝叶斯公式最大的作用就是可以通过联合概率分布去计算后验概率。其实通过贝叶斯公式,我们往往能得到很多很有意思的结论,这里举一个我在知乎上看到的例子,大快人心。话说啊,这个首富榜排行前十里面有五位没有上过大学,这时候出来一种论调,说读书管个卵用啊,看那些最成功的人里面上没上过大学的不也是五五开吗?首先我们不去讨论是否能够用一个人的财富来衡量他的成功程度这种价值观问题,单单是这种反智的言论是否就让人觉得不舒服,但你是不是不知道如何去反驳呀。对的,贝叶斯公式,假设A是上过大学,B是进入富豪榜前十,现在我们已经知道的是


这个真能说明读不读书有用吗?如果真的要比较读书的作用我们是不是应该比较读书人中进入富豪榜的比例和没读书人当中进入富豪榜的比例呢?也就是说比较P(B|A)和P(B|~A),那么这里就要用到贝叶斯公式了,这里我们还要做几个粗略的估计,假设全国一共有13亿人,其中上过大学的有1亿人,那么就有


虽然不管怎样进入富豪榜前十都不是一个容易的事儿,但从结果还是可以很明显的看出来,读书相比于不读书上榜的概率高了十倍左右,所以千万别再提什么读书无用论了好吗,多读点书挺好的。

OK,回到我们今天的主题朴素贝叶斯,首先聊一聊为啥我们会使用它。

场景是这样的,我们有一个n维的输入向量空间,还有一个对应k个类别的集合作为输出空间,也就是说把一个n维向量对应到一个类别上。然后给了我们一定的数据进行训练,再任意给我一个n维向量让我去预测它所属的类别。

首先,服从我们的天性,直觉想要怎么做呢?根据给我们的训练数据,分别统计每个参数对应某个值然后属于某一类的概率,然后一旦给出了测试向量,根据其参数确定其属于某一类的概率,选择最大的概率那个种类。这么做肯定没问题,除了可能有一点过拟合的嫌疑之外,我觉得非常好。但事实往往是残酷的,在数据量很小的情况下,这样做当然OK,但是如果数据量比较多,似乎参数数量就爆炸了。假如这个n维向量每个可以的取值数目为Sj,那么总共需要的参数数目是


要了亲命了,这是个连乘,参数数量指数级上升。比如5个类别,10维的输入空间,每个维度上可以有5个取值,那么最后的参数个数为5的11次方,我就无聊的把它算出来是48828125,是不是多的有点过分了,那么怎么简化呢?

来了,朴素贝叶斯最重要的假设:在分类确定的情况下,用于分类的特征是独立的。通常我们也称之为条件独立假设,用公式表示就是


同志们,看出来好处在哪儿了吗?把各个特征从里面拆出来之后,计算参数个数的时候我们从连乘变成连加了,现在的参数个数是


同样是刚才的设置,现在所需要的参数数目是多少呢,5*(5*10),老铁们,只需要250,和之前也没差多少,就差不多20万倍这个样子,呵呵哒。

不过到这里光有朴素了,贝叶斯呢?憋急啊,这就来了。其实预测分类问题就是求一个属于不同类别的后验概率大小,我们完全可以把它转化成先验概率来求,也就是说


结合上面的条件独立假设,我们就有


那么这样我们就有了给定向量属于各个类别的概率,找出其中的最大值,就可以确定它所属的类别了。OK,OK,我知道这样做很强势,看起来很帅,但你能不能告诉我你的先验概率怎么求呢?也许你会讲,这还用问,明摆着从训练样本里分别算各个类别下各个特征等于某值的概率呗。但是讲道理的话,你得给个证明啊,李航博士的书里也只提了一句极大似然轻轻带过,那我们这边不妨推推看吧,其实算类别的先验概率和算某个类别下某个特征的先验概率方法是一样的,这里我们就选择证明前者吧。

首先,我们假设每个类别出现的概率为theta,那么这样Y的分布就可以用如下的式子来表示


这样的话假如有N个样本,我们就可以求得极大似然函数


其中Nk是属于每个类别的样本个数。下一步求对数似然函数,不过这里需要考虑一个约束条件,也就是对于所有类别对应的theta求和应该为1,这里以拉格朗日乘子的方式添加到对数似然函数中,那么对数似然函数为


下面就是老生常谈的动作了,求导为0呗,那么有


这时我们发现一个规律,那就是对于所有的theta而言它是和Nk成比例的,所以也就有了


这样的结果也和我们预期的一致。至此,朴素贝叶斯所有的工作都已完成,还挺简单的吧。

这里我们再来总结一下这个算法的步骤:

1 计算先验概率和条件概率。

2 计算给定实例属于各个类别的概率。

3 选择最大的概率所属种类作为预测值。

好像真的是很容易啊……

当然了,顺带提一句,我们这里参数估计用的是极大似然估计,有可能出现概率为0的情况,有可能对预测结果造成影响。为了解决这一问题我们可以用贝叶斯估计。等价于在各个随机变量取值的频数上再加一个lambda,lambda为0就是极大似然估计,为1则称之为拉普拉斯平滑,需要注意的是在计算先验概率的时候也要加上lambda。

感觉朴素贝叶斯的内容确实不多,感觉已经没啥好写的了,主要也是为了铺垫一下后面要讲的贝叶斯网络吧。朴素贝叶斯既然是个分类算法,那我们就找惯例搬上我们的老朋友鸢尾花数据,看看它的表现如何,代码如下

from sklearn.naive_bayes importMultinomialNBfrom sklearn.model_selection importtrain_test_splitfrom sklearn import datasets iris=datasets.load_iris()x=iris.data[:,:2]y=iris.targetx_train, x_test, y_train, y_test =train_test_split(x, y, train_size=0.7, random_state=1) model=MultinomialNB()model.fit(x_train,y_train) y_hat=model.predict(x_test)print '训练集上的正确率为%2f%%'%(model.score(x_train, y_train)*100)print '测试集上的正确率为%2f%%'%(model.score(x_test, y_test)*100)

输出的结果为

训练集上的正确率为68.571429%

测试集上的正确率为60.000000%

好像确实不怎么样啊……毕竟条件独立这个假设还是比较强的,但在实际中朴素贝叶斯还是用的比较多的,因为它计算方便,但效果嘛,就有点差强人意了。

OK,今天就到这儿,坐等五一!!!



1 0
原创粉丝点击