Я обнаружил некоторые очевидные ошибки. Прежде всего, вам нужно создать матрицу из size=(5,5)
:
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)
Во-вторых, если вы печатаете только заголовок, вы не увидите, что матрица имеет более 5 строк. Всего 5 строк, эти две:
print(df.T.head())
print(df.T)
выведите тот же результат:
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
:
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)
чтобы получить желаемый результат:
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
В приведенном выше коде также есть .astype(bool)
для предотвращения предупреждения при запуске pairwise_distance
.
Необходимо соблюдать осторожность при применении транспонирования .T
, поскольку pairwise_distance
скорее работает со столбцами, чем со строками.
С функцией jaccard_similarity_score
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)
У меня другая матрица:
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
:
print(df['A'])
print(df['B'])
jaccard_similarity_score(df['A'], df['B'], normalize = True)
показывает, что нули не были исключены результатом:
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.