Apache PredictionIO机器学习和智能推荐服务搭建 - 简书

标签: | 发表时间:2018-08-02 13:49 | 作者:
出处:https://www.jianshu.com

一、PredictionIO介绍
Apache PredictionIO 是一个孵化中的机器学习服务器,它可以为为开发人员和数据科学家创建任何机器学习任务的预测引擎。官方原文:

      Apache PredictionIO (incubating) is an open source Machine Learning Server built on 
top of a state-of-the-art open source stack for developers and data scientists 
to create predictive engines for any machine learning task.

PredictionIO以Spark为计算引擎,mysql or HBase+Elasticsearch or PostgreSql 为数据存储,并提供了常用的模板引擎:

      1、Recommenders推荐引擎。集成了Spark MLlib的协同过滤算法,可以作为电子商务、新闻、视频方面的个性化推荐。
2、Classification分类引擎。集成了Spark MLlib的朴素贝叶斯算法,提供文本内容分类、预测用户在当前会话中转化概率、(用户)流失预测等服务。
3、NPL引擎。主要做情绪分析。
4、还提供回归、聚类等其他引擎。

我们选定引擎模板,将用户行为数据导入数据库,PredictionIO帮我们完成了数据训练、建模等复杂问题,并提供了返回预测数据的restful API。
二、PredictionIO服务搭建
在服务搭建这一阶段,官方文档变得更加重要,它比任务其他的网络资料都好用,初次搭建服务的时候,一定遵照官方文档。重要的事说三遍,官方文档!官方文档!官方文档!
我在搭建服务的时候也遇到各种问题,最后把我之前已经搭好正常运行的spark环境,重新安装官方文档要求搭了一遍。所以这边文章不过是官方文档的翻译,及里面的注意点。

      1、环境要求。
以下的配置很重要,至少保证是正确的,其他的版本不能保证,Spark版本和其他编程语音的版本兼容很蛋疼。
  Apache Spark 1.6.3 for Hadoop 2.6
  JDK 1.8
和以下几项的一项:
  PostgreSQL 9.1
or
  MySql 5.1
or
  Apache HBase 0.98.5
  Elasticsearch 1.7.6
2、另外
scala版本,官网写的是2.10.6,我装的是2.10.5,因为spark 1.6.3 for Hadoop 2.6自带的spark就是2.10.5,使用没有问题。

自行去官网下载predictionIO压缩包,我安装的是0.11.0,解压

      tar zxvf PredictionIO-0.11.0-incubating.tar.gz
cd PredictionIO-0.11.0-incubating/bin/
需要执行install进行安装,官方文档没有说
./install.sh 安装

希望支持 scala 2.10.5  spark1.6.3  elasticsearch5.3.0
./make-distribution.sh -Dscala.version=2.10.5 -Dspark.version=1.6.3 -Delasticsearch.version=5.3.0

安装依赖,predictionIO自行下载依赖放在vendors目录下(如spark),需要先建目录,如果依赖另外安装,不需要vendors
mkdir PredictionIO-0.11.0-incubating/vendors

安装数据库
mysql 5.1 / postgreSql 9.1 / HBase 0.98.5 + Elasticsearch 1.7.6

配置依赖环境参数

      cd PredictionIO-0.11.0-incubating/conf/
vi pio-env.sh
配置 Spark、数据库驱动,没有驱动jar包需要自行下载
SPARK_HOME=/Users/jiazhaopu/program/spark-1.6.3
POSTGRES_JDBC_DRIVER=$PIO_HOME/lib/postgresql-42.0.0.jar
MYSQL_JDBC_DRIVER=$PIO_HOME/lib/mysql-connector-java-5.1.41.jar

为了简单,我用mysql作为存储,但配置文件里默认使用PostgreSQL
修改Storage Repositories 为
PIO_STORAGE_REPOSITORIES_METADATA_NAME=pio_meta
PIO_STORAGE_REPOSITORIES_METADATA_SOURCE=MYSQL

PIO_STORAGE_REPOSITORIES_EVENTDATA_NAME=pio_event
PIO_STORAGE_REPOSITORIES_EVENTDATA_SOURCE=MYSQL

PIO_STORAGE_REPOSITORIES_MODELDATA_NAME=pio_model
PIO_STORAGE_REPOSITORIES_MODELDATA_SOURCE=MYSQL

# Storage Data Sources

