import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
x = data.iloc[:,:-1]
y = data.iloc[:,-1]
Xtrain,Xtest,Ytrain,Ytest = train_test_split(x,y,test_size=0.2,random_state=420)
clf = KNeighborsClassifier(n_neighbors=3)
clf = clf.fit(Xtrain,Ytrain)
score = clf.score(Xtest,Ytest)
result = clf.predict()
import matplotlib.pyplot as plt
score = [ ]
krange = range(1,20)
for i in krange:
clf = KNeighborsClassifier(n_neighbors=i)
clf = clf.fit(Xtrain,Ytrain)
score.append(clf.score(Xtest,Ytest))
plt.plot(krange,score)
plt.show()
print(score.index(max(score))+1)
新たな問題がいくつかあり、データセットを分割する場合、ランダムに分割するため、最もスコアが高い k 値は異なるはずです。そこで、交差検証 (k 分割テスト) を導入します。
from sklearn.model_selection import cross_val_score as CVS
Xtrain,Xtest,Ytrain,Ytest = train_test_split(x,y,test_size=0.2,random_state=420)
clf = KNeighborsClassifier(n_neighbors=3)
cvs = CVS(clf,Xtrain,Ytrain,cv = 5)
print(cvs.mean())
print(cvs.var())
さて、この時点でまとめると、
score = [ ]
var = [ ]
krange = range(1,20)
for i in krange:
clf = KNeighborsClassifier(n_neighbors=i)
cvs = CVS(clf,Xtrain,Ytrain,cv = 5)
score.append(cvs.mean())
var.append(cvs.var())
plt.plot(krange,score,color='k')
plt.plot(krange,np.array(score)+np.array(var)*2,c='red',linestyle='--')
plt.plot(krange,np.array(score)-np.array(var)*2,c='red',linestyle='--')
そして、もう一つ問題があるのですが、knnの計算には距離が関係するので、この時に各指数の次元差が大きすぎると全くよろしくないので、【正規化】する必要があります。
(正規化、Min-Max スケーリングとも呼ばれます)
ここで注目すべき点があり、 【まずデータセットとテストセットを分割してから正規化する!】
from sklearn.preprocessing import MinMaxScaler as mms
Xtrain,Xtest,Ytrain,Ytest = train_test_split(x,y,test_size=0.2,random_state=420)
MMS_01=mms().fit(Xtrain)
MMS_02=mms().fit(Xtest)
X_train=MMS_01.transform(Xtrain)
X_test =MMS_02.transform(Xtest)
score = [ ]
var = [ ]
krange = range(1,20)
for i in krange:
clf = KNeighborsClassifier(n_neighbors=i)
cvs = CVS(clf,X_train,Y_train,cv = 5)
score.append(cvs.mean())
var.append(cvs.var())
plt.plot(krange,score,color='k')
plt.plot(krange,np.array(score)+np.array(var)*2,c='red',linestyle='--')
plt.plot(krange,np.array(score)-np.array(var)*2,c='red',linestyle='--')
print(score.index(max(score))+1)
ここで、さらに小さな問題が発生します。
knn方式は範囲内でどちらの陣営が多いかを見る1点1票の方式を採用しており、
しかし常識によれば、未知の点は彼に近い点により似ているはずです。
k が 8 の場合、点の 5 つの隣接点は彼から遠く離れており、3 つの隣接点は彼に非常に近いです。
現時点ではknnは彼を5人グループとして判断しますが、人生では間違いなく彼を3人グループとして判断します
この際、[距離ペナルティ]を追加する必要がありますが、実際には最適化効果を慎重に考慮する必要があります。
外れ値が多いデータセットに適しています
使用法: 重みを追加 = '距離'、これは距離ペナルティを追加することを意味します
score = [ ]
var = [ ]
krange = range(1,20)
for i in krange:
clf = KNeighborsClassifier(n_neighbors=i,weights='distance')
cvs = CVS(clf,X_train,Y_train,cv = 5)
score.append(cvs.mean())
var.append(cvs.var())