Jaccard系數(shù)
Jaccard系數(shù)值越大,樣本相似度越高。

image-20210306101356476.png
Jaccard 距離
與Jaccard 系數(shù)相關(guān)的指標(biāo)叫做Jaccard 距離,用于描述集合之間的不相似度。Jaccard 距離越大,樣本相似度越低。
例子
假設(shè)有6個(gè)用戶,5個(gè)產(chǎn)品,用戶可以隨機(jī)購(gòu)買,這里不止購(gòu)買,比如收藏等行為都可以。數(shù)據(jù)記錄在一張二維表中。
import pandas as pd
import numpy as np
users = [f"User{i}" for i in range(1, 6)]
items = [f"Item{i}" for i in 'ABCDE']
# 假設(shè)用戶購(gòu)買記錄
datasets = [
[1, 0, 1, 1, 0],
[1, 0, 0, 1, 1],
[1, 0, 1, 0, 0],
[0, 1, 0, 1, 1],
[1, 1, 1, 0, 1],
]
df = pd.DataFrame(datasets, columns=items, index=users)
ItemA ItemB ItemC ItemD ItemE
User1 1 0 1 1 0
User2 1 0 0 1 1
User3 1 0 1 0 0
User4 0 1 0 1 1
User5 1 1 1 0 1
比如計(jì)算ItemA與ItemB之間的相似度,itemA = [1,1,1,0,1],ItemB=[0,0,0,1,1], ItemA與ItemB 相交的有1個(gè),并集有5個(gè),注意兩個(gè)都是0的不計(jì)算,杰卡德系數(shù) j = 1/5 = 0.2,假如 ItemA = [0,1,1,0,1],ItemB=[0,0,0,1,1],j = 1/4 = 0.25
score = jaccard_score(df['ItemA'], df['ItemB']) # 0.2
任意兩個(gè)用戶之間的相似度
# 求任意兩個(gè)用戶之間的距離
from sklearn.metrics import pairwise_distances
# jaccard 距離
jaccard_dis = pairwise_distances(df.values, metric='jaccard')
[[0. 0.5 0.33333333 0.8 0.6 ]
[0.5 0. 0.75 0.5 0.6 ]
[0.33333333 0.75 0. 1. 0.5 ]
[0.8 0.5 1. 0. 0.6 ]
[0.6 0.6 0.5 0.6 0. ]]
計(jì)算過程如下:
結(jié)果數(shù)組是一個(gè)5*5的二維表,數(shù)組的第一行第一列就是a[1]與a[1]之間的jaccard距離,數(shù)組的第一行第二列就是a[1]與a[2]之間的jaccard距離
a[1] = [1, 0, 1, 1, 0]
a[2] = [1, 0, 0, 1, 1]
a[3] = [1, 0, 1, 0, 0]
a[4] = [0, 1, 0, 1, 1]
a[5] = [1, 1, 1, 0, 1]
按照上面的計(jì)算方法可以計(jì)算出jaccard距離
user_sim = 1 - jaccard_dis # jaccard相似系數(shù)
# print("任意兩個(gè)用戶相似系數(shù)")
user_sim = pd.DataFrame(user_sim, columns=users, index=users)
任意兩個(gè)物品之間的相似度
item_sim = 1 - pairwise_distances(df.T.values, metric='jaccard')
item_sim = pd.DataFrame(item_sim, columns=items, index=items)
topN
# 基于用戶的協(xié)同過濾 找每一個(gè)用戶最相似的兩個(gè)
topN_users = {}
for i in user_sim.index:
df1 = user_sim.loc[i].drop(i)
df1_sorted = df1.sort_values(ascending=False)
top2 = list(df1_sorted.index[:2])
topN_users[i] = top2
{'User1': ['User3', 'User2'], 'User2': ['User4', 'User1'], 'User3': ['User1', 'User5'], 'User4': ['User2', 'User5'], 'User5': ['User3', 'User4']}
推薦結(jié)果
# 根據(jù)topN的相似用戶構(gòu)建推薦結(jié)果
rs_results = {}
for user, sim_users in topN_users.items():
rs_result = set()
for sim_user in sim_users:
# 獲取物品共同購(gòu)買過的集合
rs_result |= set(df.loc[sim_user].replace(0, np.nan).dropna().index)
# 過濾掉已經(jīng)購(gòu)買的商品
rs_result -= set(df.loc[user].replace(0, np.nan).dropna().index)
rs_results[user] = rs_result
{'User1': {'ItemE'}, 'User2': {'ItemB', 'ItemC'}, 'User3': {'ItemD', 'ItemB', 'ItemE'}, 'User4': {'ItemA', 'ItemC'}, 'User5': {'ItemD'}}
相關(guān)研究中,基于物品協(xié)同過濾系統(tǒng)的相似性度量方法普遍使用余弦相似性。 然而,在許多實(shí)際應(yīng)用中,評(píng)價(jià)數(shù)據(jù)稀疏度過高,物品之間通過余弦相似度計(jì)算會(huì)產(chǎn)生誤導(dǎo)性結(jié)果。 將杰卡德相似性度量應(yīng)用到基于物品的協(xié)同過濾系統(tǒng)中,并建立起相應(yīng)的評(píng)價(jià)分析方法。 與傳統(tǒng)相似性度量方法相比,杰卡德方法完善了余弦相似性只考慮用戶評(píng)分而忽略了其他信息量的弊端,特別適合于應(yīng)用到稀疏度過高的數(shù)據(jù)