K近鄰算法(KNN)的簡單python實現

1 算法思想

給定測試樣本,基於某種距離度量找出訓練集中與其最靠近的 k 個訓練樣本,然後基於這 k 個“鄰居”的信息來進行預測。通常,在分類任務中可使用“投票法”,即選擇這 k 個樣本中出現最多的類別標記作爲預測結果;在迴歸任務中可使用“平均法”,即將這 k 個樣本的實值輸出標記的平均值作爲預測結果;還可以基於距離遠近進行加權平均或加權投票,距離越近的樣本權重越大。(來源於周志華《機器學習》第225頁)

2 算法實現

import numpy as np
import matplotlib.pyplot as plt

# 初始化模擬數據
# X_train 爲樣本點
X_train = np.array([[2, 1],[3, 2],[4, 2],[1, 3],[1.5, 4],[1.7, 3],[2.6, 5],[3.4, 3],
                    [3, 6],[1, 7],[4, 5],[1.2, 6],[1.8, 7],[2.2, 8],[3.7, 7],[4.8, 5]])
# y_train 爲樣本點標記
y_train = np.array([0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1])
# X_test 爲測試樣本
X_test = np.array([3.2, 5.4])
# k 爲鄰居數
k = 3

# 這裏的距離公式採用歐式距離
square_ = (X_train - X_test) ** 2
square_sum = square_.sum(axis=1) ** 0.5
# 根據距離大小排序並找到 測試樣本 與 所有樣本k個最近的樣本的序列
square_sum_sort = square_sum.argsort()
small_k = square_sum_sort[:k]
# K近鄰用於分類則統計K個鄰居分別屬於哪類的個數,用於迴歸則計算K個鄰居的y的平均值作爲預測結果
# 統計距離最近的k個樣本 分別屬於哪一類的個數 別返回個數最多一類的序列 作爲預測結果
y_test_sum = np.bincount(np.array([y_train[i] for i in small_k])).argsort()
# 打印預測結果
print('predict: class {}'.format(y_test_sum[-1]))

# 將數據可視化 更生動形象
# 將 class0 一類的樣本點 放到 X_train_0中
X_train_0 = np.array([X_train[i, :] for i in range(len(y_train)) if y_train[i] == 0])
# 將 class1 一類的樣本點 放到 X_train_1中
X_train_1 = np.array([X_train[i, :] for i in range(len(y_train)) if y_train[i] == 1])

# 繪製所有樣本點 並採用不同的顏色 分別標記 class0 以及 class1
plt.scatter(X_train_0[:,0], X_train_0[:,1], c='g', marker='o', label='train_class0')
plt.scatter(X_train_1[:,0], X_train_1[:,1], c='m', marker='o', label='train_class1')
if y_test_sum[-1] == 0:
    test_class = 'g'
elif y_test_sum[-1] == 1:
    test_class = 'm'
plt.scatter(X_test[0], X_test[1], c=test_class, marker='*', s=100, label='test_class')
# 連接 測試樣本 與k個近鄰
for i in small_k:
    plt.plot([X_test[0], X_train[i, :][0]], [X_test[1], X_train[i, :][1]], c='c')
plt.legend(loc='best')
plt.show()

3 數據可視化

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章