kaggle入门之Digital Recognition(数字识别)

 

 python 版本:python 3.7

1.获取数据

2.分析train.csv数据

      train.csv是训练样本集,大小42001*785,第一行是文字描述,所以实际的样本数据大小是42000*785,其中第一列的每一个数字是它对应行的label,可以将第一列单独取出来,得到42000*1的向量trainLabel,剩下的就是42000*784的特征向量集trainData,所以从train.csv可以获取两个矩阵trainLabel、trainData。

 

def loadTrainData():
    l=[]
    with open('train.csv') as file:
         lines=csv.reader(file)
         for line in lines:
             #把数据一行行存入列表
             l.append(line) #42001*785
    #删除第一行文字描述( 42000*785)
    l.remove(l[0])
    #使用numpy包中的array()函数把列表l转换为数组
    l=array(l)
    #截取数组的第一列,即标签向量列(42000*1)
    label=l[:,0]
    #截取数组除第一列外所有数据(42000*784)
    data=l[:,1:]
    return nomalizing(toInt(data)),toInt(label)

 

      这里还有两个函数需要说明一下,toInt()函数,是将字符串转换为整数,因为从csv文件读取出来的,是字符串类型的,比如‘253’,而我们接下来运算需要的是整数类型的,因此要转换,int(‘253’)=253。toInt()函数如下:

 

def toInt(array):
    #调用numpy中mat()函数将数组转换为矩阵,然后可以对矩阵进行一些线性代数的操作。
    array=mat(array)
    #调用numpy中的shape()函数求出矩阵的维度
    m,n=shape(array)
    #调用numpy中的zeros()函数生成一个和所求矩阵同维度(m,n)大小的以 0 填充的矩阵
    newArray=zeros((m,n))
    for i in range(m):
        for j in range(n):
                newArray[i,j]=int(array[i,j])
    return newArray

 

      nomalizing()函数做的工作是归一化,因为train.csv里面提供的表示图像的数据是0~255的,为了简化运算,我们可以将其转化为二值图像,因此将所有非0的数字,即1~255都归一化为1。nomalizing()函数如下:

 

def nomalizing(array):
    #调用numpy中的shape()函数求出矩阵的维度
    m,n=shape(array)
    for i in range(m):
        for j in range(n):
            if array[i,j]!=0:
                array[i,j]=1
    return array

 

3.分析test.csv数据

      test.csv里的数据大小是28001*784,第一行是文字描述,因此实际的测试数据样本是28000*784,与train.csv不同,没有label,28000*784即28000个测试样本,我们要做的工作就是为这28000个测试样本找出正确的label。所以从test.csv我们可以得到测试样本集testData,代码如下:
 

def loadTestData():
    l=[]
    with open('test.csv') as file:
         lines=csv.reader(file)
         for line in lines:
             l.append(line)
     #28001*784 -----> 28000*784
    l.remove(l[0])
    data=array(l)
    return nomalizing(toInt(data))  

    到这里,数据分析和处理已经完成,我们获得的矩阵有:trainData、trainLabel、testData

 

4.算法设计

   这里我们采用kNN算法来分类,核心代码:

 

def classify(inX, dataSet, labels, k):
    #待分类的输入向量inX,输入的训练样本集dataset,标签向量labels, k表示用于选择最近邻居的数目
    #调用numpy中mat()函数将输入向量inX转换为矩阵,然后可以对矩阵进行一些线性代数的操作。
    inX=mat(inX)
    dataSet=mat(dataSet)
    labels=mat(labels)
    #获取训练样本集dataSet的行数
    dataSetSize = dataSet.shape[0]      
    #先把标签向量重复dataSet行 1列生成一个和dataSet同维度的矩阵再减去dataSet            
    diffMat = tile(inX, (dataSetSize,1)) - dataSet   
    sqDiffMat = array(diffMat)**2
    #将矩阵每一行里面的所有元素相加形成一个dataSize行 1列的矩阵
    sqDistances = sqDiffMat.sum(axis=1)                  
    distances = sqDistances**0.5
    #将所求距调用numpy中的argsort()函数离排序
    #argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引号) 
    sortedDistIndicies = distances.argsort()            
    classCount={}                                      
    for i in range(k):
        voteIlabel = labels[0,sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    #函数 sorted 方法返回的是一个新的 list
    #  key=operator.itemgetter(1), reverse=True 以第二个值【itemgetter(1)】降序排列
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

      简单说明一下,inX就是输入的单个样本,是一个特征向量。dataSet是训练样本,对应上面的trainData,labels对应trainLabel,k是knn算法选定的k,一般选择0~20之间的数字。这个函数将返回inX的label,即图片inX对应的数字。
对于测试集里28000个样本,调用28000次这个函数即可。
 

5.保存结果

      kaggle上要求提交的文件格式是csv,上面我们得到了28000个测试样本的label,必须将其保存成csv格式文件才可以提交

     代码:

def saveResult(result):
    with open('result.csv','w',newline = '') as myFile:    
        myWriter=csv.writer(myFile)
        for i in result:
            tmp = []
            tmp.append(i)
            myWriter.writerow(tmp)

 

6.综合各函数

      上面各个函数已经做完了所有需要做的工作,现在需要写一个函数将它们组合起来解决digit recognition这个题目。我们写一个handwritingClassTest函数,运行这个函数,就可以得到训练结果result.csv。

def handwritingClassTest():
    trainData,trainLabel=loadTrainData()
    testData=loadTestData()
    m,n=shape(testData)
    errorCount=0
    resultList=[]
    for i in range(m):
         classifierResult = classify(testData[i], trainData, trainLabel, 5)
         resultList.append(classifierResult)
         print ("the classifier came back with: %d" % classifierResult)          
    saveResult(resultList)

 

7.kaggle 提交结果

 

kaggle入门之Digital Recognition(数字识别)_第1张图片


8.参考文献(刚开始学机器学习,第一次做kaggle上的题,所以这篇博客基本上基本上是翻译下面这篇博客)

参考博客:https://blog.csdn.net/u012162613/article/details/41929171

你可能感兴趣的:(kaggle入门之Digital Recognition(数字识别))