机器学习sklearn-朴素贝叶斯

目录

概述

sklearn中的朴素贝叶斯

 高斯朴素贝叶斯


概述

算法得出的结论,永远不是 100% 确定的,更多的是判断出了一种 样本的标签更可能是某类的可能
,而非一种 确定 ”。
我们通过某些规定,比如说,在决策树的叶子节点上占比较多的标签,就是叶子节点上所有
样本的标签,来强行让算法为我们返回一个固定结果。但许多时候,我们也希望能够理解算法判断出的可能性本身。
每种算法使用不同的指标来衡量这种可能性。比如说,决策树使用的就是叶子节点上占比较多的标签所占的比例(接口predict_proba 调用),逻辑回归使用的是 sigmoid 函数压缩后的似然(接口 predict_proba 调用),而 SVM 使用的是样本点到决策边界的距离(接口decision_function 调用)。但这些指标的本质,其实都是一种 类概率 的表示,我们可以通过归一化或sigmoid 函数将这些指标压缩到 0~1 之间,让他们表示我们的模型对预测的结果究竟有多大的把握(置信度)。但无论如何,我们都希望使用真正的概率来衡量可能性,因此就有了真正的概率算法:朴素贝叶斯。
朴素贝叶斯是一种直接衡量标签和特征之间的概率关系的有监督学习算法,是一种专注分类的算法。朴素贝叶斯的算法根源就是基于概率论和数理统计的贝叶斯理论,因此它是根正苗红的概率模型。
贝叶斯理论等式:

机器学习sklearn-朴素贝叶斯_第1张图片

机器学习sklearn-朴素贝叶斯_第2张图片

这个式子证明,在Y=1的条件下,多个特征的取值被同时取到的概率,就等于Y=1的条件下,多个特征的取值被分别取到的概率相乘

假设特征之间是有条件独立的,可以解决众多问题,也简化了很多计算过程,这是朴素贝叶斯被称为 朴素 的理由
因此,贝叶斯在特征之间有较多相关性的数据集上表现不佳,而现实中的数据多多少少都会有一些相关性,所以贝叶斯的分类效力在分类算法中不算特别强大。同时,一些影响特征本身的相关性的降维算法,比如PCA SVD ,和贝叶斯连用效果也会不佳。
朴素贝叶斯是一个不建模的算法 。以往我们学的不建模算法,比如 KMeans ,比如 PCA ,都是无监督学习,而朴素贝叶斯是第一个有监督的,不建模的分类算法。
要处理连续型变量,我们可以有两种方法。第一种是把连续型变量分成 个箱,把连续型强行变成分类型变量。 这个过程的主要问题是,箱子不能太大也不能太小,如果箱子太大,就失去了分箱的基本意义,如果 箱子太小,可能每个箱子里就没有足够的样本来帮助我们计算概率 ,因此我们必须要适当地衡量我们的分箱效 果。

sklearn中的朴素贝叶斯

虽然朴素贝叶斯使用了过于简化的假设,这个分类器在许多实际情况中都运行良好,著名的是文档分类和垃圾邮件过滤。而且由于贝叶斯是从概率角度进行估计,它所需要的样本量比较少,极端情况下甚至我们可以使用1% 的数据作为训练集,依然可以得到很好的拟合效果。当然,如果样本量少于特征数目,贝叶斯的效果就会被削弱。

机器学习sklearn-朴素贝叶斯_第3张图片

 高斯朴素贝叶斯

机器学习sklearn-朴素贝叶斯_第4张图片 

但在实例化的时候,我们不需要对高斯朴素贝叶斯类输入任何的参数,调用的接口也全部 sklearn 中比较标准的一些搭配,可以说是一个非常轻量级的类,操作非常容易。但过于简单也意味着贝叶斯没有太多的参数可以调整,因此贝叶斯算法的成长空间并不是太大,如果贝叶斯算法的效果不是太理想,我们一般都会考虑换模型。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB #导入高斯分布下的朴素贝叶斯
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split

digits=load_digits()
X,y=digits.data,digits.target
Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,y,test_size=0.3,random_state=40)

#建模
gnb=GaussianNB().fit(Xtrain,Ytrain)
acc_score=gnb.score(Xtest,Ytest)
print(acc_score)
#0.837037037037037

机器学习sklearn-朴素贝叶斯_第5张图片

 

高斯贝叶斯属于比较特殊的一类分类器,其分类效果在二分数据和月亮型数据上表现优秀,但是环形数据不太擅长。我们之前学过的模型中,许多线性模型比如逻辑回归,线性SVM 等等,在线性数据集上会绘制直线决策边界,因此难以对月亮型和环形数据进行区分,但高斯朴素贝叶斯的决策边界是曲线,可以是环形也可以是弧线,所以尽管贝叶斯本身更加擅长线性可分的二分数据,但朴素贝叶斯在环形数据和月亮型数据上也可以有远远胜过其他线性模型的表现。
机器学习sklearn-朴素贝叶斯_第6张图片
import numpy as np
import matplotlib.pyplot as plt
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.tree import DecisionTreeClassifier as DTC
from sklearn.linear_model import LogisticRegression as LR
from sklearn.datasets import load_digits
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit #设置交叉验证
from time import time
import datetime

def plot_learning_curve(estimator,title,X,y,ax,ylim=None,cv=None,n_jobs=None):
    """:argument
        estimator 使用的评估器
        tit1e:文章标题
        X,y:所用的数据和标签
        ax:选择子图
        ylim:设置纵坐标范围
        cv:交叉验证模式
        n_jobs:调用的线程数量
    """
    train_sizes, train_scores, test_scores = learning_curve(estimator, X, y,cv=cv,n_jobs=n_jobs)
    ax.set_title(title,fontsize=25)
    if ylim is not None:
        ax.set_ylim(*ylim)
    ax.set_xlabel("Training examples")
    ax.set_ylabel("Score")
    ax.grid() #显示网格作为背景,不是必须
    ax.plot(train_sizes, np.mean(train_scores, axis=1), 'o-', color="r",label="Training score")
    ax.plot(train_sizes, np.mean(test_scores, axis=1), 'o-', color="g",label="Test score")
    ax.legend(loc="best")
    return ax


digits = load_digits()
X, y = digits.data, digits.target
title = ["Naive Bayes", "DecisionTree", "SVM, RBF kernel", "RandomForest", "Logistic"]
model = [GaussianNB(), DTC(), SVC(gamma=0.001), RFC(n_estimators=50), LR(C=.1, solver="lbfgs")]
cv = ShuffleSplit(n_splits=50, test_size=0.2, random_state=0) #把数据分成多少分 测试集所占比例
fig, axes = plt.subplots(1, 5, figsize=(20, 8))
for ind, title_, estimator in zip(range(len(title)), title, model):
    times = time()
    plot_learning_curve(estimator, title_, X, y, ax=axes[ind], ylim=[0.7, 1.05], n_jobs=4, cv=cv)
    print("{}:{}".format(title_, datetime.datetime.fromtimestamp(time() - times).strftime("%M:%S:%f")))
plt.tight_layout()
plt.show()

 

 

你可能感兴趣的:(sklearn,机器学习,python)