php - Slope One 实现提供了糟糕的建议

标签 php collaborative-filtering

我正在尝试通过 PHP 实现 Slope One 算法以进行基于用户的项目推荐。为此,我使用了 OpenSlopeOne图书馆。我遇到的问题是生成的推荐与用户完全不相关。

目前我有两个表:user_ratings 和 slope_one。 user_ratings 表相当简单。它包含特定用户给出的每个项目评级(user_id、item_id 和 user_item_rating)。 slope_one 表遵循 OpenSlopeOne 的默认模式:item_id1、item_id2、times 和 rating。

slope_one 表是使用以下 SQL 过程填充的:

CREATE PROCEDURE `slope_one`()
begin                    
    DECLARE tmp_item_id int;
    DECLARE done int default 0;                    
    DECLARE mycursor CURSOR FOR select distinct item_id from user_ratings;
    DECLARE CONTINUE HANDLER FOR NOT FOUND set done=1;
    open mycursor;
    while (!done) do
        fetch mycursor into tmp_item_id;
        if (!done) then
            insert into slope_one (select a.item_id as item_id1,b.item_id as item_id2,count(*) as times, sum(a.rating-b.rating) as rating from user_ratings a, user_ratings b where a.item_id = tmp_item_id and b.item_id != a.item_id and a.user_id=b.user_id group by a.item_id,b.item_id);
        end if;
    END while;
    close mycursor;
end

为了获取给定用户最相关的推荐,我执行以下查询:

SELECT
    item.* 
FROM
    slope_one s,
    user_ratings u,
    item
WHERE 
    u.user_id = '{USER_ID}' AND 
    s.item_id1 = u.item_id AND 
    s.item_id2 != u.item_id AND
    item.id = s.item_id2
GROUP BY 
    s.item_id2 
ORDER BY
    SUM(u.rating * s.times - s.rating) / SUM(s.times) DESC
LIMIT 20

如前所述,这似乎不起作用。我正在处理一个相当大的数据集(超过 10,000 个建议),但我只是没有看到任何形式的相关性。事实上,大多数推荐对于用户来说似乎是相同的,即使项目评级完全不同。

最佳答案

(是的,我故意给出另一个答案。)

另一个答案是,所有这些算法都有优点和缺点,并且在某一天表现良好,但在其他时候表现不佳。但我前段时间对 slope-one 也有类似的观察,甚至从最初提出该实现的 Daniel Lemire 那里得到了一些评论。

考虑一下当数据变得 100% 密集时会发生什么——每个用户都对每个项目进行评分。项目 A 和项目 B 之间的评分差异是评分差异的所有共同评分用户 u 的平均值:average(r_uB - r_uA)。但是当所有用户评分时,这简单地接近 B 的平均评分(所有用户)减去 A 的平均评分:average(r_uB) - average(r_uA)。为方便起见,称它们为 average(B) 和 average(A)。

想象一下总体平均评分最高的项目 P。 A 和 P 之间的差异将大于 A 和任何其他 B 之间的差异;它是(平均值(P)-平均值(A))与(平均值(B)-平均值(A))。 P 的差异总是比任何其他 B 高(平均(P)- 平均(B))。

但是由于该算法通过将这些差异添加到用户的评分并对其进行平均来估计偏好,因此 P 始终成为所有用户的最高推荐。无论用户的评分如何,也无论差异如何,P 的总和(以及平均值)都是最大的。等等。

这就是数据变得密集时的趋势,我想您已经看到了这种影响的一些 echo 。这不是“错误”(毕竟 P 的评价很高!)但随着推荐变得非个性化,直觉上感觉不是最理想的。

Daniel Lemire 说,一些后续论文中描述的更好的方法是将数据模型分为“正面”和“负面”评级,并从两者构建独立模型。它避免了其中的一些问题并提供了更好的性能。

在 Apache Mahout 中实现的另一个变体是在估计的偏好计算中使用更好的权重。它可以选择对具有高标准差和低标准差的差异进行加权。这有利于对许多用户计算的差异。这是一个粗略的步骤,但很有帮助。

关于php - Slope One 实现提供了糟糕的建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4910887/

相关文章:

php - 如何从表中选择全部并跳过具有特定值的某些行

javascript - 如何在PHP中使用foreach只显示一次重复的数据?

R:从推荐实验室包中获取客户购买前 N 件商品的概率

php - 如何使用 php 将类 ='active' 添加到 html 菜单

php - 获取 mp4 文件标签

php - 如何在 laravel 中使用多个输入字段在 laravel 中实现搜索功能

machine-learning - 推荐系统 : Is it content-based filtering?

python - 在 Django 中捕获感兴趣的隐式信号

collaborative-filtering - 什么时候用user-user协同过滤,什么时候用Item-Item协同过滤?

推荐系统 - 将交易计数转换为星级评级