实验4 贝叶斯分类

一、实验目的

1. 了解并学习机器学习相关库的使用。

2. 熟悉贝叶斯分类原理和方法,并对MNIST数据集进行分类。

二、实验内容

1. 使用贝叶斯方法对mnist或mnist variation数据集进行分类,并计算准确率。数据集从网上下载(如百度飞桨平台)。

2. 改变算法参数,观察对识别准确率的影响。

三、实验环境

平台

Jupyter Notebook (anaconda3)

Python版本

python 3.9

第三方依赖

numpy、scikit-learn、matplotlib

四、方法流程

1:配置第三方依赖;

2:下载mnist数据集;

3:划分数据集为训练集train和测试集test;

4:调用机器学习库的贝叶斯分类模型;

5:设置pred为模型预测的结果;

6:比较test和pred,计算准确率;

7:输出测试集test的混淆矩阵;

8:按照上述方法继续对其他模型进行调参并对比模型的训练结果。

五、实验展示(训练过程和训练部分结果进行可视化)

1:三种贝叶斯模型的训练结果对比

模型

名称

分类准确率

GaussianNB

高斯Bayes算法

55.58%

MultinomialNB

多项式Bayes算法

83.65%

BernoulliNB

伯努利Bayes算法

84.13%

可视化训练结果(混淆矩阵):


GaussianNB


MultinomialNB


BernoulliNB

训练数据:


X = mnist.data(像素结果)


y = mnist.target(标签结果)

2:高斯Bayes算法(GaussianNB)在不同平滑参数下的训练结果对比

平滑参数var_smoothing

分类准确率

0.95

74.97%

0.8

75.89%

0.5

77.91%

0.3

79.77%

0.05

81.40%

不采用

55.58%

3:高斯Bayes算法(GaussianNB)在设置均等先验概率下的训练结果


可以发现,与未设置priors参数时候的结果一致,说明模型预先就均分了先验概率。

4:伯努利Bayes算法(BernoulliNB)在是否禁用学习类的先验概率的训练结果对比

先验概率使用fit_prior

分类准确率

True

84.13%

False

84.15%

5:伯努利Bayes算法(BernoulliNB)在不同加法(Laplace/Lidstone)平滑参数下的训练结果对比

平滑参数alpha

分类准确率

0.1

84.15%

0.5

84.14%

0.9

84.14%

6:伯努利Bayes算法(BernoulliNB)在不同二值化阈值参数下的训练结果对比

二值化阈值参数binarize

分类准确率

0.0

84.13%

0.5

84.13%

1.0

84.13%

7:多项式Bayes算法(MultinomialNB)在不同加法(Laplace/Lidstone)平滑参数下的训练结果对比

平滑参数alpha

分类准确率

0.1

83.67%

0.5

83.66%

0.9

83.65%

8:伯努利Bayes算法(BernoulliNB)在是否禁用学习类的先验概率的训练结果对比

先验概率使用fit_prior

分类准确率

True

83.65%

False

83.65%

9:多项式Bayes算法(MultinomialNB)的单张图片测试结果

10:对数据集进行主成分分析、标准化和归一化处理后的训练结果

主成分分析:

PCA_Transfer=PCA(n_components=0.95)

PCA_x=PCA_Transfer.fit_transform(x)

标准化:

Standard_Transfer=StandardScaler()

standard_x_train=Standard_Transfer.fit_transform(x_train)

standard_x_test=Standard_Transfer.fit_transform(x_test)

归一化:

MinMax_Transfer=MinMaxScaler()

Guiyihua_x_train=MinMax_Transfer.fit_transform(x_train)

Guiyihua_x_test=MinMax_Transfer.fit_transform(x_test)

经过上述操作后的模型训练结果:

模型

名称

分类准确率

GaussianNB

高斯Bayes算法

77.49%

MultinomialNB

多项式Bayes算法

85.45%

BernoulliNB

伯努利Bayes算法

74.14%

六、实验结论

1:在GaussianNB中,我们可以改变的主要参数是priors和var_smoothing。priors参数可以手动设置每个类别的先验概率,默认让模型根据数据自动计算先验概率。var_smoothing参数用于控制对类别不确定性的处理方式。var_smoothing值过大,可能会让模型对实际数据中的变化不敏感,导致模型性能降低;var_smoothing值过小,可能会对数据中的噪声和异常值更敏感,导致训练数据过拟合。

