机器学习中的维度诅咒通常是在您拥有的几个数据点之间爆炸空白的问题。低歧管数据会使情况更糟。这是一个具有10000个样本的示例设置,其中我尝试与1个邻居进行kNN。
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平面周围。碰巧的是,较小的维度之一是可预测的(当该维度为正数时,标签为1)。
精度随着尺寸的增加而迅速下降。
当然,precision = 0.5将是随机猜测。如果决策面比飞机复杂,它将变得更糟。
就像kNN球太稀疏,不足以帮助探测光滑的超平面。有了更高的尺寸,他们会感到越来越孤独。
另一方面,诸如SVM之类的方法具有全局性,并且效果更好。