首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用Python实现jaccard距离的非对称计算

用Python实现jaccard距离的非对称计算
EN

Stack Overflow用户
提问于 2019-04-03 13:22:28
回答 1查看 535关注 0票数 3

我有一些SAS代码,我正试图将其转换为Python。我在计算非对称数据的jaccard距离时遇到了困难-在计算中应该忽略零。我确实在jaccard上找到了一些示例,但它们不计算非对称距离。在我尝试重新发明轮子之前,我只是检查一下是否有库可以使用它。如果有人能给我指引正确的方向,我将不胜感激。

我的测试数据集包含5个头和5行

代码语言:javascript
复制
H0  H1  H2  H3  H4

A  1  1  1  1  0

B  1  0  1  1  0

C  1  1  1  1  0

D  0  0  1  1  1

E  1  1  0  1  0

以下是速记和使用SAS计算的预期结果(距离):

代码语言:javascript
复制
. |  A   |    B   |    C   |   D   |   E

A |  0   |    0.25|    0   |   0.6 |   0.25

B |  0.25|    0   |    0.25|   0.5 |   0.5

C |  0   |    0.25|    0   |   0.6 |   0.25

D |  0.6 |    0.5 |    0.6 |   0   |   0.8

E |  0.25|    0.5 |    0.25|   0.8 |   0        

但是,在python中使用jaccard,我得到的结果如下:

代码语言:javascript
复制
.  |A    |   B   |   C   |   D  |   E

A  |1.00 | 0.43  |  0.61 | 0.55 |   0.46

B  |0.43 | 1.00  |  0.52 | 0.56 |   0.49

C  |0.61 | 0.52  |  1.00 | 0.48 |   0.53

D  |0.55 | 0.56  |  0.48 | 1.00 |   0.49

E  |0.46 | 0.49  |  0.53 | 0.49 |   1.00

下面是我实验过的代码。我是Python的新手,所以我可能犯了一个明显的错误。我在底部添加了SAS代码,以防有人需要它作为参考:

Python代码:

代码语言:javascript
复制
np.random.seed(0)
df = pd.DataFrame(np.random.binomial(1, 0.5, size=(100, 5)), 
columns=list('ABCDE'))
print(df.head())

jac_sim = 1 - pairwise_distances(df.T, metric = "jaccard")
jac_sim = pd.DataFrame(jac_sim, index=df.columns, columns=df.columns)

import itertools
sim_df = pd.DataFrame(np.ones((5, 5)), index=df.columns, columns=df.columns)
for col_pair in itertools.combinations(df.columns, 2):
    sim_df.loc[col_pair] = sim_df.loc[tuple(reversed(col_pair))] = 
    jaccard_similarity_score(df[col_pair[0]], df[col_pair[1]])
print(sim_df)

SAS代码:

代码语言:javascript
复制
proc import datafile = '/home/xxx/xxx.csv'  
 out = work.Binary2 replace
 dbms = CSV;
 GUESSINGROWS=MAX;
run;
proc sort;
by VAR1;
run;
title ’Data Clustering of BN’;
proc distance data=Binary2 method=djaccard absent=0 out=distjacc;
var anominal (r0--r4);
id VAR1;
run;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-03 14:49:10

我发现了一些明显的错误。首先,您需要创建size=(5,5)矩阵

代码语言:javascript
复制
import pandas as pd
import numpy as np
from sklearn.metrics import pairwise_distances, jaccard_similarity_score

np.random.seed(0)
df = pd.DataFrame(np.random.binomial(1, 0.5, size=(5, 5)).T, columns=list('ABCDE'))
print(df.T)

第二件事是,如果只打印head,您看不到矩阵有超过5行。这两行代码只有5行:

代码语言:javascript
复制
print(df.T.head())

print(df.T)

打印相同的结果:

代码语言:javascript
复制
   0  1  2  3  4
A  1  1  1  1  0
B  1  0  1  1  0
C  1  1  1  1  0
D  0  0  1  1  1
E  1  1  0  1  0

在上述更改之后,可以使用pairwise_distances

代码语言:javascript
复制
jac_sim = pairwise_distances(df.T.astype(bool), metric = "jaccard")
jac_sim = pd.DataFrame(jac_sim, index=df.columns, columns=df.columns)
print(jac_sim)

为了获得想要的结果:

代码语言:javascript
复制
      A     B     C    D     E
A  0.00  0.25  0.00  0.6  0.25
B  0.25  0.00  0.25  0.5  0.50
C  0.00  0.25  0.00  0.6  0.25
D  0.60  0.50  0.60  0.0  0.80
E  0.25  0.50  0.25  0.8  0.00

为了防止在运行pairwise_distance时出现警告,在上面的代码中也有.astype(bool)

由于pairwise_distance似乎使用列而不是行,因此在应用转置.T时必须小心。

使用函数jaccard_similarity_score

代码语言:javascript
复制
import itertools
sim_df = pd.DataFrame(np.zeros((5, 5)), index=df.columns, columns=df.columns)
for col_pair in itertools.combinations(df.columns, 2):
    sim_df.loc[col_pair] = sim_df.loc[tuple(reversed(col_pair))] = \
        1 - jaccard_similarity_score(df[col_pair[0]], df[col_pair[1]], normalize = True)
print(sim_df)

我得到了一个不同的矩阵:

代码语言:javascript
复制
     A    B    C    D    E
A  0.0  0.2  0.0  0.6  0.2
B  0.2  0.0  0.2  0.4  0.4
C  0.0  0.2  0.0  0.6  0.2
D  0.6  0.4  0.6  0.0  0.8
E  0.2  0.4  0.2  0.8  0.0

更仔细地看jaccard_similarity_score

代码语言:javascript
复制
print(df['A'])
print(df['B'])
jaccard_similarity_score(df['A'], df['B'], normalize = True)

显示结果中没有排除零:

代码语言:javascript
复制
0    1
1    1
2    1
3    1
4    0
Name: A, dtype: int32
0    1
1    0
2    1
3    1
4    0
Name: B, dtype: int32
Out[123]: 0.8

因为结果是4个相似的/5个总数= 0.8,而不是3个相似的非零/4个总的非零= 0.75。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55487592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档