监督机器学习——基于手写数字数据集的图像分类

监督机器学习——基于手写数字数据集的图像分类

MNIST手写数据集介绍

输入数据集是 MNIST,这是机器学习中的一个经典数据集,由大小为 28×28 的手写数字的灰度图像组成。原始训练数据集包含 60000 个样本(手写数字图像和标签,用于训练机器学习模型),测试数据集包含 10000 个样本(手写数字图像和标签作为基本真值,用于测试所学习模型的准确性)。给定一组手写数字和图像及其标签(0~9),目标是学习一种机器学习模型,该模型可以自动识别不可见图像中的数字,并为图像分配一个标签0~9)。具体步骤如下。
(1)使用训练数据集训练一些监督机器学习(多类分类)模型(分类器)。
(2)它们将用于预测来自测试数据集的图像的标签。
(3)将预测的标签与基本真值标签进行比较,以评估分类器的性能。
训练、预测和评估基本分类模型的步骤如下图所示。当在训练数据集上训练更多不同的模型(可能是使用不同的算法,或者使用相同的算法但算法具有不同的超参数值)时,为了选择最好的模型,需要第三个数据集,也就是验证数据集(训练数据集分为两部分,一部分用于训练,另一部分用于验证),用于模型选择和超参调优。
在这里插入图片描述

同样,先导入所需的库,如下面的代码所示:

import matplotlib
from sklearn.naive_bayes import MultinomialNB
import pandas as pd 
import seaborn as sn 
from sklearn import metrics 
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC 
import time 
from sklearn.neighbors import BallTree 
import gzip, os, sys 
import numpy as np 
import urllib.request as ureq
from scipy.stats import multivariate_normal
from keras.datasets import mnist
from keras.utils import to_categorical
from sklearn.datasets import fetch_openml
from sklearn.datasets import fetch_openml
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import  StandardScaler
from sklearn.utils import check_random_state

下载 MNIST(手写数字)数据集

从下载 MNIST 数据集开始。如下代码运用爬虫方法下载训练数据集和测试数据集:

# Function that downloads a specified MNIST data file from Yann Le Cun's website 
def download(filename, source='http://yann.lecun.com/exdb/mnist/'): 
     print("Downloading %s" % filename) 
     ureq.urlretrieve(source + filename, filename) 
# Invokes download() if necessary, then reads in images 
def load_mnist_images(filename): 
     if not os.path.exists(filename): 
         download(filename) 
     with gzip.open(filename, 'rb') as f: 
         data = np.frombuffer(f.read(), np.uint8, offset=16) 
     data = data.reshape(-1,784) 
     return data 
def load_mnist_labels(filename): 
     if not os.path.exists(filename): 
         download(filename) 
     with gzip.open(filename, 'rb') as f: 
         data = np.frombuffer(f.read(), np.uint8, offset=8) 
     return data 
## Load the training set 
train_data = load_mnist_images('train-images-idx3-ubyte.gz') 
train_labels = load_mnist_labels('train-labels-idx1-ubyte.gz') 
## Load the testing set 
test_data = load_mnist_images('t10k-images-idx3-ubyte.gz') 
test_labels = load_mnist_labels('t10k-labels-idx1-ubyte.gz') 
print(train_data.shape) 
# (60000, 784) ## 60k 28x28 handwritten digits 
print(test_data.shape) 
# (10000, 784) ## 10k 2bx28 handwritten digits

可视化数据集

def show_digit(x, label): 
     pylab.axis('off') 
     pylab.imshow(x.reshape((28,28)), cmap=pylab.cm.gray) 
     pylab.title('Label ' + str(label ))
pylab.figure(figsize=(10,10)) 
for i in range(25): 
     pylab.subplot(5, 5, i+1) 
     show_digit(test_data[i,:], test_labels[i]) 
     pylab.tight_layout() 
pylab.show() 
import time 
from sklearn.neighbors import BallTree 
## Build nearest neighbor structure on training data 
t_before = time.time() 

在训练数据集上训练的 KNN 分类器对这个未知的测试数据集的标签进行预测,并将预测的标签与基本真值标签进行比较,以评价分类器的准确性。
在这里插入图片描述

通过训练 KNN、高斯贝叶斯和 SVM 模型对 MNIST 数据集分类