# PostgreSQL Default Settings
# Please change "pio" to your database name in PIO_STORAGE_SOURCES_PGSQL_URL
# Please change PIO_STORAGE_SOURCES_PGSQL_USERNAME and
# PIO_STORAGE_SOURCES_PGSQL_PASSWORD accordingly
# PIO_STORAGE_SOURCES_PGSQL_TYPE=jdbc
# PIO_STORAGE_SOURCES_PGSQL_URL=jdbc:postgresql://localhost/pio
# PIO_STORAGE_SOURCES_PGSQL_USERNAME=pio
# PIO_STORAGE_SOURCES_PGSQL_PASSWORD=pio

# MySQL Example
PIO_STORAGE_SOURCES_MYSQL_TYPE=jdbc
PIO_STORAGE_SOURCES_MYSQL_URL=jdbc:mysql://127.0.0.1:3306/pio
PIO_STORAGE_SOURCES_MYSQL_USERNAME=root
PIO_STORAGE_SOURCES_MYSQL_PASSWORD=root
#PIO_STORAGE_SOURCES_MYSQL_URL 配置了数据库ip 库名,所以需要先建数据库,这里是pio库

到这里PredictionIO基础服务算搭好了,需要给PredictionIO配置环境变量

      vi /etc/profile
export PATH=$PATH:/Users/jiazhaopu/program/spark-1.6.3/bin
export PATH=$PATH:/Users/jiazhaopu/program/mongodb-osx-x86_64-enterprise-3.4.9/bin
export PATH=$PATH:/usr/local/mysql/bin
export PATH=$PATH:/Users/jiazhaopu/program/apache-predictionio-0.11.0-incubating/PredictionIO/bin
export PATH=$PATH:/Users/jiazhaopu/program/scala-2.10.5/bin

配置完环境变量

      启动命令
pio-start-all
如果您使用PostgreSQL或MySQL,请运行以下命令启动PredictionIO Event Server:
pio eventserver &

输出以下日志
[INFO] [HttpListener] Bound to /0.0.0.0:7070
[INFO] [EventServerActor] Bound received. EventServer is ready
说明启动成功
停服命令
pio-stop-all

访问 http://localhost:7070/返回

      {"status":"alive"}
      执行pio status查看服务运行情况
[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] [Management$] Your system is all ready to go.
      jps -l命令查看已经启动的
54305 sun.tools.jps.Jps
10546 org.jetbrains.jps.cmdline.Launcher
28594 org.apache.predictionio.tools.console.Console
738 
54164 org.apache.predictionio.tools.console.Console
774 org.jetbrains.idea.maven.server.RemoteMavenServer
28649 org.apache.spark.deploy.SparkSubmit

三、部署模板引擎
1、下载模板引擎
这里下载的是一个数据推荐引擎,推荐原理是:
收集用户买了哪些商品,用户给商品打分这两项数据,通过协同过滤算法训练出用户喜好模型,推荐用户还会买哪些商品。

      git clone https://github.com/apache/incubator-predictionio-template-recommender.git MyRecommendation
$ cd MyRecommendation

2、创建App ID 和 Access Key

      pio app new MyApp1
会看到以下输出
[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

记住App ID、Access Key、Name,在收集数据的服务器和代码里会用到

执行 pio app list 命令会列出已存在的App 列表
[INFO] [App$]                 Name |   ID |                                                       Access Key | Allowed Event(s)
[INFO] [App$]               MyApp1 |    1 | 3mZWDzci2D5YsqAnqNnXH9SB6Rg3dsTBs8iHkK6X2i54IQsIZI1eEeQQyMfs7b3F | (all)
[INFO] [App$]               MyApp2 |    2 | io5lz6Eg4m3Xe4JZTBFE13GMAf1dhFl6ZteuJfrO84XpdOz9wRCrDU44EUaYuXq5 | (all)
[INFO] [App$] Finished listing 2 app(s).

3、收集数据
PredictionIO提供了收集数据的接口,在启动了Prediction服务后可以调用它,这里需要用到Access Key。

      $ curl -i -X POST http://localhost:7070/events.json?accessKey=$ACCESS_KEY \
-H "Content-Type: application/json" \
-d '{
  "event" : "rate",
  "entityType" : "user",
  "entityId" : "u0",
  "targetEntityType" : "item",
  "targetEntityId" : "i0",
  "properties" : {
    "rating" : 5
  }
  "eventTime" : "2014-11-02T09:39:45.618-08:00"
}'

模板代码里也提供了Python批量导入的方法,这里给出了两个事件,
一个是用户买商品,一个是用户给商品打分

      import predictionio
client = predictionio.EventClient(
   access_key=<ACCESS KEY>,
   url=<URL OF EVENTSERVER>,
   threads=5,
   qsize=500
)
# 用户给商品打分
client.create_event(
   event="rate",
   entity_type="user",
   entity_id=<USER ID>,
   target_entity_type="item",
   target_entity_id=<ITEM ID>,
   properties= { "rating" : float(<RATING>) }
)

