sklearn中的朴素贝叶斯分类器

隐身守侯 提交于 2019-11-28 09:18:07

sklearn中的朴素贝叶斯分类器

之前理解朴素贝叶斯中的结尾对sklearn中的朴素贝叶斯进行了简单的介绍. 
此处对sklearn中的则对sklearn中的朴素贝叶斯算法进行比较详细介绍.不过手下还是对朴素贝叶斯本身进行一些补充.

朴素贝叶斯算法

朴素贝叶斯算法的数学基础都是围绕贝叶斯定理展开的,因此这一类算法都被称为朴素贝叶斯算法.

朴素贝叶斯的分类原理是通过对象的先验概率,利用贝叶斯公式计算出后验概率.即对象属于某一类的概率. 
选择具有后验概率最大的类作为该对象所属的类.同时朴素–’特征为独同分布’, 
同时因为先验概率需要我们先假设一个事件分布的概率分布方式(三种),因此也就有了我们在sklearn中对应的三种朴素贝叶斯算法 
- 高斯朴素贝叶斯分类器(默认条件概率分布概率符合高斯分布) 
- 多项式朴素贝叶斯分类器(条件概率符合多项式分布) 
- 伯努利朴素贝叶斯分类器(条件概率符合二项分布)

尽管其假设过于简单,但是在很多实际情况下,朴素贝叶斯工作得很好,特别是文档分类和垃圾邮件过滤。 
这些工作都要求一个小的训练集来估计必需参数。

同时相比于其他更复杂的方法,朴素贝叶斯学习器和分类器非常快。 
分类条件分布的解耦意味着可以独立单独地把每个特征视为一维分布来估计。这样反过来有助于缓解维度灾难带来的问题。

* 最后总结其特点有以下几个 * 
- 属性可以离散可以连续 
- 数学基础扎实,分类效率稳定 
- 对噪音数据与缺失数据不太敏感 
- 属性如果不相关,分类效果很好;如果相关,则不低于决策树 
- 假设简单,但是在很多实际情况下表现很好 
- 速度较快,一定程度上缓解了维度灾难

%matplotlib inline
from sklearn import datasets, model_selection, naive_bayes
import matplotlib.pyplot as plt
import numpy as np
def load_data(datasets_name='iris'):
    if datasets_name == 'iris':
        data = datasets.load_iris()  # 加载 scikit-learn 自带的 iris 鸢尾花数据集-分类
    elif datasets_name == 'wine': # 0.18.2 没有
        data = datasets.load_wine()  # 加载 scikit-learn 自带的 wine 红酒起源数据集-分类
    elif datasets_name == 'cancer':
        data = datasets.load_breast_cancer()  # 加载 scikit-learn 自带的 乳腺癌数据集-分类
    elif datasets_name == 'digits':
        data = datasets.load_digits()  # 加载 scikit-learn 自带的 digits 糖尿病数据集-回归
    elif datasets_name == 'boston':
        data = datasets.load_boston()  # 加载 scikit-learn 自带的 boston 波士顿房价数据集-回归
    else:
        pass

    return model_selection.train_test_split(data.data, data.target,test_size=0.25, random_state=0,stratify=data.target) 
    # 分层采样拆分成训练集和测试集,测试集大小为原始数据集大小的 1/4

测试sklearn中的朴素贝叶斯算法,sklearn中朴素贝叶斯算法比较简单,只有三种

也正是因为朴素贝叶斯算法比较简单,下面的代码已经基本给出了sklearn中朴素贝叶斯算法的所以有关内容. 
你可以运行下面的代码进行测试,同时下面也包括一定的可视化内容.

朴素贝叶斯模型可以解决整个训练集不能导入内存的大规模分类问题。 为了解决这个问题, MultinomialNB, BernoulliNB, 和 GaussianNB 实现了 partial_fit 方法,可以动态的增加数据,使用方法与其他分类器的一样,使用示例见 Out-of-core classification of text documents 。所有的朴素贝叶斯分类器都支持样本权重。

与 fit 方法不同,首次调用 partial_fit 方法需要传递一个所有期望的类标签的列表,之后只需要调用数据即可.

