[译] 第四天: PredictionIO - 怎样创建博客推荐引擎

前言

这是我30天学习30种技术挑战的第四天,到目前为止,我很享受这项挑战,也从程序员同行那里得到很好的反响。我会十分积极的去完成这30天的挑战。在这篇博客里,我会讲到怎样用PredictionIO来轻松创建博客推荐引擎。我没有找到太多关于Java使用PredictionIO的文档。所以,通过这篇博客,也许对要找PredictionIO Java端到端指导文档的人有用。完整的博客系列可以从这里看到。

什么是PredictionIO?

PredictionIO 是一个开源的机器学习服务器,用Scale语言开发。它提供了简单的方式使用REST API来创建推荐引擎,也提供客户端SDK,包含REST
API.
客户端SDKJava, Python, PHP都适用。PredictionIO核心使用Apache Mahout.Apache
Mahout
是一个可扩展的机器学习应用,提供各种聚类,分类,过滤算法,可以在分布式的Hapoop集群上运行这些算法。
 

作为用户,我们不用担心那些细节,只需安装PredictionIO来开始使用。想了解更多信息可以点击介绍

我为什么关注PredictionIO?

PredictionIO是因为我想使用能帮我添加机器学习能力的库。 PredictionIO有助于实现一些功能如为用户推荐有趣服务,发掘相似内容。

安装PredictionIO

在介绍里面有多种安装方式。我用的是Vagrant方式,避免让我弄坏机器环境,也不用自己去安装每一步。

  1. 下载最新的vagrant包,你可以从这里下载。
  2. 下载并安装VirtualBox, 参考 https://www.virtualbox.org/wiki/Downloads.
  3. 下载最新的PredictionIO      vagrant包,地址https://github.com/PredictionIO/PredictionIO-Vagrant/releases.
  4. 解压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"

 

  1. 现在就等vagrant 自己安装,所花时间由你的网速而定。
  2. 接下来创建管理员账号,参考http://docs.prediction.io/current/installation/install-predictionio-with-virtualbox-vagrant.html#create-an-administrator-account.
  3. 服务程序会运行在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>

从以上代码可以注意到MavenPredictionIO 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");
 
    }
 
}

这个类做了以下几点:

  1. 创建客户端实例。客户端类覆盖了PredictionIO REST      API. 我们需要提供PredictionIO博客推荐程序的API_KEY
  2. 接着我们用客户端实例创建了两个账号,这些账号在PredictionIO程序里,必填项只有 userId.
  3. 然后用客户端实例添加了10篇博客,这些博客也在PredictionIO程序里。创建的时候你只需传itemIditemType. itemId blog1,…blog10, itemTypejavascript,scala等。
  1. 然后我们对其进行了些操作,"shekhar"用户浏览了"blog1","blog2""blog4",      "rahul"用户浏览了"blog1","blog4", "blog6" ,           "blog7".
  2. 最后,关掉客户端。

 

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

posted on 2013-12-13 17:50  百花宫  阅读(2091)  评论(0编辑  收藏  举报