2:在MultinomialNB中,我们可以改变的主要参数是alpha、fit_prior、class_prior和min_categories。加法平滑参数alpha用于处理因数据稀疏而在学习数据中未观察到的特征,防止概率计算时出现0值。是否学习类的先验概率fit_prior如果为假,使用均匀的先验概率,即认为所有输出类别的可能性相等。类别的先验概率class_prior如果指定,则不根据数据调整先验概率。指定每个特征的最小类别数min_categories帮助防止在特征维度非常高但训练样本相对较少时出现过拟合。

3:在BernoulliNB中,我们可以改变的主要参数是alpha、binarize、fit_prior和class_prior。与MultinomialNB相比,binarize是用于二值化输入特征的阈值。如果设定,则输入特征大于这个阈值的将会被二值化为1,否则二值化为0。

4:在模型选择方面,MultinomialNB和BernoulliNB更适合处理MNIST数据集,因为MNIST的图像可以表示为像素强度计数(适合多项式分布)或二值化的像素存在与否(适合伯努利分布)。GaussianNB可能在没有适当预处理(如归一化)的情况下表现不佳。

5:在使用贝叶斯分类器后,进行误差分析(比如混淆矩阵)可以揭示某些数字更难区分。数字之间难以区分通常是由贝叶斯模型的独立性假设造成的。

七、遇到的问题及其解决方案

问题1:安装第三方依赖时,显示pip有更新。

解决1:采用【pip install –upgrade pip】命令,升级pip即可。

问题2:Jupyter Notebook只显示ipykernel为python 3,不显示具体的python版本。

解决2:采用【!pip3 -V】命令进行查看,结果如下图所示。

八、附件

1:三类贝叶斯模型的基本调用源代码

import numpy as np

import matplotlib.pyplot as plt

from sklearn.datasets import fetch_openml

# 加载MNIST或MNIST Variation数据集

mnist = fetch_openml(‘mnist_784’, version=1)

X, y = mnist.data, mnist.target

X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[:60000], y[60000:]

# 训练贝叶斯分类器

from sklearn.naive_bayes import GaussianNB

gnb = GaussianNB()

gnb.fit(X_train, y_train)

# 预测测试集

y_pred = gnb.predict(X_test)

# 计算准确率

acc = np.sum(y_pred == y_test) / len(y_test)

print(“Accuracy:”, acc)

# 可视化结果

plt.scatter(y_pred, y_test, s=20)

plt.xlabel(“Predicted label”)

plt.ylabel(“True label”)

plt.title(“Confusion Matrix”)

plt.show()

plt.savefig(‘ret.png’)

# 训练贝叶斯分类器

from sklearn.naive_bayes import MultinomialNB

gnb1 = MultinomialNB()

gnb1.fit(X_train, y_train)

# 预测测试集

y_pred = gnb1.predict(X_test)

# 计算准确率

acc = np.sum(y_pred == y_test) / len(y_test)

print(“Accuracy:”, acc)

# 可视化结果

plt.scatter(y_pred, y_test, s=20)

plt.xlabel(“Predicted label”)

plt.ylabel(“True label”)

plt.title(“Confusion Matrix”)

plt.show()

plt.savefig(‘ret1.png’)

# 训练贝叶斯分类器

from sklearn.naive_bayes import BernoulliNB

gnb2 = BernoulliNB()

gnb2.fit(X_train, y_train)

# 预测测试集

y_pred = gnb2.predict(X_test)

# 计算准确率

acc = np.sum(y_pred == y_test) / len(y_test)

print(“Accuracy:”, acc)

# 可视化结果

plt.scatter(y_pred, y_test, s=20)

plt.xlabel(“Predicted label”)

plt.ylabel(“True label”)

plt.title(“Confusion Matrix”)

plt.show()

plt.savefig(‘ret2.png’)

2:单张图片对模型进行测试的代码

import matplotlib.pyplot as plt

from sklearn.datasets import fetch_openml

from sklearn.model_selection import train_test_split

from sklearn.naive_bayes import GaussianNB

from sklearn.metrics import accuracy_score

