機器學習(一)KNN,K近鄰算法(K-Nearest Neighbors)

💡 建議初學者掌握KNN作為理解其他復雜算法(如SVM、決策樹、神經網絡)的基石。

K近鄰算法(K-Nearest Neighbors, KNN)詳解:原理、實踐與優化

K近鄰算法(K-Nearest NeighboKrs,簡稱KNN)是一種經典、直觀且易于實現的監督學習方法,既可用于分類,也可用于回歸。它“懶惰”地存儲所有訓練樣本,直到有新樣本需要預測時才臨時計算,因此也被稱為“懶惰學習算法”。
本文將系統介紹KNN的核心思想、算法流程、距離度量、超參數、優缺點、使用方法與完整Python實戰案例,幫助讀者從理論到實踐全面掌握這一算法。


一、核心思想 🧠

KNN 基于以下假設:

近朱者赤,近墨者黑”:一個樣本的標簽很可能與其最近鄰的樣本標簽一致。

具體流程:

  • 對新樣本,計算它與訓練集中所有樣本的距離;

  • 選出距離最小的 K 個鄰居;

  • 分類:根據鄰居類別投票(通常為多數投票,但可加權);

  • 回歸:返回鄰居標簽的平均值或加權平均值。

其中,三個核心超參數影響性能:

  • K 值

  • 距離度量方式

  • 投票或加權策略


二、算法流程(以分類為例)

  1. 準備訓練集與測試集

  2. 對測試集中每個新樣本,計算其與所有訓練樣本的距離

  3. 對距離排序,選取最近的 K 個鄰居

  4. 投票或加權,輸出預測類別

  5. 返回所有樣本的預測值(分類/回歸結果)


三、常見距離度量方法

不同的任務場景和數據類型,可能需要不同的距離度量方式:

