我目前使用Mahout的内存推荐API实现了一个推荐器。然而,我希望迁移到使用Hadoop的分布式解决方案,以便计算离线推荐。这是我的第一次使用Hadoop,我希望能在一些概念和API使用上得到澄清。
目前,我对Hadoop的理解非常有限,我认为正确的做法如下:
-
使用类似Apache Drill的工具将用户和商品数据填充到HDFS中。
-
使用Mahout中的推荐作业在HDFS中的数据上进行训练。
-
将HDFS中的结果数据转换为索引分片,供Solr使用。
-
使用Solr向用户提供推荐结果。
然而,我希望在设计的几个方面得到澄清:
-
如何像在内存实时推荐中那样使用重新评分器?
-
调用推荐作业的最佳方式是什么?
除了这两个问题外,我还有其他问题,但这两个问题的答案将非常有帮助。
回答:
您可能在讨论Mahout + Hadoop + Solr的推荐器。这种方法以几种不同的方式处理重新评分。
基本的推荐器可以以两种方式组装:
- 将数据以(用户ID,商品ID,偏好权重)的形式导入HDFS后,在数据上运行ItemSimilarityJob(通常使用LLR相似度,这是最佳选择)。它将创建一个称为指示矩阵的东西。这将是一个商品ID与商品ID的稀疏矩阵,值表示任意两个商品之间的相似度大小。然后,您必须将其转换为Solr可以索引的值。这意味着将Mahout内部的整数ID转换为某种唯一的字符串表示,这可能是它们最初的形式。这将看起来像(item123,item223 item643 item293 item445…)作为CSV。因此有两个Solr字段,第一个是商品ID,第二个是相似商品列表。所有ID必须是文本标记。然后,推荐查询是由特定用户显示偏好的商品ID组成的Solr查询。所以查询 = “item223 item344 item445…”。对包含指示矩阵值的字段进行查询。您将得到一个有序的商品ID列表
- 一个更简单的方法,可能会适合您,就是使用Mahout 1.0-SNAPSHOT的/examples文件夹中的工具,或者这里:https://github.com/pferrel/solr-recommender。它接受带有用户和商品ID的唯一字符串的原始日志文件。它在Hadoop上完成所有工作,输出可以直接由Solr索引的CSV,或者如上所述加载到数据库中。
我制作演示网站(https://guide.finderbots.com)的方式是使用我的Solr Web应用集成,将指示矩阵放入数据库,将相似商品列表附加到我的商品集合中。所以item123在其指示字段中获得了item223 item643 item293 item445…。在您索引集合后,查询就是 = “item223 item344 item445…” — 用户的偏好商品。
以下是三种重新评分的方式:
- 在查询中混合元数据。所以您可以对指示字段进行查询 = “item223 item344 item445…” 并且对“genre”字段进行查询 = “SciFi”。这为您提供了混合的协同过滤和元数据在您的查询中,正如您所想象的,推荐结果基于用户的偏好但倾向于“SciFi”。一旦您将商品+指示器+元数据放入索引中,您可以做很多其他有趣的事情。
- 通过元数据过滤推荐结果。如果您愿意,您可以得到未经偏斜但经过过滤的推荐结果。使用Solr查询 = “item223 item344 item445…” 对指示字段进行查询,并且使用“SciFi”作为“genre”字段的过滤器。在这种情况下,您只会得到“SciFi”,而#1您会得到大部分“SciFi”。
- 获取您的有序推荐列表,并根据您对用户、上下文或商品的其他了解,以任何您喜欢的方式重新评分。通常这些可以编码成Solr查询,并通过一个查询完成,但重新排序和过滤也可以在推荐结果返回后进行。您需要编写这些代码,它不是内置的。
有趣的是,您可以混合使用过滤器、元数据字段和用户偏好,以及Solr称为“boost”的值来获得各种重新评分方式。Solr甚至可以使用位置来查询、偏斜或过滤。
注意:您不必担心Solr分片。Solr可以直接索引大多数数据库和HDFS,但只有索引是分片的。如果您有一个非常大的索引,您会分片它,如果您有大量的每秒查询(或为了故障转移),您会复制它。Solr查询通常非常快,所以我建议在您有一个功能系统后再考虑这个问题,因为这是一个配置问题,不应影响您的其他工作流程。