k近鄰法(一)

算法描述

給定一個訓練數據集,對新的輸入實例,在訓練數據集中找到與該實例最鄰近的k個實例,這k個實例的多數屬於某個類,就把該輸入實例分爲這個類。

三個基本要素

1.距離度量
兩個實例之間的距離可以用LpL_p範數來定義,其中p可以選擇。LPL_P範數的定義爲:
在這裏插入圖片描述
這裏面的xix_ixjx_j代表兩個實例,這兩個實例都有n個分量。
比較常用的是p=2,此時稱爲歐氏距離,即:
在這裏插入圖片描述
例如xi=(1,2,3)x_i=(1,2,3)xj=(4,5,6)x_j=(4,5,6),則這兩個實例之間的歐氏距離爲:
distance=(142+252+362)1/2distance=(|1-4|^2+|2-5|^2+|3-6|^2)^{1/2}

2.k值選擇
k選的小的話近似誤差會減小,但估計誤差會增大。

k選的大的話近似誤差會增大,估計誤差會減小。
比如k選1的話,對一個點進行分類的時候就只找到與它距離最近的1個點就行,所找到的點的類別就是這個點的類別。但在實際情況下會有噪聲點,這時k=1就很容易分錯了。如下圖所示,○是一類,×是另一類,此時放入一個△,直觀上覺得它屬於○這一類的概率大一些,但是由於噪聲的存在,如果k=1的話因爲離△最近的是一個×,這時就會把△分到×類,如果k=3的話就會把△分到○類。
在這裏插入圖片描述
另一個例子如下:
在這裏插入圖片描述
在這個例子中如果k=1或k=2的話是可以正確地把△分在○類裏面的,如果k取一個特別大的值的話△就會被錯誤地分到×中去。

3.分類決策規則
一般都是用多數表決,即離輸入實例最近的k個實例屬於哪個類別的實例數量最多那麼輸入實例就屬於哪個類別。

代碼

import numpy as np
import operator


class Knn:
    def __init__(self, point, samples, labels, k):
        self.point = point
        self.samples = samples
        self.labels = labels
        self.k = k

    def distance(self, lp):
        """計算要進行分類的點與樣本之間的距離(lp範數)"""
        samples_len = len(self.samples)
        subtract = np.tile(self.point, (samples_len, 1)) - self.samples
        absolute_value = abs(subtract)
        p_power = absolute_value ** lp
        sum_value = p_power.sum(axis=1)
        p_norm = sum_value ** (1/lp)
        return p_norm

    def classification(self, distances):
        small_to_large_index = distances.argsort()  # argsort函數返回的是數組值從小到大的索引值
        class_count = {}
        for i in range(self.k):
            near_label = self.labels[small_to_large_index[i]]

            # 統計前k箇中標籤的數目
            # 也就是說最後這個字典中存的是A類的有多少個,B類的有多少個
            # 字典(Dictionary) get() 函數返回指定鍵的值,如果值不在字典中返回默認值
            class_count[near_label] = class_count.get(near_label, 0) + 1

        # reverse=True代表逆序排列
        # key=operator.itemgetter(1)定義函數key爲獲取對象的序號爲1的值,也就是比較value,如果括號裏爲0就是比較key
        # sorted是個排序函數
        # class_count.items()爲字典裏面的內容
        sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
        return sorted_class_count[0][0]


samples_out = [[1, 2], [3, 4], [5, 6], [7, 8]]
labels_out = ['A', 'A', 'B', 'B']
knn = Knn([0, 0], samples_out, labels_out, 3)
distance_out = knn.distance(2)
classification_result = knn.classification(distance_out)
print(classification_result)

結果爲:

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