Scikit learn 为什么要学习';当我的训练样本和测试样本数量很大时,s kNN Classifier运行得非常快

Scikit learn 为什么要学习';当我的训练样本和测试样本数量很大时,s kNN Classifier运行得非常快,scikit-learn,classification,knn,Scikit Learn,Classification,Knn,据我了解,对于每个测试样本,kNN分类器算法计算当前测试样本与所有训练样本之间的距离,选择一定数量的最近邻,并确定测试样本的标签,然后进行下一个测试样本 我的代码类似于下面超链接中的示例kNN分类器代码,非常简单: 我的培训样本数量为8000,测试样本数量为1500,样本维度为12 当我运行sklearn kNN分类器代码时,它只花了2秒钟,并且精度很好 我怀疑sklearn kNN算法花费的时间,因此我编写了一个简单的代码来计算测试样本和所有训练样本之间的距离,发现这是一个耗时的过程,甚至不

据我了解,对于每个测试样本,kNN分类器算法计算当前测试样本与所有训练样本之间的距离,选择一定数量的最近邻,并确定测试样本的标签,然后进行下一个测试样本

我的代码类似于下面超链接中的示例kNN分类器代码,非常简单:

我的培训样本数量为8000,测试样本数量为1500,样本维度为12

当我运行sklearn kNN分类器代码时,它只花了2秒钟,并且精度很好

我怀疑sklearn kNN算法花费的时间,因此我编写了一个简单的代码来计算测试样本和所有训练样本之间的距离,发现这是一个耗时的过程,甚至不包括排序算法。距离计算的代码如下:

for i in range(X_test.shape[0]):
    for j in range(X_train.shape[0]):
        ## calculate distances between a test sample and all train samples
        Distance[j,0] = (X_test.iloc[i,0]-X_train.iloc[j,0])*(X_test.iloc[i,0]-X_train.iloc[j,0]) + \
                   (X_test.iloc[i,1]-X_train.iloc[j,1])*(X_test.iloc[i,1]-X_train.iloc[j,1]) + \
                   (X_test.iloc[i,2]-X_train.iloc[j,2])*(X_test.iloc[i,2]-X_train.iloc[j,2]) + \
                   (X_test.iloc[i,3]-X_train.iloc[j,3])*(X_test.iloc[i,3]-X_train.iloc[j,3]) + \
                   (X_test.iloc[i,4]-X_train.iloc[j,4])*(X_test.iloc[i,4]-X_train.iloc[j,4]) + \
                   (X_test.iloc[i,5]-X_train.iloc[j,5])*(X_test.iloc[i,5]-X_train.iloc[j,5]) + \
                   (X_test.iloc[i,6]-X_train.iloc[j,6])*(X_test.iloc[i,6]-X_train.iloc[j,6]) + \
                   (X_test.iloc[i,7]-X_train.iloc[j,7])*(X_test.iloc[i,7]-X_train.iloc[j,7]) + \
                   (X_test.iloc[i,8]-X_train.iloc[j,8])*(X_test.iloc[i,8]-X_train.iloc[j,8]) + \
                   (X_test.iloc[i,9]-X_train.iloc[j,9])*(X_test.iloc[i,9]-X_train.iloc[j,9]) + \
                   (X_test.iloc[i,10]-X_train.iloc[j,10])*(X_test.iloc[i,10]-X_train.iloc[j,10]) + \
                   (X_test.iloc[i,11]-X_train.iloc[j,11])*(X_test.iloc[i,11]-X_train.iloc[j,11])
我不确定sklearn是否使用整个训练数据集来计算k个最近邻。如果有,sklearn使用什么优化算法


提前谢谢。

你说得对,最近邻搜索确实需要大量时间。如果您天真地这样做,那么您的运行时间是O(n^2)。好的是,sklearn使用了一些聪明的算法来规避所有距离的计算

查看,您将看到一个参数是用于最近邻搜索的
算法,例如。这些算法大大加快了计算速度

另一方面,您的代码有点低效。您可以执行以下操作,而不是手动计算每个尺寸:

((X_test.iloc[i,:] - X_train.iloc[j,:]) ** 2).sum()

这充分利用了pandas的矢量化功能,使其速度更快。

hi Tilman 151,我分别尝试了“算法=ball_树、kd_树和brute”,运行时间没有显著差异。我用你的代码来计算距离,它比我的代码快一点。我仍然有一个问题:给定一个测试样本,kNN算法需要计算测试样本和8000个训练样本之间的距离,然后选择k个最近邻,即使使用balltree,这也是时间密集型的。我仍然怀疑sklearn没有使用整个训练样本。对于BallTree,它不需要在预测时计算所有距离。它在训练时构建树,然后只检查树的哪一片叶子。leaf只包含少量靠近测试样本的训练样本,因此sklearn只为它们计算距离。感谢您的解释,似乎我需要学习balltree算法。