机器学习 之朴素贝叶斯

朴素贝叶斯

贝叶斯模型同样是流行的十大挖掘算法之一,属于有监督的学习算法,是专门用于解决分类问题的模型,该模型的数学理论并不复杂,只需要具备概率论和数理统计的部分知识,该分类器的实现思想非常简单,即通过已知类别的训练数据及计算样本先验概率,然后利用贝叶斯公式测算未知类别样本属于某个类别的后验概率,最终以最大的后验概率所对应的类别作为样本的预测值。

朴素贝叶斯模型,在对于未知类别的样本进行预测时,有几大优点:

  • 首先算法在运算过程中简单而且高效
  • 其次算法拥有古典概型的理论支撑分类效率稳定
  • 最后算法对于缺失数据和异常数据不太敏感

同时缺点也是存在的:

  • 模型的判断结果依赖于先验概率,所以分类结果存在一定的错误率
  • 对于输入的自变量X要求具有相同的特征
  • 模型的前提假设在实际应用中很难得满足。

由于该模型只用到数理统计中的朴素贝叶斯公式,所以在这里就不再赘述,相信大家也都有所了解朴素贝叶斯。

高斯朴素贝叶斯中的参数

GaussianNB(priors=None) # 没错,它的主要参数就这一个。
该参数用于指定因变量各类别的先验概率,默认以数据集中的类别频率作为先验概率
所以通常情况下,我们不对高斯普速被淹死,做任何参数的调整。

高斯朴素贝叶斯的使用

from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix as CM
from sklearn.datasets import load_digits
digits=load_digits()
x,y=digits.data,digits.target
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=10)
gnb=GaussianNB().fit(x_train,y_train)
gnb.score(x_train,y_train)
gnb.predict_proba(x_test).sum(axis=1).shape
y_pro=gnb.predict(x_test)
CM(y_test,y_pro)

模型评估指标

布里尔分数
from sklearn.metrics import brier_score_loss
brier_score_loss(y_true # 真实标签
				, y_prob # 标签正概率
				, pos_label=None # 填写正样本标签
				)
需要注意的是布里尔分数只能用于二分类,不能用于多分类。
他返回的是一个浮点类型的数据,表示的是模型丢失数据的比例。所以越小越好。
对数似然
from sklearn.metrics import log_loss
log_loss(y_true# 真是标签结果
		, y_prede # 预测结果,predict_proba返回的值,不是predict返回的值  
		)
返回的是损失值,因此对数自然函数的取值越小,证明概率估计越准确。

高斯朴素贝叶斯对不同数据集的效果

from sklearn.naive_bayes import GaussianNB
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import make_moons, make_circles, make_classification

######生成三种数据集######
# 二分类数据集
X, y = make_classification(n_samples=100, #生成100个样本
 n_features=2,#有两个特征
 n_redundant=0, #添加冗余特征0个
 n_informative=2, #包含信息的特征是2个
 random_state=1,#随机模式1
n_clusters_per_class=1 #每个簇内包含的标签类别有1个
 )
rng = np.random.RandomState(2) #生成一种随机模式
X += 2 * rng.uniform(size=X.shape) #加减0~1之间的随机数
linearly_separable = (X, y) #生成了新的X,依然可以画散点图来观察一下特征的分布
#plt.scatter(X[:,0],X[:,1])

#用make_moons创建月亮型数据,make_circles创建环形数据,并将三组数据打包起来放在列表datasets中
moons=make_moons(noise=0.3, random_state=0)
circles=make_circles(noise=0.2, factor=0.5, random_state=1)
datasets = [moons,circles,linearly_separable]


figure = plt.figure(figsize=(6, 9))
i=1
#设置用来安排图像显示位置的全局变量i i = 1
#开始迭代数据,对datasets中的数据进行for循环
for ds_index, ds in enumerate(datasets):
    X, y = ds
    # 对数据进行标准化处理
    X = StandardScaler().fit_transform(X)
    #划分数据集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4,
random_state=42)

    #定数据范围,以便后续进行画图背景的确定
    #注意X[:,0]指横坐标,X[:,1]指纵坐标
    x1_min, x1_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    x2_min, x2_max = X[:, 1].min() - .5, X[:, 1].max() + .5

    #使画板上每个点组成坐标的形式(没间隔0.2取一个),array1表示横坐标,array2表示纵坐标
    array1,array2 = np.meshgrid(np.arange(x1_min, x1_max, 0.2), np.arange(x2_min, x2_max, 0.2))
    # 颜色列表
    cm_bright = ListedColormap(['#FF0000', '#0000FF'])

