为什么在使用 scipy pdist(metric = 'jaccard') 与 scipy jaccard 生成距离矩阵时存在差异?

Why are there discrepanices when generating a distance matrix with scipy pdist(metric = 'jaccard') vs scipy jaccard?

我正在比较使用 pdist 和 DIY Jaccard 距离矩阵函数处理数据集时得到的 Jaccard 距离矩阵。我在输出距离矩阵中得到不同的结果,我不确定为什么。

我认为是以下原因之一:

squareform 的文档有点让我头疼,所以可能正在发生某种形式的规范化。然而,方形距离矩阵在单元格之间没有相同的相对距离大小,这令人困惑(例如,我的 DIY 距离矩阵中的第 0 行是 0, 0.571429, 1pdist0, 1, 1 - 中间值是 pdist) 的两倍。

谁能解释为什么我在使用相同的指标进行分析时会得到不同的距离矩阵?

我的代码:

import numpy as np
from scipy.spatial.distance import jaccard, squareform, pdist

def jaccard_dissimilarity(feature_list1, feature_list2, filler_val): #binary
    #I don't care about every value in the array for my use case, so dont want to include them in my comparison
    all_features = set([i for i in feature_list1 if i != filler_val])
    all_features.update(set([i for i in feature_list2 if i != filler_val]))
    counts_1 = [1 if feature in feature_list1 else 0 for feature in all_features]
    counts_2 = [1 if feature in feature_list2 else 0 for feature in all_features]
    return jaccard(counts_1, counts_2)
 
    
data_array = np.array([[1, 2, 3, 4, 5],
                      [3, 4, 5, 6, 7],
                      [8, 9, 10, 11, 12]])

# =============================================================================
# DIY distance matrix
# =============================================================================
#set filler val to None, so the arrays being compared are equivalent to pdist
dist_diy = np.array([[jaccard_dissimilarity(a,b, None) for a in data_array] for b in data_array])

# =============================================================================
# pdist distance matrix
# =============================================================================
dist_pdist = squareform(pdist(data_array, metric = 'jaccard'))

输入数组:

1   2   3   4   5
3   4   5   6   7
8   9   10  11  12

dist_diy:

0           0.571429    1
0.571429    0           1
1           1           0

dist_pdist:

0   1   1
1   0   1
1   1   0

看起来 pdist 在比较数组时考虑给定索引处的对象,而不仅仅是数组本身中存在的对象 - 如果我将 data_array[1] 更改为 3, 4, 5, 4, 5 那么距离矩阵发生变化以反映 data_array[0][3:5] == data_array[1][3:5]:

0   0.6 1
0.6 0   1
1   1   0

讨论了行为 here,但根据上述测试,数组不必是布尔值(如果数组被视为布尔值,则距离矩阵不会改变,因为所有数字都是 > 1 因此 == True)。

DIY 函数考虑的是存在的对象而不是找到这些对象的索引,因此存在差异!