kaggle--Digital Recognition(數字識別)--kNN算法

關於kaggle-----Digital Recognition(數字識別)項目的算法詳解,
題目鏈接:
https://www.kaggle.com/c/digit-recognizer

需說明,因爲本題目使用了KNN算法,所以運行時會十分緩慢,本條也在KNN算法的詳解中有提到,如果做嘗試需等待很長時間,實際運行出的數據爲2w8,可根據運行中的打印輸出內容推算處理時間。

全代碼

以下爲項目全代碼,內附逐條註釋,可以按照註釋理解,後部分附詳情解答。

import numpy as np
import pandas as pd
import operator
import csv
 
 
# inX:進行類別判斷的一條數據
# trainSet:訓練數據
# labels:每條數據對應的標籤
# k:近鄰數量
def classify(inX, trainSet, labels, k):
#shape[0]得出trainSet的行數,即樣本個數
    trainSetSize = trainSet.shape[0]
#tile(A,(m,n))將數組A作爲元素構造m行n列的數組
    diffMatrix = np.tile(inX, (trainSetSize, 1)) - trainSet
    sqDiffMatrix = diffMatrix ** 2
#array.sum(axis=1)按行累加,axis=0爲按列累加
    sqDistance = sqDiffMatrix.sum(axis=1)
    distances = sqDistance ** 0.5
# argsort() 返回排序索引
    sortedDistanceIndices = distances.argsort()
#sortedDistIndicies[0]表示排序後排在第一個的那個數在原來數組中的下標
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistanceIndices[i]]
#get(key,x)從字典中獲取key對應的value,沒有key的話返回0
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
 #sorted()函數,按照第二個元素即value的次序逆向(reverse=True)排序
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]
 
 
def DigitRecognition():
    # 構造訓練集和測試集
    pdTrainData = pd.read_csv("路徑/train.csv")
    # 轉換成array對象
    trainSet = pdTrainData.values
    # 對array對象進行切片操作
    trainSetLabels = trainSet[:, 0]
    # 將標籤數據從訓練數據集中剔除,方便和測試數據進行數值運算
    trainSet = trainSet[:, 1:]
    pdTestData = pd.read_csv("路徑/test.csv")
    testSet = pdTestData.values
 
    # 保存結果的列表
    index = []
    result = []
    # 對測試集中的每條數據進行處理
    for i in range(testSet.shape[0]):
        print("開始判斷第%d條數據"%i)
        index.append(i + 1)
        predictNum = classify(testSet[i], trainSet, trainSetLabels, 3)
        result.append(predictNum)
    # 將數據保存到csv文件中
    predictions = pd.DataFrame({"ImageId":index, "Label":result})
    predictions.to_csv("路徑/submission.csv", index=False)
 
DigitRecognition()

詳情解答

第一部分:KNN算法模塊
KNN算法詳解鏈接:
https://blog.csdn.net/weixin_41744624/article/details/104694204

本部分步驟:

  1. 得出訓練集的行數。(根據KNN算法,kaggle已經將訓練集轉換爲了每個數字信息爲1行的矩陣,一共n行的n條數據,此步驟爲獲取訓練集中的數據個數)
  2. 把inX(也就是我們需要判別是什麼數字的數據),轉換成和訓練集中,一樣行數的,僅有1列的數組矩陣
  3. diffmatrix是被測試的向量inX變化的矩陣與訓練集的矩陣相減而得的矩陣(也就是我們所定義的求被測試的向量與訓練集中點的距離)
  4. 根據每一條求得的距離做按列加和,也就是總距離sqDistance
  5. 執行k次選取排序,臨近的出現距離最小的k個點做記錄,出現類別最多的就是這個被測試點inX的類別
import numpy as np
import pandas as pd
import operator
import csv
 
 
# inX:進行類別判斷的一條數據
# trainSet:訓練數據
# labels:每條數據對應的標籤
# k:近鄰數量
def classify(inX, trainSet, labels, k):
#shape[0]得出trainSet的行數,即樣本個數
    trainSetSize = trainSet.shape[0]
#tile(A,(m,n))將數組A作爲元素構造m行n列的數組
    diffMatrix = np.tile(inX, (trainSetSize, 1)) - trainSet
    sqDiffMatrix = diffMatrix ** 2
#array.sum(axis=1)按行累加,axis=0爲按列累加
    sqDistance = sqDiffMatrix.sum(axis=1)
    distances = sqDistance ** 0.5
# argsort() 返回排序索引
    sortedDistanceIndices = distances.argsort()
#sortedDistIndicies[0]表示排序後排在第一個的那個數在原來數組中的下標
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistanceIndices[i]]
#get(key,x)從字典中獲取key對應的value,沒有key的話返回0
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
 #sorted()函數,按照第二個元素即value的次序逆向(reverse=True)排序
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

第二部分:數據使用模塊

  1. 讀取訓練集數據,將數據轉化爲array對象(爲了執行切片操作)
  2. 剔除第一行的名稱,再剔除第一列的標籤(kaggle數據訓練集中有介紹存在標籤列)
  3. 測試集做同樣的處理
  4. 保存到提交文件中
def DigitRecognition():
    # 構造訓練集和測試集
    pdTrainData = pd.read_csv("路徑/train.csv")
    # 轉換成array對象
    trainSet = pdTrainData.values
    # 對array對象進行切片操作
    trainSetLabels = trainSet[:, 0]
    # 將標籤數據從訓練數據集中剔除,方便和測試數據進行數值運算
    trainSet = trainSet[:, 1:]
    pdTestData = pd.read_csv("路徑/test.csv")
    testSet = pdTestData.values
 
    # 保存結果的列表
    index = []
    result = []
    # 對測試集中的每條數據進行處理
    for i in range(testSet.shape[0]):
        print("開始判斷第%d條數據"%i)
        index.append(i + 1)
        predictNum = classify(testSet[i], trainSet, trainSetLabels, 3)
        result.append(predictNum)
    # 將數據保存到csv文件中
    predictions = pd.DataFrame({"ImageId":index, "Label":result})
    predictions.to_csv("路徑/submission.csv", index=False)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章