Jaccard相似度介绍
- 两个集合的交集元素个数在并集中所占的比例, 非常适用于布尔向量表示
- 分子是两个布尔向量做点积计算, 得到的就是交集元素的个数
- 分母是两个布尔向量做或运算, 再求元素和
- 杰卡德相似度适用于隐式反馈数据(0,1布尔值),主要应用于是否收藏,是否点击,是否加购物车。
简单地来说就是交集/并集
J(A,B)=|A∩B|/|A∪B|
Jaccard相似度计算推荐结果代码及实现
基本介绍
-
我们通过简单的一个DataFrame例子来实现其算法,最终输出结果。通常有两种协同过滤:基于用户的协同过滤推荐(User-based CF)、基于物品的协同过滤推荐(Item-based CF)。这里我们会构建一个用户+物品的DataFrame。
-
这里为了方便,可以使用jupyternotebook进行书写
import numpy as np
import pandas as pd
users = ["Thomas", "Cauchy", "Alice", "Bob", "Alex"]
items = ["iPad", "MacBook", "iPhone", "iWatch", "AirPods"]
#用户购买记录数据集
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)
print(df)
print(df.index)
print(df.columns)
Jaccard相似度计算代码
#导入杰卡德相似度
from sklearn.metrics import jaccard_score
#计算iPad和MacBook的相似度
jaccard_score(df['iPad'],df['MacBook'])
#结果
0.2
#计算所有的数据两两的杰卡德相似系数
from sklearn.metrics.pairwise import pairwise_distances
#计算所有的数据两两的杰卡德相似系数(1-jaccard距离就是相似度)
user_similar = 1-pairwise_distances(df.values,metric='jaccard')
user_similar = pd.DataFrame(user_similar,columns=users,index = users)
#用户相似度
user_similar
#以相同的思路我们来试着做一下物品的相似度(记住物品需要先进行转置才可以计算)
item_similar = 1-pairwise_distances(df.T.values,metric='jaccard')
item_similar = pd.DataFrame(item_similar,columns=items,index = items)
item_similar
协同过滤推荐代码实现
- 通过计算杰卡德相似度,已经得出了用户相似度,接下来我们就需要进行协同过滤推荐了。
- 实现协同过滤推荐有2个步骤:
- 找出最相似的人或物品:TOP-N相似的人或物品
#为每一个用户找到最相似的2个用户
#创建空的dict保存最终结果
topN_users = {}
#遍历每一行数据
for i in user_similar.index:
#取出每一列数据, 删除自己,按照相似度排序(降序)
_df = user_similar.loc[i].drop([i])
_df_sorted = _df.sort_values(ascending = False)
#排序之后切片取出前两个值,传入空dict
top2 = list(_df_sorted.index[:2])
topN_users[i] = top2
- 根据相似的人或物品产生推荐结果
#根据topn的相似用户构建推荐结果
rs_results={}
for user,sim_users in topN_users.items():
rs_result = set() #为每一用户保存推荐结果
for sim_user in sim_users:
#将0替换为控制,去掉空值,做union联合
rs_result = rs_result.union(set(df.loc[sim_user].replace(0,np.nan).dropna().index))
#过滤掉已经购买的商品(得到的结果需要减去user已经购买过的)
rs_result -= set(df.loc[user].replace(0,np.nan).dropna().index)
#将结果传入到dict中
rs_results[user] = rs_result