Python機器學習之K最近鄰算法

一、K最近鄰算法的原理

原理部分直接看我另一篇《KNN是什么東東?》,本文主要針對如何應用。
?K這個字母的含義就是最近鄰的個數(shù)。在scikit-learn中,K最近鄰算法的K值是通過 n_neighbors 參數(shù)來調節(jié)的,默認值是 5。
?K最近鄰算法也可以用于回歸。當使用K最近鄰回歸計算某個數(shù)據(jù)點的預測值時,模型會選擇離該數(shù)據(jù)點最近的若干個訓練數(shù)據(jù)集中的點,并且將他們的 y 值取平均值,并把該平均值作為新數(shù)據(jù)點的預測值。

二、K最近鄰算法在二分類任務中的應用

?首先,使用 scikit-learn 的 make_blobs 函數(shù)來生成一個樣本數(shù)量為 200,分類數(shù)為 2 的數(shù)據(jù)集,并賦值給 X 和 y,并使用 matplotlib 繪制出數(shù)據(jù)集圖形。

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier #導入 KNN 分類器
import matplotlib.pyplot as plt # 導入畫圖工具
from sklearn.model_selection import train_test_split # 導入數(shù)據(jù)集拆分工具

#生成樣本數(shù)為 200,分類為 2 的數(shù)據(jù)集;n_features默認為2,即2個特征
data = make_blobs(n_samples=200, centers=2, random_state=8)
data = make_blobs(n_samples=200, centers=2, random_state=8)
X, y= data

#將生成的數(shù)據(jù)可視化
plt.scatter(X[:,0],X[:,1], c=y,cmap=plt.cm.spring, edgecolors='k')
plt.show()

執(zhí)行結果為:


使用 make_blobs 生成的數(shù)據(jù)集.png

注釋1:

sklearn.datasets.make_blobs

函數(shù)原型:sklearn.datasets.make_blobs(n_samples=100, n_features=2, centers=None, cluster_std=1.0, center_box=(-10.0, 10.0), shuffle=True, random_state=None)

參數(shù)解釋
?n_samples(int/array): 如果參數(shù)為int,代表總樣本數(shù);如果參數(shù)為array-like,數(shù)組中的每個數(shù)代表每一簇的樣本數(shù)。
?n_features(int): 樣本點的維度。
?centers(int): 樣本中心數(shù)。如果樣本數(shù)為int且centers=None,生成三個樣本中心;如果樣本數(shù)(n_samples)為數(shù)組,則centers 要么為None,要么為數(shù)組的長度。
?cluster_std(float/sequence of floats): 樣本中,簇的標準差。
?center_box(pair of floats (min, max)): 每個簇的上下限。
?shuffle(boolean): 是否將樣本打亂。
?random_state(int/RandomState instance /None): 指定隨機數(shù)種子,每個種子生成的序列相同,與minecraft地圖種子同理。

返回類型:X : 樣本數(shù)組 [n_samples, n_features]
      產生的樣本
     y : array of shape [n_samples]
      每個簇的標簽

注釋2:

matplotlib.pyplot.scatter

用來繪制散點圖
參考:《Python中scatter函數(shù)參數(shù)詳解》

?接下來,用 K最近鄰算法來擬合數(shù)據(jù)

import numpy as np
clf = KNeighborsClassifier() #KNN
clf.fit(X, y) #訓練

#畫圖
#分別確定兩個屬性值的最大和最小值,用于繪圖邊界
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

#返回坐標矩陣
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),
                     np.arange(y_min, y_max, .02))

#預測
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z= Z.reshape(xx.shape)
#分類圖繪制
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Pastel1)
#將生成的樣本數(shù)據(jù)可視化
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.spring, edgecolors='k')
#坐標軸范圍限定
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
#繪圖標題
plt.title("Claccifier:KNN")

plt.show()

執(zhí)行結果為:

預測結果為:
==========================
新數(shù)據(jù)的分類是: [1]
knn_two_classify.png

