赞
踩
Task05 基于鸢尾花数据集的贝叶斯分类算法实践
一、学习内容概括
学习资料:
1.阿里云天池-AI训练营机器学习:https://tianchi.aliyun.com/specials/promotion/aicampml?invite_channel=1&accounttraceid=7df048c2ce194081b514fd2c8e9a3f00cqmm
2.sklearnAPI:https://scikit-learn.org/stable/modules/classes.html
二、具体学习内容
朴素贝叶斯算法原理:
由上述原理,分析出朴素贝叶斯解决什么问题:
样本数据集D和对应的特征属性集X可以合二为一形成一个二维数组(样本数n_samples,特征数n_features),我们把这个二维数组称为数据集。原理中提到的类变量Y,我们也形成一个一维数组(样本数n_samples,),我们把这个一维数组称为标签集。从整个数据集中可以再划分出训练集和测试集,标签集也相应划分出训练标签集和测试标签集。
我们先输入训练集和对应的标签集进行学习,通过学习得到朴素贝叶斯模型。基于模型,输入某个样本X,就可以得到相应的标签预测概率值集P(Y|X)(X条件下Y的概率),这里为什么说是一个值集,因为Y中有很多类别,针对一个样本,属于什么类别,每种类别都有其预测概率值P(Yi|X),有的值大有的值小,其实这个值集在代码中表示就是一个(1,标签数)型的二维数组(当然这是针对一个样本而言,多个样本就是(样本数,标签数))。通过预测结果,我们可以直接看出P(Y|X)中最大的那个概率值,这个概率值对应的类别就是我们想知道的类别Yi。这就是朴素贝叶斯解决的问题。另外,我们把P(Y|X)记为Y的后验概率。
说到这里还是比较抽象,下面从代码中一步步解读。
代码流程:
1 库函数导入
- import warnings
- warnings.filterwarnings('ignore')
- import numpy as np
- # 加载莺尾花数据集
- from sklearn import datasets
- # 导入高斯朴素贝叶斯分类器
- from sklearn.naive_bayes import GaussianNB
- from sklearn.model_selection import train_test_split
1.1 忽略警告信息
Q:在python中,代码可以正常运行但是会提示警告。
A:调用warnings模块中警告过滤器filterwarnings()函数忽略警告消息。
1.2 sklearn.naive_bayes:朴素贝叶斯。其中naive_bayes.GaussianNB(* [,先验,...]):高斯朴素贝叶斯(GaussianNB)
1.3 sklearn.model_selection:选型。model_selection.train_test_split(*数组,...)用于数据集的分割,分割成训练集和测试集
2 数据导入&分析
- ## return_X_y默认为False,如果为True,表示返回的是(data,target)
- ## X=data是(样本数,特征数)数组;y=target是(1,标签数)数组
- X, y = datasets.load_iris(return_X_y=True)
- ## X,y是待拆分的数据集;test_size是指将0.2比例的数据集拿出来作为测试集;
- ## random_state默认值为None,不设置则每次复现代码时都会随机分割,如果设置为一个值,那复现代码时会是与本次一样的分割结果
- X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
这里可以看一下各个数据的形状:X(150,4)、y(150,)、X_train(120,4)、X_test(30,4)、y_train(120,)、y_test(30,4)。看得出来150*0.2=30。这里的X就是数据集,y就是标签集。X_train和X_test是从X中划分出的训练集、测试集;y_train、y_test是从y中划分出的与X相对应的标签集。
通过分析发现训练数据是数值类型的数据,这里假设每个特征服从高斯分布,因此我们选择高斯朴素贝叶斯来进行分类计算。高斯朴素贝叶斯假设每个特征都服从高斯分布,我们把一个随机变量X服从数学期望为μ,方差为σ^2的数据分布称为高斯分布。对于每个特征我们一般使用平均值来估计μ和使用所有特征的方差估计σ^2。
3 模型训练
- # 使用高斯朴素贝叶斯进行计算
- ## var_smoothing:float,默认值= 1e-9。表示所有特征的最大方差部分,已添加到方差中以提高计算稳定性。
- ## var_smoothing是sklearn0.20版中的新功能
- clf = GaussianNB(var_smoothing=1e-8)
- clf.fit(X_train, y_train)
我们根据X_train和y_train训练出高斯朴素贝叶斯模型。
通过sklearn.__version__检查sklearn版本,发现是“0.19”,var_smoothing是sklearn0.20版中的新功能,所以var_smoothing不能用。因此我们在控制台更新sklearn版本:pip install scikit-learn==0.23
4 模型预测
- # 评估
- ## GaussianNB.predict(X)对测试向量X进行分类,返回X的预测目标值。
- ## 输入(n_samples, n_features)型数组。输出(n_samples,)型数组。
- ## X_test.shape(30,4),y_pred.shape(30,)
- y_pred = clf.predict(X_test)
- print(y_pred.shape[0],"个预测值:",y_pred)
-
- ## 测试集标签值y_test与估计值y_pred比较,共30个测试样本。得到一个正确率acc
- acc = np.sum(y_test == y_pred) / X_test.shape[0]
- print("Test Acc : %.3f" % acc)
输出结果:
- 30 个预测值: [2 1 0 2 0 2 0 1 1 1 1 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0]
- Test Acc : 0.967
通过训练得到的模型,在测试集上表现不错,正确率达到96.7%。
基于训练好的模型,对X_test进行一个预测,与y_test对比来对模型进行一个评估。
- # 预测
- ## GaussianNB.predict_proba(X)对测试向量X的概率估计。输入、输出都是(n_samples, n_features)型数组,
- ## X_test[:1]数组切片,只取一行样本
- y_proba = clf.predict_proba(X_test[:1])
-
- print("\n测试样本",X_test[:1],"的预测类别为:",clf.predict(X_test[:1]))
- print("\n测试样本",X_test[:1],"的预测概率为:\n",y_proba)
输出结果:
- 测试样本 [[5.8 2.8 5.1 2.4]] 的预测类别为: [2]
-
- 测试样本 [[5.8 2.8 5.1 2.4]] 的预测概率为:
- [[1.63542393e-232 2.18880483e-006 9.99997811e-001]]
输入一个样本,不光可以根据predict()函数直接得到其预测类别,还可以根据predict_proba()函数看到针对每一种类别/标签,预测的概率都是多少,几个预测概率值相比较,最大的那个预测值9.99997811e-001对应的类别[2]就是我们想要的类别,也就是predict()函数直接预测到的那个。
重复一遍朴素贝叶斯的功能,就是输入样本,根据学习好的模型进行预测,预测出样本属于几种类别的概率,其中,几种类别预测概率值中最大的那个对应的类别就是我们想要的类别Yi。也就是说事件X最有可能的结果是Yi。
从上述例子中的预测结果中,我们可以看到类别2对应的后验概率值最大,所以我们认为类别2是最优的结果。
三、学习总结
sklearn对朴素贝叶斯算法进行了封装,我们就像在使用一个黑盒子。这个例子只是展示了贝叶斯算法的使用,并没有展现算法的具体细节。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。