用kNN算法识别手写数字(digits, kNN)
digits数据集的说明
digits数据集类似mnist数据集是一个手写数字识别的数据集,美中不足是这个数据集里的样本没有mnist多,但是优点是数据格式很简单易懂。
digits可以用KNN,SVM,NN(取决于调参和代价函数,激活函数选择,所以我只是大概取了一种情况,给了个naive版本的估计值,事实上神经网络效果可以很好)等多种方法实现。(虽然这个数据集很适合KNN,因为数字形态很类似)
以下为2017年3月初各个版本的score:
version | Training error (%) | Test error (%) |
---|---|---|
SVM RBF, 100 | 4.5 | 4.3 |
SVM Linear | 2.7 | 2.2 |
kNN | 0 | 1.1 |
NN | 5 | 5 |
kNN
K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别,属于有监督的机器学习算法。
看了Machine Learning in Action里面的第一章k邻近算法(kNN),感觉这个算法简单易懂,那么决定动手做一做,在书里面最直观可视好玩的例子某过于识别手写数字这个任务了。所以做了一下任务digits。
首先看懂了书里的代码,书里的代码巧妙地用来了矩阵运算库简化代码编程复杂度,我对numpy库和其他数据结构了解的太少,所以程序写的很吃力,看来为了入门机器学习,我必须要加强python3学习,这样才能更快的验证表达我的idea。接下来为了方便自己练习测试先写了driver.py来方便测试并更改书里的源码,除了书里标准的classifier外实现myClassifier来比较测试。
看懂书里的代码后发现一个问题,书里直接取k=3,那么这样有没有道理呢?我更改了k的值测试了一下,发现k取3可以令error最小(虽然不知道为什么)。
我决定简单优化一下kNN,从两个方面入手:
1.书里的代码只考虑票数,没考虑次序,所以我考虑了次序,具体就是i票权=1+EPS/(i+1),EPS很小。这就是我的myClassifierV1。
2.k=3的确最优了,那么能不能动态的决定k的值,比入0NN和1NN一样就不必再投票了,但是出现了摆动就多投票几次?这就是我的myClassifierV2。
当然还尝试过其他奇奇怪怪的优化,比如k由比较接近的若干个决定,可以我没能刻画好接近这一概念。比如要求得票超过一定比例,可以往往这样得不出最优值。成功的优化只有上面两个,就算告一段落了吧。
测试结果
先测试V1,再测试V2,可以看出V1,V2都以微弱优势战胜课本程序,但是有意思的是V2与V1和课本程序在不同地方失误,由于样本不够大,所以难免不是特别准确,但是可以看出大体上算法还是取得一定效果的。
zzy@zzy-lenovo-g50-80:~/zzy/MachineLearing/MyProject/digits$ python3 driver.py
Hello, this is a small drive to test myClassifier.
errorDetailMode(print error detail)? Y/N > y
9_14.txt : classifier/myClassifier came back with: 1/1, the real answer is: 9
3_11.txt : classifier/myClassifier came back with: 9/9, the real answer is: 3
5_43.txt : classifier/myClassifier came back with: 6/6, the real answer is: 5
8_36.txt : classifier/myClassifier came back with: 1/1, the real answer is: 8
8_23.txt : classifier/myClassifier came back with: 3/3, the real answer is: 8
1_86.txt : classifier/myClassifier came back with: 7/7, the real answer is: 1
8_45.txt : classifier/myClassifier came back with: 1/1, the real answer is: 8
5_42.txt : classifier/myClassifier came back with: 3/3, the real answer is: 5
9_60.txt : classifier/myClassifier came back with: 7/7, the real answer is: 9
3_55.txt : classifier/myClassifier came back with: 9/3, the real answer is: 3
8_11.txt : classifier/myClassifier came back with: 6/6, the real answer is: 8classifier performance:
the total number of errors is: 11
the total error rate is: 1.163%myClassifier performance:
the total number of errors is: 10
the total error rate is: 1.057%zzy@zzy-lenovo-g50-80:~/zzy/MachineLearing/MyProject/digits