在 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),这里有几个比较主要的参数:

n_neighbors

即 KNN 中的 K 值,代表的是邻居的数量。

k小过拟合,k大欠拟合;一般默认使用5

weights

weights=uniform

代表所有邻居的权重相同

weights=distance

代表权重是距离的倒数,即与距离成反比
自定义函数 你可以自定义不同距离所对应的权重。

algorithm

algorithm=auto

根据数据的情况自动选择适合的算法,默认情况选择 auto

algorithm=kd_tree

也叫作 KD 树,是多维空间的数据结构,方便对关键数据进行检索;不过 KD 树适用于维度少的情况,一般维数不超过 20,如果维数大于 20 之后,效率反而会下降;

algorithm=ball_tree

也叫作球树,它和 KD 树一样都是多维空间的数据结果,不同于 KD 树,球树更适用于维度大的情况;

algorithm=brute

也叫作暴力搜索,它和 KD 树不同的地方是在于采用的是线性扫描,,而不是通过构造树结构进行快速检索。

leaf_size

代表构造 KD 树或球树时的叶子数,默认是 30,调整 leaf_size 会影响到树的构造和搜索速度。

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

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

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

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

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

训练分三个阶段:

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

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

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

#加载库
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_digits
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import MultinomialNB
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
# 加载数据
digits = load_digits()
data = digits.data
# 数据探索
print(data.shape)
# 查看第一幅图像
print(digits.images[0])
# 第一幅图像代表的数字含义
print(digits.target[0])
# 将第一幅图像显示出来
plt.gray()
plt.imshow(digits.images[0])
plt.show()

运行结果:

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

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

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

# 分割数据,将 25% 的数据作为测试集,其余作为训练集(你也可以指定其他比例的数据作为训练集)
train_x, test_x, train_y, test_y = train_test_split(data, digits.target, test_size=0.25, random_state=33)
# 采用 Z-Score 规范化
ss = preprocessing.StandardScaler()
train_ss_x = ss.fit_transform(train_x)
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 分类器准确率,

# 创建 KNN 分类器
knn = KNeighborsClassifier()
knn.fit(train_ss_x, train_y)
predict_y = knn.predict(test_ss_x)
print("KNN 准确率: %.4lf" % accuracy_score(predict_y, test_y))

knn.fit(训练集输入特征,训练集输出特征)

knn.predict(测试集输入特征)=模型输出值

accquary_score(knn.predict(测试集输入特征),测试集输出特征)

KNN 准确率: 0.9756

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

# 创建 SVM 分类器
svm = SVC()
svm.fit(train_ss_x, train_y)
predict_y=svm.predict(test_ss_x)
print('SVM 准确率: %0.4lf' % accuracy_score(predict_y, test_y))
# 采用 Min-Max 规范化
mm = preprocessing.MinMaxScaler()
train_mm_x = mm.fit_transform(train_x)
test_mm_x = mm.transform(test_x)
# 创建 Naive Bayes 分类器
mnb = MultinomialNB()
mnb.fit(train_mm_x, train_y)
predict_y = mnb.predict(test_mm_x)
print(" 多项式朴素贝叶斯准确率: %.4lf" % accuracy_score(predict_y, test_y))
# 创建 CART 决策树分类器
dtc = DecisionTreeClassifier()
dtc.fit(train_mm_x, train_y)
predict_y = dtc.predict(test_mm_x)
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-主成分分析

特征工程:根据原有的特征,设计新的特征(实际应用需要反复验证)

倘若同样的数据集,改变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语言数据挖掘--特征工程

数据预处理