from skimage import io, color, filters

from skimage.transform import resize

import numpy as np

# 训练贝叶斯分类器

from sklearn.naive_bayes import MultinomialNB

gnb = MultinomialNB()

gnb.fit(X_train, y_train)

# 读取图像文件

image_path = r’C:\Users\86158\Desktop\train_labels\train_examples_labels\train_new\5.png’

image = io.imread(image_path)

# 将图像缩放到28×28像素

scaled_image = resize(image, (28, 28), anti_aliasing=True)

# 将图像数据转换为一维数组

flat_image = scaled_image.flatten()

# 将像素值缩放到0到1(如果你的模型是在这个范围的数据上训练的)

processed_image = flat_image / 255.0

# 确保这里的processed_image具有与模型训练数据相同的形状

# 如果是MNIST,它应该有784个特征

processed_image = processed_image.reshape(1, -1)

# 使用模型进行预测

prediction = gnb.predict(processed_image)

print(f”Predicted class for the input image: {prediction[0]}”)

# 可选:显示图像

plt.imshow(scaled_image, cmap=’gray’)

plt.title(f’Predicted Class: {prediction[0]}’)

plt.show()

3:对数据集进行主成分分析、标准化和归一化处理的完整代码

from sklearn.datasets import fetch_openml

from sklearn.model_selection import train_test_split

from sklearn.preprocessing import StandardScaler

from sklearn.decomposition import PCA

from sklearn.neighbors import KNeighborsClassifier

from sklearn.naive_bayes import MultinomialNB,GaussianNB,BernoulliNB

import matplotlib.pyplot as plt

from sklearn.preprocessing import MinMaxScaler

from sklearn.model_selection import GridSearchCV

from sklearn.tree import DecisionTreeClassifier

from sklearn.tree import plot_tree

from sklearn.tree import export_graphviz

from sklearn.ensemble import RandomForestClassifier

from sklearn.linear_model import LogisticRegression

from sklearn.model_selection import learning_curve

from sklearn.metrics import classification_report

import numpy as np

mnist=fetch_openml(“mnist_784”,version=1,cache=True)

x=mnist.data

y=mnist.target

# 对输入特征进行主成分分析降维

print(“降维前的特征数:”,x.shape[1])

PCA_Transfer=PCA(n_components=0.95)

PCA_x=PCA_Transfer.fit_transform(x)

print(“降维后的特征数:”,PCA_x.shape[1])

# 划分训练集和测试集

x_train,x_test,y_train,y_test=train_test_split(PCA_x,y,test_size=0.2,random_state=1)

# 对输入特征值进行标准化处理

Standard_Transfer=StandardScaler()

standard_x_train=Standard_Transfer.fit_transform(x_train)

standard_x_test=Standard_Transfer.fit_transform(x_test)

# 对输入特征值进行归一化处理

MinMax_Transfer=MinMaxScaler()

Guiyihua_x_train=MinMax_Transfer.fit_transform(x_train)

Guiyihua_x_test=MinMax_Transfer.fit_transform(x_test)

Bayes_estimator1=MultinomialNB()

param_dic={“alpha”:[0.5,0.6,0.7,0.8,0.9,1,1.1,1.2]}

Bayes_estimator1=GridSearchCV(Bayes_estimator1,param_grid=param_dic,cv=10,n_jobs=-1)

Bayes_estimator1.fit(Guiyihua_x_train,y_train)

print(“多项式Bayes算法在测试集上的平均预测成功率:”,Bayes_estimator1.score(Guiyihua_x_test,y_test))

Bayes_estimator2=GaussianNB()

Bayes_estimator2=GridSearchCV(Bayes_estimator2,cv=10,param_grid={},n_jobs=-1)

Bayes_estimator2.fit(x_train,y_train)

print(“高斯Bayes算法在测试集上的平均预测成功率:”,Bayes_estimator2.score(x_test,y_test))

Bayes_estimator3=BernoulliNB()

Bayes_estimator2=GridSearchCV(Bayes_estimator2,cv=10,param_grid={},n_jobs=-1)

Bayes_estimator3.fit(x_train,y_train)

print(“伯努利Bayes算法在测试集上的平均预测成功率:”,Bayes_estimator3.score(x_test,y_test))