sklearn之朴素贝叶斯类库介绍

转载自:http://blog.sina.com.cn/s/articlelist_1654066213_0_1.html
本文重点讲述scikit-learn朴素贝叶斯类库的使用和参数调优。

1. scikit-learn朴素贝叶斯类库概述
朴素贝叶斯是一类比较简单的算法,因此scikit-learn中朴素贝叶斯类库的使用也比较简单。在scikit-learn中,一共有3个朴素贝叶斯的分类算法类,分别是GaussianNB,MultinomialNB和BernoulliNB,其中GaussianNB是先验为高斯分布的朴素贝叶斯,MultinomialNB是先验为多项式分布的朴素贝叶斯,而BernoulliNB是先验为伯努利分布的朴素贝叶斯。
这三个类适用的分类场景各不相同。一般来说,如果样本特征的分布大部分是连续值,则使用GaussianNB会比较好;如果样本特征的分布大部分是多元离散值,则使用MultinomialNB比较合适;而如果样本特征是二元离散值或者很稀疏的多元离散值,则应该使用BernoulliNB。

2.GaussianNB类
GaussianNB假设特征的先验概率为正态分布(又称高斯分布),即如下式:
scikit-learn(sklearn)朴素贝叶斯类库介绍
其中scikit-learn(sklearn)朴素贝叶斯类库介绍是Y的第k个类别,scikit-learn(sklearn)朴素贝叶斯类库介绍scikit-learn(sklearn)朴素贝叶斯类库介绍是需要从训练集估计的值。
GaussianNB会根据训练集求出scikit-learn(sklearn)朴素贝叶斯类库介绍scikit-learn(sklearn)朴素贝叶斯类库介绍scikit-learn(sklearn)朴素贝叶斯类库介绍是在样本类别scikit-learn(sklearn)朴素贝叶斯类库介绍中所有scikit-learn(sklearn)朴素贝叶斯类库介绍的均值,scikit-learn(sklearn)朴素贝叶斯类库介绍是在样本类别scikit-learn(sklearn)朴素贝叶斯类库介绍中所有scikit-learn(sklearn)朴素贝叶斯类库介绍的方差。
GaussianNB类的主要参数仅有一个,即先验概率priors ,对应Y的各个类别的先验概率scikit-learn(sklearn)朴素贝叶斯类库介绍。这个值默认不给出,此时scikit-learn(sklearn)朴素贝叶斯类库介绍,其中m是训练集样本总数,scikit-learn(sklearn)朴素贝叶斯类库介绍是输出为第k个类别的训练集样本数。如果给出的话则以priors为准。
在使用GaussianNB的fit()方法拟合训练数据后,我们就可以进行预测了。预测的方法有三种,包括predict(),predict_proba()和predict_log_proba()。
  • predict()方法是最常用的预测方法,直接给出测试集的预测类别输出。
  • predict_proba()方法则不同,它会给出测试集样本在各个类别上预测的概率。很容易理解,这个方法预测出的各个类别概率里的最大值对应的类别即为predict()方法得到类别。
  • predict_log_proba()方法和predict_proba()方法类似,它会给出测试集样本在各个类别上预测的概率的对数转化,转化后predict_log_proba()预测出的各个类别对数概率里的最大值对应的类别也是predict()方法得到类别。
此外,GaussianNB有一个非常重要的partial_fit()方法,这个方法一般用在如果训练集数据量非常大,一次不能全部载入内存的时候,我们可以把训练集分成若干等分,重复调用partial_fit()方法来一步步的学习训练集,非常方便。



3.MultinomialNB类
MultinomialNB假设特征的先验概率为多项式分布,即如下式:
scikit-learn(sklearn)朴素贝叶斯类库介绍
其中scikit-learn(sklearn)朴素贝叶斯类库介绍是第k个类别的第j维特征的第l个取值的条件概率,scikit-learn(sklearn)朴素贝叶斯类库介绍是训练集中输出为第k个类别的样本个数,λ是一个大于0的常数,通常取为1,它就是拉普拉斯平滑。
MultinomialNB类的参数比GaussianNB类多,但是也只有3个。其中,参数alpha即为上面的常数λ,如果没有特别的需要,用默认值1即可;如果发现拟合得不好,需要调优时,可以选择稍大于1或者稍小于1的数。布尔参数fit_prior表示是否要考虑先验概率,如果是false,则所有的样本类别输出都有相同的类别先验概率,否则可以用第三个参数class_prior输入先验概率,也可以不输入第三个参数class_prior,而是让MultinomialNB类自己从训练集样本中计算先验概率,此时的先验概率即为scikit-learn(sklearn)朴素贝叶斯类库介绍,其中m是训练集样本总数,scikit-learn(sklearn)朴素贝叶斯类库介绍输出为第k个类别的训练集样本数。总结如下:
 fit_prior  class_prior  最终先验概率
 false  填不填没有意义  P(Y=Ck)=1/k
 true  不填  P(Y=Ck)=mk/m
 true    P(Y=Ck)=class_prior
在使用MultinomialNB类的fit()方法或者partial_fit()方法拟合训练集数据后,我们就可以进行预测了。预测的方法也有三种,包括predict(),predict_proba()和predict_log_proba()。这些方法的用法和前面的GaussianNB类完全一样。