def test_GaussianNB(*data, show=False):
    X_train, X_test, y_train, y_test = data
    cls = naive_bayes.GaussianNB()
    cls.fit(X_train, y_train)
    # print('GaussianNB Training Score: %.2f' % cls.score(X_train, y_train))
    print('GaussianNB Testing Score: %.2f' % cls.score(X_test, y_test))
def test_MultinomialNB(*data, show=False):
    X_train, X_test, y_train, y_test = data
    cls = naive_bayes.MultinomialNB()
    cls.fit(X_train, y_train)
    # print('MultinomialNB Training Score: %.2f' % cls.score(X_train, y_train))
    print('MultinomialNB Testing Score: %.2f' % cls.score(X_test, y_test))
def test_MultinomialNB_alpha(*data, show=False):
    X_train, X_test, y_train, y_test = data
    alphas = np.logspace(-2, 5, num=200)
    train_scores = []
    test_scores = []
    for alpha in alphas:
        cls = naive_bayes.MultinomialNB(alpha=alpha)
        cls.fit(X_train, y_train)
        train_scores.append(cls.score(X_train, y_train))
        test_scores.append(cls.score(X_test, y_test))

    if show:
        ## 绘图:MultinomialNB 的预测性能随 alpha 参数的影响
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)
        ax.plot(alphas, train_scores, label='Training Score')
        ax.plot(alphas, test_scores, label='Testing Score')
        ax.set_xlabel(r'$\alpha$')
        ax.set_ylabel('score')
        ax.set_ylim(0, 1.0)
        ax.set_title('MultinomialNB')
        ax.set_xscale('log')
        plt.show()

    # print('MultinomialNB_alpha best train_scores %.2f' % (max(train_scores)))
    print('MultinomialNB_alpha best test_scores %.2f' % (max(test_scores)))
def test_BernoulliNB(*data, show=False):
    X_train, X_test, y_train, y_test = data
    cls = naive_bayes.BernoulliNB()
    cls.fit(X_train, y_train)
    # print('BernoulliNB Training Score: %.2f' % cls.score(X_train, y_train))
    print('BernoulliNB Testing Score: %.2f' % cls.score(X_test, y_test))
def test_BernoulliNB_alpha(*data, show=False):
    X_train, X_test, y_train, y_test = data
    alphas = np.logspace(-2, 5, num=200)
    train_scores = []
    test_scores = []
    for alpha in alphas:
        cls = naive_bayes.BernoulliNB(alpha=alpha)
        cls.fit(X_train, y_train)
        train_scores.append(cls.score(X_train, y_train))
        test_scores.append(cls.score(X_test, y_test))

    if show:
        ## 绘图-展示BernoulliNB 的预测性能随 alpha 参数的影响
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)
        ax.plot(alphas, train_scores, label='Training Score')
        ax.plot(alphas, test_scores, label='Testing Score')
        ax.set_xlabel(r'$\alpha$')
        ax.set_ylabel('score')
        ax.set_ylim(0, 1.0)
        ax.set_title('BernoulliNB')
        ax.set_xscale('log')
        ax.legend(loc='best')
        plt.show()

    # print('BernoulliNB_alpha best train_scores %.2f' % (max(train_scores)))
    print('BernoulliNB_alpha best test_scores %.2f' % (max(test_scores)))
def test_BernoulliNB_binarize(*data, show=False):
    X_train, X_test, y_train, y_test = data
    min_x = min(np.min(X_train.ravel()), np.min(X_test.ravel())) - 0.1
    max_x = max(np.max(X_train.ravel()), np.max(X_test.ravel())) + 0.1
    binarizes = np.linspace(min_x, max_x, endpoint=True, num=100)
    train_scores = []
    test_scores = []
    for binarize in binarizes:
        cls = naive_bayes.BernoulliNB(binarize=binarize)
        cls.fit(X_train, y_train)
        train_scores.append(cls.score(X_train, y_train))
        test_scores.append(cls.score(X_test, y_test))

    if show:
        ## 绘图-展示BernoulliNB 的预测性能随 binarize 参数的影响
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)
        ax.plot(binarizes, train_scores, label='Training Score')
        ax.plot(binarizes, test_scores, label='Testing Score')
        ax.set_xlabel('binarize')
        ax.set_ylabel('score')
        ax.set_ylim(0, 1.0)
        ax.set_xlim(min_x - 1, max_x + 1)
        ax.set_title('BernoulliNB')
        ax.legend(loc='best')
        plt.show()

    # print('BernoulliNB_binarize best train_scores %.2f' % (max(train_scores)))
    print('BernoulliNB_binarize best test_scores %.2f' % (max(test_scores)))
