KNN算法,故名思議,K個最鄰近值的分類算法。監督學習中的一種,典型的懶人算法,經過計算全部的預測樣本到學習樣本的距離,選取其中K個最小值加入樣本組中,樣本組中的樣本隸屬於那個分類的個數最多,那麼咱們就預測咱們的預測樣本是屬於這個類型的。算法
學習來源某個pdf(別人的學習筆記):數組
第四章 KNN(k最鄰近分類算法) 最鄰近分類算法) 最鄰近分類算法) 最鄰近分類算法) 最鄰近分類算法) 最鄰近分類算法) 最鄰近分類算法) 最鄰近分類算法) 1.算法 思路 經過計算每一個訓練樣例到待分類品的 距離,取和最近K個訓練 樣例, K個 樣品中哪一個類別 的訓練例佔多數,則待分就屬於核心思想: 若是一個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別,並具備這個類別上樣本的特性。該方法在肯定分類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。 kNN方法在類別決策時,只與極少許的相鄰樣本有關。因爲kNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來肯定所屬類別的,所以對於類域的交叉或重疊較多的待分樣本集來講,kNN方法較其餘方法更爲適合。 2.算法描述 1. 算距離 :給定測試對象,計它與訓練集中的每一個依公式計算 Item 與 D一、D2 … …、Dj 之類似度。獲得Sim(Item, D1)、Sim(Item, D2)… …、Sim(Item, Dj)。 2. 將Sim(Item, D1)、Sim(Item, D2)… …、Sim(Item, Dj)排序,如果超過類似度閾值t則放入鄰居案例集合NN。 找鄰居:圈定距離最近的k個訓練對象,做爲測試對象的近鄰 3. 自鄰居案例集合NN中取出前k名,依多數決,獲得Item可能類別。 作分類:根據這k個近鄰歸屬的主要類別,來對測試對象分類 3.算法步驟 • step.1---初始化距離爲最大值 初始化距離爲最大值 • step.2---計算未知樣本和每一個訓練的距離 計算未知樣本和每一個訓練的距離 dist • step.3---獲得目前 獲得目前 K個最臨近樣本中的大距離 maxdist • step.4---若是 dist小於 maxdist,則將該訓練樣本做爲 K-最近鄰樣本 • step.5---重複步驟 重複步驟 二、三、4,直到未知樣本和全部訓練的距離都算完 • step.6---統計 K-最近鄰樣本中每一個類標號出現的次數 • step.7---選擇出現頻率最大的類標號 做爲未知樣本選擇出現頻率最大的類標號 做爲未知樣本該算法涉及 3個主要因素: 訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量訓練集、 距離或類似的衡量k的大小。 的大小。 的大小。 4. k鄰近模型三個基本要素 鄰近模型三個基本要素 鄰近模型三個基本要素 鄰近模型三個基本要素 鄰近模型三個基本要素 鄰近模型三個基本要素 鄰近模型三個基本要素 鄰近模型三個基本要素 三個基本要素爲 距離度量、 距離度量、 距離度量、 距離度量、 k值的選擇和分類決策規則 值的選擇和分類決策規則 值的選擇和分類決策規則 值的選擇和分類決策規則 值的選擇和分類決策規則 值的選擇和分類決策規則 值的選擇和分類決策規則 值的選擇和分類決策規則 值的選擇和分類決策規則 距離度量: 設特徵空間 χ是 n維實數向量空間 𝑅𝑛,𝑥𝑖,𝑥𝑗∈𝜒,𝑥𝑖=(𝑥𝑖(1),𝑥𝑖(2),…,𝑥𝑖(𝑛))𝑇, 𝑥𝑗=(𝑥𝑗(1),𝑥𝑗(2),…,𝑥𝑗(𝑛))𝑇 𝒙𝒊,𝒙𝒋的𝐿𝑝距離定義爲: 𝐿𝑝(𝑥𝑖,𝑥𝑗)=(Σ|𝑥𝑖(𝑙)−𝑥𝑗(𝑙)|𝑝𝑛𝑙=1)1/𝑝 p≥1 p=2時爲歐式距離: 𝐿2(𝑥𝑖,𝑥𝑗)=(Σ|𝑥𝑖(𝑙)−𝑥𝑗(𝑙)|2𝑛𝑙=1)1/2 p=1時爲曼哈頓 距離: 𝐿1(𝑥𝑖,𝑥𝑗)=Σ|𝑥𝑖(𝑙)−𝑥𝑗(𝑙)|𝑛𝑙=1 p=∞時,它是各個座標距離的最大值 𝐿∞(𝑥𝑖,𝑥𝑗)=max𝑙|𝑥𝑖(𝑙)−𝑥𝑗(𝑙)| 5.算法優缺點 算法優缺點 算法優缺點 算法優缺點 1) 優勢 簡單,易於理解實現無需估計參數訓練; 適合樣本容量比較大的分類問題 特別適合於多分類問題 (multi-modal,對象具備多個類別標籤 ),例如根據基因特徵來判斷其功能 分類, kNN比 SVM的表現要好 2) 缺點 懶惰算法,對測試樣本分類時的計量大內存開銷評慢; 可解釋性較差,沒法給出決策樹那樣的規則 對於樣本量較小的分 類問題,會產生誤6.常見問題 1)K值設定爲多大 k過小,分類結果易受噪聲點影響; k太大,近鄰中又可能包含多的其它類別點。(對距離加 太大,近鄰中又可能包含多的其它類別點。(對距離加 權,能夠下降 k值設定的影響) k值一般是採用 交叉檢驗 交叉檢驗 交叉檢驗 來肯定(以 k=1爲基準) 經驗規則: k通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 通常低於訓練樣本數的平方根 2)類別如何斷定最合適 投票法沒有考慮近鄰的距離遠,更也許應該決定最終分類因此加權更恰當一些。 3)如何選定合適的距離衡量 高維度對距離衡量的影響:衆所周知當變數越多,歐式區分能力就差。 變量值域對距離的影響:越大常會在計算中佔據主導做用,所以應先進行標準化。 4)訓練樣本是否要一視同仁 在訓練集中,有些樣本多是更值得依賴的。 能夠給不一樣的樣本施加權重,強依賴下降信影響。 5)性能問題 kNN是一種懶惰算法,平時很差學習考試(對測樣 是一種懶惰算法,平時很差學習考試(對測樣 本分類)時才臨陣磨槍(去找 k個近 鄰)。 鄰)。 懶惰的後果:構造模型很簡單,但在對測試樣本分類地系統開銷大由於要掃描所有訓練並計算距離。 已經有一些方法提升計算的效率,例如壓縮訓練樣本量等。 6)可否大幅減小訓練樣本量,同時又保持分類精度? 濃縮技術 (condensing) 編輯技術 (editing) 6.KNN算法 Python實現例之電影分類 實現例之電影分類 實現例之電影分類 實現例之電影分類 實現例之電影分類 實現例之電影分類 實現例之電影分類 實現例之電影分類 電影名稱 打鬥次數 接吻次數 電影類型 California Man 3 104 Romance He’s Not Really into Dudes 2 100 Romance Beautiful Woman 1 81 Romance Kevin Longblade 101 10 Action Robo Slayer 3000 99 5 Action Amped II 98 2 Action 未知 18 90 Unknown 任務描述:經過打鬥次數和接吻來界定電影類型 調用 Python的 sklearn模塊求解 1. import numpy as np 2. from sklearn import neighbors 3. knn = neighbors.KNeighborsClassifier() #取得knn分類器 4. data = np.array([[3,104],[2,100],[1,81],[101,10],[99,5],[98,2]]) # <span style="font-family:Arial, Helvetica, sans-serif;">data對應着打鬥次數和接吻次數</span> 5. labels = np.array([1,1,1,2,2,2]) #<span style="font-family:Arial, Helvetica, sans-serif;">labels則是對應Romance和Action</span> 6. knn.fit(data,labels) #導入數據進行訓練''' 7. #Out:KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', 8. metric_params=None, n_jobs=1, n_neighbors=5, p=2, 9. weights='uniform') 10. knn.predict([18,90]) 說明: 首先,用 labels數組中的 數組中的 1和 2表明 Romance和 Aciton,由於 sklearn不接受字符數組做爲標誌,只 不接受字符數組做爲標誌,只 能用 1,2這樣的 int型數據來表示,後面處理能夠將 型數據來表示,後面處理能夠將 1和 2映射到 Romance和 Action上來。 fit則是 用 data和 labels進行訓練, 進行訓練, data對應的是打鬥次數和接吻構成向量,稱之爲特徵。 labels則是這個數據所表明的電影屬類型。調用 predict 進行預測,將未知 電影的特徵向量代入,則能 分析出該未知電影所屬的類型。此處計算結果爲 1,也就是該未知電影屬於 Romance,
容我水一發根據球星的得分數據(瞎編的,懶得去爬,後面能夠寫個系列啊,挖個坑,後面填),得出球星所打的位置是中鋒仍是後衛(沒錯,我就是在說rondo):框架
不廢話,根據前面四我的的數據,預測下我可能是否真是大中鋒:性能
遇到問題:ValueError: Expected n_neighbors <= n_samples, but n_samples = 4, n_neighbors = 5,訓練的樣本數小於維度,那我再加幾個樣本。學習
#-*- coding:utf-8 -*- #導入sklearn,裏面有knn框架,就不用本身去算了,雖然我曾經寫過一個相似的推薦算法。 from sklearn import neighbors import numpy as np #創建knn模型,knn分類器 knn=neighbors.KNeighborsClassifier() #導入訓練樣本 data=np.array([[25,10,2,0,5],[35,5,10,3,1],[32,15,2,1,5],[21,1,15,1,0],[20,15,1,2,8],[30,10,10,1,8]]) #導入預測值 locations=np.array(['C','PG','C','PG','C','PG']) #模型訓練 knn.fit(data,locations) #進行預測 print 'Rondo is %s'%knn.predict([15,15,10,8,0])[0] #運行結果 #C:\Python27\lib\site-packages\sklearn\utils\validation.py:395: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and will raise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample.DeprecationWarning)
是否是很水,是的我多就是大中鋒,不服來戰。測試