介绍基准预测思想在推荐里的应用
背景 接上文,KNN在推荐领域的应用 文章里介绍了KNN在推荐系统里如何预测评分。但是,在实际用户评论时,每个用户都有自己的评分体系,有的用户要求相对苛刻,五分制的评分里一般只给到一二分,有的用户相对“心慈手软”一般会给到四五分。同时,对于电影来说,有的电影本身自带光环,随上映时间等因素也会有偏差。如何减少上述问题给预测带来的负面影响,本文将着重阐述。
解决思路 无论是个体用户还是物品,评分普遍高于或低于平均值的差值,我们称为偏置(bias)。
所有电影的平均评分$\mu$(即全局平均评分)
每个用户评分与平均评分$\mu$的偏置值$b_u$
每部电影所接受的评分与平均评分$\mu$的偏置值$b_i$
那么,预测用户对电影的评分则是:
举例[1] :
比如我们想通过Baseline来预测用户A对电影“阿甘正传”的评分,那么首先计算出整个评分数据集的平均评分$\mu$是3.5分;而用户A是一个比较苛刻的用户,他的评分比较严格,普遍比平均评分低0.5分,即用户A的偏置值$b_i$是-0.5;而电影“阿甘正传”是一部比较热门而且备受好评的电影,它的评分普遍比平均评分要高1.2分,那么电影“阿甘正传”的偏置值$b_i$是+1.2,因此就可以预测出用户A对电影“阿甘正传”的评分为:$3.5+(-0.5)+1.2$,也就是4.2分。
由此而来,我们把预测某个用户对某个电影的评分,转变成求偏置参数$b_u$和$b_i$的最优解的线性回归问题。
代价函数是:
最优化问题是应用数学的重要研究领域,主要研究在给定约束的情况下如何寻求某个因素,使某一指标达到最优。
梯度下降解法 如果将代价函数是 $y=k(x+b)^2$,求当y的最小值时,x应该为多少。这个问题很简单,属于高中数学。但是问题在复杂一些,变成$y=k(x+z+b)^2$,x和z 与将会组成一个三维图形。如何找到最低点,可以采用一个逐步逼近的策略,即梯度下降。具体可以参见深入浅出—梯度下降法及其实现 。
推导过程 损失函数:
梯度下降参数更新原始公式:
损失函数偏导推导:
bu更新(因为alpha可以人为控制,所以2可以省略掉):
同理可得,梯度下降更新$b_i$:
代码说明 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import pandas as pdimport numpy as npdtype = [("userId" , np.int32), ("movieId" , np.int32), ("rating" , np.float32)] dataset = pd.read_csv("./data/ml-latest-small/ratings.csv" , usecols=range(3 ), dtype=dict(dtype)) print(dataset.head()) users_ratings = dataset.groupby("userId" ).agg([list]) print(users_ratings.head()) items_ratings = dataset.groupby("movieId" ).agg([list]) print(items_ratings.head()) global_mean = dataset['rating' ].mean() bu = dict(zip(users_ratings.index, np.zeros(len(users_ratings.index)))) bi = dict(zip(items_ratings.index, np.zeros(len(items_ratings.index)))) for i in range(10 ): print('iter%d' % i) for uid, iid, real_rating in dataset.itertuples(index=False ): error = real_rating - (global_mean + bu[uid] + bi[iid]) bu[uid] += 0.1 * (error - 0.1 * bu[uid]) bi[iid] += 0.1 * (error - 0.1 * bi[iid]) print(bu) print(bi) def predit (uid, iid) : predit_rating = global_mean + bu[uid] + bi[iid] return predit_rating print(predit(1 ,1 ))