# 用户买商品
client.create_event(
   event="buy",
   entity_type="user",
   entity_id=<USER ID>,
   target_entity_type="item",
   target_entity_id=<ITEM ID>
)
      官方给出了数据模板
https://raw.githubusercontent.com/apache/spark/master/data/mllib/sample_movielens_data.txt

把数据导入到代码中的数据文件,并执行导入代码

      cd MyRecommendation
$ curl https://raw.githubusercontent.com/apache/spark/master/data/mllib/sample_movielens_data.txt --create-dirs -o data/sample_movielens_data.txt
$ python data/import_eventserver.py --access_key $ACCESS_KEY

你会看到

      Importing data...
1501 events are imported.

4、部署你的引擎
编辑你的模板代码里的Engine.json,将appName 改成你自己创建的

      ...
  "datasource": {
    "params" : {
      "appName": "MyApp1"
    }
  },
  ...

Building 你的引擎

      pio build --verbose

这里可能会出现如下错误

      [INFO] [Engine$] If the path above is incorrect, this process will fail.
[INFO] [Engine$] Uber JAR disabled. Making sure lib/pio-assembly-0.11.0-incubating.jar is absent.
[INFO] [Engine$] Going to run: /Users/jiazhaopu/program/apache-predictionio-0.11.0-incubating/PredictionIO/sbt/sbt  package assemblyPackageDependency in /Users/jiazhaopu/workspace/incubator-predictionio-template-recommender
[ERROR] [Engine$] Downloading sbt launcher for 0.13.15:
[ERROR] [Engine$]   From  http://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.15/sbt-launch.jar
[ERROR] [Engine$]     To  /Users/jiazhaopu/.sbt/launchers/0.13.15/sbt-launch.jar

是因为下载sbt-launch.jar出错,可以自己下载好 sbt-launch.jar,放到响应的位置,下载地址

      http://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.15/sbt-launch.jar

最后你会看到

      [INFO] [Console$] Your engine is ready for training.
准备好训练数据了

5、训练数据
执行以下命令开始训练数据

      pio train

以为spark是基于内存的计算框架,如果内存、并行任务数配置不好,可能会运行出错,尤其是在内存不够大的PC上,可能会OutOfMemoryError 或 StackOverflowError。
我遇到的StackOverflowError错误


436542A97FAC3258145AA877DB6F57B0.jpg

我这台PC配置如下:

      处理器 4核
内存  16G

原因是因为spark内存、并行任务数等相关参数配置不当。
最终的配置结果:

      #spark-defaults.conf 
spark.eventLog.enabled             true
spark.driver.memory                512M  #驱动内存
spark.driver.maxResultSize         1g   #驱动最大内存
spark.driver.extraJavaOptions      -Xss32m-XX:PermSize=128M -XX:MaxPermSize=512M
spark.executor.memory              10g
spark.executor.extraJavaOptions    -XX:+PrintGCDetails -Dkey=value -Dnumbers="three"
#spark.sql.shuffle.partitions       4
spark.default.parallelism          800
spark.serializer                   org.apache.spark.serializer.KryoSerializer

spark.default.parallelism 并行任务数,一般设置在500~1000之间。我这台机器 500 和 1000都会StackOverflowErro

spark.serializer org.apache.spark.serializer.KryoSerializer 序列化,也很重要

      #spark-env.sh
export SPARK_WORKER_MEMORY=14g
export SPARK_EXECUTOR_INSTANCES=1
export SPARK_EXECUTOR_CORES=4
export SCALA_HOME=/Users/jiazhaopu/program/scala-2.10.5

SPARK_WORKER_MEMORY 工作内存,尽量大
SPARK_EXECUTOR_INSTANCES 执行器实例数,单机设置1
SPARK_EXECUTOR_CORES 执行核数,等于处理器核数
SPARK_EXECUTOR_INSTANCES * SPARK_EXECUTOR_CORES = 处理器核数

数据训练完成,可以看到

      [INFO] [CoreWorkflow$] Training completed successfully.

部署引擎

      $ pio deploy

部署成功

      [INFO] [HttpListener] Bound to /0.0.0.0:8000
[INFO] [MasterActor] Bind successful. Ready to serve.

引擎默认绑定到 http://localhost:8000/,打开链接看的

QQ20170929-195738@2x.png

好了,现在可以提供API来访问服务,来获取推荐结果。

      为user 1 推荐的前4个数据
