k近鄰演算法沒有顯示的學習過程,由三個基本要素——距離度量,k值的選擇和分類決策規則決定。
距離選擇可以是歐式距離,lp距離或minkowski距離
k值的選擇過大會使模型變得簡單;過小會導致過擬合,通常取乙個比較小的數值採用交叉驗證法來取最優。
分類決策規則往往是多數表決(等價於經驗風險最小化)。
kd樹最近鄰搜尋
建樹過程比較簡單,詳見文末**,這裡直接從搜尋開始。
其中nearest和nearestdis在初始化類時定義# 用kd樹的最近鄰搜尋演算法,樹已構造好
defsearch
(self, node, aim, depth=0)
:if node is
notnone
: n =
len(aim)
# aim是目標點,計算維度
axis = depth % n
if aim[axis]
< node.data[axis]
: self.search(node.lchild, aim, depth+1)
else
: self.search(node.rchild, aim, depth+1)
dis = self.dist(aim, node.data)
# 歐式距離
if self.nearest is
none
or self.nearestdis > dis:
self.nearest = node.data # 儲存當前最近點
self.nearestdis = dis # 當前最近距離
# 演算法3.3(3)(b) 判斷是否需要去另一子結點搜尋
ifabs
(node.data[axis]
- aim[axis]
)<= self.nearestdis:
if aim[axis]
< node.data[axis]
: self.search(node.rchild, aim, depth +1)
else
: self.search(node.lchild, aim, depth +
1)
演算法的實現學習了這位大佬:k近鄰 kd樹的python實現def
__init__
(self)
: self.kdtree =
none
self.nearest =
none
self.nearestdis =
0
kd樹實現k近鄰演算法
在上述演算法的基礎上進行改進:用列表來儲存k個最近的點,初始化函式變為
演算法框架不變,先找到包含目標點的區域然後開始回退。def
__init__
(self)
: self.kdtree =
none
self.nearest =
self.nearestdis =
當列表中的點不足k個時,將當前結點加入nearest列表,同時將當前結點與目標點的距離加入nearestdis列表;另外,當前結點與目標點距離小於nearestdis列表中的最大距離時,對nearest和nearestdis列表進行更新,替換此最遠點和對應的距離。
檢查是否需要去當前結點的另一子結點搜尋,只需將之前的判斷半徑變為nearest中最遠點到目標點的距離就可以。
k預設為1;當k大於資料集中所有點時,不報錯,輸出所有點。# 用kd樹的k近鄰搜尋演算法,k預設為1
defsearch
(self, node, aim, k=
1, depth=0)
:if node is
notnone
: n =
len(aim)
axis = depth % n
if aim[axis]
< node.data[axis]
: self.search(node.lchild, aim, k, depth+1)
else
: self.search(node.rchild, aim, k, depth+1)
dis = self.dist(aim, node.data)
# 歐式距離
iflen
(self.nearest)
< k:
# 若不夠k個,加入k近鄰列表
elif
max(self.nearestdis)
> dis:
# 當小於k近鄰列表中最大值時替換此最大值
maxindex = self.nearestdis.index(
max(self.nearestdis)
) self.nearest[maxindex]
= node.data
self.nearestdis[maxindex]
= dis
# 判斷是否需要去另一子結點搜尋
ifabs
(node.data[axis]
- aim[axis]
)<=
max(self.nearestdis)
:# 搜尋半徑
if aim[axis]
< node.data[axis]
: self.search(node.rchild, aim, k, depth +1)
else
: self.search(node.lchild, aim, k, depth +
1)
對書上例項執行如下:
data =[[
2,3]
,[5,
4],[
9,6]
,[4,
7],[
8,1]
,[7,
2]]x =[5
,3]kdtree = kdtree(
)# 定義乙個kd樹例項
tree = kdtree.create(data)
# 構造樹
# kdtree.preorder(tree)
kdtree.search(tree, x,3)
# 搜尋
(kdtree.nearest)
(kdtree.nearestdis)
結果:[[2
,3],
[5,4
],[7
,2]]
[3.0
,1.0
,2.23606797749979
]
統計學習方法之kNN演算法
統計學習方法讀書筆記之knn演算法 k 近鄰法是機器學習中最基本的分類和回歸方法,也稱為knn演算法。通常k近鄰法用於分類問題。k近鄰法假定給定乙個訓練資料集,其中例項類別已定。分類時,對新的例項,根據其k個最近鄰的訓練例項類別,一般通過多數表決的方式來進行 例如,有兩堆水果,一堆是橙子,一堆是柚子...
統計學習方法筆記 KNN
k近鄰法 k nearest neighbor,k nn 這裡只討論基於knn的分類問題,1968年由cover和hart提出,屬於判別模型 k近鄰法不具有顯式的學習過程,演算法比較簡單,每次分類都是根據訓練集中k個最近鄰,通過多數表決的方式進行 所以模型需要保留所有訓練集資料,而象感知機這樣的模型...
統計學習方法筆記 KNN
k近鄰法 k nearest neighbor,k nn 這裡只討論基於knn的分類問題,1968年由cover和hart提出,屬於判別模型 k近鄰法不具有顯式的學習過程,演算法比較簡單,每次分類都是根據訓練集中k個最近鄰,通過多數表決的方式進行 所以模型需要保留所有訓練集資料,而象感知機這樣的模型...