【问题标题】:Slope One implementations offers poor recommendations斜坡一实施提供了糟糕的建议
【发布时间】:2014-03-09 08:35:58
【问题描述】:

我正在尝试通过 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。

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

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 条建议),但我没有看到任何形式的相关性。事实上,大多数推荐对用户来说似乎是相同的,即使项目评分完全不同。

【问题讨论】:

    标签: php collaborative-filtering


    【解决方案1】:

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

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

    考虑当数据变得 100% 密集时会发生什么 - 每个用户对每个项目进行评分。项目 A 和项目 B 之间的评分差异是所有共同评分用户 u 的评分差异的平均值:average(r_uB - r_uA)。但随着所有用户的评分,这仅接近 B 的平均评分(所有用户)减去 A 的平均评分:平均(r_uB)-平均(r_uA)。轻松调用这些平均值(B)和平均值(A)。

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      您可以尝试Apache Mahout 中的Java implementation。 Mahout in Action 中有一个excerpt,其中涵盖了它的用法。这可能作为第二个数据点有用,有助于区分算法和实现问题。

      从 Mahout 0.9 开始,提醒功能已停止。看 https://mahout.apache.org/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-07-13
        • 2021-07-25
        • 2010-10-08
        • 1970-01-01
        • 2015-06-22
        • 2018-08-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多