KNN算法介紹
KNN(K Near Neighbor):k個最近的鄰居,即每個樣本都可以用它最接近的k個鄰居來代表。KNN算法屬于監(jiān)督學習方式的分類算法,我的理解就是計算某給點到每個點的距離作為相似度的反饋。
簡單來講,KNN就是“近朱者赤,近墨者黑”的一種分類算法。
KNN是一種基于實例的學習,屬于懶惰學習,即沒有顯式學習過程。
要區(qū)分一下聚類(如Kmeans等),KNN是監(jiān)督學習分類,而Kmeans是無監(jiān)督學習的聚類,聚類將無標簽的數(shù)據(jù)分成不同的簇。
KNN算法三要素
距離度量
特征連續(xù):距離函數(shù)選用曼哈頓距離(L1距離)/歐氏距離(L2距離)
當p=1 的時候,它是曼哈頓距離
當p=2的時候,它是歐式距離
當p不選擇的時候,它是切比雪夫
特征離散:漢明距離
舉最簡單的例子來說明歐式/曼哈頓距離公式是什么樣的。
K取值
在scikit-learn重KNN算法的K值是通過n_neighbors參數(shù)來調(diào)節(jié)的,默認值是5。
參考李航博士一書統(tǒng)計學習方法中寫道的K值選擇:
K值小,相當于用較小的領域中的訓練實例進行預測,只要與輸入實例相近的實例才會對預測結(jié)果,模型變得復雜,只要改變一點點就可能導致分類結(jié)果出錯,泛化性不佳。(學習近似誤差小,但是估計誤差增大,過擬合)
K值大,相當于用較大的領域中的訓練實例進行預測,與輸入實例較遠的實例也會對預測結(jié)果產(chǎn)生影響,模型變得簡單,可能預測出錯。(學習近似誤差大,但是估計誤差小,欠擬合)
極端情況:K=0,沒有可以類比的鄰居;K=N,模型太簡單,輸出的分類就是所有類中數(shù)量最多的,距離都沒有產(chǎn)生作用。
什么是近似誤差和估計誤差:
近似誤差:訓練集上的誤差
估計誤差:測試集上的誤差
分類規(guī)則
knn使用的分類決策規(guī)則是多數(shù)表決,如果損失函數(shù)為0-1損失函數(shù),那么要使誤分類率最小即使經(jīng)驗風險最小,多數(shù)表決規(guī)則實際上就等同于經(jīng)驗風險最小化。
KNN實際應用
案例引入
我們先看一個案例,這樣可以更直觀的理解KNN算法。數(shù)據(jù)如下表,其中包括10個人的身高、體重和年齡數(shù)據(jù),然后預測第十一個人的體重。
為了更清晰地了解數(shù)據(jù)間的關(guān)系,我們用坐標軸將身高和年齡表示出來,其中橫坐標為年齡(age)、縱坐標為身高(Height)。
通過上圖可以看到,11點的值是需要求解的,那么怎么求呢?我們可以看到在圖中11點更接近于5點和1點,所以其體重應該更接近于5點和1點的值,也就是在72-77之間,這樣我們就可以大致得到11點的體重值。下面我們用算法來實現(xiàn)這一過程。
KNN算法工作
如上所述,KNN可以用于分類和回歸問題,通過樣本間的某些相似特征來進行預測未知元素的值,即“物以類聚”:相同或相似的事物之間具有一些相似的特征。
在分類問題中,我們可以直接將其最近的樣本值作為預測結(jié)果,那么在回歸問題中怎么計算最終的預測結(jié)果呢?就像上面的例子,11點取值介于72-77之間,最終結(jié)果應該取多少合適呢?一般來說,我們將其平均值作為最終的預測結(jié)果。
1、計算待測點到已知點的距離
2、選擇距離待測點最近的K個點,k值為人工設置的,至于k值如何設置合適在后邊討論。在這個例子中,我們假設k=3,即點1、5、6被選擇。
3、將點1、5、6的值取平均值作為最終的預測結(jié)果。即11點的Weight=(77+72+60)/3 = 69.66 kg
K值選擇
K值代表最近鄰的個數(shù),k值的選擇對預測結(jié)果有較大影響。
在上面的例子中,我們選擇k=3時
最終的預測結(jié)果為
ID11 = (77+72+60)/3
ID11 = 69.66 kg
當我們選擇k=5時
最終的預測結(jié)果為
ID 11 = (77+59+72+60+58)/5
ID 11 = 65.2 kg
我們可以看到k值不同結(jié)果也將不同,因此我們需要選擇一個合適的k值來獲得最佳的預測結(jié)果。我們的目標就是獲得預測值與真實值之間最小的誤差。
下面我們看一下k值與誤差的關(guān)系曲線
由曲線可得,如果K值太小,則會發(fā)生過擬合;如果k值太大,則會發(fā)生欠擬合。因此我們根據(jù)誤差曲線選擇最佳k值為9,你也可以使用其他方法尋找最佳k值。
python實現(xiàn)代碼
1、讀取數(shù)據(jù)
import pandas as pd
df = pd.read_csv('train.csv')
df.head()
2、處理缺失值
df.isnull().sum()
#missing values in Item_weight and Outlet_size needs to be imputed
mean = df['Item_Weight'].mean() #imputing item_weight with mean
df['Item_Weight'].fillna(mean, inplace =True)
mode = df['Outlet_Size'].mode() #imputing outlet size with mode
df['Outlet_Size'].fillna(mode[0], inplace =True)
3、處理分類變量并刪除ID列
df.drop(['Item_Identifier', 'Outlet_Identifier'], axis=1, inplace=True)
df = pd.get_dummies(df)
4、劃分訓練集與測試
df.drop(['Item_Identifier', 'Outlet_Identifier'], axis=1, inplace=True)from sklearn.model_selection import train_test_split
train , test = train_test_split(df, test_size = 0.3)
x_train = train.drop('Item_Outlet_Sales', axis=1)
y_train = train['Item_Outlet_Sales']
x_test = test.drop('Item_Outlet_Sales', axis = 1)
y_test = test['Item_Outlet_Sales']
df = pd.get_dummies(df)
5、特征標準化
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
x_train_scaled = scaler.fit_transform(x_train)
x_train = pd.DataFrame(x_train_scaled)
x_test_scaled = scaler.fit_transform(x_test)
x_test = pd.DataFrame(x_test_scaled)
6、查看誤差曲線
from sklearn import neighbors
from sklearn.metrics import mean_squared_error
from math import sqrt
import matplotlib.pyplot as plt
%matplotlib inline
rmse_val = [] #to store rmse values for different k
for K in range(20):
K = K+1
model = neighbors.KNeighborsRegressor(n_neighbors = K)
model.fit(x_train, y_train) #fit the model
pred=model.predict(x_test) #make prediction on test set
error = sqrt(mean_squared_error(y_test,pred)) #calculate rmse
rmse_val.append(error) #store rmse values
print('RMSE value for k= ' , K , 'is:', error)
curve = pd.DataFrame(rmse_val) #elbow curve
curve.plot()
輸出
由誤差曲線可得我們選擇k=7可以獲得最優(yōu)結(jié)果
預測結(jié)果
test = pd.read_csv('test.csv')
submission = pd.read_csv('SampleSubmission.csv')
submission['Item_Identifier'] = test['Item_Identifier']
submission['Outlet_Identifier'] = test['Outlet_Identifier']
#preprocessing test dataset
test.drop(['Item_Identifier', 'Outlet_Identifier'], axis=1, inplace=True)
test['Item_Weight'].fillna(mean, inplace =True)
test = pd.get_dummies(test)
test_scaled = scaler.fit_transform(test)
test = pd.DataFrame(test_scaled)
#predicting on the test set and creating submission file
predict = model.predict(test)
submission['Item_Outlet_Sales'] = predict
submission.to_csv('submit_file.csv',index=False)
KNN算法優(yōu)點,缺點,適用場景
優(yōu)點
流程簡單明了,易于實現(xiàn)
方便進行多分類任務,效果優(yōu)于SVM
適合對稀有事件進行分類
缺點
計算量大,T = O ( n ) T=O(n)T=O(n),需要計算到每個點的距離
樣本不平衡時(一些分類數(shù)量少,一些多),前K個樣本中大容量類別占據(jù)多數(shù),這種情況會影響到分類結(jié)果
K太小過擬合,K太大欠擬合,K較難決定得完美,通過交叉驗證確定K
適用場景文章來源:http://www.zghlxwxcb.cn/news/detail-453266.html
多分類問題
稀有事件分類問題
文本分類問題
模式識別
聚類分析
樣本數(shù)量較少的分類問題文章來源地址http://www.zghlxwxcb.cn/news/detail-453266.html
到了這里,關(guān)于【KNN算法詳解(用法,優(yōu)缺點,適用場景)及應用】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!