推荐系统公平性之校准化推荐--calibrated recommendations

主要参考论文:论文1《Calibrated Recommendations》、论文2《Crank up the volume: preference bias amplification in collaborative recommendation》

推荐系统中的偏好放大现象(preference bias amplification)

你是否有过这样的经历:某天在淘宝搜索了一样东西后,接下了一段时间的推荐都是关于这个物品的,哪怕你已经购买了这个物品或者你只是简单地搜来瞧瞧;在抖音上给某些视频点了赞,后面抖音会疯狂推荐这类视频给你,尽管你已经不想看这类视频了。

再举个直观的例子,佩琪在购物网站上购买了3条裙子和1双鞋子,那么接下来推荐系统会怎么给她推荐呢?
在这里插入图片描述
有很大的可能是,推荐系统只给她推荐裙子,因为推荐系统放大了她对裙子的偏好,从而忽略了她对鞋子的偏好。这可能给佩琪带来不好的使用体验。
在这里插入图片描述
换句话说,推荐系统的这种偏好放大现象将逐渐缩小用户的兴趣范围,类似于回声室效应。这对于推荐系统中的各个利益相关者都是不利的:
对于用户来说会让他们看到的东西越来越单一,丧失了多元化,让用户看不到本来想要的东西或者未来会感兴趣的东西。
对于物品方而言,部分类别的物品,特别是小众的物品,可能很少会有展示的机会。
对于推荐平台,就意味着这款APP让用户觉得乏味,没有用户粘度,从而造成用户流失。

为什么会出现偏好放大现象

  1. 从类别不平衡的分类问题角度来看。在类别不平衡的分类问题中,如果我们没有其他可用的信息,那么将结果全部预测为最多的那一类就可以得到最高的准确率。对于推荐来说,继续用上面的例子,如果我们没有别的可用信息,只知道佩琪购买的物品中75%都是裙子,那么我们只推荐裙子给她就可以得到最好的准确率。

  2. 从模型训练的角度来看。以BPR训练为例,在训练过程中为每个用户采样正样本时,数量占比多的类别被采样到的概率更大,所以训练时这种偏差就刻入模型中了,但这本不是错,相反这恰恰是个性化推荐所需要的,但错在往往得到的推荐结果会过分放大这种偏差,而没有维持住原有的比例。

校准化推荐(calibrated recommendations)

由于推荐系统存在的偏好放大现象,我们需要让推荐系统的结果更加符合用户的原始偏好,校准化推荐应运而生。用论文1中的例子:假设在某个用户的观影记录中,有70部爱情类电影和30部动作类电影,那么在推荐列表中的爱情类电影应该占70%,同时动作类电影应该占30%,这样就与用户的偏好相符。我们把推荐列表的这种特性称为校准(calibration)。

规范化描述,校准推荐的目标是让推荐列表按照合适的比例反映用户的兴趣偏好。

校准(calibration)与多样性(diversity)

典型的多样性的优化目标是最小化推荐列表中各物品间的相似度,用上面的例子来说,一个多样性的推荐列表只需要保证同时有爱情类电影和动作类电影就好了,当然如果有其他类别的电影,也应该加入到列表中,而且最好每种类别数量相等。

但calibration强调的是推荐列表中的各类别的电影要满足一定的比例,即尽可能地吻合用户的兴趣偏好。但却不具备多样性那样可以发现用户潜在兴趣类别的性质。

如何度量校准(calibration metrics)

  1. 为了评估我们的推荐结果和用户原始的兴趣偏好间的差异,我们可以假设用户历史记录中类别的分布为,推荐列表中类别分布为,那么可以计算两个分布间的f-散度(f-divergence)来量化它们间差异,值越小说明分布越接近,calibration就做得越好。
    如上面与多样性的对比时所述,如果我们想要让推荐结果的类型不那么死板,希望稍微地引入一些其他类别,以发现用户的潜在兴趣,我们可以让没出现在用户历史中的类别所对应的不为零。

  2. 我更偏爱论文2采用的指标:bias disparity。其同样是通过计算输入数据中的偏好与系统输出中的偏好间的差异(公式具体见论文2)。它既可以用来计算推荐系统对所有用户的偏好放大情况,也可以分别推荐系统对计算不同组(如男性和女性)的用户的偏好放大情况,且计算简便。

如何实现校准

在训练的时候,很难将calibration加入优化目标,所以实做上大多采用简单地重排序(re-rank),即先从推荐系统中得到以准确率为优化目标的推荐结果,再利用前面提到的度量指标,通过重排序来权衡准确率和calibration。

文献链接

  1. 《Calibrated Recommendations》
  2. 《Crank up the volume: preference bias amplification in collaborative recommendation》

希望我的文章可以给你们的工作或者学习带来一丝灵感,共勉~

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据您的要求,我将用Python代码实现Harald Steck在2018年发表的论文《Calibrated Recommendations》中的校准推荐算法。该算法通过对推荐系统进行校准,可以提高推荐的准确性和可靠性。 首先,需要安装必要的Python包,包括numpy、pandas、scipy和sklearn。可以使用以下命令进行安装: ``` !pip install numpy pandas scipy sklearn ``` 然后,我们需要加载数据集并进行预处理。在这里,我将使用MovieLens数据集,并将其划分为训练集和测试集。以下是数据加载和预处理的代码: ``` python import pandas as pd import numpy as np from sklearn.model_selection import train_test_split # 加载数据集 ratings = pd.read_csv('ratings.csv') movies = pd.read_csv('movies.csv') # 将电影id转换为连续的整数值 movies['movieId'] = movies['movieId'].apply(lambda x: int(x)) # 将电影标题与电影id对应起来 movie_to_idx = { movie: i for i, movie in enumerate(list(movies.set_index('movieId').loc[ratings['movieId']]['title'])) } # 将用户id与电影id映射到整数值 user_to_idx = { user: i for i, user in enumerate(list(ratings.set_index('userId').index.unique())) } # 将电影标题和用户id转换为整数值 ratings['movie_idx'] = ratings['movieId'].apply(lambda x: movie_to_idx[movies[movies['movieId']==x]['title'].iloc[0]]) ratings['user_idx'] = ratings['userId'].apply(lambda x: user_to_idx[x]) # 划分训练集和测试集 train_ratings, test_ratings = train_test_split(ratings, test_size=0.2, random_state=42) ``` 接下来,我们需要实现校准推荐算法。以下是算法的代码: ``` python from scipy.sparse import csr_matrix from sklearn.metrics import pairwise_distances # 创建用户-电影矩阵 train_matrix = csr_matrix( (train_ratings['rating'], (train_ratings['user_idx'], train_ratings['movie_idx'])) ) # 计算用户之间的相似性 user_similarity = pairwise_distances(train_matrix, metric='cosine') # 预测每个用户对每个电影的评分 def predict(user_idx, movie_idx): similarity_sum = np.sum(user_similarity[user_idx]) if similarity_sum == 0: return 0 weighted_sum = np.sum(user_similarity[user_idx] * train_matrix[:, movie_idx].toarray().T) return weighted_sum / similarity_sum # 对测试集中的每个用户-电影对进行预测 test_ratings['predicted_rating'] = test_ratings.apply(lambda x: predict(x['user_idx'], x['movie_idx']), axis=1) ``` 最后,我们可以使用均方根误差(RMSE)评估推荐结果的准确性。以下是计算RMSE的代码: ``` python from sklearn.metrics import mean_squared_error # 计算RMSE rmse = np.sqrt(mean_squared_error(test_ratings['

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值