【问题标题】:What does sklearn's pairwise_distances with metric='correlation' do?sklearn 的 pairwise_distances with metric='correlation' 有什么作用?
【发布时间】:2019-04-15 16:27:13
【问题描述】:

我在这个函数中输入了不同的值并观察了输出。但我在输出的内容中找不到可预测的模式。

然后我尝试挖掘 function 本身,但它令人困惑,因为它可以进行许多不同的计算。

根据Docs

Compute the distance matrix from a vector array X and optional Y.

我看到它返回一个高度和宽度矩阵,等于输入的嵌套列表的数量,这意味着它正在比较每个列表。

但除此之外,我很难理解它在做什么以及价值来自哪里。

我尝试过的示例:

pairwise_distances([[1]], metric='correlation')
>>> array([[0.]])

pairwise_distances([[1], [1]], metric='correlation')
>>> array([[ 0., nan],
>>>        [nan,  0.]])

# returns same as last input although input values differ
pairwise_distances([[1], [2]], metric='correlation')
>>> array([[ 0., nan],
>>>        [nan,  0.]])

pairwise_distances([[1,2], [1,2]], metric='correlation')
>>> array([[0.00000000e+00, 2.22044605e-16],
>>>        [2.22044605e-16, 0.00000000e+00]])

# returns same as last input although input values differ
# I incorrectly expected more distance because input values differ more
pairwise_distances([[1,2], [1,3]], metric='correlation')
>>> array([[0.00000000e+00, 2.22044605e-16],
>>>       [2.22044605e-16, 0.00000000e+00]])

用 Scipy 计算相关距离

如果 scipy 针对相同的输入返回 0.0,我不明白 sklearn 2.22044605e-16 值的来源。

# Scipy
import scipy
scipy.spatial.distance.correlation([1,2], [1,2])
>>> 0.0

# Sklearn
pairwise_distances([[1,2], [1,2]], metric='correlation')
>>> array([[0.00000000e+00, 2.22044605e-16],
>>>        [2.22044605e-16, 0.00000000e+00]])

我不是在寻找高级别的解释,而是如何计算数字的示例。

【问题讨论】:

  • 正如其他人所说,2.22e-16 is 0 用于所有密集目的,因为 python 中的浮点数并不比这更精确。

标签: python scikit-learn pairwise-distance


【解决方案1】:

pairwise_distances 内部调用distance.pdist(),当yNone(这意味着我们要计算X 中每个向量的距离矩阵)

参考12

实现类似于以下内容:

X = np.array([[1,2], [1,2]])

import numpy as np
from numpy.linalg import norm

X2 = X - X.mean(axis=1, keepdims=True)

u, v =[*X2]

1 - (sum(u*v)/(norm(u) * norm(v)))

#2.220446049250313e-16

scipy.spatial.distance.correlation 的实现在最新版本中有所不同

latest version, old version

如果我们将权重设置为None,下面的sn-p就是它的简化版:

u, v = np.array([1,2]), np.array([1,2])

umu = np.average(u)
vmu = np.average(v)
u = u - umu
v = v - vmu
uv = np.average(u * v)
uu = np.average(np.square(u))
vv = np.average(np.square(v))
dist = 1.0 - uv / np.sqrt(uu * vv)
dist

#0

【讨论】:

    【解决方案2】:

    【讨论】:

    • 谢谢。我添加了关于尝试scipy.spatial.distance.correlation() 的部分。获得与 sklearn 不同的值,所以我仍然认为我缺少一些重要的东西。
    【解决方案3】:
    import sklearn
    
    X = [[1, 2, 3, 4], [2, 2, 4, 4], [4, 3, 2, 1]]
    
    D = sklearn.metrics.pairwise_distances(X, metric='correlation')
    print(D)
    

    输出:

    [[0.         0.10557281 2.        ]
     [0.10557281 0.         1.89442719]
     [2.         1.89442719 0.        ]]
    

    D 是一个距离矩阵,使得 D{i, j} 是第 ith 和 jth 给定矩阵的向量X

    import scipy
    
    X = [[1, 2, 3, 4], [2, 2, 4, 4], [4, 3, 2, 1]]
    
    c_00 = scipy.spatial.distance.correlation(X[0], X[0])        # c_00 = 0.0
    c_01 = scipy.spatial.distance.correlation(X[0], X[1])        # c_01 = 0.10557280900008414
    c_02 = scipy.spatial.distance.correlation(X[0], X[2])        # c_02 = 2.0
    

    如果 scipy 针对相同的输入返回 0.0,我不明白 sklearn 2.22044605e-16 值的来源。

    这可能是round-off error

    import numpy as np
    epsilon = np.finfo(float).eps
    print(epsilon)
    

    输出:

    2.220446049250313e-16                                    # This value is machine dependent
    

    您可以使用np.isclose 将极小的值四舍五入为 0。

    【讨论】:

      【解决方案4】:

      我完全理解这种困惑。

      在向量上计算相关性,sklearn 将标量转换为大小为 1 的向量。

      结果

      from sklearn.metrics import pairwise_distances
      from scipy.spatial.distance import correlation
      pairwise_distances([u,v,w], metric='correlation')
      

      是一个矩阵M,形状为(len([u,v,w]),len([u,v,w]))=(3,3),其中:

      M[0,0] = correlation(u,u)
      M[0,1] = correlation(u,v)
      M[0,2] = correlation(u,w)
      M[1,0] = correlation(v,u)
      M[1,1] = correlation(v,v)
      M[1,2] = correlation(v,w)
      M[2,0] = correlation(w,u)
      M[2,1] = correlation(w,v)
      M[2,2] = correlation(w,w)
      

      您正在查看的 correlation([u,v,w], [u,v,w]) 只有在 uvw 是标量时才具有有效值。

      【讨论】:

        猜你喜欢
        • 2017-08-18
        • 2019-05-23
        • 1970-01-01
        • 2023-03-20
        • 2017-11-21
        • 1970-01-01
        • 1970-01-01
        • 2016-04-25
        • 1970-01-01
        相关资源
        最近更新 更多