2016-05-03 2 views
6

У меня есть dataframe следующим образом: форма кадра (1510, 1399). Столбцы представляют продукты, строки представляют значения (0 или 1), назначенные пользователем для данного продукта. Как я могу вычислить jaccard_similarity_score?Как вычислить сходство с jaccard из pandas dataframe

enter image description here

Я создал замещающий dataframe листинг продукта по сравнению с продуктом

data_ibs = pd.DataFrame(index=data_g.columns,columns=data_g.columns) 

Я не уверен, как перебрать хотя data_ibs для вычисления сходства.

for i in range(0,len(data_ibs.columns)) : 
    # Loop through the columns for each column 
    for j in range(0,len(data_ibs.columns)) : 
......... 

ответ

17

Короткий и векторизация (быстрый) Ответ:

Используйте 'Хэмминга' из попарных расстояний 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 
+0

На самом деле, я думаю, что могу получить расстояние Жакара на 1 минус сходство с Jaccard. – kitchenprinzessin

+0

Конечно, исходя из определения, которое может измениться. Я имел в виду, что jaccard_similarity_score от sklearn не равен 1 - расстоянию jaccard от sklearn. Но он равен расстоянию до 1 - sklearn. Определение Википедии, например, отличается от определения sklearn. – ayhan

+3

Я не могу поверить, что у него больше нет болей. Отличная работа. Спасибо – Private

Смежные вопросы