fuli2020

2020-08-27   阅读量: 1676

机器学习——概率算法贝叶斯

扫码加入数据分析学习群

图片.png


图片.png


P(Y)称为先验概率,即在Y事件发生之前,我们对X事件概率的一个判断

P(Y|X)称为后验概率,即在Y事件发生之后,我们对X事件概率的重新评估

P(X|Y)/P(X)称为可能性函数,这是一个调整因子,使得预估概率更接近真实概率

条件概率可以理解为:后验概率=先验概率*调整因子

如果可能性函数>1,意味着先验概率被增强,事件Y的发生的可能性变大

如果可能性函数=1,意味着X事件无助于判断事件Y的可能性

如果可能性函数<1,意味着先验概率被削弱,事件Y可能性变小


不同分布下的贝叶斯

  1. 高斯朴素贝叶斯GaussianNB

    class sklearn.naive_bayes.GaussianNB(priors=None,var_smoothing=1e-09)

    如果xi是连续值,通常Xi的先验概率为高斯分布(也就是正态分布),即在样本类别Ck中,Xi的值符合正态分布。以此来估计每个特征下每个类别上的条件概率,对于每个特征下的取值,高斯朴素贝叶斯的公式:

    图片.png


图片.png是正态分布的期望和方差。


对于任意一个Y的取值,贝叶斯都以求解最大化的图片.png为目标,这样我们才能够比较在不同标签下我们的样本究竟更靠近哪一个取值。


图片.png


prior:可输入任何类数组结构,形状为n_classes,表示类的先验概率。如果指定,则不根据数据调整先验,如果不指定,则自行根据数据计算先验概率P(Y)


var_smoothing:浮点数,可不填(默认值=1e-9),在估计方差时,为了追求估计的稳定性,将所有特征的方差中最大的方差以某个比例添加到估计的方差中。这个比例,由var_smoothing参数控制。

1)导入需要的库和数据

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=420)


2). 建模,探索建模结果

gnb=GaussianNB().fit(Xtrain,Ytrain)


acc_score=gnb.score(Xtest,Ytest)

acc_score

#查看预测结果

Y_pred=gnb.predict(Xtest)


#查看预测的概率结果

prob=gnb.predict_proba(Xtest)

prob.shape


prob[1,:].sum()


prob.sum(axis=1)


from sklearn.metrics import confusion_matrix as CM

CM(Ytest,Y_pred)


#多分类状况下最佳的模型评估指标是混淆矩阵和整体的准确度


2. 多项式朴素贝叶斯以及其变化

多项式朴素贝叶斯MultinomialNB

多项式分布擅长的是分类型变量,在其原理假设中,P(xi|Y)的概率是离散的,并且不同xi下的P(xi|Y)相互独立,互不影响。虽然sklearn中的多项式分布也可以处理连续型变量,但现实中,如果我们真要处理连续型变量,应当使用高斯朴素贝叶斯。多项式实验中的实验结果都很具体,它所涉及的特征往往是次数,频率,计数,出现与否这样的概念,这些概念都是离散的正整数,因此sklearn中的多项式朴素贝叶斯不接受负值的输入。


在sklearn中,用来执行多项式朴素贝叶斯的类MultinomialNB包含如下参数和属性:

class sklearn.naive_bayes.MultinomialNB(alpha=1.0,fit_prior=True,class_prior=None)


alpha:浮点数,可不填(默认为1.0)

拉普拉斯或利德斯通平滑的参数λ,如果设置为0则表示完全没有平滑选项。但是需要注意的是,平滑相当于人为给概率加上一些噪音,因此λ设置得越大,多项式朴素贝叶斯精确性会越低


fit_prior:布尔值,可不填(默认为True)

是否学习先验概率P(Y=c),如果设置为false,则所有的样本类别输出都有相同的类别先验概率,即认为每个标签类出现的概率是1/n_classes。


class_prior:形似数组的结构,结构为(n_classes),可不填(默认为None)

类的先验概率P(Y=c),如果没有给出具体的先验概率则自动根据数据来进行计算。


布尔参数fit_prior表示是否要考虑先验概率,如果是False,则所有的样本类别输出都有相同的类别先验概率。否则,可以自己用第三个参数class_prior输入先验概率,或者不输入第三个参数class_prior让MultinomialNB自己从训练集样本来计算先验概率,此时的先验概率为P(Y=Ck)=mk/m。其中m为训练集样本总数量,mk为输出第k个类别的训练集样本数。


图片.png


1)导入需要的模块和库

from sklearn.preprocessing import MinMaxScaler

from sklearn.naive_bayes import MultinomialNB

from sklearn.model_selection import train_test_split

from sklearn.datasets import make_blobs


2)建立数据集

class_1=500

class_2=500 #两个类别分别设定500个样本

centers=[[0.0,0.0],[2.0,2.0]] #设定两个类别的中心

clusters_std=[0.5,0.5] #设定两个类别的方差

X,y=make_blobs(n_samples=[class_1,class_2],

centers=centers,

cluster_std=clusters_std,

random_state=0,shuffle=False)


Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,y,test_size=0.3,random_state=420)