4. BernoulliNB类
BernoulliNB假设特征的先验概率为二元伯努利分布,即如下式:
scikit-learn(sklearn)朴素贝叶斯类库介绍
此时
scikit-learn(sklearn)朴素贝叶斯类库介绍只能取值为0或者1。
BernoulliNB类共有4个参数,其中3个参数的名称和意义与MultinomialNB类完全相同,唯一不同的是增加了binarize参数,这个参数主要是用来帮助BernoulliNB类处理二项分布的,可以是数值或者不输入。如果不输入,则BernoulliNB类认为每个数据特征都已经是二元的;否则,小于binarize的数值归为一类,大于binarize的数值归为另外一类。
在使用BernoulliNB类的fit()方法或者partial_fit()方法拟合训练集数据后,我们就可以进行预测了。预测的方法也是三种,包括predict(),predict_proba()和predict_log_proba()。这些方法的用法和前面的GaussianNB类完全一样。

5.使用Mnist数据集测试scikit-learn朴素贝叶斯类
代码如下所示:
—————————————————————————————————
from time import time
from sklearn.naive_bayes import GaussianNB, MultinomialNB, BernoulliNB
from sklearn import metrics
import numpy as np
import mnist

if __name__ == “__main__”:
    # 读取Mnist数据集
    mnistSet = mnist.loadLecunMnistSet()
    train_X, train_Y, test_X, test_Y = mnistSet[0], mnistSet[1], mnistSet[2], mnistSet[3]

    # 数据集总样本数
    m = np.shape(train_X)[0]
    # 分批训练数据时每次拟合的样本数
    num = 10000

    print “**********测试先验为高斯分布的朴素贝叶斯**********”
    t = time()
    model = GaussianNB()
    # 整体拟合
    model.fit(train_X, train_Y)
    # 分批拟合
    # for i in range(int(np.ceil(m/num))):
    #     minEnd = min((i+1)*num, m)
    #     model.partial_fit(train_X[i*num:minEnd], train_Y[i*num:minEnd], classes=train_Y)
    idx = range(m)
    np.random.shuffle(idx)
    # 分批预测训练集(在我的电脑上整体预测时报MemoryError,所以采用分批预测的方式)
    for i in range(int(np.ceil(m/num))):
        minEnd = min((i+1)*num, m)
        sub_idx = idx[i*num:minEnd]
        train_Y_hat = model.predict(train_X[sub_idx])
        print ‘训练集子集精确度: ‘, metrics.accuracy_score(train_Y[sub_idx], train_Y_hat)
    # 预测测试集
    test_Y_hat = model.predict(test_X)
    print ‘测试集精确度: ‘, metrics.accuracy_score(test_Y, test_Y_hat)
    print “总耗时:”, time() - t, “秒”

    print “\n**********测试先验为多项式分布的朴素贝叶斯**********”
    t = time()
    model = MultinomialNB()
    # 拟合训练集数据
    model.fit(train_X, train_Y)
    idx = range(m)
    np.random.shuffle(idx)
    # 预测训练集
    train_Y_hat = model.predict(train_X[idx])
    print ‘训练集精确度: ‘, metrics.accuracy_score(train_Y[idx], train_Y_hat)
    # 预测测试集
    test_Y_hat = model.predict(test_X)
    print ‘测试集精确度: ‘, metrics.accuracy_score(test_Y, test_Y_hat)
    print “总耗时:”, time() - t, “秒”

    print “\n**********测试先验为伯努利分布的朴素贝叶斯**********”
    t = time()
    model = BernoulliNB()
    # 拟合训练集数据
    model.fit(train_X, train_Y)
    idx = range(m)
    np.random.shuffle(idx)
    # 预测训练集
    train_Y_hat = model.predict(train_X[idx])
    print ‘训练集精确度: ‘, metrics.accuracy_score(train_Y[idx], train_Y_hat)
    # 预测测试集
    test_Y_hat = model.predict(test_X)
    print ‘测试集精确度: ‘, metrics.accuracy_score(test_Y, test_Y_hat)
    print “总耗时:”, time() - t, “秒”
—————————————————————————————————
输出结果为:
—————————————————————————————————
**********测试先验为高斯分布的朴素贝叶斯**********
训练集子集精确度:  0.5692
训练集子集精确度:  0.5635
训练集子集精确度:  0.5655
训练集子集精确度:  0.5597
训练集子集精确度:  0.5701
训练集子集精确度:  0.5614
测试集精确度:  0.5558
总耗时: 12.3289999962 秒

**********测试先验为多项式分布的朴素贝叶斯**********
训练集精确度:  0.825283333333
测试集精确度:  0.8365
总耗时: 1.10299992561 秒

**********测试先验为伯努利分布的朴素贝叶斯**********
训练集精确度:  0.83125
测试集精确度:  0.8413
总耗时: 2.11500000954 秒
—————————————————————————————————
从结果可以看出,Mnist数据集使用MultinomialNB和BernoulliNB预测的准确率比较高,符合Mnist数据集的分布。

猜你喜欢

转载自blog.csdn.net/zztingfeng/article/details/80590407