$ curl -H "Content-Type: application/json" \
-d '{ "user": "1", "num": 4 }' http://localhost:8000/queries.json

返回Json

      按照评分降序
{
  "itemScores":[
    {"item":"22","score":4.072304374729956},
    {"item":"62","score":4.058482414005789},
    {"item":"75","score":4.046063009943821},
    {"item":"68","score":3.8153661512945325}
  ]
}
QQ20170929-200305@2x.png

到这里predictionIO的推荐服务全部搭建完成,谢谢大家的掌声。

下面是一些其他细节
1、训练数据


QQ20170929-160719@2x.png

按说spark是基于内存的计算,应该是比较耗内存,但是从表现上,内存占用很小,可能是数据小的原因,但是cpu占用很大,最高突破90%。


QQ20170929-161014@2x.png

2、部署引擎
QQ20170929-161305@2x.png

3、数据存储

为了简单,为用了mysql存储训练数据,predictionIO生成了

      mysql> show tables;
+------------------------------+
| Tables_in_pio                |
+------------------------------+
| pio_event_1                  |
| pio_meta_accesskeys          |
| pio_meta_apps                |
| pio_meta_channels            |
| pio_meta_engineinstances     |
| pio_meta_evaluationinstances |
| pio_model_models             |
+------------------------------+
7 rows in set (0.00 sec)

pio_event_1 保存训练数据

      mysql> select * from pio_event_1 limit 10;
+----------------------------------+-------+------------+----------+------------------+----------------+----------------+---------------------+---------------+------+------+---------------------+------------------+
| id                               | event | entityType | entityId | targetEntityType | targetEntityId | properties     | eventTime           | eventTimeZone | tags | prId | creationTime        | creationTimeZone |
+----------------------------------+-------+------------+----------+------------------+----------------+----------------+---------------------+---------------+------+------+---------------------+------------------+
| 00476c09f05240b1b46e519af98bbc5b | buy   | user       | 11       | item             | 30             | {}             | 2017-09-28 15:52:27 | UTC           | NULL | NULL | 2017-09-28 15:52:27 | UTC              |
| 004db334651f4aa6b074a91a879f90cf | buy   | user       | 8        | item             | 69             | {}             | 2017-09-28 15:52:27 | UTC           | NULL | NULL | 2017-09-28 15:52:27 | UTC              |
| 0063564f4ab945a9ae72c62654511526 | rate  | user       | 18       | item             | 75             | {"rating":1.0} | 2017-09-28 15:52:29 | UTC           | NULL | NULL | 2017-09-28 15:52:29 | UTC              |
| 007b8e2e6b9a422dbb3080649d59bd82 | buy   | user       | 11       | item             | 36             | {}             | 2017-09-28 15:52:27 | UTC           | NULL | NULL | 2017-09-28 15:52:27 | UTC              |
| 009d6156c48f44a89eec9d2aa6c3736e | buy   | user       | 4        | item             | 98             | {}             | 2017-09-28 15:52:26 | UTC           | NULL | NULL | 2017-09-28 15:52:26 | UTC              |
| 00ca2326e9414b0f8ad35d824dbe2edd | rate  | user       | 22       | item             | 19             | {"rating":1.0} | 2017-09-28 15:52:29 | UTC           | NULL | NULL | 2017-09-28 15:52:29 | UTC              |
| 00cc79d0dc20466b907cc58eb040d151 | rate  | user       | 3        | item             | 47             | {"rating":1.0} | 2017-09-28 15:52:25 | UTC           | NULL | NULL | 2017-09-28 15:52:25 | UTC              |
| 014315797d564a94abc463dbd6e1e96b | rate  | user       | 17       | item             | 60             | {"rating":1.0} | 2017-09-28 15:52:28 | UTC           | NULL | NULL | 2017-09-28 15:52:28 | UTC              |
| 01660b9b40fe411eae4f6fdf993082d4 | rate  | user       | 16       | item             | 30             | {"rating":2.0} | 2017-09-28 15:52:28 | UTC           | NULL | NULL | 2017-09-28 15:52:28 | UTC              |
| 01b0a512e1aa40bf823fd01ba7712741 | buy   | user       | 1        | item             | 54             | {}             | 2017-09-28 15:52:25 | UTC           | NULL | NULL | 2017-09-28 15:52:25 | UTC              |
+----------------------------------+-------+------------+----------+------------------+----------------+----------------+---------------------+---------------+------+------+---------------------+------------------+
10 rows in set (0.00 sec)

相关 [apache predictionio 机器学习] 推荐:

