首页 文章

(穷人的)产品推荐实施

提问于
浏览
5

我正在尝试为网上商店 Build 一个穷人的推荐系统 . 我想要意识到那种亚马逊“买了这个项目的顾客也买了”的功能,我读了很多关于它的内容 . 我知道有Apache Mahout的事情,但我无法以这种方式调整服务器 . 然后会有谷歌预测API,但它需要花钱,所以我开始尝试自己 .

我得到了250.000项的orderhistory,我写了一个嵌套的MySQL查询来查找包含当前文章的订单,对其他订单项进行排名并对该表排序进行排序,因此我得到了一组其他人随当前订购的产品文章 .

问题是,查询可能需要10秒 - 所以这不能直接使用 . 我想到了一个缓存表,但这个查询在20分钟后停止(有60.000个产品和250.000个订购商品)所以我无法填写该表 .

我目前的解决方法如下:推荐HTML通过AJAX ondocumentready加载,因此网站加载,而推荐在后台加载 . 推荐数据处理一次并存储在filecache(PEAR简单缓存)中,以便下次加载更快 . 因此,如果有人访问该网站并存储一天或一周,则按需制作缓存 .

我问自己和你,这是一种可接受的方法,还是愚蠢无知?将缓存的数据存储在db或文件中是否更好(我考虑性能和并行命中) . 我的意思是,在最坏的情况下,我会以60.000缓存文件结束 .

我更喜欢带有所有数据的预先计算的表,但正如我所说,它需要很长时间,我不知道如何优化它 . (等到SQL Dude从假期回来^^)

感谢任何提示,意见 .

顺便说一句 . 这是查询:

SELECT c.ArtNr as artnr , count(c.ArtNr) as rank, s.ArtNr as parent_artnr
FROM (
SELECT a.ID_order, a.ArtNr
        FROM net_orderposition a
        WHERE a.ArtNr = 'TT-PV0005'
) s
JOIN net_orderposition c 
WHERE s.ID_order = c.ID_order AND s.ArtNr != c.ArtNr
GROUP BY c.ArtNr
ORDER BY rank DESC,c.Stamp DESC
LIMIT 10;

EDIT:

我想到了给定的答案,我认为它们与我最初的想法相似 . 上面的代码结果如下表所示:

ID,ParentID , ChildID  , Rank
1, TT-PV0005, TT-PV0040, 220
2, TT-PV0005, TT-PV0355, 135
3, TT-PV0005, TT-PV0450, 134
4, TT-PV0005, TT-PV0451, 89
5, TT-PV0005, RH-01V2  , 83
6, TT-PV0005, TT-PV0041, 83
7, TT-PV0005, TT-PV0353, 82
8, TT-PV0005, TT-PV0037, 80

ParentID是当前项目,ChildID是过去订购的项目以及ParentID,Rank是预计算孩子与当前项目一起订购的次数 . 现在我可以在每个新订单上更新或插入相关项目,如果它已经存在于DB中,则计算Rank . 我唯一担心的是,我会在一张非常大的 table 上结束 . 也许这应该不是问题,如果我每周离线预先计算一次?但后来我必须优化查询,因此每个项目不需要10秒 .

你怎么看?

3 回答

  • 0

    查看easyrec它具有您需要的功能并且是免费的 . 无需调整,您可以使用谷歌分析等演示实例 . 我认为使用这个免费使用Web服务然后自己编写整个逻辑会更容易 .

    在_6.89334_今天他们提到他们支持对easyrec的完全mahout支持,所以你可以使用easyrec . 你可以使用easyrec的免费web服务或在你的网络服务器上部署免费的WAR文件 .

  • 2

    要添加到@ GalacticCowboy的答案并填写您评论的位置,@ Mathus ......

    实现此目的的一个模式是创建一个表,如:

    RelatedItems
    RelatedItemsId
    purchasedItemId
    relatedItemId
    

    然后,当订单完成(或根据您的要求查看)时,您会将记录写入RelatedItems表,其中每个购买的商品都会获得一条记录,其中该ID是purchaseItemId . 然后所有其他项目将被写为relatedItemId .

    例如,如果我购买了第5,9,12和19项,我将有12条写入我的表的记录,如下所示:

    RelatedItemId, PurchasedItemId, RelatedItemId
    1, 5, 9
    2, 5, 12
    3, 5, 19
    4, 9, 5
    5, 9, 12
    6, 9, 19
    7, 12, 5
    8, 12, 9
    9, 12, 19
    10, 19, 5
    11, 19, 9
    12, 19, 12
    

    然后,您可以使用类似于GalacticCowboy的查询来获取通常与这些项目一起购买的前10个项目 .

    请注意,对于像这样的任务来说,这不是最有效的模式,它可以进行相当多的调整以减少冗余数据,但鉴于我们对您的系统和整体架构设计(以及似乎对一些SQL概念的不确定理解)我不打算深入研究它 .

  • 3

    每次订单时,都会在订单中的不同商品之间存储关系记录 . 然后做一些事情:

    SELECT ItemID, COUNT(RelatedItemID) AS RelatedItemCount
    FROM RelatedItems
    WHERE RelatedItemID = @viewingItemID
    GROUP BY ItemID
    ORDER BY RelatedItemCount DESC
    LIMIT 10
    

    你也可以使用隔夜流程或其他东西预先假定这个,并且有一个表格,其中只包含每个项目ID的前n个相关项目 .

相关问题