機械学習における次元の呪いは、多くの場合、少数のデータポイント間の空きスペースを爆発させる問題です。多様なデータが少ないと、さらに悪化する可能性があります。これは、1つの近傍でkNNを実行しようとする10000サンプルのセットアップ例です。
from numpy.random import normal
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import precision_score
import matplotlib.pyplot as plt
import numpy as np
from math import sqrt
from scipy.special import gamma
N=10000
N_broad=2
scale=20
dims=[]
precs=[]
def avg_distance(k):
return sqrt(2)*gamma((k+1)/2)/gamma(k/2)
for dim in range(N_broad+1,30):
clf = KNeighborsClassifier(1, n_jobs=-1)
X_train=np.hstack([normal(size=(N,N_broad)), normal(size=(N,dim-N_broad))/avg_distance(dim-N_broad)/scale])
y_train=(X_train[:,N_broad]>0).astype(int)
clf.fit(X_train, y_train)
X_test=np.hstack([normal(size=(N,N_broad)), normal(size=(N,dim-N_broad))/avg_distance(dim-N_broad)/scale])
y_test=(X_test[:,N_broad]>0).astype(int)
y_test_pred=clf.predict(X_test)
prec=precision_score(y_test, y_test_pred)
dims.append(dim)
precs.append(prec)
print(dim, prec)
plt.plot(dims, precs)
plt.ylim([0.5,1])
plt.xlabel("Dimension")
plt.ylabel("Precision")
plt.title("kNN(1) on {} samples".format(N))
plt.show()
あなたは完全に均一な分布が好きではなかったので、これをscale
最初の2つの座標の2D平面に散らばる小さな寸法(で縮小)の2D多様体にしました。たまたま、小さいディメンションの1つが予測的です(そのディメンションが正の場合、ラベルは1です)。
寸法が大きくなると、精度は急速に低下します。
もちろん、precision = 0.5はランダムな推測になります。飛行機よりも複雑な意思決定面では、さらに悪化します。
kNNボールがあまりにもまばらであるため、滑らかな超平面の探査に役立ちません。より高い次元で、彼らはますます孤独を感じます。
一方、SVMのようなメソッドにはグローバルビューがあり、はるかに優れています。