knn实战:如何对手写数字进行识别?相关推荐

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

    在 Python 的 sklearn 工具包中有 KNN 算法.KNN 既可以做分类器,也可以做回归. 如果是做分类,你需要引用: from sklearn.neighbors import KNei ...

  2. ML之SVM:利用SVM算法对手写数字图片识别数据集(PCA降维处理)进行预测并评估模型(两种算法)性能

    ML之SVM:利用SVM算法对手写数字图片识别数据集(PCA降维处理)进行预测并评估模型(两种算法)性能 目录 输出结果 设计思路 核心代码 输出结果 设计思路 核心代码 estimator = PC ...

  3. ML之DR之PCA:利用PCA对手写数字图片识别数据集进行降维处理(理解PCA)

    ML之DR之PCA:利用PCA对手写数字图片识别数据集进行降维处理(理解PCA) 目录 初步理解PCA 输出结果 核心代码 初步理解PCA #理解PCA:线性相关矩阵秩计算样例 import nump ...

  4. ML之SVM:基于SVM(支持向量机)之SVC算法对手写数字图片识别进行预测

    ML之SVM:基于SVM(支持向量机)之SVC算法对手写数字图片识别进行预测 目录 输出结果 设计思路 核心代码 输出结果 设计思路 核心代码 X_train = ss.fit_transform(X ...

  5. PyTorch之LeNet-5:利用PyTorch实现最经典的LeNet-5卷积神经网络对手写数字图片识别CNN

    PyTorch之LeNet-5:利用PyTorch实现最经典的LeNet-5卷积神经网络对手写数字图片识别CNN 目录 训练过程 代码设计 训练过程 代码设计 #PyTorch:利用PyTorch实现 ...

  6. KNN算法(K临近算法)及使用KNN算法实现手写数字0-9识别

    首先感谢博主倔强的小彬雅,本文使用的素材及部分代码来源其博文机器学习入门-用KNN实现手写数字图片识别(包含自己图片转化),需要下载素材的可以到其博文最后进行下载. 关于KNN算法 knn算法也叫K临 ...

  7. 【机器学习实战】利用KNN和其他分类器对手写数字进行识别

    一.在sklearn中创建KNN分类器 KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_si ...

  8. pytorch 预测手写体数字_教你用PyTorch从零开始实现LeNet 5手写数字的识别

    背景 LeNET-5是最早的卷积神经网络之一,曾广泛用于美国银行.手写数字识别正确率在99%以上. PyTorch是Facebook 人工智能研究院在2017年1月,基于Torch退出的一个Pytho ...

  9. linux手写数字识别opencv,opencv实现KNN手写数字的识别

    人工智能是当下很热门的话题,手写识别是一个典型的应用.为了进一步了解这个领域,我阅读了大量的论文,并借助opencv完成了对28x28的数字图片(预处理后的二值图像)的识别任务. 预处理一张图片: 首 ...

最新文章

  1. 禁用GPU版本TensorFlow,切换到CPU版本TensorFlow。
  2. Solaris下调整opt分区的inode结构
  3. SQL 2005完全卸载,重新安装
  4. python内存管理变量_Python变量内存管理
  5. 【sprinb-boot】Junit测试
  6. WebAPI(part2)--获取元素
  7. 【youcans 的 OpenCV 例程 200 篇】101. 自适应中值滤波器
  8. 红橙Darren视频笔记 启动不在清单文件注册的activity 安卓8有效
  9. (65)FPGA模块例化(parameter)
  10. 【Hadoop Summit Tokyo 2016】基于Apache Spark的数据科学
  11. C++常用函数有哪些?
  12. 利用winrar安全加密
  13. 从 Resource Hacker 到 Heaventools PE Explorer 1.99 R6
  14. 计算机四级网络工程师考过指南
  15. ER Studio 使用笔记
  16. 【MISC怼题入门系列】BUU-MISC-page2
  17. mysql获取表属性和表结构
  18. PACS—医学影像信息化的基础
  19. 关于NFT的版权的保护认证
  20. CMDB资产管理系统

热门文章

  1. HashMap 详解
  2. Linux第五章自测习题——Linux系列学习笔记
  3. 【高效解法】1065 单身狗 (25分)_27行代码AC
  4. ironpython使用dictionary_在C#环境中动态调用IronPython脚本(一)
  5. cobbler网络装机
  6. K8S——单master节点和基于单master节点的双master节点二进制部署(本机实验,防止卡顿,所以多master就不做3台了)
  7. 华三服务器怎么设置系统启动模式,H3C 开局设置
  8. android布局DSL,android – 使用自定义Anko布局DSL解除警报对话框
  9. linux ls的所有参数,Linux ls命令参数详解
  10. iterm2 ssh 乱码_【已解决】Mac中iTerm2通过SSH连接远程服务器