scikit-learn 库函数实现以下分类器:k 最近邻分类算法、朴树贝叶斯分类器(生成模型)、随机森林、支持向量机分类器。从 k 最近邻分类器开始介绍。

1 k 最近邻分类器

该分类器用于接收手写数字图像,并使用一种称为最近邻分类器的特别简单的策略输出标签(0~9)。预测看不见的测试数字图像的方法是非常简
单的。首先,只需要从训练数据集中找到离测试图像最近的 k 个实例;其次,只需要简单地使用多数投票来计算测试图像的标签,也就是说,来自 k 个最近的训练数据点的大部分数据点的标签将被分配给测试图像(任意断开连接)。
(1)计算欧氏距离平方。欲计算数据集中的最近邻,必须计算数据点之间的距离。自然距离函数是欧氏距离,对于两个向量 x, y∈Rd,其欧氏距离定义为:
在这里插入图片描述

通常省略平方根,只计算欧氏距离的平方。对于最近邻计算,这两个是等价的:对于 3 个向量 x, y, z∈Rd,当且仅当||x − y||2 ≤ ||x − z||2时,才有||x − y|| ≤ ||x − z||成立。因此,现在只需要计算欧氏距离的平方。
(2)计算最近邻。k 最近邻的一个简单实现就是扫描每个测试图像的每个训练图像。以这种方式实施的最近邻分类需要遍历训练集才能对单个点进行分类。如果在 Rd 中有 N个训练点,时间花费将为 O (Nd),这是非常缓慢的。幸运的是,如果愿意花一些时间对训练集进行预处理,就有更快的方法来执行最近邻查找。scikit-learn 库有两个有用的最近邻数据结构的快速实现:球树和 k-d 树。如下代码展示了如何在训练时创建一个球树数据结构,然后在测试 1 − NN(k = 1)时将其用于快速最近邻计算:

import time 
from sklearn.neighbors import BallTree 
## Build nearest neighbor structure on training data 
t_before = time.time() 
ball_tree = BallTree(train_data) 
t_after = time.time() 
## Compute training time 
t_training = t_after - t_before 
print("Time to build data structure (seconds): ", t_training) 
## Get nearest neighbor predictions on testing data 
t_before = time.time() 
test_neighbors = np.squeeze(ball_tree.query(test_data, k=1,return_distance=False)) 
# test_predictions = train_labels[test_neighbors] 
t_after = time.time() 
## Compute testing time 
t_testing = t_after - t_before 
print("Time to classify test set (seconds): ", t_testing) 
# Time to build data structure (seconds): 20.65474772453308 
# Time to classify test set (seconds): 532.3929145336151
运行结果如下

在这里插入图片描述
(3)评估分类器的性能。接下来将评估分类器在测试数据集上的性能。如下代码展示了如何实现这一点:

font1 = {'family': 'Times New Roman',
'weight': 'normal',
'size': 10,}
# fontdict = {'family':'Times New Roman', 'size':19}
cm = metrics.confusion_matrix(test_labels,test_predictions) 
df_cm = pd.DataFrame(cm,range(10),range(10)) 
sn.set(font_scale=0.5,font="Times New Roman")#for label size 
plt.figure(dpi=300)
plt.subplot(2,2,1)
ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
ax.set_title("Confusion Matrix/KNN",fontdict=font1)
# plt.rc('font',family='Times New Roman',size=12)
t_accuracy = sum(test_predictions == test_labels) / float(len(test_labels)) 
t_accuracy 

运行上述代码,输出混淆矩阵,如图 所示。可以看到,虽然训练数据集的整体准确率达到 96.9%,但仍存在一些错误分类的测试图像。当 K-NN 预测标签和 True 标签均为 0 时,预测成功;当 K-NN 预测标签为 2,True 标签为 3 时,预测失败.
在这里插入图片描述

2.贝叶斯分类器(高斯生成模型)

