【问题标题】:Why is KNN slow with custom metric?为什么 KNN 在使用自定义指标时很慢?
【发布时间】:2017-03-10 07:01:51
【问题描述】:

我使用的数据集包含大约 200k 个对象。每个对象都有 4 个特征。我用欧几里德度量通过 K 个最近邻 (KNN) 对它们进行分类。进程在大约 20 秒内完成。

最近我有理由使用自定义指标。或许它会取得更好的结果。我已经实现了自定义指标,KNN 已经工作了一个多小时。我没有等待它完成。

我认为这个问题的一个原因是我的指标。我用return 1 替换我的代码。 KNN 仍然工作了一个多小时。我假设一个原因是算法 Ball Tree,但带有它的 KNN 和欧几里得度量在大约 20 秒内起作用。

现在我不知道出了什么问题。我使用 Python 3 和 sklearn 0.17.1。 Here 进程无法使用自定义指标完成。我也尝试了算法brute,但效果相同。 scikit-learn 的升级和降级没有效果。在 Python 2 上通过自定义指标实现分类也没有积极影响。我在 Cython 上实现了这个指标(只返回 1),它具有相同的效果。

def custom_metric(x: np.ndarray, y: np.ndarray) -> float:
    return 1

clf = KNeighborsClassifier(n_jobs=1, metric=custom_metric)
clf.fit(X, Y)

我可以使用自定义指标来提升 KNN 的分类过程吗?

对不起,如果我的英语不清楚。

【问题讨论】:

  • 用户定义的函数在 Python 中并不是特别快;调用它们有很多开销。您的自定义指标可能正在替换在 C 中实现的某些内容。
  • KNN 的欧式距离矩阵可以用矩阵加法和乘法来实现(利用 ||ab||^2 = ||a||^2 + ||b ||^2 - 2) 高度优化和并行化(OpenBLAS、ATLAS 或 MKL)
  • @chepner 即使仅在函数return 1 中也存在开销吗?此外,正如我上面指出的,我已经在 Cython 上实现了指标,并且执行时间也很长。 @damienfrancois 我对欧几里得度量没有问题。它是 sklearn 的标准度量。当我尝试使用我的自定义指标时,我遇到了性能问题。我应该看看 C/C++ 库并在 C/C++ 上重新实现我的程序吗?

标签: python algorithm scikit-learn


【解决方案1】:

Sklearn 已经过优化并使用 cython 和几个进程尽可能快地运行。编写纯 Python 代码,尤其是当它被多次调用时,会导致代码变慢。我建议您使用 cython 编写自定义指标。 你有一个教程,你可以在这里学习:https://blog.sicara.com/https-medium-com-redaboumahdi-speed-sklearn-algorithms-custom-metrics-using-cython-de92e5a325c

【讨论】:

  • 答案中的链接不起作用。但是讨论了相同的内容here
【解决方案2】:

正如@Réda Boumahdi 正确指出的那样,原因是使用了 python 中定义的自定义指标。这是here 讨论的已知问题。在讨论结束时它被关闭为“wontfix”。因此,建议的唯一解决方案是在 cython 中编写您的自定义指标,以避免 GIL 在使用 python 指标时变慢。

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 2014-01-29
    • 2021-09-05
    • 2012-04-06
    • 1970-01-01
    • 2016-10-04
    • 2016-06-01
    • 2019-11-01
    • 1970-01-01
    相关资源
    最近更新 更多