注釋1:

meshgrid()

meshgrid函數(shù)用兩個坐標軸上的點在平面上畫網格,即從坐標向量中返回坐標矩陣
可以參考以下兩篇文章:《3分鐘理解np.meshgrid()》《Numpy中Meshgrid函數(shù)介紹及2種應用場景》

注釋2:

numpy.ravel()

將多維數(shù)組將為一維數(shù)組
參考:《numpy 辨異 (五)—— numpy.ravel() vs numpy.flatten()》

注釋3:

pcolormesh()

繪制分類圖
函數(shù)原型: matplotlib.pyplot.pcolormesh(*args, alpha=None, norm=None, cmap=None, vmin=None, vmax=None, shading='flat', antialiased=False, data=None, **kwargs) 創(chuàng)建一個帶有不規(guī)則矩形網格的偽彩色圖

具體的參數(shù)解釋參見 :pcolormesh參數(shù)

具體使用方法參考:利用plt.pcolormesh繪制分類圖

?最后,附上二分類任務的完整代碼

import numpy as np
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier #導入 KNN 分類器
import matplotlib.pyplot as plt # 導入畫圖工具
from sklearn.model_selection import train_test_split # 導入數(shù)據(jù)集拆分工具

#生成樣本數(shù)為 200,分類為 2 的數(shù)據(jù)集,n_features默認為2,即2個特征
data = make_blobs(n_samples=200, centers=2, random_state=8)
X, y= data

clf = KNeighborsClassifier() #KNN
clf.fit(X, y) #訓練

#畫圖
#分別確定兩個屬性值的最大和最小值,用于繪圖邊界
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

#返回坐標矩陣
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),
                     np.arange(y_min, y_max, .02))

#預測
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z= Z.reshape(xx.shape)
#分類圖繪制
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Pastel1)
#將生成的樣本數(shù)據(jù)可視化
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.spring, edgecolors='k')
#坐標軸范圍限定
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
#繪圖標題
plt.title("Claccifier:KNN")

#對特征值為 6.75 和4.82 的新數(shù)據(jù)點分類進行預測
print('預測結果為:')
print('==========================')
print('新數(shù)據(jù)的分類是:', clf.predict([[6.75, 4.82]]))
#可視化的數(shù)據(jù)分類
plt.scatter(6.75, 4.82, marker='*', c='red',s=200)
plt.show()

三、K最近鄰算法在多元分類任務中的應用

?首先,使用 scikit-learn 的 make_blobs 函數(shù)來生成一個樣本數(shù)量為 500,分類數(shù)為 5 的數(shù)據(jù)集,并賦值給 X 和 y,與二分類構造數(shù)類似,不再贅述樣本繪圖部分

import numpy as np
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier #導入 KNN 分類器
import matplotlib.pyplot as plt # 導入畫圖工具

#生成樣本數(shù)為 500,分類為 5 的數(shù)據(jù)集,n_features默認為2,即2個特征
data = make_blobs(n_samples=500, centers=5, random_state=8)
X, y= data

clf = KNeighborsClassifier() #KNN
clf.fit(X, y) #訓練

#畫圖
#分別確定兩個屬性值的最大和最小值,用于繪圖邊界
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

#返回坐標矩陣
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),
                     np.arange(y_min, y_max, .02))

#預測
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z= Z.reshape(xx.shape)
#分類圖繪制
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Pastel1)
#將生成的樣本數(shù)據(jù)可視化
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.spring, edgecolors='k')
#坐標軸范圍限定
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
#繪圖標題
plt.title("Claccifier:KNN")

#模型評分
print('==========================')
print('模型評分:{:.2f}'.format(clf.score(X, y)))
plt.show()

執(zhí)行結果為:

==========================
模型評分:0.96
knn_multi_classify.png

四、K最近鄰算法用于回歸分析