正如我们在上一小节所看到的,K-NN 分类器对手写数字 MNIST 数据集的测试错误率为 3.09%。现在,我们将构建一个高斯生成模型,使其几乎可以达到同样的效果,但明显更快、更紧凑。同样,必须像上次一样首先加载 MNIST 训练数据集和测试数据集,然后将高斯生成模型拟合到训练数据集中。
(1)训练生成模型—计算高斯参数的最大似然估计。下面定义了一个函数
fit_generative_model(),它接收一个训练集(x 数据和 y 标签)作为输入,并将高斯生成模型与之匹配。对于每个标签 j = 0,1,…,9,返回以下几种生成模型的参数。
• πj:标签的频率(即优先的);
• μj:784 维均值向量;
• ∑j:784 × 784 协方差矩阵。
这意味着π是 10 × 1、μ是 10 × 784、∑是 10 × 784 × 784 的矩阵。最大似然估计(Maximum Likelihood Estimation,MLE)为经验估计,如下图 所示。
在这里插入图片描述
经验协方差很可能是奇异的(或接近奇异),这意味着不能用它们来进行计算,因此对这些矩阵进行正则化是很重要的。这样做的标准方法是加上 c*I,其中 c 是一个常数,I是 784 维单位矩阵(换言之,先计算经验协方差,然后将它们的对角元素增加某个常数 c)。对于任何 c > 0,无论 c 多么小,这样修改可以确保产生非奇异的协方差矩阵。现在c 成为一个(正则化)参数,适当地设置它,可以提高模型的性能。为此,应该选择一
个好的 c 值。然而至关重要的是需要单独使用训练集来完成,通过将部分训练集作为验证集,或者使用某种交叉验证。这将作为练习留给读者完成。需要特别注意的是,display_char()函数将用于可视化前 3 位数字的高斯均值,如下面的代码所示:

def display_char(image): 
     plt.imshow(np.reshape(image, (28,28)), cmap=plt.cm.gray) 
     plt.axis('off'),
     plt.show()

def fit_generative_model(x,y): 
     k = 10 # labels 0,1,...,k-1 
     d = (x.shape)[1] # number of features 
     mu = np.zeros((k,d)) 
     sigma = np.zeros((k,d,d)) 
     pi = np.zeros(k) 
     c = 3500 #10000 #1000 #100 #10 #0.1 #1e9 
     for label in range(k): 
         indices = (y == label) 
         pi[label] = sum(indices) / float(len(y)) 
         mu[label] = np.mean(x[indices,:], axis=0) 
         sigma[label] = np.cov(x[indices,:], rowvar=0, bias=1) + c*np.eye(d) 
     return mu, sigma, pi 
mu, sigma, pi = fit_generative_model(train_data, train_labels) 
display_char(mu[0]) 
display_char(mu[1]) 
display_char(mu[2]) 

运行上述代码,输出前 3 位数字的均值的最大似然估计,如下图所示。
在这里插入图片描述
(2)计算后验概率,以对测试数据进行预测和模型评价。为了预测新图像的标签 x,需要找到标签 j,其后验概率 Pr(y = j|x)最大。可以用贝叶斯规则计算,如图。
在这里插入图片描述
如下代码展示了如何使用生成模型预测测试数据集的标签,以及如何计算模型在测试数据集上产生错误的数量。可以看出,测试数据集的准确率为 95.6%,略低于 K-NN 分类器。

k = 10 
score = np.zeros((len(test_labels),k)) 
for label in range(0,k): 
     rv = multivariate_normal(mean=mu[label], cov=sigma[label]) 
     for i in range(0,len(test_labels)): 
         score[i,label] = np.log(pi[label]) + rv.logpdf(test_data[i,:]) 
