mahout_使用Apache Mahout创建在线推荐系统

mahout

mahout

最近,我们一直在为Yap.TV实施推荐系统:您可以在安装应用程序并转到“ Just for you”标签后才能看到它的运行情况。 我们以Apache Mahout为基础进行建议。 Mahout是一个“可扩展的机器学习库”,包含使用协作过滤算法的基于用户和项目的推荐者的本地和分布式实现。

屏幕568x568

现在,我们将专注于本地单机实施。 如果您拥有多达数千万的首选项值,它应该会很好地工作。 除此之外,您可能应该考虑基于Hadoop实现,因为数据根本无法放入内存中。

用Mahout编写基本的推荐器非常简单; 由于Mahout具有很高的可配置性,因此通常可以选择不同的实现方式。 我只描述我认为是“好的起点”。

基本

首先,您需要一个包含输入数据的文件。 格式非常简单:以逗号分隔的(用户ID,商品ID)对或(用户ID,商品ID,偏好值)三倍。 这表示您已经知道:哪些用户喜欢哪些项目,以及可选多少(例如1-5比例)。 id必须是整数,首选项值被视为浮点型。

让我们首先创建一个基于用户的推荐器:这是一个推荐器,当被问到对用户A的推荐时,它首先查找与“ A”相似的用户,然后尝试查找这些相似的用户已对其评分的最佳商品,但A还没有。 为此,我们需要创建4个组件:

  • 数据模型:这将使用文件
  • 用户相似度:给定两个用户的度量,将返回一个数字,表示他们的相似度
  • 邻域:用于查找给定用户的邻域
  • 推荐器:将这些片段组合在一起以产生推荐

对于一元输入数据(用户喜欢项目或我们不知道的数据),一个好的起点是:

val dataModel = new FileDataModel(file)
val userSimilarity = new LogLikelihoodSimilarity(dataModel)
val neighborhood = new NearestNUserNeighborhood(25, userSimilarity, dataModel)
val recommender = new GenericBooleanPrefUserBasedRecommender(dataModel, neighborhood, userSimilarity)

如果我们有偏好值(输入数据中的三倍):

val dataModel = new FileDataModel(file)
val userSimilarity = new PearsonCorrelationSimilarity(dataModel)
val neighborhood = new NearestNUserNeighborhood(25, userSimilarity, dataModel)
val recommender = new GenericUserBasedRecommender(dataModel, neighborhood, userSimilarity)

现在我们准备得到一些建议; 这很简单:

// Gets 10 recommendations
val result = recommender.recommend(userId, 10)

// We get back a list of item-estimated preference value, 
// sorted from the highest score
result.foreach(r => println(r.getItemID() + ": " + r.getValue()))

线上

在线方面呢? 以上内容对现有用户非常有用; 在服务中注册的新用户呢? 当然,我们也想为他们提供一些合理的建议。 创建推荐器实例非常昂贵(肯定会比“正常”网络请求花费更长的时间),因此我们不能每次都创建一个新的推荐器。

幸运的是Mahout可以将临时用户添加到数据模型中。 常规设置如下:

  • 使用当前数据定期重新创建整个推荐器(例如每天或每小时-取决于需要多长时间)
  • 进行推荐时,请检查用户是否存在于系统中
  • 如果是,请像往常一样做建议
  • 如果不是,请创建一个临时用户,填写首选项,然后进行建议

如果内存有限,第一部分(定期重新创建推荐器)实际上可能会非常棘手:创建新推荐器时,您需要在内存中保存两个数据副本(以便仍然能够处理来自服务器的请求老)。 但这与建议实际上没有任何关系,因此在这里我将不做详细介绍。

对于临时用户,我们可以使用PlusAnonymousConcurrentUserDataModel实例包装数据模型。 此类允许获取临时用户ID。 该ID必须稍后释放,以便可以重复使用(此类ID的数量有限)。 获取ID后,我们必须填写首选项,然后我们可以像往常一样继续进行推荐:

val dataModel = new PlusAnonymousConcurrentUserDataModel(
    new FileDataModel(file),
    100)

val recommender: org.apache.mahout.cf.taste.recommender.Recommender = ...

// we are assuming a unary model: we only know which items a user likes
def recommendFor(userId: Long, userPreferences: List[Long]) = {
  if (userExistsInDataModel(userId)) {
    recommendForExistingUser(userId)
  } else {
    recommendForNewUser(userPreferences)
  }
}

def recommendForNewUser(userPreferences: List[Long]) = {
  val tempUserId = dataModel.takeAvailableUser()

  try {
    // filling in a Mahout data structure with the user's preferences
    val tempPrefs = new BooleanUserPreferenceArray(userPreferences.size)
    tempPrefs.setUserID(0, tempUserId)
    userPreferences.zipWithIndex.foreach { case (preference, idx) => 
      tempPrefs.setItemID(idx, preference) 
    }
    dataModel.setTempPrefs(tempPrefs, tempUserId)

    recommendForExistingUser(tempUserId)
  } finally {
    dataModel.releaseUser(tempUserId)
  }
}

def recommendForExistingUser(userId: Long) = {
  recommender.recommend(userId, 10)
}

整合业务逻辑

由于某些业务规则,我们常常想提高所选项目的得分。 在我们的用例中,例如,如果某个节目有新剧集,我们希望给它更高的分数。 使用Mahout的IDRescorer接口可以实现。 调用Recommender.recommend时,提供了一个rescorer实例。 例如:

val rescorer = new IDRescorer {
  def rescore(id: Long, originalScore: Double) = {
    if (showIsNew(id)) {
      originalScore * 1.2 
    } else {
      originalScore
    }
  }

  def isFiltered(id: Long) = false
}

// Gets 10 recommendations
val result = recommender.recommend(userId, 10, rescorer)

概要

Mahout是创建推荐器的重要基础。 它是非常可配置的,并提供许多扩展点。 选择正确的配置参数值,设置评分和评估推荐结果还有很多工作要做,但是算法是可靠的,因此无需担心。

还有一本非常好的书,《 Mahout in Action》 ,其中涵盖了推荐系统和Mahout的其他组件。 它基于版本0.5(当前版本为0.8),但是代码示例大部分都可以工作,并且项目的主要逻辑是相同的。

翻译自: https://www.javacodegeeks.com/2013/10/creating-an-on-line-recommender-system-with-apache-mahout.html

mahout

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值