[译] 第四天: PredictionIO - 怎样创建博客推荐引擎
前言
这是我30天学习30种技术挑战的第四天,到目前为止,我很享受这项挑战,也从程序员同行那里得到很好的反响。我会十分积极的去完成这30天的挑战。在这篇博客里,我会讲到怎样用PredictionIO来轻松创建博客推荐引擎。我没有找到太多关于Java使用PredictionIO的文档。所以,通过这篇博客,也许对要找PredictionIO Java端到端指导文档的人有用。完整的博客系列可以从这里看到。
什么是PredictionIO?
PredictionIO 是一个开源的机器学习服务器,用Scale语言开发。它提供了简单的方式使用REST API来创建推荐引擎,也提供客户端SDK,包含REST
API. 客户端SDK对Java, Python,
PHP都适用。PredictionIO核心使用Apache Mahout.Apache
Mahout是一个可扩展的机器学习应用,提供各种聚类,分类,过滤算法,可以在分布式的Hapoop集群上运行这些算法。
作为用户,我们不用担心那些细节,只需安装PredictionIO来开始使用。想了解更多信息可以点击介绍。
我为什么关注PredictionIO?
学PredictionIO是因为我想使用能帮我添加机器学习能力的库。 PredictionIO有助于实现一些功能如为用户推荐有趣服务,发掘相似内容。
安装PredictionIO
在介绍里面有多种安装方式。我用的是Vagrant方式,避免让我弄坏机器环境,也不用自己去安装每一步。
- 下载最新的vagrant包,你可以从这里下载。
- 下载并安装VirtualBox, 参考 https://www.virtualbox.org/wiki/Downloads.
- 下载最新的PredictionIO vagrant包,地址https://github.com/PredictionIO/PredictionIO-Vagrant/releases.
- 解压PredictionIO-x.x.x.zip, 包里包含安装PredictionIO所需要的脚本,打开命令器,设置路径到PredictionIO-x.x.x.
Vagrant脚本首先会下载Ubuntu Vagrant Box, 然后安装所需的 MongoDB, Java, Hadoop, 和PredictionIO服务器。可能会花挺长时间,视你的连接而定。如果你的网络连接不稳定,建议你用wget下载Ubuntu, wget 支持断点下载。下载precise64.
wget -c http://files.vagrantup.com/precise64.box
下载完成后,打开Vagrantfile, 更改config.vm.box_url, 指向precise64.box的下载路径。
config.vm.box_url = "/Users/shekhargulati/tools/vagrant/precise64.box"
- 现在就等vagrant 自己安装,所花时间由你的网速而定。
- 接下来创建管理员账号,参考http://docs.prediction.io/current/installation/install-predictionio-with-virtualbox-vagrant.html#create-an-administrator-account.
- 服务程序会运行在http://localhost:9000. 更多了解请看 http://docs.prediction.io/current/installation/install-predictionio-with-virtualbox-vagrant.html#accessing-predictionio-server-vm-from-the-host-machine. 程序会要求你登录,登录后可以看到如下显示
创建PredictionIO程序
我们即将开始创建博客推荐程序,点击 Add an App 按钮,输入 blog-recommender.
创建好后你可以在Applications下看到如下显示。
然后点击 Develop, 你可以看到详细的程序信息,这里的关键信息 App Key, 这是我们写这个程序必需的。
程序用例
我们这里使用的用例类似于亚马逊的功能“买了这个的用户同时也买了这些”。我们显示的是浏览了这篇博客的读者还浏览了这些博客。
用Java开发博客推荐程序
我们已经创建了PredictionIO,该写Java程序了,用Eclipse来开发。我用的是Eclipse Kepler,集成了m2eclipse. 通过导航File>New>Maven新建一个Maven项目。选maven-archetype-quickstart然后选择Maven的详细信息。用一下内容替代pom.xml文件。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelversion> <groupId>com.shekhar</groupid> <artifactId>blog-recommender</artifactid> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>blog-recommender</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceencoding> </properties> <dependencies> <dependency> <groupId>io.prediction</groupid> <artifactId>client</artifactid> <version>0.6.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupid> <artifactId>maven-compiler-plugin</artifactid> <version>3.1</version> <configuration> <!-- http://maven.apache.org/plugins/maven-compiler-plugin/ --> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>
从以上代码可以注意到Maven和PredictionIO Java API的依赖。
现在写插入数据到PredictionIO的类,代码如下:
package com.shekhar.blog_recommender; import io.prediction.Client; import io.prediction.CreateItemRequestBuilder; public class BlogDataInserter { private static final String API_KEY = "wwoTLn0FR7vH6k51Op8KbU1z4tqeFGZyvBpSgafOaSSe40WqdMf90lEncOA0SB13"; public static void main(String[] args) throws Exception { Client client = new Client(API_KEY); addUsers(client); addBlogs(client); userItemViews(client); client.close(); } private static void addUsers(Client client) throws Exception { String[] users = { "shekhar", "rahul"}; for (String user : users) { System.out.println("Added User " + user); client.createUser(user); } } private static void addBlogs(Client client) throws Exception { CreateItemRequestBuilder blog1 = client.getCreateItemRequestBuilder("blog1", new String[]{"machine-learning"}); client.createItem(blog1); CreateItemRequestBuilder blog2 = client.getCreateItemRequestBuilder("blog2", new String[]{"javascript"}); client.createItem(blog2); CreateItemRequestBuilder blog3 = client.getCreateItemRequestBuilder("blog3", new String[]{"scala"}); client.createItem(blog3); CreateItemRequestBuilder blog4 = client.getCreateItemRequestBuilder("blog4", new String[]{"artificial-intelligence"}); client.createItem(blog4); CreateItemRequestBuilder blog5 = client.getCreateItemRequestBuilder("blog5", new String[]{"statistics"}); client.createItem(blog5); CreateItemRequestBuilder blog6 = client.getCreateItemRequestBuilder("blog6", new String[]{"python"}); client.createItem(blog6); CreateItemRequestBuilder blog7 = client.getCreateItemRequestBuilder("blog7", new String[]{"web-development"}); client.createItem(blog7); CreateItemRequestBuilder blog8 = client.getCreateItemRequestBuilder("blog8", new String[]{"security"}); client.createItem(blog8); CreateItemRequestBuilder blog9 = client.getCreateItemRequestBuilder("blog9", new String[]{"ruby"}); client.createItem(blog9); CreateItemRequestBuilder blog10 = client.getCreateItemRequestBuilder("blog10", new String[]{"openshift"}); client.createItem(blog10); } private static void userItemViews(Client client) throws Exception { client.identify("shekhar"); client.userActionItem("view","blog1"); client.userActionItem("view","blog4"); client.userActionItem("view","blog5"); client.identify("rahul"); client.userActionItem("view","blog1"); client.userActionItem("view","blog4"); client.userActionItem("view","blog6"); client.userActionItem("view","blog7"); } }
这个类做了以下几点:
- 创建客户端实例。客户端类覆盖了PredictionIO REST API. 我们需要提供PredictionIO博客推荐程序的API_KEY。
- 接着我们用客户端实例创建了两个账号,这些账号在PredictionIO程序里,必填项只有 userId.
- 然后用客户端实例添加了10篇博客,这些博客也在PredictionIO程序里。创建的时候你只需传itemId和itemType. itemId指 blog1,…blog10, itemType指javascript,scala等。
- 然后我们对其进行了些操作,"shekhar"用户浏览了"blog1","blog2"和"blog4", "rahul"用户浏览了"blog1","blog4", "blog6" , 和 "blog7".
- 最后,关掉客户端。
用Java运行这个类,它会在PredictionIO程序里插入数据,你可以通过页面看到记录。
现在数据已经插入到PredictionIO程序,我们需要添加引擎到我们的程序,点击 Add an Engine按钮,选择如下Item Similarity Engine.
然后输入名字如"engine1" 创建Item Similarity Engine
点击Create按钮后,你就有了类似项引擎,现在你可以修改配置了,不过我们这里使用的时候默认设置。到Algorithms页面下,看到引擎没有启动,点击"Train Data Model Now"来启动。
等几分钟,数据模型启动后你可以看到状态显示Running.
这个用例我们解决的是根据读者浏览的博客,然后推荐博客。通过以下代码,我们可以得到所有和用户"shekhar"读过的blog1相似的博客。
import io.prediction.Client; import java.util.Arrays; public class BlogrRecommender { public static void main(String[] args) throws Exception { Client client = new Client("wwoTLn0FR7vH6k51Op8KbU1z4tqeFGZyvBpSgafOaSSe40WqdMf90lEncOA0SB13"); client.identify("shekhar"); String[] recommendedItems = client.getItemSimTopN("engine1", "blog1", 5); System.out.println(String.format("User %s is recommended %s", "shekhar", Arrays.toString(recommendedItems))); client.close(); } }
运行Java你可以看到显示结果"blog4","blog5","blog6",和"blog7".
从以上示例可以看出,给程序添加推荐功能很简单,我会在以后的项目中用到它,再多花些时间研究。
这是今天的内容,留下你的建议和意见吧!
原文:https://www.openshift.com/blogs/day-4-predictionio-how-to-build-a-blog-recommender