k近鄰算法K-Nearest Neighbors(KNN)

算法核心

KNN算法的核心思想是“近朱者赤,近墨者黑”。對于一個待分類或預測的樣本點,它會查找訓練集中與其距離最近的K個樣本點(即“最近鄰”)。然后根據這K個最近鄰的標簽信息來對當前樣本進行分類或回歸。 在分類任務中,通常是根據K個最近鄰中出現次數最多的類別來確定待分類樣本的類別;在回歸任務中,則是根據K個最近鄰的目標值的平均值來預測待預測樣本的目標值。

?例如在圖中:

如果我們以k=3畫圓,因為在圓圈內ClassB出現的數量要比ClassA更多,因此我們可以把它歸到ClassB

但如果我們以k=6畫圓,因為在圓圈內ClassA出現的數量要比ClassB更多,因此我們可以把它歸到ClassA

值得注意的是:這里的k是離我們觀測點最近的第k個點,而非半徑

距離選擇

這里的距離可以采用不同的求法,常見的距離度量方式有:

? 歐氏距離:這是最常見的距離度量方式,它計算的是樣本點在多維空間中的直線距離。對于兩個樣本點 x = (x_1, x_2, ..., x_n) 和 y = (y_1, y_2, ..., y_n) ,歐氏距離定義為 \sqrt{(x_1 - y_1)^2 + (x_2 - y_2)^2 + ...?+ (x_n - y_n)^2} 。? 曼哈頓距離:它計算的是樣本點在坐標軸方向上的絕對距離之和,即 |x_1 - y_1| + |x_2 - y_2| + ...?+ |x_n - y_n| 。在某些場景下,比如在城市街區網格中計算兩點之間的距離時,曼哈頓距離更符合實際情況。

? 明可夫斯基距離:它是一種更通用的距離度量,歐氏距離和曼哈頓距離都是它的特例。明可夫斯基距離的定義為

?當 p = 2 時,就是歐氏距離;當 p = 1 時,就是曼哈頓距離

?K值的選擇

K值的選擇對KNN算法的性能影響很大。 如果K值選得太小,算法會過于敏感,容易受到噪聲數據的影響。例如,當K = 1時,一個噪聲點可能會直接影響到分類或回歸的結果。如果K值選得太大,算法又會過于“平滑”,可能會將不同類別的樣本混合在一起。比如在一個復雜的分類問題中,如果K值過大,可能會導致不同類別之間的邊界模糊。 通常,k值選擇時一般選擇的是比較小的值,像是3、5、7、9這樣的個位單數

kd樹優化算法

kd樹(k-d tree,k維樹)是用于優化KNN算法中最近鄰搜索過程的一種數據結構。

kd樹的作用

1. 加速最近鄰搜索

? 在KNN算法中,最耗時的部分是計算待預測點與訓練集中所有點之間的距離,以找到最近的K個鄰居。當訓練集規模很大時,這種暴力搜索方法效率非常低。

? kd樹通過將訓練數據組織成一種樹形結構,能夠快速定位到與目標點最近的區域,從而減少需要計算距離的點的數量,大大加快最近鄰搜索的速度。

2. 空間劃分

? kd樹是一種二叉樹結構,它通過遞歸地將數據空間劃分為超矩形區域。在每次劃分時,選擇一個維度(通常是方差最大的維度)作為劃分軸,將數據點按照該維度的中值分為兩部分,分別存儲在樹的左子樹和右子樹中。通過這種方式,kd樹將整個數據空間劃分為多個小區域,每個區域對應樹中的一個節點。

kd樹的構建過程

1. 選擇劃分維度

? 在構建kd樹時,需要選擇一個維度作為劃分軸。通常會選擇方差最大的維度,因為方差大的維度意味著數據在這個方向上的分布更分散,劃分效果更好。

2. 選擇劃分點

? 在選定的維度上,選擇該維度的中值作為劃分點。將小于中值的點分配到左子樹,大于中值的點分配到右子樹。

3. 遞歸劃分

? 對左右子樹重復上述過程,每次選擇不同的維度進行劃分,直到每個區域只包含一個數據點,或者滿足其他停止條件。

kd樹在KNN中的使用

1. 搜索最近鄰

? 當需要找到某個目標點的最近鄰時,kd樹會從根節點開始,沿著樹的結構向下搜索。根據目標點在當前劃分維度上的值,決定是進入左子樹還是右子樹。通過這種方式,可以快速定位到目標點所在的區域。