3) 归一化,确保输入的矩阵不带有负数

#先归一化,保证输入多项式朴素贝叶斯的特征矩阵中不带有负数

mms=MinMaxScaler().fit(Xtrain)

Xtrain_=mms.transform(Xtrain)

Xtest_=mms.transform(Xtest)


4)建立一个多项式朴素贝叶斯分类器

mnb=MultinomialNB().fit(Xtrain_,Ytrain)


#重要属性:调用根据数据获取的,每个标签类的对数先验概率log(P(Y))

#由于概率永远是在[0,1]之间,因此对数先验概率返回的永远是负值

mnb.class_log_prior_

(Ytrain==1).sum()/Ytrain.shape[0]

mnb.class_log_prior_.shape


#可以使用np.exp来查看真正的概率值

np.exp(mnb.class_log_prior_)


#重要属性:返回一个固定标签类别下的每个特征的对数概率log(P(Xi|y))

mnb.feature_log_prob_


#重要属性:在fit时每个标签类别下包含的样本数。当fit接口中的sample_weight被设置时,该接口返回的值也会受到加权的影响

mnb.class_count_


分类器预测效果

mnb.predict(Xtest_)

mnb.predict_proba(Xtest_)

mnb.score(Xtest_,Ytest)


#效果不太理想,试试把Xtrain转换成分类型数据

from sklearn.preprocessing import KBinsDiscretizer

kbs=KBinsDiscretizer(n_bins=10,encode='onehot').fit(Xtrain) #strategy='quantile' 按分布等分分箱

Xtrain_=kbs.transform(Xtrain)

Xtest_=kbs.transform(Xtest)


mnb=MultinomialNB().fit(Xtrain_,Ytrain)

mnb.score(Xtest_,Ytest)


3. 伯努利朴素贝叶斯BernoulliNB

多项式朴素贝叶斯可同时处理二项分布和多项分布,其中二项分布又叫伯努利分布,专门用来处理二项分布的朴素贝叶斯。

伯努利贝叶斯类BernoulliNB假设数据服从多元伯努利分布,并在此基础上应用朴素贝叶斯的训练和分类过程。多元伯努利分布简单来说,就是数据集中可以存在多个特征,但每个特征都是二分类的,可以以布尔变量表示,也可以表示为{0,1}或者{-1,1}等任意二分类组合。因此,这个类要求将样本转换为二分类特征向量,如果数据本身不是二分类的,可以使用类中专门用来二值化的参数binarize来改变数据。


from sklearn.naive_bayes import BernoulliNB


#普通来说我们应该使用二值化的类sklearn.preprocessing.Binarizer来将特征一个个二值化

#然后这样效率过低,因此我们选择归一化之后直接设置一个阈值


mms=MinMaxScaler().fit(Xtrain)

Xtrain_=mms.transform(Xtrain)

Xtest_=mms.transform(Xtest)


#不设置二值化

bnl_=BernoulliNB().fit(Xtrain_,Ytrain)

bnl_.score(Xtest_,Ytest)


#设置二值化阈值为0.5

bnl=BernoulliNB(binarize=0.5).fit(Xtrain_,Ytrain)

bnl.score(Xtest_,Ytest)


探索贝叶斯:贝叶斯的样本不均衡问题

接下来,我们来探讨一个 分类算法永远都逃不过的核心问题:样本不平衡。多项式朴素贝叶斯判断出了所有的多数类样本,但放弃了全部的少数类样本,受到样本不均衡问题影响最严重。伯努利贝叶斯最能够忍受样本不均衡问题。


概率分类模型评估指标

接受者操作特征(Receiver Operating Characteristic Curve,ROC)曲线是显示分类器真正率和假正率之间折中 的一种图形化方法,也是最常用的评估分类模型好坏的可视化图形。


该曲线的横坐标为假正率,N是真实负样本的个数,FP是N个负样本中被分类器预测为正样本的个数。

图片.png


纵坐标为真正率:

图片.png


P是真实正样本的个数,TP是P个正样本中被分类器预测为正样本的个数。


AUC值为ROC曲线所覆盖的区域面积,显然,AUC越大,分类器分类效果越好。

  AUC = 1,是完美分类器,采用这个预测模型时,不管设定什么阈值都能得出完美预测。绝大多数预测的场合,不存在完美分类器。

  0.5 < AUC < 1,优于随机猜测。这个分类器(模型)妥善设定阈值的话,能有预测价值。

  AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。

  AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。


AUC值得物理意义:

假设分类器的输出是样本属于正类的socre(置信度),则AUC的物理意义为,任取一对(正、负)样本,正样本的score大于负样本的score的概率。







添加CDA认证专家【维克多阿涛】,微信号:【cdashijiazhuang】,提供数据分析指导及CDA考试秘籍。已助千人通过CDA数字化人才认证。欢迎交流,共同成长!
38.5549 1 0 关注作者 收藏

评论(0)


暂无数据

推荐课程