K最近鄰(k-Nearest Neighbor,KNN)分類算法的核心思想是如果一個(gè)樣本在特征空間中的k個(gè)最相似(即特征空間中最鄰近)的樣本中的大多數(shù)屬于某一個(gè)類別比勉,則該樣本也屬于這個(gè)類別躬充。KNN算法可用于多分類突硝,KNN算法不僅可以用于分類,還可以用于回歸苛骨。通過找出一個(gè)樣本的k個(gè)最近鄰居稼钩,將這些鄰居的屬性的平均值賦給該樣本顾稀,作為預(yù)測值达罗。
一坝撑、kNN概念描述
kNN算法又稱為k最近鄰(k-nearest neighbor classification)分類算法。所謂的k最近鄰粮揉,就是指最接近的k個(gè)鄰居(數(shù)據(jù))巡李,即每個(gè)樣本都可以由它的K個(gè)鄰居來表達(dá)。
kNN算法的核心思想是扶认,在一個(gè)含未知樣本的空間侨拦,可以根據(jù)離這個(gè)樣本最鄰近的k個(gè)樣本的數(shù)據(jù)類型來確定樣本的數(shù)據(jù)類型。
該算法涉及3個(gè)主要因素:訓(xùn)練集辐宾、距離與相似的衡量狱从、k的大信蚵;主要考慮因素:距離與相似度季研;
二敞葛、舉例說明
右圖中,綠色圓要被決定賦予哪個(gè)類与涡,是紅色三角形還是藍(lán)色四方形惹谐?
KNN的算法過程是是這樣的:
最小的圈K=3,第二個(gè)圈K=5
從上圖中我們可以看到驼卖,圖中的數(shù)據(jù)集是良好的數(shù)據(jù)氨肌,即都打好了label,一類是藍(lán)色的正方形酌畜,一類是紅色的三角形怎囚,那個(gè)綠色的圓形是我們待分類的數(shù)據(jù)。
如果K=3檩奠,那么離綠色點(diǎn)最近的有2個(gè)紅色三角形和1個(gè)藍(lán)色的正方形桩了,這3個(gè)點(diǎn)投票,于是綠色的這個(gè)待分類點(diǎn)屬于紅色的三角形埠戳。
如果K=5井誉,那么離綠色點(diǎn)最近的有2個(gè)紅色三角形和3個(gè)藍(lán)色的正方形,這5個(gè)點(diǎn)投票整胃,于是綠色的這個(gè)待分類點(diǎn)屬于藍(lán)色的正方形颗圣。(參考 酷殼的 K Nearest Neighbor 算法 )
我們可以看到,KNN本質(zhì)是基于一種數(shù)據(jù)統(tǒng)計(jì)的方法屁使!其實(shí)很多機(jī)器學(xué)習(xí)算法也是基于數(shù)據(jù)統(tǒng)計(jì)的在岂。
三、kNN算法的特點(diǎn)
KNN算法不僅可以用于分類蛮寂,還可以用于過渡蔽午,比如在兩個(gè)色度之間取過渡色。
KNN算法當(dāng)前主要使用加權(quán)投票法酬蹋,即根據(jù)距離的遠(yuǎn)近及老,對近鄰的投票進(jìn)行加權(quán),距離越近則權(quán)重越大(權(quán)重為距離平方的倒數(shù))范抓。
優(yōu)點(diǎn):易于實(shí)現(xiàn)骄恶,無需估計(jì)參數(shù),無需訓(xùn)練匕垫,支持增量學(xué)習(xí)僧鲁,能對超多邊形的復(fù)雜決策空間建模;
KNN 算法的主要缺點(diǎn)是, 當(dāng)訓(xùn)練樣本數(shù)量很大時(shí)將導(dǎo)致很高的計(jì)算開銷。KNN 算法是懶散的分類算法, 對于分類所需的計(jì)算都推遲到分類時(shí)才進(jìn)行, 在其分類器中存儲有大量的樣本向量, 在未知類別樣本需要分類時(shí), 再計(jì)算和所有存儲樣本的距離, 對于高維文本向量或樣本集規(guī)模較大的情況, 其時(shí)間和空間復(fù)雜度較高寞秃。
四斟叼、sk-learn中的KNN
sklearn.neighbors可以處理 Numpy 數(shù)組或 scipy.sparse矩陣作為其輸入。 對于密集矩陣春寿,大多數(shù)可能的距離度量都是支持的犁柜。對于稀疏矩陣,支持搜索任意的 Minkowski 度量堂淡。
盡管它簡單馋缅,但最近鄰算法已經(jīng)成功地適用于很多的分類和回歸問題,例如手寫數(shù)字或衛(wèi)星圖像的場景绢淀。 作為一個(gè) non-parametric(非參數(shù)化)方法萤悴,它經(jīng)常成功地應(yīng)用于決策邊界非常不規(guī)則的分類情景下。
1皆的、為了完成找到兩組數(shù)據(jù)集中最近鄰點(diǎn)的簡單任務(wù), 可以使用 sklearn.neighbors 中的無監(jiān)督算法:
from sklearn.neighbors import NearestNeighbors
import numpy as np
#生成數(shù)組
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
nbrs = NearestNeighbors(n_neighbors=2, algorithm='ball_tree').fit(X)
distances, indices = nbrs.kneighbors(X)
print(indices)
print(distances)
'''
輸出:
[[0 1]
[1 0]
[2 1]
[3 4]
[4 3]
[5 4]]
[[0. 1. ]
[0. 1. ]
[0. 1.41421356]
[0. 1. ]
[0. 1. ]
[0. 1.41421356]]
'''
2覆履、利用KNeighborsClassifier 分析鳶尾花的數(shù)據(jù)集
from sklearn import datasets
#導(dǎo)入內(nèi)置數(shù)據(jù)集模塊
from sklearn.neighbors import KNeighborsClassifier
#導(dǎo)入sklearn.neighbors模塊中KNN類
import numpy as np
iris=datasets.load_iris()
# print(iris)
#導(dǎo)入鳶尾花的數(shù)據(jù)集,iris是一個(gè)數(shù)據(jù)集费薄,內(nèi)部有樣本數(shù)據(jù)
iris_x=iris.data
iris_y=iris.target
indices = np.random.permutation(len(iris_x))
#permutation接收一個(gè)數(shù)作為參數(shù)(150),產(chǎn)生一個(gè)0-149一維數(shù)組硝全,只不過是隨機(jī)打亂的
iris_x_train = iris_x[indices[:-10]]
#隨機(jī)選取140個(gè)樣本作為訓(xùn)練數(shù)據(jù)集
iris_y_train = iris_y[indices[:-10]]
# 并且選取這140個(gè)樣本的標(biāo)簽作為訓(xùn)練數(shù)據(jù)集的標(biāo)簽
iris_x_test = iris_x[indices[-10:]]
# 剩下的10個(gè)樣本作為測試數(shù)據(jù)集
iris_y_test = iris_y[indices[-10:]]
# 并且把剩下10個(gè)樣本對應(yīng)標(biāo)簽作為測試數(shù)據(jù)及的標(biāo)簽
knn = KNeighborsClassifier()
# 定義一個(gè)knn分類器對象
knn.fit(iris_x_train, iris_y_train)
# 調(diào)用該對象的訓(xùn)練方法,主要接收兩個(gè)參數(shù):訓(xùn)練數(shù)據(jù)集及其樣本標(biāo)簽
iris_y_predict = knn.predict(iris_x_test)
# 調(diào)用該對象的測試方法楞抡,主要接收一個(gè)參數(shù):測試數(shù)據(jù)集
score = knn.score(iris_x_test, iris_y_test, sample_weight=None)
# 調(diào)用該對象的打分方法伟众,計(jì)算出準(zhǔn)確率
print('iris_y_predict = ')
print(iris_y_predict)
# 輸出測試的結(jié)果
print('iris_y_test = ')
print(iris_y_test)
# 輸出原始測試數(shù)據(jù)集的正確標(biāo)簽,以方便對比
print('Accuracy:', score)
# 輸出準(zhǔn)確率計(jì)算結(jié)果</span>
'''
iris_y_predict =
[2 0 2 2 2 0 0 1 2 0]
iris_y_test =
[2 0 2 2 2 0 0 1 1 0]
Accuracy: 0.9
'''
end...