PredictionIO能做什么?

PredictionIO是一个开源的机器学习服务器,建立在最先进的开源堆栈之上,供开发人员和数据科学家为任何机器学习任务创建预测引擎。

  • 可以作为web服务提供实时的Restful API
  • 底层基于Apache Spark, MLlib, HBase, Elasticsearch等开源解决方案
  • 官方拥有丰富的模板库,包含电商商品推荐、产品评分、NLP等常见预测模型

PredictionIO的核心

PredictionIO 是由三个元件所组成:

  1. PredictionIO platform
  2. Event Server: 数据收集,可以是单条信息的api调用收集,也可以批量导入。
  3. Engine: 训练模型,并且将结果以 Restful API 提供查询。

PredictionIO的优势

  1. 学习成本低:让0基础搭建推荐系统成为可能,不需要懂java、scala、spark、Hbase等机器学习相关的技能,只需要按照官方文档搭建系统,所有的数据收集和数据查询都可以通过curl api的方式进行;
  2. 丰富的模板:PredictionIO官方收录了很多模板,有常见的电商推荐、产品评分、归类、回归、自然语言处理等
  3. 多模型支持:一个服务端可以跑多个训练模型
  4. 部署简单:官方文档里提供了常规安装和docker安装的详细步骤,傻瓜式
  5. 灵活性:除了使用官方模板外如果有开发能力可以开发自己的模板,使用scala或java都可以
  6. mac和linux都有很好的支持,暂不支持windows

安装

官方文档里提供了多种安装方式,这里推荐使用一键快速安装Quick Install或者Docker安装

1
$ bash -c "$(curl -s https://install.prediction.io/install.sh)"

当然也可以手动安装:

还有更方便的docker安装方式:

安装完以后将PredictionIO/bin目录配置到环境变量里,然后可以使用pio status来检查安装情况:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$ pio status

### Return:
[INFO] [Console$] Inspecting PredictionIO...
[INFO] [Console$] PredictionIO 0.9.6 is installed at ...
[INFO] [Console$] Inspecting Apache Spark...
[INFO] [Console$] Apache Spark is installed at ...
[INFO] [Console$] Apache Spark 1.6.0 detected ...
[INFO] [Console$] Inspecting storage backend connections...
[INFO] [Storage$] Verifying Meta Data Backend (Source: MYSQL)...
[INFO] [Storage$] Verifying Model Data Backend (Source: MYSQL)...
[INFO] [Storage$] Verifying Event Data Backend (Source: MYSQL)...
[INFO] [Storage$] Test writing to Event Store (App Id 0)...
[INFO] [Console$] (sleeping 5 seconds for all messages to show up...)
[INFO] [Console$] Your system is all ready to go.

这里需要注意,如果是docker安装的话可执行文件位于PredictionIO/docker/bin目录下,命令也是对应的 pio-docker status

使用

1. 启动

先执行 PredictionIO 主程式,针对不同的储存器,有不同的执行方法:

1
2
3
4
5
6
7
$ pio eventserver &
# If you are using PostgreSQL or MySQL, run the following to start PredictionIO Event Server

or

$ pio-start-all
# If instead you are running HBase and Elasticsearch, run the following to start all PredictionIO Event Server, HBase, and Elasticsearch

如果是docker安装的话:

1
2
3
4
5
6
docker-compose -f docker-compose.yml \
    -f pgsql/docker-compose.base.yml \
    -f pgsql/docker-compose.meta.yml \
    -f pgsql/docker-compose.event.yml \
    -f pgsql/docker-compose.model.yml \
    up

2. 选择合适的引擎模板

可以从官方的 Engine Template Gallery 选择适合自己业务场景的模板,官方提供了Recommenders、Classification、Regression、NLP、Clustering、Similarity等不同使用场景的模板,这里我们以E-Commerce Recommendation 模板为例简单介绍下如何使用。

模板中收集数据事件包含:

  • Users’ view events 用户浏览事件
  • Users’ buy events 用户购买事件
  • Items’ with categories properties 商品分类
  • Constraint unavailableItems set events 商品不可用事件

官方文档说这个模板可以轻松扩展增加事件,如用户评分和用户点赞收藏等

查询推荐结果API支持的参数

  • UserID 用户ID
  • Num of items to be recommended 返回记录条数
  • List of white-listed item categories 分类白名单 (可选)
  • List of white-listed ItemIds 商品id白名单 (可选)
  • List of black-listed ItemIds 商品id黑名单 (可选)

查询支持黑名单和白名单,这个灵活性就非常高了,尤其是面对多租户的saas平台,经常需要推荐的产品不能跨租户

通过git下载电商推荐引擎的模板

1
2
$ git clone https://github.com/apache/predictionio-template-ecom-recommender.git MyECommerceRecommendation
$ cd MyECommerceRecommendation

3. 创建 App ID 和 Access Key

通过如下命令创建应用用来存储数据,收集来的数据将用来供机器学习建模:

1
$ pio-docker app new MyApp1

该命令将返回如下结果:

1
2
3
4
5
6
...
[INFO] [App$] Initialized Event Store for this app ID: 1.
[INFO] [App$] Created new app:
[INFO] [App$]       Name: MyApp1
[INFO] [App$]         ID: 1
[INFO] [App$] Access Key: 3mZWDzci2D5YsqAnqNnXH9SB6Rg3dsTBs8iHkK6X2i54IQsIZI1eEeQQyMfs7b3F

使用如下命令可查看所有应用的信息:

1
pio-docker app list