test_predictions = np.argmax(score, axis=1) 
# Finally, tally up score 
errors = np.sum(test_predictions != test_labels) 
print("The generative model makes " + str(errors) + " errors out of 10000") 
# The generative model makes 438 errors out of 10000 
t_accuracy = sum(test_predictions == test_labels) / float(len(test_labels) 
t_accuracy 
# 0.95620000000000005 
df_cm = pd.DataFrame(cm) 
sn.set(font_scale=0.5,font="Times New Roman")#for label size 
plt.subplot(2,2,2)
ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
ax.set_title("Confusion Matrix/Bayes",fontdict=font1)

3.SVM 分类器

本节将使用 MNIST 训练数据集训练(多类)支持向量机(SVM)分类器,然后用它预测来自 MNIST 测试数据集的图像的标签。支持向量机是一种非常复杂的二值分类器,它使用二次规划来最大化分离超平面之间的边界。利用 1∶全部或 1∶1 技术,将二值 SVM 分类器扩展到处理多类分类问题,svm分类原理见下图。使用 scikit-learn 的实现 SVC(),后者具有多项式核(degree 为 2),利用训练数据集来拟合(训练)软边缘(核化)SVM 分类器,然后用 score()函数预测测试图像的标签。如下代码展示了如何使用 MNIST 数据集训练、预测和评估 SVM 分类器。可以看到,使用该分类器在测试数据集上所得到的准确率提高到了 98%。
在这里插入图片描述

clf = SVC(C=1, kernel='poly', degree=2) 
clf.fit(train_data,train_labels) 
test_predictions = clf.predict(test_data) 
cm = metrics.confusion_matrix(test_labels,test_predictions) 
df_cm = pd.DataFrame(cm, range(10), range(10)) 
plt.subplot(2,2,3)
sn.set(font_scale=1.2) 
ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
ax.set_title("Confusion Matrix/SVC",fontdict=font1)
t_accuracy = sum(test_predictions == test_labels) / float(len(test_labels) 
t_accuracy 

3. 随机森林分类器

  1. 简介:
    随机森林就是通过集成学习的Bagging思想将多棵树集成的一种算法:它的基本单元就是决策树。随机森林的名称中有两个关键词,一个是“随机”,一个就是“森林”。“森林”很好理解,一棵叫做树,那么成百上千棵就可以叫做森林了,其实这也是随机森林的主要思想–集成思想的体现。“随机”的含义我们会在下面讲到。我们要将一个输入样本进行分类,就需要将它输入到每棵树中进行分类。将若干个弱分类器的分类结果进行投票选择,从而组成一个强分类器,这就是随机森林bagging的思想:
    在这里插入图片描述
    每棵树的按照如下规则生成:

(1)如果训练集大小为N,对于每棵树而言,随机且有放回地从训练集中的抽取N个训练样本(就是bootstrap sample方法, 拔靴法采样)作为该树的训练集;从这里我们可以知道:每棵树的训练集都是不同的,而且里面包含重复的训练样本。

(2)如果存在M个特征,则在每个节点分裂的时候,从M中随机选择m个特征维度(m << M),使用这些m个特征维度中最佳特征(最大化信息增益)来分割节点。在森林生长期间,m的值保持不变。

一开始我们提到的随机森林中的“随机”就是指的这里的两个随机性。两个随机性的引入对随机森林的分类性能至关重要。由于它们的引入,使得随机森林不容易陷入过拟合,并且具有很好得抗噪能力(比如:对缺省值不敏感)。
随机森林分类效果(错误率)与两个因素有关:1,森林中任意两棵树的相关性:相关性越大,错误率越大;(弱分类器应该good且different)2,森林中每棵树的分类能力:每棵树的分类能力越强,整个森林的错误率越低。(弱分类器应该good且different)

减小特征选择个数m,树的相关性和分类能力也会相应的降低;增大m,两者也会随之增大。所以关键问题是如何选择最优的m,这也是随机森林的一个重要参数。

  1. OOB (袋外错误率)
    上面我们提到,构建随机森林的关键问题就是如何选择最优的特征数m这个参数,要解决这个问题主要依据计算袋外错误率OOB error(out-of-bag error)。

随机森林有一个重要的优点就是,没有必要对它进行交叉验证或者用一个独立的测试集来获得误差的一个无偏估计。它可以在内部进行评估,也就是说在生成的过程中就可以对误差建立一个无偏估计。

我们知道,在构建每棵树时,我们对训练集使用了不同的bootstrap sample(随机且有放回地抽取)。所以对于每棵树而言(假设对于第k棵树),大约有1/3的训练实例没有参与第k棵树的生成,它们称为第k棵树的oob样本。而这样的采样特点就允许我们进行oob估计,它的计算方式如下:

对每个样本,计算它作为oob样本的树对它的分类情况(约1/3的树);
然后以简单多数投票作为该样本的分类结果;
最后用误分个数占样本总数的比率作为随机森林的oob误分率。
oob误分率是随机森林泛化误差的一个无偏估计,它的结果近似于需要大量计算的k折交叉验证。这样,就可以通过比较oob误分率来选择一个最好的特征数m。

  1. 随机森林参数
    在scikit-learn中,RF的分类器是RandomForestClassifier,回归器是RandomForestRegressor。RF的参数也包括两部分,第一部分是Bagging框架的参数,第二部分是一棵CART决策树的参数。具体的参数参考随机森林分类器的函数原型:
sklearn.ensemble.RandomForestClassifier(
        n_estimators=10, criterion='gini',
        max_depth=None,min_samples_split=2, 
        min_samples_leaf=1, min_weight_fraction_leaf=0.0,
        max_features='auto', max_leaf_nodes=None,
        min_impurity_split=1e-07,bootstrap=True,
        oob_score=False, n_jobs=1, 
        random_state=None, verbose=0,
        warm_start=False, class_weight=None)

3.1 Bagging框架参数

下面来看看RF重要的Bagging框架的参数,由于RandomForestClassifier和RandomForestRegressor参数绝大部分相同,这里会将它们一起讲,不同点会指出。

  1. n_estimators: 弱学习器(决策树)的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,计算量会太大,并且n_estimators到一定的数量后,再增大n_estimators获得的模型提升会很小,所以一般选择一个适中的数值。默认是100。

  2. oob_score:即是否采用袋外样本来评估模型的好坏。默认False。推荐设置为True,因为袋外分数反应了一个模型拟合后的泛化能力。

  3. criterion: 即CART树做划分时对特征的评价标准。分类模型和回归模型的损失函数是不一样的。分类RF对应的CART分类树默认是基尼系数gini,另一个可选择的标准是信息增益(information gain)。回归RF对应的CART回归树默认是均方差mse,另一个可以选择的标准是绝对值差mae。一般来说选择默认的标准就已经很好的。

从上面可以看出, RF重要的框架参数比较少,主要需要关注的是 n_estimators,即森林中决策树的个数。

3.2 决策树参数

下面我们再来看RF的决策树参数:

  1. RF划分时考虑的最大特征数 max_features: 就是之前提到的“在每个节点处,从M中随机选择m个特征维度”中的那个m。默认是"auto",意味着每个节点在划分时随机考虑 个特征;如果是"log2"意味着划分时随机考虑 个特征;如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑百分比*总特征维度数取整后的特征数。一般用默认的"auto"就可以了;如果特征数非常多,可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。

  2. 决策树最大深度max_depth: 默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。

  3. 内部节点再划分所需最小样本数min_samples_split: 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再划分。默认是2。如果样本量数量级非常大,则推荐增大这个值。

  4. 叶子节点最少样本数min_samples_leaf: 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝,只保留原来的父节点。默认是1。如果样本量数量级非常大,则推荐增大这个值。

5)叶子节点最小的样本权重和min_weight_fraction_leaf:这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝,只保留原来的父节点。 默认是0,就是不考虑权重问题。如果我们有较多样本有缺失值,或者分类树样本的分布类别非常不平衡,就会引入样本权重,这时我们就要注意这个值了。

  1. 最大叶子节点数max_leaf_nodes: 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征非常多的话,可以加以限制,具体的值可以通过交叉验证得到。

  2. 节点划分最小不纯度min_impurity_split: 这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。即为叶子节点 。一般不推荐改动,默认值1e-7。

上面决策树参数中最重要的包括最大特征数max_features, 最大深度max_depth, 内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf,这里我们运用随机森林API对 MNIST 训练,代码如下:

rf = RandomForestClassifier()
rf.fit(train_data,train_labels)
test_predictions = rf.predict(test_data) 
cm = metrics.confusion_matrix(test_labels,test_predictions) 
df_cm = pd.DataFrame(cm, range(10), range(10)) 
plt.subplot(2,2,4)
sn.set(font_scale=1.2) 
ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
ax.set_title("Confusion Matrix/RF",fontdict=font1)
t_accuracy = sum(test_predictions == test_labels) / float(len(test_labels) 
t_accuracy 
# plt.rc('font',family='Times New Roman',size=12)

代码完整版总结``

import matplotlib
from sklearn.naive_bayes import MultinomialNB
import pandas as pd 
import seaborn as sn 
from sklearn import metrics 
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC 
import time 
from sklearn.neighbors import BallTree 
import gzip, os, sys 
import numpy as np 
import urllib.request as ureq
from scipy.stats import multivariate_normal
from keras.datasets import mnist
from keras.utils import to_categorical
from sklearn.datasets import fetch_openml
from sklearn.datasets import fetch_openml
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import  StandardScaler
from sklearn.utils import check_random_state
font1 = {'family': 'Times New Roman',
'weight': 'normal',
'size': 10,}
# fontdict = {'family':'Times New Roman', 'size':19}
cm = metrics.confusion_matrix(test_labels,test_predictions) 
df_cm = pd.DataFrame(cm,range(10),range(10)) 
sn.set(font_scale=0.5,font="Times New Roman")#for label size 
plt.figure(dpi=300)
plt.subplot(2,2,1)
ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
ax.set_title("Confusion Matrix/KNN",fontdict=font1)
# plt.rc('font',family='Times New Roman',size=12)
def display_char(image): 
     plt.imshow(np.reshape(image, (28,28)), cmap=plt.cm.gray) 
     plt.axis('off'),
     plt.show()

def fit_generative_model(x,y): 
     k = 10 # labels 0,1,...,k-1 
     d = (x.shape)[1] # number of features 
     mu = np.zeros((k,d)) 
     sigma = np.zeros((k,d,d)) 
     pi = np.zeros(k) 
     c = 3500 #10000 #1000 #100 #10 #0.1 #1e9 
     for label in range(k): 
         indices = (y == label) 
         pi[label] = sum(indices) / float(len(y)) 
         mu[label] = np.mean(x[indices,:], axis=0) 
         sigma[label] = np.cov(x[indices,:], rowvar=0, bias=1) + c*np.eye(d) 
     return mu, sigma, pi 
mu, sigma, pi = fit_generative_model(train_data, train_labels) 
display_char(mu[0]) 
display_char(mu[1]) 
display_char(mu[2]) 
# Compute log Pr(label|image) for each [test image,label] pair. 
k = 10 
score = np.zeros((len(test_labels),k)) 
for label in range(0,k): 
     rv = multivariate_normal(mean=mu[label], cov=sigma[label]) 
     for i in range(0,len(test_labels)): 
         score[i,label] = np.log(pi[label]) + rv.logpdf(test_data[i,:]) 
test_predictions = np.argmax(score, axis=1) 
# Finally, tally up score 
errors = np.sum(test_predictions != test_labels) 
print("The generative model makes " + str(errors) + " errors out of 10000") 
# The generative model makes 438 errors out of 10000 
t_accuracy = sum(test_predictions == test_labels) / float(len(test_labels) 
t_accuracy 
# 0.95620000000000005 
df_cm = pd.DataFrame(cm) 
sn.set(font_scale=0.5,font="Times New Roman")#for label size 
plt.subplot(2,2,2)
ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
ax.set_title("Confusion Matrix/Bayes",fontdict=font1)
# mlb = MultinomialNB(alpha=1.0)
# mlb.fit(train_data, train_labels)
# y_predict = mlb.predict(x_test)
# cm = metrics.confusion_matrix(test_labels,test_prediction) 
# df_cm = pd.DataFrame(cm) 
# sn.set(font_scale=0.5,font="Times New Roman")#for label size 
# plt.subplot(2,2,2)
# ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
# ax.set_title("Confusion Matrix/Bayes",fontdict=font1)
# plt.rc('font',family='Times New Roman',size=12)
# from sklearn.svm import SVC 
clf = SVC(C=1, kernel='poly', degree=2) 
clf.fit(train_data,train_labels) 
test_predictions = clf.predict(test_data) 
cm = metrics.confusion_matrix(test_labels,test_predictions) 
df_cm = pd.DataFrame(cm, range(10), range(10)) 
plt.subplot(2,2,3)
sn.set(font_scale=1.2) 
ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
ax.set_title("Confusion Matrix/SVC",fontdict=font1)
# plt.rc('font',family='Times New Roman',size=12)
rf = RandomForestClassifier()
rf.fit(train_data,train_labels)
test_predictions = rf.predict(test_data) 
cm = metrics.confusion_matrix(test_labels,test_predictions) 
df_cm = pd.DataFrame(cm, range(10), range(10)) 
plt.subplot(2,2,4)
sn.set(font_scale=1.2) 
ax=sn.heatmap(df_cm, annot=True,annot_kws={"size": 5,'family': 'Times New Roman'}, fmt="g",cmap="Greens",linewidths=0.05) 
ax.set_title("Confusion Matrix/RF",fontdict=font1)
# plt.rc('font',family='Times New Roman',size=12)
pylab.tight_layout() 
# plt.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05) 

运行结果如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值