2. 回溯查找

? 單純沿著樹向下搜索可能無法找到真正的最近鄰,因為可能存在其他區域的點距離目標點更近。因此,在搜索到葉子節點后,需要進行回溯。在回溯過程中,檢查每個節點的劃分超平面與目標點的距離,如果這個距離小于當前已知的最近距離,就需要檢查另一側子樹,以確保找到真正的最近鄰。

示例場景

假設我們有一個二維空間中的數據點集合,目標是找到某個目標點\(P\)的最近鄰點。我們將通過以下步驟來展示如何利用空間劃分和距離關系來優化搜索過程。

1.數據點和目標點

假設我們有以下數據點:

? \(A(1,1)\)

? \(B(2,2)\)

? \(C(10,10)\)

? \(D(11,11)\)

? \(E(12,12)\)

目標點\(P\)的坐標為\((0,0)\)。

2.構建空間劃分結構(如kd樹)

為了優化搜索過程,我們首先構建一個kd樹。假設我們按照以下步驟構建kd樹:

1. 選擇第一個維度(x軸)作為劃分軸,找到中值點\(B(2,2)\)。

2. 將數據點分為兩部分:

? 左子樹:\(A(1,1)\)

? 右子樹:\(C(10,10)\),\(D(11,11)\),\(E(12,12)\)

3. 對右子樹,選擇第二個維度(y軸)作為劃分軸,找到中值點\(D(11,11)\)。

4. 繼續劃分,直到每個區域只包含一個點。

構建的kd樹如下:

? ? ? ? B(2, 2)/ \A(1, 1) D(11, 11)/ \C(10, 10) E(12, 12)

3.利用距離關系跳過某些點

現在,我們從目標點\(P(0,0)\)開始搜索其最近鄰點。

第一步:從根節點開始

? 從根節點\(B(2,2)\)開始,計算\(P\)與\(B\)的距離:

?第二步:選擇子樹

? 由于\(P\)的 x 坐標小于\(B\)的 x 坐標,我們進入左子樹,到達點\(A(1,1)\)。

? 計算\(P\)與\(A\)的距離:

?? 目前,\(A\)是最近鄰點,最近距離為\(\sqrt{2}\)。

第三步:回溯并跳過某些點

? 回溯到根節點\(B\)。檢查右子樹是否可能包含更近的點。

? 計算目標點\(P\)到右子樹劃分超平面(x=2)的距離:

?? 由于\(2>\sqrt{2}\),這意味著右子樹中任何點到\(P\)的距離都不會小于當前的最近距離\(\sqrt{2}\)。因此,我們可以跳過右子樹中的所有點(\(C\),\(D\),\(E\)),而不需要進一步計算它們與\(P\)的距離。

4.優化后的搜索過程

通過上述步驟,我們利用了空間劃分(kd樹)和距離關系(跳過距離遠的點)來優化搜索過程。最終,我們確定\(A(1,1)\)是目標點\(P(0,0)\)的最近鄰點,而無需計算\(P\)與右子樹中所有點的距離。

5.復雜度分析

? 暴力搜索:計算目標點與所有點的距離,復雜度為\(O(DN)\)。

? 優化后的搜索:通過kd樹的空間劃分和跳過無關區域,復雜度降低到\(O(DN\log N)\)。這是因為:

? 構建kd樹的復雜度為\(O(N\log N)\)。

? 搜索過程通過遞歸和回溯,每次只需要檢查部分點,而不是所有點。

應用實例

以下是一個使用Python和`scikit-learn`庫實現的KNN算法對鳶尾花(Iris)數據集進行分類的完整代碼示例。鳶尾花數據集是機器學習中常用的入門數據集,包含150個樣本,每個樣本有4個特征(花萼長度、花萼寬度、花瓣長度、花瓣寬度),分為3個類別。
?

# 導入必要的庫
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score# 加載鳶尾花數據集
iris = load_iris()
X = iris.data ?# 特征數據
y = iris.target ?# 標簽數據# 劃分訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 數據標準化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)# 創建KNN分類器
k = 3 ?# 選擇K值
knn = KNeighborsClassifier(n_neighbors=k)# 訓練模型
knn.fit(X_train, y_train)# 進行預測
y_pred = knn.predict(X_test)# 評估模型
print("混淆矩陣:")
print(confusion_matrix(y_test, y_pred))
print("\n分類報告:")
print(classification_report(y_test, y_pred))
print("\n準確率:")
print(accuracy_score(y_test, y_pred))# 輸出測試集的真實標簽和預測標簽
print("\n測試集的真實標簽:", y_test)
print("測試集的預測標簽:", y_pred)