距離類型定義適用場景
歐氏距離(L?)∑(xi?yi)2\sqrt{\sum (x_i - y_i)^2}連續特征,標準的距離度量
曼哈頓距離(L?)(\sumx_i - y_i
閔可夫斯基距離(L?)(\left(\sumx_i - y_i
余弦相似度x?y∥x∥∥y∥\dfrac{x \cdot y}{\|x\|\|y\|}文本或向量空間數據的方向相似度
漢明距離不同位數數目分類特征、二進制特征或字符串比較

?? 注意:使用KNN前通常需要對數據做標準化(如Z-score或Min-Max),防止量綱不同導致距離計算失真。


四、KNN的關鍵超參數

1. K值選擇

  • K太小 → 模型復雜,容易過擬合,對噪聲敏感;

  • K太大 → 模型過于平滑,可能欠擬合。

通常使用**交叉驗證(GridSearchCV)**選擇合適的K值。

2. 距離度量方式

根據特征類型和數據分布選擇距離函數(見上表)。

3. 權重策略

  • uniform:每個鄰居權重相同;

  • distance:距離越近的鄰居權重越大。

4. 最近鄰搜索算法

  • brute:暴力搜索,適合小規模數據;

  • kd_tree / ball_tree:適合中等維度(<30)的數據;

  • 高維/大規模數據推薦使用近似搜索庫:如 Faiss、Annoy、ScaNN。


五、KNN的優缺點

? 優點

  • 簡單直觀,易于實現;

  • 無需訓練,可直接使用訓練數據;

  • 天然支持多分類與回歸;

  • 非線性決策邊界處理能力強。

? 缺點

  • 預測時計算量大,難以實時響應;

  • 內存消耗高,需保存全部訓練樣本;

  • 高維數據效果差(維度災難);

  • 對異常值、數據不平衡敏感。


六、KNN使用方法

發揮knn作用的代碼:

# 創建一個 KNN 分類器對象,設置鄰居數量 k=3
knn = KNeighborsClassifier(n_neighbors=3)# 在訓練集上訓練模型
knn.fit(X_train, y_train)# 在測試集上進行預測
y_pred = knn.predict(X_test)# 評估預測結果的準確率
accuracy = accuracy_score(y_test, y_pred)

核心參數:

  1. n_neighbors

    • 類型:整數,默認值為 5。
    • 作用:指定用于分類的近鄰數量(即 K 值)。
    • 示例n_neighbors=3表示選擇最近的 3 個樣本進行投票。
  2. weights

    • 類型:字符串或可調用函數,默認值為'uniform'
    • 作用:確定近鄰的權重計算方式。
      • 'uniform':所有近鄰權重相等。
      • 'distance':權重與距離成反比(距離越近,權重越大)。
      • 自定義函數:需接受距離數組并返回權重數組。
  3. algorithm

    • 類型:字符串,可選值為'auto''ball_tree''kd_tree''brute',默認'auto'
    • 作用:選擇用于計算最近鄰的算法。
      • 'auto':自動選擇最合適的算法。
      • 'brute':暴力搜索(適用于小規模數據)。
      • 'kd_tree':KD 樹(適用于低維數據)。
      • 'ball_tree':球樹(適用于高維數據)。
  4. leaf_size

    • 類型:整數,默認值為 30。
    • 作用:控制ball_treekd_tree的葉節點大小。
    • 影響:較小的值會增加樹的構建時間,但可能提高查詢效率。
  5. p

    • 類型:整數,默認值為 2。
    • 作用:明可夫斯基距離(Minkowski distance)的參數。
      • p=1:曼哈頓距離(L1 范數)。
      • p=2:歐氏距離(L2 范數)。
      • 其他值:推廣的 Minkowski 距離。

使用案例:

以鳶尾花數據為例(可直接導入數據)完整代碼:

# 導入所需的庫
from sklearn.datasets import load_iris                      # 用于加載鳶尾花數據集
from sklearn.model_selection import train_test_split        # 用于劃分訓練集和測試集
from sklearn.neighbors import KNeighborsClassifier          # K近鄰分類器
from sklearn.metrics import accuracy_score                  # 用于評估模型準確率# 1. 加載鳶尾花數據集(Iris 數據集是一個經典的機器學習分類數據集)
iris = load_iris()          # 加載數據集
X = iris.data               # 特征數據:4個特征(花萼長度、花萼寬度、花瓣長度、花瓣寬度)
y = iris.target             # 標簽數據:3個類別(0=setosa,1=versicolor,2=virginica)# 2. 將數據集劃分為訓練集和測試集
# test_size=0.2 表示20%作為測試集,80%作為訓練集
# random_state=42 保證每次運行劃分方式一致(可復現)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 3. 創建一個 KNN 分類器對象,設置鄰居數量 k=3
knn = KNeighborsClassifier(n_neighbors=3)# 4. 在訓練集上訓練模型
knn.fit(X_train, y_train)# 5. 在測試集上進行預測
y_pred = knn.predict(X_test)# 6. 評估預測結果的準確率
accuracy = accuracy_score(y_test, y_pred)
print("模型在測試集上的準確率:", accuracy)


七、實踐建議與優化技巧

問題類型優化建議
高維數據(維度災難)使用 PCA、t?SNE、UMAP 等進行降維處理
類別不平衡使用加權投票(distance)或 SMOTE 等過采樣方法
大規模訓練樣本使用 Faiss、Annoy 等近似鄰居搜索庫
實時響應需求構建索引結構(KD?Tree、Ball?Tree)或 LSH 近似搜索
噪音點/異常值結合局部加權(如 LOF)、數據清洗與異常檢測
特征不同類型混合對類別型特征采用合適距離度量(如漢明距離 + 歐氏距離組合)


八、應用場景與適用領域

KNN 雖然簡單,但在以下領域仍有廣泛應用:

  • 推薦系統(基于用戶/物品最近鄰推薦)

  • 圖像檢索(基于特征向量的最近鄰搜索)

  • 異常檢測(判斷樣本是否偏離常見鄰居)

  • 文本分類(TF?IDF 向量 + 余弦相似度)


九、總結與拓展

  • 優點:無訓練過程、易于理解、適用性廣;

  • 挑戰:對計算資源依賴高、受高維影響嚴重;

  • 優化路徑:標準化、降維、加速鄰居搜索、參數調優、類別平衡處理。

KNN憑借其“無需訓練,拿來即用”的特點,是機器學習中最容易理解和實現的算法之一。雖然它在高維、高頻場景中存在計算瓶頸,但通過特征工程、參數調優和搜索優化,KNN依然能夠在推薦系統、圖像檢索、異常檢測、文本分類等任務中大放異彩

💡 建議初學者掌握KNN作為理解其他復雜算法(如SVM、決策樹、神經網絡)的基石。

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

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

相關文章

Qt 多線程數據庫操作優化

在多線程應用中&#xff0c;數據庫操作往往是性能瓶頸與穩定性風險的高發區。當多個線程同時讀寫數據庫時&#xff0c;若處理不當&#xff0c;輕則出現查詢卡頓、事務沖突&#xff0c;重則導致數據錯亂、連接泄漏甚至程序崩潰。Qt作為跨平臺框架&#xff0c;提供了QSql系列類支…

Qt 狀態機框架:復雜交互邏輯的處理

Qt狀態機框架&#xff08;Qt State Machine Framework&#xff09;是一個強大的工具&#xff0c;用于簡化復雜的交互邏輯和狀態管理。它基于UML狀態圖概念&#xff0c;提供了聲明式的方式來定義對象行為&#xff0c;特別適合處理具有多種狀態和轉換的場景&#xff08;如GUI交互…

【docker】DM8達夢數據庫的docker-compose以及一些啟動踩坑

摘要&#xff1a;本文介紹了通過docker-compose配置啟動達夢數據庫(DM8)的方法。配置包括容器鏡像、端口映射、數據卷掛載以及關鍵環境變量設置&#xff08;如字符集、大小寫敏感等&#xff09;。也說明了啟動過程可能遇到的一些問題。通過docker-compose啟動達夢數據庫可以按照…

服務器中的防火墻設置需要打開嗎

服務器中的防火墻屬于是一種保護計算機網絡不會受到未經授權的網絡設備所訪問的技術手段&#xff0c;防火墻還有著將內部網絡和外部網絡進行隔離的功能&#xff0c;在網絡之間創建安全屏障&#xff0c;以此來保護網絡中數據的安全。防火墻是一種網絡安全系統&#xff0c;可以幫…

Java項目:基于SSM框架實現的社區團購管理系統【ssm+B/S架構+源碼+數據庫+畢業論文+答辯PPT+遠程部署】

摘 要 使用舊方法對社區團購信息進行系統化管理已經不再讓人們信賴了&#xff0c;把現在的網絡信息技術運用在社區團購信息的管理上面可以解決許多信息管理上面的難題&#xff0c;比如處理數據時間很長&#xff0c;數據存在錯誤不能及時糾正等問題。 這次開發的社區團購系統有…

介紹一下static關鍵字

在Java中&#xff0c;被static修飾的成員稱為靜態成員&#xff0c;static關鍵字可以用來修飾方法或者成員變量&#xff0c;且被static修飾的方法或者成員變量屬于類方法或者類屬性&#xff0c;也就是說被static修飾的方法或者成員變量不是單獨存儲在某一個對象的空間&#xff0…

【Java學習|黑馬筆記|Day23】網絡編程、反射、動態代理

【DAY23】 文章目錄【DAY23】一.網絡編程1&#xff09;三要素1.1&#xff09;IPInetAddress類的使用1.2&#xff09;端口號1.3&#xff09;協議2.1&#xff09;UDP協議發送數據2.2&#xff09;UDP協議接收數據2.3&#xff09;UDP的三種通信方式3.1&#xff09;TCP協議的發送和接…

【Zephyr】Window下的Zephyr編譯和使用

工具下載 參考文檔&#xff08;Getting Started Guide — Zephyr Project Documentation&#xff09;中介紹&#xff0c;可以直接通過winget下載&#xff1a; winget download Kitware.CMake Ninja-build.Ninja oss-winget.gperf python Git.Git oss-winget.dtc wget 7zip.7z…

圖論(BFS)構造鄰接表(運用隊列實現搜索)

碼蹄集OJ-夏日漫步 #include<bits/stdc.h> using namespace std; int n; int a[200010],dis[200010],qaq[1000010]; vector<int>son[200010]; int que[200010]; int main( ) {memset(qaq,-1,sizeof(qaq));memset(dis,-1,sizeof(dis));cin>>n;for(int i1;i…

vue怎么實現導入excel表功能

<el-uploadref"upload":action"aaa":on-change"importProject"name"excelFile"multiple:auto-upload"false":show-file-list"false"><el-button type"warning">導入</el-button><…

Linux DNS解析3 -- DNS解析代理配置使用

當網關設備配置了 /etc/hosts 文件時&#xff0c;確實可以為終端設備提供自定義DNS解析功能&#xff0c;但具體效果取決于網關的DNS代理服務配置。下面詳細解釋其工作原理和限制&#xff1a; 一、/etc/hosts 文件的作用 /etc/hosts 是本地靜態域名解析文件&#xff0c;格式為&a…

歷史版本的vscode下載地址

我有點厭惡vscode越來越臃腫的體積&#xff0c;也不需要層出不窮的新功能&#xff0c;于是網上找尋歷史版本。 首先是這個頁面&#xff1a;https://code.visualstudio.com/updates &#xff0c;但最多只顯示兩年&#xff0c;更早的就要手工修改地址欄&#xff0c;我試了最早的…

如何規范化項目執行

要實現項目執行的規范化&#xff0c;應做到以下幾點&#xff1a;制定詳細的項目執行計劃、明確項目團隊角色職責、建立高效溝通與協調機制、實施全面的質量與風險管理、采用合適的項目管理工具。其中&#xff0c;尤其重要的是明確項目團隊角色職責&#xff0c;通過構建清晰的責…

【Rust異步】async和await異步編程實戰:高并發任務處理全解析

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

在Linux上使用DuckCP實現從csv文件匯總數據到SQLite數據庫的表

從pypi網站Duckcp頁面下載duckcp-0.1.1-py3-none-any.whl 一開始用的Python 3.11.2環境。 繼續沿用上文打補丁的方法&#xff0c;得到一個支持python3.11.1的安裝包。 因為缺少zip壓縮工具&#xff0c;使用python程序來完成對修改后文件的重新壓縮。 import os import zipfile…

基于深度學習的圖像分類:使用EfficientNet實現高效分類

前言 圖像分類是計算機視覺領域中的一個基礎任務&#xff0c;其目標是將輸入的圖像分配到預定義的類別中。近年來&#xff0c;深度學習技術&#xff0c;尤其是卷積神經網絡&#xff08;CNN&#xff09;&#xff0c;在圖像分類任務中取得了顯著的進展。EfficientNet是一種新型的…

Java基礎-綜合案例

1、設計一個可以執行基本數學運算&#xff08;加減乘除&#xff09;的計算器程序功能描述&#xff1a;用戶輸入兩個數字、一個運算符&#xff08;、-、*、/&#xff09;。根據所選運算符執行相應的數學運算&#xff0c;顯示運算結果。import java.util.Scanner;public class Te…

四、計算機組成原理——第3章:存儲系統

目錄 3.1存儲器概述 3.1.1存儲器的分類 1.按在計算機中的作用(層次)分類 2.按存儲介質分類 3.按存取方式分類 4.按信息的可保存性分類 3.1.2存儲器的性能指標 3.2主存儲器 3.2.1SRAM芯片和DRAM芯片 1.SRAM的工作原理 2.DRAM的工作原理 3.SRAM和DRAM的比較 4.存儲器芯片的內部結…

3D Semantic Occupancy Prediction

3D 語義占用預測&#xff08;3D Semantic Occupancy Prediction&#xff09;旨在將真實世界環境劃分為規則的三維體素&#xff08;voxel&#xff09;網格&#xff0c;并對每個體素同時預測&#xff1a; 占用狀態&#xff08;Occupancy&#xff09;&#xff1a;該體素是否被物體…

在Word和WPS文字中添加的拼音放到文字右邊

在Word和WPS文字中&#xff0c;可以方便地為中文漢字添加拼音。默認的是拼音在漢字的上方&#xff0c;而且不方便直接編輯。可以簡單操作后把拼音放在漢字的右邊&#xff0c;并且可以方便地編輯。一、Word&#xff1a;先為漢字添加拼音&#xff0c;然后選擇性粘貼為純文本即可1…