【问题标题】:How to calculate the Jaccard Index in Python?如何在 Python 中计算 Jaccard 指数?
【发布时间】:2020-06-01 21:16:32
【问题描述】:

我有一个如下所示的数据集:

它显示了哪家商店出售了哪本书。

import pandas as pd

books = {'shop': ["A", "B", "C", "D", "E", "A", "B", "C", "D",],
        'book_id': [1, 1, 2, 3, 3, 3, 4, 5, 1,]
        }

df = pd.DataFrame(books, columns = ['shop', 'book_id'])

这是印刷品:

  shop  book_id
0    A        1
1    B        1
2    C        2
3    D        3
4    E        3
5    A        3
6    B        4
7    C        5
8    D        1

在数据集中,

  • 店铺A卖1、3
  • 店铺B卖1、4
  • 店铺C卖2、5
  • 店铺D卖3、1
  • 店铺E只卖3个

所以现在,我想在这里计算 Jaccard 指数。例如,我们以 shop Ashop B 为例。 A 和 B 出售 三本 不同的书(书 1、书 3、书 4)。但是,两家商店只出售 一种 产品(这是产品 1)。所以,这里的 Jaccard 指数应该是 33.3% (1/3)。

这是所需数据的示例:

result = {'shop_1': ["A", "B", "A", "C", "A", "D", "A", "E",],
          'shop_2': ["B", "A", "C", "A", "D", "A", "E", "A",],
          'jaccard':  [33.3, 33.33, 0, 0, 100, 100, 50, 50,]
        }
desired_df = pd.DataFrame(result, columns = ['shop_1', 'shop_2', 'jaccard'])
Print
  shop_1 shop_2  jaccard
0      A      B    33.30
1      B      A    33.33
2      A      C     0.00
3      C      A     0.00
4      A      D   100.00
5      D      A   100.00
6      A      E    50.00
7      E      A    50.00
.      .      .      .
.      .      .      .
.      .      .      .   

有人可以帮我做这件事吗?有没有实现 Jaccard 索引的库?

【问题讨论】:

标签: python pandas machine-learning


【解决方案1】:

如果你的数据不是太大,可以使用广播的方式:

books = pd.crosstab(df.shop, df.book_id)

# underlying numpy
arr = books.values

common = (arr[None,...] | arr[:,None,:]).sum(-1)

output = (books @ books.T)/common

输出:

shop         A         B    C         D    E
shop                                        
A     1.000000  0.333333  0.0  1.000000  0.5
B     0.333333  1.000000  0.0  0.333333  0.0
C     0.000000  0.000000  1.0  0.000000  0.0
D     1.000000  0.333333  0.0  1.000000  0.5
E     0.500000  0.000000  0.0  0.500000  1.0

要匹配您的预期输出:

output = (output.stack().rename_axis(['shop_1','shop_2'])
                .reset_index(name='jaccard')
                .query('shop_1 != shop_2')
         )

输出:

   shop_1 shop_2   jaccard
1       A      B  0.333333
2       A      C  0.000000
3       A      D  1.000000
4       A      E  0.500000
5       B      A  0.333333
7       B      C  0.000000
8       B      D  0.333333
9       B      E  0.000000
10      C      A  0.000000
11      C      B  0.000000
13      C      D  0.000000
14      C      E  0.000000
15      D      A  1.000000
16      D      B  0.333333
17      D      C  0.000000
19      D      E  0.500000
20      E      A  0.500000
21      E      B  0.000000
22      E      C  0.000000
23      E      D  0.500000

【讨论】:

  • 非常感谢@Quany Hoang。请问'a'在这里代表什么: common = (a[None,...] | a[:,None,:]).sum(-1)
  • 错过了重构,它是上面定义的 numpy 数组。查看更新。
  • 嗨@Quang Hoang,我刚刚尝试用我的真实数据来做,但不幸的是,内核在运行时已经死了:pd.crosstab(df.shop, df.book_id) 你呢认为是因为我的数据很大(980 MB)?你会建议我如何解决这个问题?
  • @datazang 你的数据太大了。你有多少个独特的 book_ids/stores?
  • 有 2900 万本书 id,但我试图获取类别 id(即 240K)而不是 book_id。内核仍在死亡。 @Quang Hoang
猜你喜欢
  • 2017-03-27
  • 1970-01-01
  • 1970-01-01
  • 2021-10-19
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多