Короткий и векторизация (быстрый) Ответ:
Используйте 'Хэмминга' из попарных расстояний scikit узнать:
from sklearn.metrics.pairwise import pairwise_distances
jac_sim = 1 - pairwise_distances(df.T, metric = "hamming")
# optionally convert it to a DataFrame
jac_sim = pd.DataFrame(jac_sim, index=df.columns, columns=df.columns)
Объяснение:
Предположим, что это ваш набор данных:
Использование jaccard_similarity_score sklearn в, сходство между колонки А и В:
from sklearn.metrics import jaccard_similarity_score
print(jaccard_similarity_score(df['A'], df['B']))
0.43
Это число строк, которые имеют одинаковое значение в течение общего количества строк, 100.
Насколько я знаете, нет парной версии jaccard_similarity_score, но есть попарные версии расстояний.
Однако SciPy определяет Jaccard distance следующим образом:
даны два вектора, U и V, то Jaccard расстояние доля этих элементов и [I] и V [I], которые не согласны где по крайней мере один из них отлична от нуля.
Таким образом, он исключает строки, в которых оба столбца имеют 0 значений. jaccard_similarity_score нет. Расстояние Хэмминга, с другой стороны, является рядный с определением подобия:
Доля этих векторных элементов между двумя п-векторы и и у , которые не согласны.
Так что, если вы хотите, чтобы вычислить jaccard_similarity_score, вы можете использовать 1 - Хэмминга:
from sklearn.metrics.pairwise import pairwise_distances
print(1 - pairwise_distances(df.T, metric = "hamming"))
array([[ 1. , 0.43, 0.61, 0.55, 0.46],
[ 0.43, 1. , 0.52, 0.56, 0.49],
[ 0.61, 0.52, 1. , 0.48, 0.53],
[ 0.55, 0.56, 0.48, 1. , 0.49],
[ 0.46, 0.49, 0.53, 0.49, 1. ]])
В формате DataFrame:
jac_sim = 1 - pairwise_distances(df.T, metric = "hamming")
jac_sim = pd.DataFrame(jac_sim, index=df.columns, columns=df.columns)
# jac_sim = np.triu(jac_sim) to set the lower diagonal to zero
# jac_sim = np.tril(jac_sim) to set the upper diagonal to zero
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
Вы можете сделать то же самое итерация комбинаций но он будет намного медленнее.
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)
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
На самом деле, я думаю, что могу получить расстояние Жакара на 1 минус сходство с Jaccard. – kitchenprinzessin
Конечно, исходя из определения, которое может измениться. Я имел в виду, что jaccard_similarity_score от sklearn не равен 1 - расстоянию jaccard от sklearn. Но он равен расстоянию до 1 - sklearn. Определение Википедии, например, отличается от определения sklearn. – ayhan
Я не могу поверить, что у него больше нет болей. Отличная работа. Спасибо – Private