使用锯齿状数组创建相似度矩阵

问题描述 投票:0回答:2

我有一个这样的数据框。

id 行动 enc
细胞1 跑步、游泳、步行 1,2,3
细胞2 游泳、爬山、冲浪、健身 2,4,5,6
细胞3 慢跑、跑步] 7,1

该表大约有 30k 行。收集所有这些操作并使用 labelencoder 进行编码后。

我想创建一个相似性矩阵,我可以用它来将具有相似动作的细胞聚集在一起。

我尝试使用

pairwise_distances(df['enc'],metric='jaccard')
,但遇到了设置数组元素错误。填充它对我来说也没有多大意义。

有没有办法基于jaccard生成相似度矩阵?谢谢。

python pandas similarity
2个回答
0
投票

第 1 步,这是您的数据框

import pandas as pd
data = [['Cell 1', ['run','swim','walk'], [1,2,3]], ['Cell 2', ['swim','climb','surf','gym'], [2,4,5,6]], ['Cell 3', ['jog','run'], [7,1]]]

df = pd.DataFrame(data, columns=['id', 'action', 'label_encoder'])
print(df)

     id       action                      label_encoder
0   Cell 1  [run, swim, walk]           [1, 2, 3]
1   Cell 2  [swim, climb, surf, gym]    [2, 4, 5, 6]
2   Cell 3  [jog, run]                  [7, 1]

第2步,添加one_hot列表作为新列

from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()

one_hot = mlb.fit_transform(df['label_encoder'])

# add one_hot list as a new column
df['label_encoder_one_hot'] = list(one_hot)
print(df)

       id                    action  labelen_coder  label_encoder_one_hot
0  Cell 1         [run, swim, walk]     [1, 2, 3]  [1, 1, 1, 0, 0, 0, 0]
1  Cell 2  [swim, climb, surf, gym]  [2, 4, 5, 6]  [0, 1, 0, 1, 1, 1, 0]
2  Cell 3                [jog, run]        [7, 1]  [1, 0, 0, 0, 0, 0, 1]

第3步,基于Jaccard生成相似度矩阵

from sklearn.metrics import jaccard_score
import numpy as np

similarity_matrix = np.zeros((len(df), len(df)))

for i in range(len(df)):
    for j in range(i+1, len(df)):
        similarity = jaccard_score(df['label_encoder_one_hot'][i], df['label_encoder_one_hot'][j])
        similarity_matrix[i,j] = similarity
        similarity_matrix[j,i] = similarity

print(similarity_matrix)
[[0.         0.16666667 0.25      ]
 [0.16666667 0.         0.        ]
 [0.25       0.         0.        ]]

0
投票

您可以使用

itertools.combinations
和 python
set
操作:

from itertools import combinations
from scipy.spatial.distance import squareform

s = df['enc'].str.split(',').apply(set)

tmp = squareform([len(a&b)/len(a|b) for a,b in combinations(s, 2)])

idx = df['id'].tolist()
out = pd.DataFrame(tmp, index=idx, columns=idx)

输出:

          Cell 1    Cell 2   Cell 3 
Cell 1   0.000000  0.166667     0.25
Cell 2   0.166667  0.000000     0.00
Cell 3   0.250000  0.000000     0.00
© www.soinside.com 2019 - 2024. All rights reserved.