机器学习kaggle入门——手写体数字识别

国庆前后才慢慢开始学习机器学习,在师姐的推荐下选了kaggle上的入门题目,手写体数字识别练练手。一开始接触kaggle感觉想要用一个好的学习算法解决题目还是有难度得,数据量大,还要保证正确率。由于是初学并且刚好最近在书上看到过用KNN算法解决该题目的,所以选择了比较简单的KNN算法。
首先在kaggle上阅读了题目和数据的描述,数据是用.csv格式保存的。训练数据有785列,包括第一列标记,后面的则是784个像素值(0-255,越大约暗),总有42000个例子。测试数据则有28000个例子,同样是784个像素值。

数据处理

上面已经讲了数据的基本格式,现在准备读取数据并写出前面几行。

import pandas as pd
import numpy as np
import operator
import time

dataset = pd.read_csv('train.csv')
print('dataset{0[0]},{0[1]}'.format(dataset.shape))
print(dataset.head())

机器学习kaggle入门——手写体数字识别_第1张图片

从上图中可以看到第一行是label值,因为我们用到的KNN算法中需要比较的只是后面的像素值,所以需要将数据分为两个,一个包含标签,一个是比较的数据。

datalabel = dataset.iloc[:,0].values
datamat = dataset.iloc[:,1:].values
#看到网上有人在这里将矩阵二值化为0,1。想了一下可能会将不同数字二值化为同一个矩阵。

KNN算法

KNN算法非常简单,就是计算出每个训练样本离测试样本的距离,选择最近的一个。下面的代码参考了机器学习实战上的代码。

def handwritting_classify(inx, dataset, labels, k):
    """inx是用于分类的输入向量,输入样本的训练集为dataset,标签向量是labels,k表示最近邻居的数目"""
    dataset_size = dataset.shape[0]
    diffmat = np.tile(inx,(dataset_size,1)) - dataset
    sqdiffmat = diffmaat ** 2
    #axis=1,表示将矩阵的每一行相加。
    sqdistances = sqdiffmat.sum(axis=1)
    distances = sqdistances ** 0.5
    #argsort()返回从小到大数值的索引值。
    sorted_distindicies = distances.argsort()
    classcount = {}

    for i in range(k):
        vote_label = labels[sorted_distindicies[i]]
        classCount[vote_label] = classCount.get(vote_label,0) + 1
    #从大到小排序
    sorted_classcount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sorted_classcount[0][0]

对测试集进行分类

有了分类算法,现在需要对测试集进行分类。这里我们要注意,test.csv没有lable项,重要读取像素值就行了。因为我们用的是KNN算法所以在跑程序时会比较慢,最好在程序里面加入一些能够说明所需时间的变量。

def handwriting_classtest(trainfile, testfile):
    #读取训练,测试数据跟开头讲的方法一样,也可以写一个函数在这里调用
    #mtest是测试用的数据
    mtest = len(testmat)
    result = []

    for i in range(m):
        start_time = time.clock()
        result.append(handwritting_classify(testmat[i,:], trainmat, trainlabel, 3))
        circletime = time.clock() - start_time
        print("%d tasks lest,you need wait %.2f hours" % (mtest-1-i, (mtest-1-i)*circletime/3600))

    return result

将数据存入csv文件中 ##

也是利用pandas中的函数。首先生成能被pandas使用的数据结构DataFrame

result = handwriting_classtest('train.csv', 'test.csv')
submissions = pd.DataFrame({"Imageld":list(range(1,len(pred)+1)), "Label":pred})
submissions.to_csv("submissions.csv",index=False,header=True)

小结

程序跑完总共用了将近4个小时,这也是KNN算法的缺点,每一个测试数据都要重新计算与训练样本的距离。最终精确度是0.96多,排名1000多,百分之60,是比较偏下的名次了。需要进步的还有很多。看了kaggle上的许多笔记,下次可以试着用神经网络去解决这道题目,还要学会用其他的工具来改进程序。希望下次更新时,能得到一个较好的名次。

你可能感兴趣的:(机器学习kaggle入门——手写体数字识别)