Apache PredictionIO机器学习和智能推荐服务搭建 - 简书

- -
一、PredictionIO介绍. Apache PredictionIO 是一个孵化中的机器学习服务器,它可以为为开发人员和数据科学家创建任何机器学习任务的预测引擎. PredictionIO以Spark为计算引擎,mysql or HBase+Elasticsearch or PostgreSql 为数据存储,并提供了常用的模板引擎:.

Apache Mahout 0.8 发布,机器学习库

- - 开源中国社区最新新闻
Apache Mahout 0.8 发布了,Apache Mahout 是 Apache Software Foundation (ASF) 开发的一个全新的开源项目,其主要目标是创建一些可伸缩的机器学习算法,供开发人员在 Apache 在许可下免费使用. 该项目已经发展到了它的最二个年头,目前只有一个公共发行版.

机器学习五步走

- - 我爱机器学习
经常会有人问“我该如何在机器学习方面更进一步,我不知道我接下来要学什么了. 一般我都会给出继续钻研教科书的答案. 每当这时候我都会收到一种大惑不解的表情. 但是进步确实就是持续的练习,保持较强的求知欲,并尽你可能的完成具有挑战性的工作. 因为他是为数不多的几种可以让你真真让你获取坚实知识的媒介. 是的,你可以选择选一门课,注册MOOC,参加一些讨论班.

机器学习之路

- - 我爱机器学习
自从答应简二毛博士将自己的机器学习历程和心得分享给大家至今,转眼间半年已经过去了,感谢简博士分享和开源精神的鼓舞,这也正是本系列关于机器学习介绍博客的动力来源. 之前有些网友,师弟们问我,学习机器学习怎么入手,从看什么书开始. 如果你只愿意看一本书,那么推荐Bishop的PRML,全名Pattern Recognition and Machine Learning. 这本书是机器学习的圣经之作,尤其对于贝叶斯方法,介绍非常完善.

Apache Shiro 介绍

- - CSDN博客推荐文章
什么是Apache Shiro?. Apache shiro 是一个强大而灵活的开源安全框架,可清晰地处理身份认证、授权、会话(session)和加密. Apache Shiro最主要的初衷是为了易用和易理解,处理安全问题可能非常复杂甚至非常痛苦,但并非一定要如此. 一个框架应该尽可能地将复杂的问题隐藏起来,提供清晰直观的API使开发者可以很轻松地开发自己的程序安全代码.

Apache防止攻击

- - 小彰
为了防止恶意用户对Apache进行攻击,我们需要安装mod_security这个安全模块. mod_security 1.9.x模块的下载与安装. 下载地址: http://www.modsecurity.org/download/index.html. 建议使用1.9.x,因为2.x的配置指令与1.x完全不同,解压后进入解压目录,执行:.

Apache OpenOffice 3.4发布

- - Solidot
Apache OpenOffice的第一个版本v3.4正式发布. 主要新特性包括:改进ODF支持,包括ODF 1.2加密选项和新电子表格功能;改进Calc组件的数据透视表(Pivot Table)支持;原生支持SVG,增强图形如线帽和剪切变形;简体和繁体中文等原生语言支持;改进性能等. 在甲骨文将OpenOffice.org捐给Apache软件基金会后,OOo的命运曾存在许多争议.

Apache PDFBox 1.8.0 发布

- - 开源中国社区最新新闻
Apache PDFBox 1.8.0 发布了,该版本除了修复大量 bug 之外,还包含如下新特性:. PDFBox是Java实现的PDF文档协作类库,提供PDF文档的创建、处理以及文档内容提取功能,也包含了一些命令行实用工具. PDF 文档加密与解密. 与 Lucene搜索引擎的集成. 填充PDF/XFDF表单数据.

Apache Log4j 2.0介绍

- - CSDN博客推荐文章
Apache Log4j 2.0介绍. 作者:chszs,转载需注明. 作者博客主页:http://blog.csdn.net/chszs. Apache Log4j是著名的Java日志框架之一,在早些年应用最广. 但近两年来,随着SLF4J和LogBack的兴起,很多流行的开源框架在日志模块方面逐步转移到SLF4J+LogBack上,Log4j日渐衰落.

Apache 的 MaxClients 與 MaxRequestsPerChild

- - SSORC.tw
對於 Apache 架設的伺服器,在遇到連線數問題上,以下參數是會考慮微調的. 不過遇到多個 VirtualHost 與連線變多時,需要適時調整. ServerLimit 與 MaxClients 是針對同時間最大連線數為多少,也等於是 Apache 程序數量,ps 一下就會有多少個 /usr/sbin/httpd 等.