代碼說明


1. 加載數據集

? 使用`load_iris()`函數加載鳶尾花數據集。

? 數據集包含150個樣本,每個樣本有4個特征,分為3個類別(0、1、2)。


2. 劃分訓練集和測試集

? 使用`train_test_split()`函數將數據集劃分為訓練集和測試集,其中測試集占30%。

? 設置`random_state`參數以確保結果的可重復性。


3. 數據標準化

? 使用`StandardScaler`對特征數據進行標準化處理,使每個特征的均值為0,標準差為1。這有助于提高KNN算法的性能。


4. 創建KNN分類器

? 使用`KNeighborsClassifier`創建KNN分類器,設置`n_neighbors=k`,其中`k`是最近鄰的數量。


5. 訓練模型

? 使用`fit()`方法訓練模型。


6. 進行預測

? 使用`predict()`方法對測試集進行預測。


7. 評估模型

? 使用`confusion_matrix`、`classification_report`和`accuracy_score`評估模型的性能。

? 輸出混淆矩陣、分類報告和準確率。

?注意事項

1. K值的選擇

? K值的選擇對KNN算法的性能有很大影響。可以通過交叉驗證等方法來選擇最優的K值。

2. 數據標準化

? 對于KNN算法,數據標準化是非常重要的,因為KNN依賴于距離計算,而不同特征的量綱可能不同。

3. 數據集劃分

? 數據集的劃分方式可能會影響模型的性能,可以通過多次劃分或使用交叉驗證來評估模型的穩定性。

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/899686.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/899686.shtml
英文地址,請注明出處:http://en.pswp.cn/news/899686.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Feign】??使用 openFeign 時傳遞 MultipartFile 類型的參數參考

💥💥????歡迎閱讀本文章????💥💥 🏆本篇文章閱讀大約耗時三分鐘。 ??motto:不積跬步、無以千里 📋📋📋本文目錄如下:🎁🎁&a…

zk基礎—1.一致性原理和算法二

大綱 1.分布式系統特點 2.分布式系統的理論 3.兩階段提交Two-Phase Commit(2PC) 4.三階段提交Three-Phase Commit(3PC) 5.Paxos島的故事來對應ZooKeeper 6.Paxos算法推導過程 7.Paxos協議的核心思想 8.ZAB算法簡述 6.Paxos算法推導過程 (1)Paxos的概念 (2)問題描述 …

216. 組合總和 III 回溯

目錄 問題描述 解決思路 關鍵點 代碼實現 代碼解析 1. 初始化結果和路徑 2. 深度優先搜索(DFS) 3. 遍歷候選數字 4. 遞歸與回溯 示例分析 復雜度與優化 回溯算法三部曲 1. 路徑選擇:記錄當前路徑 2. 遞歸探索:進入下…

從AI大模型到MCP中臺:構建下一代智能服務的核心架構

從AI大模型到MCP中臺:構建下一代智能服務的核心架構 引言:AI大模型帶來的服務重構革命 在ChatGPT掀起全球AI熱潮的今天,大模型展現出的驚人能力正在重塑整個軟件服務架構。但鮮為人知的是,真正決定AI服務成敗的不僅是模型本身&a…

美團小程序 mtgsig1.2 拼好飯案例 分析 mtgsig

聲明 本文章中所有內容僅供學習交流使用,不用于其他任何目的,抓包內容、敏感網址、數據接口等均已做脫敏處理,嚴禁用于商業用途和非法用途,否則由此產生的一切后果均與作者無關! 逆向分析 美團網頁、小程序、app全是指…

【大模型基礎_毛玉仁】5.5 模型編輯應用

目錄 5.5 模型編輯應用5.5.1 精準模型更新5.5.2 保護被遺忘權5.5.3 提升模型安全 5.5 模型編輯應用 大語言模型面臨更新成本高、隱私保護難、安全風險大等問題。模型編輯技術: 通過細粒度修改預訓練模型,避免從頭訓練,降低更新成本&#xff…

揭秘:父子組件之間的傳遞

基礎知識 組件與組件之間有三大方面的知識點: 子組件通過props defineProps({})接收父組件傳遞到參數和方法;子組件可以通過定義 emit 事件,向父組件發送事件;父組件調用子組件通過defineExpose 導出的方法…

微前端實現方案對比Qiankun VS npm組件

