用kNN算法识别手写数字,归一化对准确率的影响?

PenguinGoHack
  • 227

最近在入门Kaggle竞赛,练习赛中手写数字识别遇到了问题。
最开始我自己写了算法,运行正确率非常低,于是从网上找了一个相近的算法来测试。
该算法用kNN算法来识别,首先取出训练数据,归一化,然后分类。
这个算法与我自己的算法只有一步不一样,就是使用了归一化把向量化为二值的。
参考算法

# 归一化,把所有不为1的值化为1
def nomalizing(array):
    m,n=shape(array)
    for i in xrange(m):
        for j in xrange(n):
            if array[i,j]!=0:
                array[i,j]=1
    return array

下面贴一下我自己的算法

# -*- coding: utf-8 -*-
import numpy as np
import _csv as csv
import operator


# path 文件路径
# rowNum 可指定取数据集中特定数量向量
# 将图片转换为向量矩阵,返回数据集、类别
def loadTrainingData(path, rowNum = -1):
    rawData = []
    with open(path) as file:
        lines = csv.reader(file)
        for line in lines:
            rawData.append(line)

    # 去除pixel行
    rawData.remove(rawData[0])

    dataSet = rawData[0:rowNum]
    # dataSet = map(int, dataSet)
    dataSet = np.array(dataSet)
    labels = dataSet[:,0]

    dataSet = dataSet[:,1:]
    dataSet = dataSet.astype(int)
    # print np.shape(dataSet)
    resultSet = dataSet
    return resultSet, labels


def loadTestData(path):
    rawData = []
    with open(path) as file:
        lines = csv.reader(file)
        for line in lines:
            rawData.append(line)
    # 去除pixel行
    rawData.remove(rawData[0])

    dataSet = np.array(rawData)
    dataSet = dataSet.astype(int)
    resultSet = dataSet
    return resultSet


# knn算法分类器
# inX 所要测试的向量
# dataSet 训练样本集
# labels 标签向量
# k 所选的最邻近数目
def knnClassifier(inX, dataSet, labels, k):
    # 矩阵化
    inX = np.mat(inX)
    dataSet = np.mat(dataSet)
    labels = np.mat(labels)

    dataSetSize = dataSet.shape[0]

    # 计算与每个样本的差值
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    # 求欧式距离
    sqDiffMat = np.array(diffMat)**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    # 得到以距离排序的索引列表,距离由近到远
    sortedDistIndicies = distances.argsort()
    #得到类别:个数的字典
    classCount={}
    for i in range(k):
        voteIlabel = labels[0,sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

运行后,我的算法准确率非常低。
请问归一化为什么能够提高准确率呢?

回复
阅读 7.2k
1 个回答

array里面存储的是什么?像素值么?

kNN不是一种很有竞争力的算法,它利用的还是裸的像素值来做图像表示。
虽然不需要训练阶段,但是预测阶段需要保留所有的标注数据以方便查找相似的图片。
而logistic regression, SVM之类的模型只需要存储有限的参数就可以了。

对于手写字符识别问题,现在最有效的模型是CNN(Convolutional Neural Network)
准确率达到90%以上是很容易的,仔细选择网络架构可以破95%.

这里有一个示例实现:http://deeplearning.net/tutorial/lenet.html

还有一个关于这个任务的调查表:http://yann.lecun.com/exdb/mnist/

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