########## 原始数据的现实  #########

    # 用画板上六个图片位置(3,2)的第i个
    ax = plt.subplot(len(datasets), 2, i)

    # 便签添加
    if ds_index == 0:
        ax.set_title("Input data")

    #画出训练数据集散点图
    ax.scatter(X_train[:, 0],#横坐标
               X_train[:, 1],#纵坐标
               c=y_train,#意思是根据y_train标签从cm_bright颜色列表中取出对应的颜色,也就是说相同的标签有相同的颜色。
               cmap = cm_bright, #颜色列表
               edgecolors = 'k'#生成散点图,每一个点边缘的颜色
               )
    #画出测试数据集的散点图,其中比训练集多出alpha = 0.4参数,以分辨训练测试集
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test,cmap = cm_bright, alpha = 0.4, edgecolors = 'k')
    #显示的坐标范围
    ax.set_xlim(array1.min(), array1.max())
    ax.set_ylim(array2.min(), array2.max())
    #不显示坐标值
    ax.set_xticks(())
    ax.set_yticks(())

    #i+1显示在下一个子图版上画图
    i += 1

####### 经过决策的数据显示 #######
    ax = plt.subplot(len(datasets), 2, i)
    #实例化训练模型
    gnd = GaussianNB().fit(X_train, y_train)
    score = gnd.score(X_test, y_test)

    # np.c_是能够将两个数组组合起来的函数
    # ravel()能够将一个多维数组转换成一维数组
    #通过对画板上每一个点的预测值确定分类结果范围,并以此为依据通,通过不同的颜色展现出来范围

    # 为了展示不同概率对应不同的颜色就不用这句代码作为contourf的z参数了Z = clf.predict(np.c_[array1.ravel(), array2.ravel()])
    # 通过计算每一个结果对应的概率,并选出其中的最大值作为contourf参数
    Z = gnd.predict_proba(np.c_[array1.ravel(), array2.ravel()])
    Z = Z[:,0].reshape(array1.shape)
    cm = plt.cm.RdBu # 自动选取颜色的实例化模型。
    ax.contourf(array1#画板横坐标。
                , array2#画板纵坐标
                , Z# 画板每个点对应的预测值m,并据此来确定底底板的颜色。
                , cmap=cm#颜颜色选取的模型,由于Z的值只有两个,也可以写出一个颜色列表,指定相应颜色,不让其自动生成
                , alpha=0.8
                )
    #和原始数据集一样,画出每个训练集和测试集的散点图
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cm_bright, edgecolors = 'k')
    ax.scatter(X_test[:, 0], X_test[:, 1], c=y_test, cmap=cm_bright, edgecolors = 'k', alpha = 0.4)
    ax.set_xlim(array1.min(), array1.max())
    ax.set_ylim(array2.min(), array2.max())
    ax.set_xticks(())
    ax.set_yticks(())

    if ds_index == 0:
        ax.set_title("GaussianNB")

    #在右下角添加模型的分数
    ax.text(array1.max() - .3, array2.min() + .3, ('{:.1f}%'.format(score * 100)),
    size = 15, horizontalalignment = 'right')
    i += 1

#自动调整子画板与子画板之间的的距离
plt.tight_layout()
plt.show()

在这里插入图片描述

可以看出高斯朴素这些线性的数据有着非常好的效果,但是对于非线性的数据的结果并不是特别的理想

不同样本量对于高斯朴素贝叶斯的影响

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression as LR
from sklearn.model_selection import learning_curve
from sklearn.model_selection import ShuffleSplit
import time

def plot_learning_curve(estimator,title,x,y,ax,ylim=None,cv=None,n_jobs=None):
    train_size,train_scores,test_scores=learning_curve(estimator # 分类器
                                                       ,x,y# 数据
                                                       ,cv=cv # 交叉验证的模式
                                                       ,n_jobs=n_jobs)
    # train_size 为每次训练和测试集划分后,在训练集上的样本数量,会自动选取
    # train_scores为(5,50)5表示划分了5次数据,50代表每次划分训练集50次交叉验证对应的分数,所以要取均值
    # test_scores为(5,50)5表示划分了5次数据,50代表每次划分测试集50次交叉验证对应的分数,所以要取均值
    ax.set_title(title)
    if ylim is not None:
        ax.set_ylim(ylim)
    ax.set_xlabel("Training examples")
    ax.set_ylabel("Score")
    ax.grid()
    ax.plot(train_size,np.mean(train_scores,axis=1),"o-",label="Training scores",color="red")
    ax.plot(train_size, np.mean(test_scores, axis=1), "o-", label="Training scores", color="green")
    ax.legend(loc="lower right")