架構層面: 1、Qiankun是典型的微前端架構,側重構建多個獨立前端應用協同工作的架構,主應用負責自用用的加載、卸載和通信;子應用不限制,可以是VUE、React等; 2、Qiankun松耦合,各個自應用獨立…

可編輯160頁PPT | 營銷流程和管理數字化轉型規劃

薦言分享:隨著技術的發展和消費者行為的變化,傳統營銷方式已難以滿足現代企業的需求。企業需要借助數字化手段,對營銷流程進行全面梳理和優化,提升營銷活動的精準度和效率。同時,通過數字化營銷管理,企業可…

Ecovadis認證需要準備哪些材料?

Ecovadis認證,作為全球領先的企業社會責任(CSR)評估平臺,其準備材料的過程不僅需要詳盡無遺,更要體現出企業在環境、社會、勞工和倫理四大方面的卓越實踐與持續改進的決心。 首先,環境管理方面&#xff0c…

程序化廣告行業(45/89):RTB競價后續流程、結算規則及相關要點解讀

程序化廣告行業(45/89):RTB競價后續流程、結算規則及相關要點解讀 大家好!一直以來,我都希望能和大家一起在程序化廣告這個領域不斷探索、共同成長,這也是我寫這系列博客的初衷。之前我們了解了程序化廣告…

權重參數矩陣

目錄 1. 權重參數矩陣的定義與作用 2. 權重矩陣的初始化與訓練 3. 權重矩陣的解讀與分析 (1) 可視化權重分布 (2) 統計指標分析 4. 權重矩陣的常見問題與優化 (1) 過擬合與欠擬合 (2) 梯度問題 (3) 權重對稱性問題 5. 實際應用示例 案例1:全連接網絡中的…

文法 2025/3/3

文法的定義 一個文法G是一個四元組:G(,,S,P) :一個非空有限的終極符號集合。它的每個元素稱為終極符號或終極符,一般用小寫字母表示。終極符號是一個語言不可再分的基本符號。 :一個非空有限的非終極符號集合。它的每個元素稱為…

字符串復習

344:反轉字符串 編寫一個函數,其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 s 的形式給出。 不要給另外的數組分配額外的空間,你必須原地修改輸入數組、使用 O(1) 的額外空間解決這一問題。 示例 1: 輸入:s ["…

【數據結構】算法效率的雙刃劍:時間復雜度與空間復雜度

前言 在算法的世界里,效率是衡量算法優劣的關鍵標準。今天,就讓我們深入探討算法效率的兩個核心維度:時間復雜度和空間復雜度,幫助你在算法設計的道路上更進一步。 一、算法效率:衡量算法好壞的關鍵 算法的效率主要…

Java基礎-26-多態-認識多態

在Java編程中,多態(Polymorphism) 是面向對象編程的核心概念之一。通過多態,我們可以編寫更加靈活、可擴展的代碼。本文將詳細介紹什么是多態、如何實現多態,并通過具體的例子來幫助你更好地理解這一重要概念。 一、什…

使用自定義的RTTI屬性對對象進行流操作

由于歷史原因,在借鑒某些特定出名的游戲引擎中,不知道當時的作者的意圖和編寫方式 特此做這篇文章。(本文出自游戲編程精粹4 中 使用自定義的RTTI屬性對對象進行流操作 文章) 載入和 保存 關卡,并不是一件容易辦到的事…

周總結aa

上周學習了Java中有關字符串的內容,與其有關的類和方法 學習了static表示靜態的相關方法和類的使用。 學習了繼承(extends) 多態(有繼承關系,有父類引用指向子類對象) 有關包的知識,final關鍵字的使用,及有…

密碼學基礎——密碼學相關概念

目錄 1.1 密碼系統(Cryptosystem) 1.2 密碼編碼學 1.3 密碼分析學 1.4 基于算法保密 1.5 基于密鑰保密 1.6密碼系統的設計要求 1.7 單鑰體制 1.8 雙鑰體制 密鑰管理 1.1 密碼系統(Cryptosystem) 也稱為密碼體制&#xff0…

初始JavaEE篇 —— Mybatis-plus 操作數據庫

找往期文章包括但不限于本期文章中不懂的知識點: 個人主頁:我要學編程程(?_?)-CSDN博客 所屬專欄:JavaEE 目錄 前言 Mybatis-plus 快速上手 Mybatis-plus 復雜操作 常用注解 TableName TableField TableId 打印日志 條件構造器 …