当前位置:   article > 正文

c++ 正态分布如何根据x求y_knn实战:如何对手写数字进行识别?

yknn

cb43ea135bbcf3bb61a0944ea59ca756.png

在 Python 的 sklearn 工具包中有 KNN 算法。KNN 既可以做分类器,也可以做回归。

如果是做分类,你需要引用:

from sklearn.neighbors import KNeighborsClassifier

如果是做回归,你需要引用:

from sklearn.neighbors import KNeighborsRegressor

如何在 sklearn 中创建 KNN 分类器:

我们使用构造函数 KNeighborsClassifier(n_neighbors=5, weights=‘uniform’,algorithm=‘auto’, leaf_size=30),这里有几个比较主要的参数:

6871bdc00b938c1f305f5d11367c27d5.png

创建完 KNN 分类器之后,我们就可以输入训练集对它进行训练,这里我们使用 fit() 函数,传入训练集中的样本特征矩阵和分类标识,会自动得到训练好的 KNN 分类器。然后可以使用 predict() 函数来对结果进行预测,这里传入测试集的特征矩阵可以得到测试集的预测分类结果。

如何用 KNN 对手写数字进行识别分类

手写数字数据集是个非常有名的用于图像识别的数据集。数字识别的过程就是将这些图片与分类结果 0-9 一一对应起来。

完整的手写数字数据集 MNIST 里面包括了 60000 个训练样本,以及 10000 个测试样本。如果你学习深度学习的话,MNIST 基本上是你接触的第一个数据集。

今天我们用 sklearn 自带的手写数字数据集做 KNN 分类,它只包括了 1797 幅数字图像,每幅图像大小是 8*8 像素。

训练分三个阶段:

1、加载数据集;本地导入,线上调取,自带数据集;在这里,我们使用自带数据集;

2、准备阶段:可视化数据描述:样本量多少,图像长啥样,输入输出特征;数据处理:缺失值处理,异常值处理、特征工程构造;

3、分类阶段:通过训练可以得到分类器,然后用测试集进行准确率的计算。

  1. #加载库
  2. from sklearn.model_selection import train_test_split
  3. from sklearn import preprocessing
  4. from sklearn.metrics import accuracy_score
  5. from sklearn.datasets import load_digits
  6. from sklearn.neighbors import KNeighborsClassifier
  7. from sklearn.svm import SVC
  8. from sklearn.naive_bayes import MultinomialNB
  9. from sklearn.tree import DecisionTreeClassifier
  10. import matplotlib.pyplot as plt
  11. # 加载数据
  12. digits = load_digits()
  13. data = digits.data
  14. # 数据探索
  15. print(data.shape)
  16. # 查看第一幅图像
  17. print(digits.images[0])
  18. # 第一幅图像代表的数字含义
  19. print(digits.target[0])
  20. # 将第一幅图像显示出来
  21. plt.gray()
  22. plt.imshow(digits.images[0])
  23. plt.show()

运行结果:

5f580c5d7b06ec768ff0b43a297983ca.png

我们对原始数据集中的第一幅进行数据可视化,可以看到图像是个 8*8 的像素矩阵,上面这幅图像是一个“0”,从训练集的分类标注中我们也可以看到分类标注为“0”。

sklearn 自带的手写数字数据集一共包括了 1797 个样本,每幅图像都是 8*8 像素的矩阵。因为并没有专门的测试集,所以我们需要对数据集做划分,划分成训练集和测试集。

因为 KNN 算法和距离定义相关,我们需要对数据进行规范化处理,采用 Z-Score 规范化:

  1. # 分割数据,将 25% 的数据作为测试集,其余作为训练集(你也可以指定其他比例的数据作为训练集)
  2. train_x, test_x, train_y, test_y = train_test_split(data, digits.target, test_size=0.25, random_state=33)
  3. # 采用 Z-Score 规范化
  4. ss = preprocessing.StandardScaler()
  5. train_ss_x = ss.fit_transform(train_x)
  6. test_ss_x = ss.transform(test_x)
75%数据作为训练集;train_x作为训练集的输入特征值矩阵,train_y作为训练集的输出特征值;
对训练集与测试集中的输入特征值进行z评分归一化;(记住一定要对测试集输入特征进行同样的处理!以后谈论的变换默认都是对输入特征进行!)
fit_transform是fit和transform两个函数都执行一次。所以ss是进行了fit拟合的。只有在fit拟合之后,才能进行transform
在进行test的时候,我们已经在train的时候fit过了,所以直接transform即可。
另外,如果我们没有fit,直接进行transform会报错,因为需要先fit拟合,才可以进行transform。

