1. 程式人生 > 其它 >python實現k-近鄰演算法

python實現k-近鄰演算法

技術標籤:機器學習python機器學習

本文不涉及k-近鄰演算法的原理,只通過python程式碼實現演算法,並且沒有用到機器學習庫,根據演算法流程一步一步實現。

程式碼實現

資料處理

假設我們已經獲取了資料及其標籤的文字檔案,如下圖所示。

在這裡插入圖片描述

資料有3個屬性,標籤分為3個型別,。python讀取資料

# 讀取資料並記錄
def readFile(filename):
    file = open(filename)              # 開啟檔案
    lines = file.readlines()           # 讀取每行資料
    num = len(lines)
# 資料的數量 X_data = np.zeros((num, 3)) # 準備儲存資料特徵矩陣 X_label = [] # 準備儲存資料標籤 index = 0 for line in lines: line = line.strip() # 丟棄資料後的換行 list = line.split('\t') # 資料分隔 X_data[index, :] = list[0:3] # 儲存資料特徵
X_label.append(int(list[-1])) # 儲存標籤 index += 1 return X_data, X_label

讀取資料之後,對特徵進行歸一化處理

# 特徵歸一化
def norm(data):
    min = data.min(0)       # 獲取每個特徵最小值
    max = data.max(0)       # 每個特徵最大值
    ranges = max - min      # 每個特徵極差
    normData = np.zeros(np.shape(data))             # 準備儲存歸一化後的特徵
m = data.shape[0] # 獲取資料的數量 normData = data - np.tile(min, (m, 1)) # 將最小值擴充套件成為矩陣的形式,大小與data相同,並相減 normData = normData / np.tile(ranges, (m, 1)) # 將極差擴充套件成為矩陣的形式,大小與data相同,並相除

資料分類

kNN分類器

# kNN分類
def classify(X_data, X_label, y_data, k):
    num = X_data.shape[0]                      # 訓練資料的數量          
    y = np.tile(y_data, (num, 1)) - X_data     # 測試資料擴充套件為訓練資料大小相同的矩陣形式,並相減
    y2 = y ** 2                                # 計算平方
    distances = (y2.sum(axis=1)) ** 0.5        # 計算距離                         
    sortedDisIndex = distances.argsort()       # 排序,並獲得索引
    classCount = {}
    # 前k個標籤
    for i in range(k):
        vote = X_label[sortedDisIndex[i]]              # 第i個標籤
        classCount[vote] = classCount.get(vote, 0) + 1  # 標籤數量加1
    sortedClassCount = sorted(classCount.items(), 
        key=operator.itemgetter(1), reverse=True)       # 標籤數量排序
    return sortedClassCount[0][0]

演算法測試

選取10%的資料用於測試

# 測試
def test():
    ratio = 0.10                               # 0.1的資料用於測試
    X_data, X_label = readFile('set.txt')      # 讀取資料
    normData, ranges, minVals = norm(X_data)   # 特徵歸一化
    num = normData.shape[0]                    # 資料數量
    numTest = int(num * ratio)                 # 測試資料數量
    errorCount = 0.0
    for i in range(numTest):
        result = classify(normData[numTest: num, :], X_label[numTest: num], normData[i, :], 3)   # 分類
        print("分類結果: %d, 實際結果: %d" % (result, X_label[i]))
        if (result != X_label[i]): errorCount += 1.0
    print("錯誤率: %f" % (errorCount / float(numTest)))
    print(errorCount)

最後通過執行test()函式即可進行測試。如果有新的資料,執行classify()函式獲得分類結果。