4. 收集数据

用户基础数据

1
2
3
4
5
6
7
8
$ curl -i -X POST http://localhost:7070/events.json?accessKey=$ACCESS_KEY \
-H "Content-Type: application/json" \
-d '{
  "event" : "$set",
  "entityType" : "user",
  "entityId" : "u0",
  "eventTime" : "2014-11-02T09:39:45.618-08:00"
}'

上面的curl命令可以导入一个用户数据,文档中也提供了Python、Java、PHP、Ruby的SDK,实际使用时第一次可能需要自己写一个批处理程序导入系统已经存在的用户,之后在新用户注册后执行单条记录写入

商品基础数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ curl -i -X POST http://localhost:7070/events.json?accessKey=$ACCESS_KEY \
-H "Content-Type: application/json" \
-d '{
  "event" : "$set",
  "entityType" : "item",
  "entityId" : "i0",
  "properties" : {
    "categories" : ["c1", "c2"]
  }
  "eventTime" : "2014-11-02T09:39:45.618-08:00"
}'

多个分类放在数组里

用户浏览事件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ curl -i -X POST http://localhost:7070/events.json?accessKey=$ACCESS_KEY \
-H "Content-Type: application/json" \
-d '{
  "event" : "view",
  "entityType" : "user",
  "entityId" : "u0",
  "targetEntityType" : "item",
  "targetEntityId" : "i0",
  "eventTime" : "2014-11-10T12:34:56.123-08:00"
}'

用户购买事件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ curl -i -X POST http://localhost:7070/events.json?accessKey=$ACCESS_KEY \
-H "Content-Type: application/json" \
-d '{
  "event" : "buy",
  "entityType" : "user",
  "entityId" : "u0",
  "targetEntityType" : "item",
  "targetEntityId" : "i0",
  "eventTime" : "2014-11-10T13:00:00.123-08:00"
}'

事件debug rest api

Get Events of an app 查询满足条件的所有事件

1
$ curl -i -X GET "http://localhost:7070/events.json?accessKey=$ACCESS_KEY"

可以通过如上方法查询事件,支持的查询参数有:

  • startTime: ISO8601格式的时间,返回eventTime >= startTime的事件.
  • untilTime: ISO8601格式的时间,返回eventTime < untilTime的事件.
  • entityType: String,仅返回此entityType的事件,如:user/item.
  • entityId: String. 仅返回此entityId的事件.
  • event: String. 仅返回此event的事件,如:view/buy.
  • targetEntityType: String. 事件目标类型,如:user/item.
  • targetEntityId: String. 事件目标Id.
  • limit: Integer. 返回记录数. 默认为20. -1 为获取全部.
  • reversed: Boolean. 是否必须配合传 entityTypeentityId 使用, 返回结果按时间顺序反转,默认false.

Get an Event 查询某一事件

1
$ curl -i -X GET http://localhost:7070/events/<your_eventId>.json?accessKey=<your_accessKey>

Delete an Event 删除事件

1
$ curl -i -X DELETE http://localhost:7070/events/<your_eventId>.json?accessKey=<your_accessKey>

Delete All Events of an App 删除app下的所有事件(慎用)

1
2
3
$ pio app data-delete <your_app_name>
# or
$ pio-docker app data-delete <your_app_name>

该命令可以删除app下所有的事件,适合测试,生产环境请勿执行。

5. Deploy the Engine as a Service 部署

进入模板目录,编辑engine.json文件,将appname改为自己的app名称

1
2
3
4
5
6
7
8
  ...
  "datasource": {
    "params" : {
      "appName": MyRecommendation
      # make sure the appName parameter match your App Name
    }
  },
  ...

部署系统到 Web Service 时,过程中分成三个步骤:

  • pio build :准备Spark运算需要的环境和资料
  • pio train :训练数据建模
  • pio deploy:将训练结果以Restful API 开放

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    $ pio-docker build
    
    ### Return:
    [INFO] [Console$] Your engine is ready for training.
    
    
    $ pio-docker train
    
    ### Return:
    [INFO] [CoreWorkflow$] Training completed successfully.
    
    $ pio-docker deploy
    
    ### Return:
    [INFO] [HttpListener] Bound to /0.0.0.0:8000
    [INFO] [MasterActor] Bind successful. Ready to serve.

此时打开浏览器输入ip:8000就能看到服务的状态了

6. 通过api调用获取推荐结果

1
2
3
$ curl -H "Content-Type: application/json" \
-d '{ "user": "u1", "num": 4 }' \
http://localhost:8000/queries.json

如上传入参数用户id及返回数量,返回如下结果:

1
2
3
4
5
6
7
8
{
  "itemScores":[
    {"item":"i4","score":0.006009267718658978},
    {"item":"i33","score":0.005999267822052033},
    {"item":"i14","score":0.005261309429391667},
    {"item":"i3","score":0.003007015026561692}
  ]
}

使用白名单

1
2
3
4
5
6
7
$ curl -H "Content-Type: application/json" \
-d '{
  "user": "u1",
  "num": 4,
  "whiteList": ["i1", "i2", "i3", "i21", "i22", "i23", "i24", "i25"]
}' \
http://localhost:8000/queries.json

使用黑名单

1
2
3
4
5
6
7
8
$ curl -H "Content-Type: application/json" \
-d '{
  "user": "u1",
  "num": 4,
  "categories" : ["c4", "c3"],
  "blackList": ["i21", "i26", "i40"]
}' \
http://localhost:8000/queries.json