title_list=["GaussianNB","LR","RandomForestClassifier","SVC"]
model_list=[GaussianNB()
    ,LR(C=1,solver="lbfgs",max_iter=3000,multi_class="auto")
    ,RandomForestClassifier(n_estimators=20)
    ,SVC(kernel="rbf",gamma=0.001)]

cv=ShuffleSplit(n_splits=50 # 将数据分成50份,验证次数
                ,test_size=0.2 # 将20%作为测试集
                ,random_state=10
                )

digits=load_digits()
x=pd.DataFrame(digits.data)
y=pd.Series(digits.target)

fig=plt.figure(figsize=(20,4))
for i in range(0,4):
    start=time.time()
    ax=fig.add_subplot(1,4,i+1)
    plot_learning_curve(model_list[i],title_list[i],x,y,ax,[0.7,1.05],cv,1)
    end=time.time()
    print(title_list[i])
    print(end-start)
plt.tight_layout()
plt.show()
GaussianNB
2.445056200027466
LR
19.8220853805542
RandomForestClassifier
12.856705665588379
SVC
26.9399311542511

在这里插入图片描述
通过这段代码也能够非常明显的看出,高斯朴素贝叶斯和其他算法之间的优劣,对于其他算法来说,在模型过拟合的时候,可以通过大量的数据对通过对于模型的提升,使测试集的分数不断上升而达到比较好的效果,但是对于高斯朴素贝叶斯来说,随着样本数据的增大,虽然过拟合的程度降低,但是测试训练及的分数也随之降低,模型的效果也相对没有其他模型那么好。但是对于它的优点来说,我们可以直观的发现,它使用的时间是非常短的效率是非常高的。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
首先,我们需要探索一下数据集。西瓜数据集 2.0 是一个经典的二分类数据集,其中包含 17 个样本和 8 个特征。我们可以使用 Python 中的 Pandas 库来读取数据集。 ```python import pandas as pd # 读取数据集 data = pd.read_csv('watermelon_2.csv') print(data.head()) ``` 接下来,我们需要对数据集进行预处理。首先,我们将数据集划分为训练集和测试集。我们可以使用 Scikit-learn 库中的 train_test_split 方法来实现。 ```python from sklearn.model_selection import train_test_split # 划分数据集 X = data.iloc[:, 1:8] y = data.iloc[:, 8] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) ``` 然后,我们可以使用朴素贝叶斯分类器来训练我们的模型。Scikit-learn 库中提供了多种朴素贝叶斯分类器,例如 GaussianNB、MultinomialNB 和 BernoulliNB。在这里,我们将使用 GaussianNB。 ```python from sklearn.naive_bayes import GaussianNB # 创建模型 model = GaussianNB() # 训练模型 model.fit(X_train, y_train) ``` 最后,我们可以使用测试集来评估我们的模型。 ```python # 预测分类 y_pred = model.predict(X_test) # 计算准确率 accuracy = (y_pred == y_test).sum() / len(y_test) print('准确率:', accuracy) ``` 完整代码如下: ```python import pandas as pd from sklearn.model_selection import train_test_split from sklearn.naive_bayes import GaussianNB # 读取数据集 data = pd.read_csv('watermelon_2.csv') # 划分数据集 X = data.iloc[:, 1:8] y = data.iloc[:, 8] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) # 创建模型 model = GaussianNB() # 训练模型 model.fit(X_train, y_train) # 预测分类 y_pred = model.predict(X_test) # 计算准确率 accuracy = (y_pred == y_test).sum() / len(y_test) print('准确率:', accuracy) ``` 执行代码后,我们可以得到如下结果: ``` 准确率: 0.6 ``` 因为样本数量比较少,所以准确率并不高。如果我们使用更多的数据或者其他的朴素贝叶斯分类器,可能会得到更好的结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「 25' h 」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值