?首先,使用 scikit-learn 的 make_regression 函數(shù)來生成一個特征數(shù)量為 1,標準差為 50 的noise 的數(shù)據(jù)集,并賦值給 X 和 y,并使用 matplotlib 繪制出數(shù)據(jù)集圖形。

from sklearn.datasets import make_regression #回歸分析數(shù)據(jù)生成器
import matplotlib.pyplot as plt # 導入畫圖工具
X, y = make_regression(n_features=1, n_informative=1, noise=50, random_state=8)
#用散點圖將數(shù)據(jù)可視化
plt.scatter(X, y, c='orange',edgecolors='k')
plt.show()

執(zhí)行結果如下,橫軸代表樣本特征的數(shù)值,縱軸代表樣本的測定值:


knn_regression_data.png

注釋:

sklearn.datasets.make_regression

函數(shù)原型:sklearn.datasets.make_regression(_samples=100, n_features=100, n_informative=10,
n_targets=1, bias=0.0, effective_rank=None,
tail_strength=0.5, noise=0.0, shuffle=True, coef=False,
random_state=None)

關鍵參數(shù)解釋
?n_samples(生成樣本數(shù))
?n_features(樣本特征數(shù))
?noise(樣本隨機噪音)
?coef(是否返回回歸系數(shù))

返回類型
?X為樣本特征
?y為樣本輸出
?coef為回歸系數(shù)

?然后,使用K最近鄰算法來進行回歸分析,并輸出模型評分

import numpy as np
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier #導入 KNN 分類器
import matplotlib.pyplot as plt # 導入畫圖工具

#生成樣本數(shù)為 500,分類為 5 的數(shù)據(jù)集,n_features默認為2,即2個特征
data = make_blobs(n_samples=500, centers=5, random_state=8)
X, y= data

clf = KNeighborsClassifier() #KNN
clf.fit(X, y) #訓練

#畫圖
#分別確定兩個屬性值的最大和最小值,用于繪圖邊界
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

#返回坐標矩陣
xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),
                     np.arange(y_min, y_max, .02))

#預測
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z= Z.reshape(xx.shape)
#分類圖繪制
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Pastel1)
#將生成的樣本數(shù)據(jù)可視化
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.spring, edgecolors='k')
#坐標軸范圍限定
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
#繪圖標題
plt.title("Claccifier:KNN")

#模型評分

print('==========================')
print('模型評分:{:.2f}'.format(clf.score(X, y)))
plt.show()

執(zhí)行結果如下圖所示,擬合效果不是很好


knn_regression_5neighbors.png
==========================
模型評分:0.77

n_neighbors 參數(shù)默認值是 5,調節(jié)該參數(shù),這是為2 ,再執(zhí)行

reg = KNeighborsRegressor(n_neighbors=2) 

執(zhí)行結果如下圖所示,擬合效果有改善,評分也有提高


knn_regression_2neighbors.png
==========================
模型評分:0.86

?最后,附上完整代碼

import numpy as np
from sklearn.datasets import make_regression #回歸分析數(shù)據(jù)生成器
from sklearn.neighbors import KNeighborsRegressor #用于回歸分析的KNN模型
import matplotlib.pyplot as plt # 導入畫圖工具
X, y = make_regression(n_features=1, n_informative=1, noise=50, random_state=8)

#n_neighbors 默認是5
#reg = KNeighborsRegressor()
#調節(jié)n_neighbors為 2
reg = KNeighborsRegressor(n_neighbors=2) #KNN
reg.fit(X, y) #擬合數(shù)據(jù)

#預測結果可視化
z = np.linspace(-3, 3, 200).reshape(-1, 1) #范圍由生成的回顧分析數(shù)據(jù)確定
#用散點圖將數(shù)據(jù)可視化
plt.scatter(X, y, c='orange',edgecolors='k')
plt.plot(z, reg.predict(z), c='k', linewidth=3)
#添加標題
plt.title('KNN Regression')

#模型評分

print('==========================')
print('模型評分:{:.2f}'.format(reg.score(X, y)))
plt.show()
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容