def testFuc(fuc,show = False,no_all = True):
    for i in ['iris', 'wine', 'cancer', 'digits', ]:
            print('\n====== %s ======\n' % i)          
            X_train, X_test, y_train, y_test = load_data(datasets_name=i)  # 产生用于分类问题的数据集
            if no_all:
                fuc(X_train, X_test, y_train, y_test,show = show) 
            else:
                test_GaussianNB(X_train, X_test, y_train, y_test,show = show)  # 调用 test_GaussianNB
                test_MultinomialNB(X_train,X_test,y_train,y_test,show = show) # 调用 test_MultinomialNB
                test_MultinomialNB_alpha(X_train, X_test, y_train, y_test,show = show)  # 调用 test_MultinomialNB_alpha
                test_BernoulliNB(X_train,X_test,y_train,y_test,show = show) # 调用 test_BernoulliNB
                test_BernoulliNB_alpha(X_train, X_test, y_train, y_test,show = show)  # 调用 test_BernoulliNB_alpha
                test_BernoulliNB_binarize(X_train, X_test, y_train, y_test,show = show)  # 调用 test_BernoulliNB_binarize

* 下面是前面我们定义的用来测试的函数*


test_GaussianNB(X_train, X_test, y_train, y_test) # 调用 test_GaussianNB 
test_MultinomialNB(X_train,X_test,y_train,y_test) # 调用 test_MultinomialNB 
test_MultinomialNB_alpha(X_train, X_test, y_train, y_test) # 调用 test_MultinomialNB_alpha 
test_BernoulliNB(X_train,X_test,y_train,y_test) # 调用 test_BernoulliNB 
test_BernoulliNB_alpha(X_train, X_test, y_train, y_test) # 调用 test_BernoulliNB_alpha 
test_BernoulliNB_binarize(X_train, X_test, y_train, y_test) # 调用 test_BernoulliNB_binarize 

testFuc(test_GaussianNB)
  • 1
====== iris ======

GaussianNB Testing Score: 0.97

====== wine ======

GaussianNB Testing Score: 0.96

====== cancer ======

GaussianNB Testing Score: 0.92

====== digits ======

GaussianNB Testing Score: 0.84
testFuc(test_MultinomialNB,no_all = False)
====== iris ======

GaussianNB Testing Score: 0.97
MultinomialNB Testing Score: 1.00
MultinomialNB_alpha best test_scores 1.00
BernoulliNB Testing Score: 0.32
BernoulliNB_alpha best test_scores 0.32
BernoulliNB_binarize best test_scores 0.92

====== wine ======

GaussianNB Testing Score: 0.96
MultinomialNB Testing Score: 0.82
MultinomialNB_alpha best test_scores 0.84
BernoulliNB Testing Score: 0.40
BernoulliNB_alpha best test_scores 0.40
BernoulliNB_binarize best test_scores 0.69

====== cancer ======

GaussianNB Testing Score: 0.92
MultinomialNB Testing Score: 0.90
MultinomialNB_alpha best test_scores 0.91
BernoulliNB Testing Score: 0.63
BernoulliNB_alpha best test_scores 0.63
BernoulliNB_binarize best test_scores 0.91

====== digits ======

GaussianNB Testing Score: 0.84
MultinomialNB Testing Score: 0.90
MultinomialNB_alpha best test_scores 0.91
BernoulliNB Testing Score: 0.87
BernoulliNB_alpha best test_scores 0.87
BernoulliNB_binarize best test_scores 0.91

不同的朴素贝叶斯算法的差异在于其假设的先验概率的不同

数据的先验概率越贴近我们假设的先验概率的时候,我们的模型结果也就越准确

* 对于同一个算法,不同的超参数也有一定的影响,这个你可以通过改变我写的test_fun中的超参数show来进行绘图操作,查看不同超参数的区别 *

参考资料

对于朴素贝叶斯原理性的理解可以参考 
理解朴素贝叶斯 
sklearn中文文档-朴素贝叶斯 
- 《python大战机器学习 数据科学家的一个小目标》 华校专,王正林编著

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!