计算欧几里得距离时 sklearn.metrics.pairwise_distances_argmin_min 的奇怪结果

Posted

技术标签:

【中文标题】计算欧几里得距离时 sklearn.metrics.pairwise_distances_argmin_min 的奇怪结果【英文标题】:Weird results of sklearn.metrics.pairwise_distances_argmin_min when computing euclidean distance 【发布时间】:2019-05-12 10:09:38 【问题描述】:

我正在实施用于异常值检测的 k-means 算法的定制版本。为此,我需要将数据点分配给聚类中心,并计算到各个中心的距离。我的数据输入是 pandas Dataframes,我使用 sklearn.metrics.pairwise_distances_argmin_min 在同一步骤中快速计算距离和集群标签。

但是当使用 metric='euclidean' 作为参数时,我遇到了奇怪的结果,导致我的算法将大多数点分类为异常值。 请考虑以下示例:

import numpy as np
import pandas as pd
from sklearn.metrics import pairwise_distances_argmin_min
from sklearn.metrics import pairwise_distances
from scipy.spatial import distance
A = np.array([[3,3],
             [2,2]])
B = np.array([[1,1]])
pair_dist = pairwise_distances(A, B, metric='euclidean')
_, pair_dist_arg = pairwise_distances_argmin_min(A, B, metric='euclidean')
dist_euclid = [distance.euclidean(A[0,:], B), distance.euclidean(A[1,:], B)]
print('pairwise distances: ', pair_dist.flatten())
print('pairwise distances argmin: ', pair_dist_arg)
print('distance.euclidean: ', dist_euclid)

输出:

pairwise distances:  [2.82842712 1.41421356]
pairwise distances argmin:  [1.68179283 1.18920712]
distance.euclidean:  [2.8284271247461903, 1.4142135623730951]

为什么在使用欧几里得距离时,pairwise_distances 和 pairwise_distances_argmin_min 的结果不同? 我尝试的各种其他指标(堪培拉、城市街区等)的结果是相同的,奇怪的是 l2(与欧几里得相同)也是如此。 似乎pairwise_distances_argmin_min 取平方根太多还是我遗漏了什么?

【问题讨论】:

【参考方案1】:

您似乎遇到了pairwise_distances_argmin_min(..., metric='euclidean') 中的错误:https://github.com/scikit-learn/scikit-learn/pull/12481/files

我使用sklearn 0.19.1 对所有三个计算得到相同的结果。

首先检查你的 sklearn 版本:

import sklearn
print(sklearn.__version__) # Or print sklearn.__version__ in Python 2.7

如果是 0.20.0 那么你就知道它可能是这个错误。这个错误似乎是regression(即它曾经在以前的版本中正常工作),所以可能是你的sklearn 版本比我高。

sklearn 更新到 0.20.1(使用 pipconda 或您使用的任何包管理器)应该可以解决问题。

【讨论】:

我正在运行 sklearn 0.20.0。用 conda 更新到 0.20.1 后,bug 消失了,非常感谢您的帮助!

以上是关于计算欧几里得距离时 sklearn.metrics.pairwise_distances_argmin_min 的奇怪结果的主要内容,如果未能解决你的问题,请参考以下文章

sklearn.metrics 用法详解

sklearn.metrics.confusion_matrix—计算混淆矩阵来评估分类的准确性

为啥增加小数位数不影响欧几里得距离的计算时间?

sklearn.metrics.roc_curve解析

将二维数组传递给 sklearn.metrics.recall_score 时,为啥会出现 ValueError?

Python Scikit - 调用 sklearn.metrics.precision_recall_curve 时输入形状错误