기계 학습에서 차원의 저주는 더 많은 데이터 포인트 사이의 빈 공간을 폭발시키는 문제입니다. 매니 폴드 데이터가 낮 으면 데이터가 더 나빠질 수 있습니다. 다음은 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
처음 두 좌표의 2D 평면 주위 에 더 작은 치수 (로 축소 )를 뿌린 2D 매니 폴드로 만들었습니다 . 이와 같이 작은 차원 중 하나는 예측 적입니다 (해당 차원이 양수이면 레이블이 1 임).
치수가 커질수록 정밀도가 급격히 떨어집니다.
물론 정밀도 = 0.5는 무작위 추측입니다. 비행기보다 더 복잡한 결정 표면을 가지면 훨씬 더 나빠질 것입니다.
kNN 공이 너무 희박하여 부드러운 초평면을 탐색하는 데 도움이되지 않습니다. 크기가 클수록 점점 외로워집니다.
반면에 SVM과 같은 방법은 전체적으로 볼 수 있으며 훨씬 더 좋습니다.