Scikit-learn的分类器算法:k-近邻及案例
k-近鄰算法采用測量不同特征值之間的距離來進行分類
優(yōu)點:精度高、對異常值不敏感、無數(shù)據(jù)輸入假定
缺點:計算復(fù)雜度高、空間復(fù)雜度高
使用數(shù)據(jù)范圍:數(shù)值型和標(biāo)稱型
一個例子弄懂k-近鄰
電影可以按照題材分類,每個題材又是如何定義的呢?那么假如兩種類型的電影,動作片和愛情片。動作片有哪些公共的特征?那么愛情片又存在哪些明顯的差別呢?我們發(fā)現(xiàn)動作片中打斗鏡頭的次數(shù)較多,而愛情片中接吻鏡頭相對更多。當(dāng)然動作片中也有一些接吻鏡頭,愛情片中也會有一些打斗鏡頭。所以不能單純通過是否存在打斗鏡頭或者接吻鏡頭來判斷影片的類別。那么現(xiàn)在我們有6部影片已經(jīng)明確了類別,也有打斗鏡頭和接吻鏡頭的次數(shù),還有一部電影類型未知。
| California Man | 3 | 104 | 愛情片 |
| He's not Really into dues | 2 | 100 | 愛情片 |
| Beautiful Woman | 1 | 81 | 愛情片 |
| Kevin Longblade | 101 | 10 | 動作片 |
| Robo Slayer 3000 | 99 | 5 | 動作片 |
| Amped II | 98 | 2 | 動作片 |
| ? | 18 | 90 | 未知 |
那么我們使用K-近鄰算法來分類愛情片和動作片:存在一個樣本數(shù)據(jù)集合,也叫訓(xùn)練樣本集,樣本個數(shù)M個,知道每一個數(shù)據(jù)特征與類別對應(yīng)關(guān)系,然后存在未知類型數(shù)據(jù)集合1個,那么我們要選擇一個測試樣本數(shù)據(jù)中與訓(xùn)練樣本中M個的距離,排序過后選出最近的K個,這個取值一般不大于20個。選擇K個最相近數(shù)據(jù)中次數(shù)最多的分類。那么我們根據(jù)這個原則去判斷未知電影的分類
| California Man | 20.5 |
| He's not Really into dues | 18.7 |
| Beautiful Woman | 19.2 |
| Kevin Longblade | 115.3 |
| Robo Slayer 3000 | 117.4 |
| Amped II | 118.9 |
我們假設(shè)K為3,那么排名前三個電影的類型都是愛情片,所以我們判定這個未知電影也是一個愛情片。那么計算距離是怎樣計算的呢?
歐氏距離那么對于兩個向量點$$a{1}$$和$$a{2}$$之間的距離,可以通過該公式表示:
$$\sqrt{\left({x{1}-x{2}}\right)^{2}+\left({y{1}-y{2}}\right)^{2}}$$
如果說輸入變量有四個特征,例如(1,3,5,2)和(7,6,9,4)之間的距離計算為:
$$\sqrt{\left({1-7}\right)^{2}+\left({3-6}\right)^{2}+\left({5-9}\right)^{2}+\left({2-4}\right)^{2}}$$
sklearn.neighbors
sklearn.neighbors提供監(jiān)督的基于鄰居的學(xué)習(xí)方法的功能,sklearn.neighbors.KNeighborsClassifier是一個最近鄰居分類器。那么KNeighborsClassifier是一個類,我們看一下實例化時候的參數(shù)
class sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=1, **kwargs)**""":param n_neighbors:int,可選(默認= 5),k_neighbors查詢默認使用的鄰居數(shù):param algorithm:{'auto','ball_tree','kd_tree','brute'},可選用于計算最近鄰居的算法:'ball_tree'將會使用 BallTree,'kd_tree'將使用 KDTree,“野獸”將使用強力搜索。'auto'將嘗試根據(jù)傳遞給fit方法的值來決定最合適的算法。:param n_jobs:int,可選(默認= 1),用于鄰居搜索的并行作業(yè)數(shù)。如果-1,則將作業(yè)數(shù)設(shè)置為CPU內(nèi)核數(shù)。不影響fit方法。""" import numpy as np from sklearn.neighbors import KNeighborsClassifierneigh = KNeighborsClassifier(n_neighbors=3)Method
fit(X, y)
使用X作為訓(xùn)練數(shù)據(jù)擬合模型,y作為X的類別值。X,y為數(shù)組或者矩陣
X = np.array([[1,1],[1,1.1],[0,0],[0,0.1]]) y = np.array([1,1,0,0]) neigh.fit(X,y)kneighbors(X=None, n_neighbors=None, return_distance=True)
找到指定點集X的n_neighbors個鄰居,return_distance為False的話,不返回距離
neigh.kneighbors(np.array([[1.1,1.1]]),return_distance= False)neigh.kneighbors(np.array([[1.1,1.1]]),return_distance= False,an_neighbors=2)predict(X)
預(yù)測提供的數(shù)據(jù)的類標(biāo)簽
neigh.predict(np.array([[0.1,0.1],[1.1,1.1]]))predict_proba(X)
返回測試數(shù)據(jù)X屬于某一類別的概率估計
neigh.predict_proba(np.array([[1.1,1.1]]))本案例使用最著名的”鳶尾“數(shù)據(jù)集
該數(shù)據(jù)集曾經(jīng)被Fisher用在經(jīng)典論文中,目前作為教科書般的數(shù)據(jù)樣本預(yù)存在Scikit-learn的工具包中。
讀入Iris數(shù)據(jù)集細節(jié)資料
from sklearn.datasets import load_iris # 使用加載器讀取數(shù)據(jù)并且存入變量iris iris = load_iris()# 查驗數(shù)據(jù)規(guī)模 iris.data.shape# 查看數(shù)據(jù)說明(這是一個好習(xí)慣) print iris.DESCR通過上述代碼對數(shù)據(jù)的查驗以及數(shù)據(jù)本身的描述,我們了解到Iris數(shù)據(jù)集共有150朵鳶尾數(shù)據(jù)樣本,并且均勻分布在3個不同的亞種;每個數(shù)據(jù)樣本有總共4個不同的關(guān)于花瓣、花萼的形狀特征所描述。由于沒有制定的測試集合,因此按照慣例,我們需要對數(shù)據(jù)進行隨即分割,25%的樣本用于測試,其余75%的樣本用于模型的訓(xùn)練。
由于不清楚數(shù)據(jù)集的排列是否隨機,可能會有按照類別去進行依次排列,這樣訓(xùn)練樣本的不均衡的,所以我們需要分割數(shù)據(jù),已經(jīng)默認有隨機采樣的功能。
對Iris數(shù)據(jù)集進行分割
from sklearn.cross_validation import train_test_split X_train,X_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.25,random_state=42)對特征數(shù)據(jù)進行標(biāo)準化
from sklearn.preprocessing import StandardScalerss = StandardScaler() X_train = ss.fit_transform(X_train) X_test = ss.fit_transform(X_test)K近鄰算法是非常直觀的機器學(xué)習(xí)模型,我們可以發(fā)現(xiàn)K近鄰算法沒有參數(shù)訓(xùn)練過程,也就是說,我們沒有通過任何學(xué)習(xí)算法分析訓(xùn)練數(shù)據(jù),而只是根據(jù)測試樣本訓(xùn)練數(shù)據(jù)的分布直接作出分類決策。因此,K近鄰屬于無參數(shù)模型中非常簡單一種。
from sklearn.datasets import load_iris from sklearn.cross_validation import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import classification_report from sklearn.model_selection import GridSearchCVdef knniris():"""鳶尾花分類:return: None"""# 數(shù)據(jù)集獲取和分割lr = load_iris()x_train, x_test, y_train, y_test = train_test_split(lr.data, lr.target, test_size=0.25)# 進行標(biāo)準化std = StandardScaler()x_train = std.fit_transform(x_train)x_test = std.transform(x_test)# estimator流程knn = KNeighborsClassifier()# # 得出模型# knn.fit(x_train,y_train)## # 進行預(yù)測或者得出精度# y_predict = knn.predict(x_test)## # score = knn.score(x_test,y_test)# 通過網(wǎng)格搜索,n_neighbors為參數(shù)列表param = {"n_neighbors": [3, 5, 7]}gs = GridSearchCV(knn, param_grid=param, cv=10)# 建立模型gs.fit(x_train,y_train)# print(gs)# 預(yù)測數(shù)據(jù)print(gs.score(x_test,y_test))# 分類模型的精確率和召回率# print("每個類別的精確率與召回率:",classification_report(y_test, y_predict,target_names=lr.target_names))return Noneif __name__ == "__main__":knniris()總結(jié)
以上是生活随笔為你收集整理的Scikit-learn的分类器算法:k-近邻及案例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sklearn分类器:朴素贝叶斯
- 下一篇: JavaScript试题练习题