然后我们构造一个 KNN 分类器 knn,把训练集的数据传入构造好的 knn,并通过测试集进行结果预测,与测试集的结果进行对比,得到 KNN 分类器准确率,

429f65f4a78dd127d0eff5dd6b2ec8a9.png
  1. # 创建 KNN 分类器
  2. knn = KNeighborsClassifier()
  3. knn.fit(train_ss_x, train_y)
  4. predict_y = knn.predict(test_ss_x)
  5. print("KNN 准确率: %.4lf" % accuracy_score(predict_y, test_y))
knn.fit(训练集输入特征,训练集输出特征)
knn.predict(测试集输入特征)=模型输出值
accquary_score(knn.predict(测试集输入特征),测试集输出特征)

KNN 准确率: 0.9756

我们选用之前学过的几个模型,进行预测:

  1. # 创建 SVM 分类器
  2. svm = SVC()
  3. svm.fit(train_ss_x, train_y)
  4. predict_y=svm.predict(test_ss_x)
  5. print('SVM 准确率: %0.4lf' % accuracy_score(predict_y, test_y))
  6. # 采用 Min-Max 规范化
  7. mm = preprocessing.MinMaxScaler()
  8. train_mm_x = mm.fit_transform(train_x)
  9. test_mm_x = mm.transform(test_x)
  10. # 创建 Naive Bayes 分类器
  11. mnb = MultinomialNB()
  12. mnb.fit(train_mm_x, train_y)
  13. predict_y = mnb.predict(test_mm_x)
  14. print(" 多项式朴素贝叶斯准确率: %.4lf" % accuracy_score(predict_y, test_y))
  15. # 创建 CART 决策树分类器
  16. dtc = DecisionTreeClassifier()
  17. dtc.fit(train_mm_x, train_y)
  18. predict_y = dtc.predict(test_mm_x)
  19. print("CART 决策树准确率: %.4lf" % accuracy_score(predict_y, test_y))
运行结果:
SVM 准确率: 0.9867
多项式朴素贝叶斯准确率: 0.8844
CART 决策树准确率: 0.8356

这里需要注意的是,我们在做多项式朴素贝叶斯分类的时候,传入的数据不能有负数。

因为 Z-Score 会将数值规范化为一个标准的正态分布,即均值为 0,方差为 1,数值会包含负数。因此我们需要采用 Min-Max 规范化,将数据规范化到 [0,1] 范围内。

数据预处理:无量纲化处理(线性:均值化与标准化;非线性),降维
当输入特征接近正态分布,使用Z评分归一化;
当输入特征呈现高度偏斜,而我们模型对输入特征的要求是正态分布时,选用Box-Cox变换;
Z评分归一化的特点:变换结果均值为0,方差为1;变换时对数值进行平移和缩放的同时,保留了密度图的总体形态
Box-Cox变换:变换时对数值进行平移和缩放的同时,改变了整体形态,产生了比原始图偏斜更少的密度图。
降维:特征缩减,比如PCA-主成分分析
特征工程:根据原有的特征,设计新的特征(实际应用需要反复验证)

b4fce43999a4da4dfbfe126585eea230.png

倘若同样的数据集,改变k值,会得出如下结论:

knn默认k值为5 准确率:0.9756
knn的k值为200的准确率:0.8489
SVM分类准确率:0.9867
高斯朴素贝叶斯准确率:0.8111
多项式朴素贝叶斯分类器准确率:0.8844
CART决策树准确率:0.8400
K值的选取如果过大,正确率降低。
算法效率排行 SVM > KNN(k值在合适范围内) >多项式朴素贝叶斯 > CART > 高斯朴素贝叶斯

分别用 KNN、SVM、朴素贝叶斯和决策树做分类器,并统计了四个分类器的准确率。在数据量不大的情况下,使用 sklearn 还是方便的。

如果数据量很大,比如 MNIST 数据集中的 6 万个训练数据和 1 万个测试数据,那么采用深度学习 +GPU 运算的方式会更适合。

因为深度学习的特点就是需要大量并行的重复计算,GPU 最擅长的就是做大量的并行计算。

总结:

1、各模型对输入特征是有分布要求的;比如多项式朴素贝叶斯分类要求数据非负;最小二乘法模型要求数据是正态分布,满足四大假设;神经网络则对数据分布无要求。

2、特征变换是针对输入特征的;特征变化是数据处理的子集,决定模型的上限,而模型的好坏只是逼近这个上限

3、skearn适合数据量较小的训练,若是数据量过大,可以采用深度学习框架+GPU运算。实际运用中,可以使用集成学习(机器学习+深度学习框架)完成。

参考:

数据分析实战45讲

用商业案例学R语言数据挖掘--特征工程

数据预处理

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/357205
推荐阅读
相关标签
  

闽ICP备14008679号