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

apache 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 preferencesval 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),但是代码示例大部分有效,并且项目的主要逻辑是相同的。

参考:在Adam Warski博客的Blog中 ,我们的JCG合作伙伴 Adam Warski 使用Apache Mahout创建了一个在线推荐系统 。

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

apache mahout

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346310.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java应用程序的简单令牌认证

“我喜欢编写身份验证和授权代码。” 〜从来没有Web开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。 JSON Web令牌已Swift成为保护Web应用程序安全的标准,并取代了Cookie和会话…

matlab中rb代表什么意思,你知道“川藏线上”女游客举着“求RB”的牌子是啥意思吗?暗语啊!...

现在穷游好像一种旅行圈的时髦,很多人都想着穷游能够锻炼人的意志,能够促进人与人的交流与合作,能够在路上遇到不一样的精彩,能够发现人性与真善美。现在穷游的人不在少数,尤其是在川藏线上,想要穷游入藏的…

华为主题锁屏壁纸换不掉_华为手机总多出莫名的照片?那是因为这3个设置没关闭,赶紧自查...

随着华为在科技、5G以及数码领域的表现越来越好,使用华为手机的人也越来越多。不知道你在使用华为手机的过程中,有没有这样的感觉,华为手机总是多出莫名其妙的照片,即使删除了下次还会出现。如果有这样的情况,可能是手…

php nginx 域名重定向,Nginx默认虚拟主机、用户认证、域名重定向

Nginx默认虚拟主机定义默认虚拟主机配置文件,在http下面加入include vhost/*.conf在/usr/local/nginx/conf/下创建目录#mkdir vhost/ //创建vhost目录#cd vhost/ //进入目录#vim aaa.com.conf //编辑文件server{listen 80 default_server; // 有这个标记的就是默认虚拟主机serv…

Java:使用SingletonStream获得性能

仅具有一个元素的Java流有时会在应用程序中造成不必要的开销。 了解如何使用SingletonStream对象并为其中某些此类流获得十倍的性能,并了解如何同时简化代码。 背景 Java 8中的Stream库是有史以来Java语言最强大的功能之一。 一旦您开始了解它的多功能性和所产生的…

php调用pdf2html,php html2pdf

*安装composer运行html2pdf时,readme里面建议按照composer-setup.exe安装过程中出现openssl的问题,在php.ini中开启相应extension即可,路径写绝对路径,否则按默认路径找不到在html2pdf的文件路径下,cmd运行composer in…

JDK 11:新的默认收集方法toArray(IntFunction)

“ JDK 11 Early-Access发行说明 ”表明JDK 11的Early Access Build 20在Collection接口上包括一个新的默认方法 ,该方法 “允许将集合的元素转移到所需运行时类型的新创建的数组中”。 这个新的默认方法 [ Collection.toArray(IntFunction) …

获取清空textarea的文字内容_运用|你会做 词云图(文字云) 吗?

词云图,也叫文字云,是对文本中出现频率较高的“关键词”予以视觉化的展现,词云图过滤掉大量的低频低质的文本信息,使得浏览者只要一眼扫过文本就可领略文本的主旨。今天,兰色就分享一下词云图的做法。制作步骤:1、打开词云图网站打开网页https://wordart…

如何在Spring Boot App中集成H2数据库

你好朋友, 在本教程中,我们将尝试探索如何在Spring Boot应用程序中与H2数据库集成。 在进行检查之前,让我们了解有关H2数据库的一些基础知识,如下所述,然后我们将讨论H2数据库与Spring Boot的集成。 什么是H2数据库…

python在路径里添加变量_想学Python?那就先从头开始吧!

作为人工智能和大数据时代最具竞争力的 Python 语言,越来越多的出现在各大编程热搜排行榜上。首先你要了解什么是python了解Python语言Python是一种解释型, 面向对象, 动态数据类型的高级程序设计语言.Python由Guido van Rossum(荷兰) 于1989…

ant 走马灯面板指示显示不出来_触摸屏报警信息显示设置方法

人机界面(HMI)是自动化设备中非常常用的器件,用于替代操作面板上的实体按钮或者显示指示。人机界面的适用极大的减小了设备操作面板的尺寸,提升了设备的整体美观度。随着自动化设备的自动化程度的提高,也对设备的报警信息提出了更高的要求。如…

oracle bbed 使用,Oracle BBED使用 四步快速启动Oracle BBED

Oracle BBED使用,四步快速启动Oracle BBED,环境:Oracle 10g RHEL 5.8,介绍:BBED全称为数据块浏览和编辑。用于对Oracle blo环境:Oracle 10g RHEL 5.8介绍:BBED全称为数据块浏览和编辑。用于对Or…

linux内核4.4和4.5,[图]Linux Kernel 4.5系列第4个维护版本发布

Greg Kroah-Hartman表示:“我今天宣布了Linux 4.5.4内核,所有Linux 4.5内核系列用户必须尽快升级。已经升级的4.5.y git tree能够在git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-4.5.y中获取,也能通过访问h…

域名是如何被墙的_如何快速搭建属于自己的个性网站?

说明一直以来都是用GithubPage搭建的博客,因为服务器在国外,访问速度一直比较慢,再后来有一批服务器被墙掉了导致国内网络环境直接无法访问。这里可以多说一句,GithubPage跟Github用的可以不是同一IP地址服务器,被墙很…

python 对象锁_也许你对 Python GIL 锁的理解是 错的。

摄影:产品经理甜白与草莓更配~我刚到现在这个公司时,听到当时一个高级工程师(现已离职)大声地跟他旁边的同事说:Python 有 GIL 锁,所以它的多线程实际上是单线程,所以写多线程代码不用考虑线程冲突,不用加…

服务性服务–服务到服务的通话

在上一篇文章中,我介绍了如何使用Knative的 Serving功能来运行示例Java应用程序。 这篇文章将介绍部署两个应用程序的步骤,其中一个应用程序调用另一个。 样品细节 整个示例可在我的github存储库中找到– https://github.com/bijukunjummen/sleuth-webf…

linux cookie 地址,SYN Cookie原理及其在Linux内核中的实现

在目前以IPv4为支撑的网络协议上搭建的网络环境中,SYN Flood是一种非常危险而常见的DoS攻击方式。到目前为止,能够有效防范SYN Flood攻击的手段并不多,而SYN Cookie就是其中最著名的一种。SYN Cookie原理由D. J. Bernstain和 Eric Schenk发明…

用置换破坏您的JUnit5测试

编写JUnit测试可能是一个乏味而乏味的过程。 了解如何使用排列结合TestFactory方法和DynamicTest对象以最少的编码工作来改进测试类。 在本文中,我将使用Java流ORM Speedment,因为它包含一个现成的Permutation类,从而帮助我节省了开发时间。…

企业应用程序开发框架的分类

如果您使用的是“最佳Java框架”,那么您很可能会迷失本文 ,它对Java Enterprise世界中的情况进行了很好的概述。 但是,从我的角度来看,它缺少一件非常重要的事情–对上述框架进行分类。 让我们看看这个生态系统的另一个角度&…

c语言中怎么定义的字符串,C语言中定义字符串的几种方式

1,什么是字符串?所谓字符串本质上就是以\0作为结尾的特殊字符数组;2,定义字符串的过程中有哪些注意点由于字符串本质上其实就是以\0作为结尾的特殊字符数组,所以定义字符串时,必须保证字符串存储的最后一个…