http://git-wip-us.apache.org/repos/asf/incubator-predictionio-site/blob/0bdbf8fe/templates/recommendation/customize-data-prep/index.html
----------------------------------------------------------------------
diff --git a/templates/recommendation/customize-data-prep/index.html 
b/templates/recommendation/customize-data-prep/index.html
new file mode 100644
index 0000000..219e7be
--- /dev/null
+++ b/templates/recommendation/customize-data-prep/index.html
@@ -0,0 +1,143 @@
+<!DOCTYPE html><html><head><title>Customizing Data Preparator 
(Recommendation)</title><meta charset="utf-8"/><meta content="IE=edge,chrome=1" 
http-equiv="X-UA-Compatible"/><meta name="viewport" 
content="width=device-width, initial-scale=1.0"/><meta class="swiftype" 
name="title" data-type="string" content="Customizing Data Preparator 
(Recommendation)"/><link rel="canonical" 
href="https://docs.prediction.io/templates/recommendation/customize-data-prep/"/><link
 href="/images/favicon/normal-b330020a.png" rel="shortcut icon"/><link 
href="/images/favicon/apple-c0febcf2.png" rel="apple-touch-icon"/><link 
href="//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800"
 rel="stylesheet"/><link 
href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" 
rel="stylesheet"/><link href="/stylesheets/application-a2a2f408.css" 
rel="stylesheet" type="text/css"/><script 
src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5
 shiv.min.js"></script><script 
src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script><script
 src="//use.typekit.net/pqo0itb.js"></script><script>try{Typekit.load({ async: 
true });}catch(e){}</script></head><body><div id="global"><header><div 
class="container" id="header-wrapper"><div class="row"><div 
class="col-sm-12"><div id="logo-wrapper"><span id="drawer-toggle"></span><a 
href="#"></a><a href="http://predictionio.incubator.apache.org/";><img 
alt="PredictionIO" id="logo" 
src="/images/logos/logo-ee2b9bb3.png"/></a></div><div id="menu-wrapper"><div 
id="pill-wrapper"><a class="pill left" 
href="/gallery/template-gallery">TEMPLATES</a> <a class="pill right" 
href="//github.com/apache/incubator-predictionio/">OPEN 
SOURCE</a></div></div><img class="mobile-search-bar-toggler hidden-md 
hidden-lg" 
src="/images/icons/search-glass-704bd4ff.png"/></div></div></div></header><div 
id="search-bar-row-wrapper"><div class="container-fluid" 
id="search-bar-row"><div clas
 s="row"><div class="col-md-9 col-sm-11 col-xs-11"><div class="hidden-md 
hidden-lg" id="mobile-page-heading-wrapper"><p>PredictionIO 
Docs</p><h4>Customizing Data Preparator (Recommendation)</h4></div><h4 
class="hidden-sm hidden-xs">PredictionIO Docs</h4></div><div class="col-md-3 
col-sm-1 col-xs-1 hidden-md hidden-lg"><img id="left-menu-indicator" 
src="/images/icons/down-arrow-dfe9f7fe.png"/></div><div class="col-md-3 
col-sm-12 col-xs-12 swiftype-wrapper"><div class="swiftype"><form 
class="search-form"><img class="search-box-toggler hidden-xs hidden-sm" 
src="/images/icons/search-glass-704bd4ff.png"/><div class="search-box"><img 
src="/images/icons/search-glass-704bd4ff.png"/><input type="text" 
id="st-search-input" class="st-search-input" placeholder="Search 
Doc..."/></div><img class="swiftype-row-hider hidden-md hidden-lg" 
src="/images/icons/drawer-toggle-active-fcbef12a.png"/></form></div></div><div 
class="mobile-left-menu-toggler hidden-md 
hidden-lg"></div></div></div></div><div id=
 "page" class="container-fluid"><div class="row"><div id="left-menu-wrapper" 
class="col-md-3"><nav id="nav-main"><ul><li class="level-1"><a 
class="expandible" href="/"><span>Apache PredictionIO (incubating) 
Documentation</span></a><ul><li class="level-2"><a class="final" 
href="/"><span>Welcome to Apache PredictionIO 
(incubating)</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><span>Getting Started</span></a><ul><li class="level-2"><a 
class="final" href="/start/"><span>A Quick Intro</span></a></li><li 
class="level-2"><a class="final" href="/install/"><span>Installing Apache 
PredictionIO (incubating)</span></a></li><li class="level-2"><a class="final" 
href="/start/download/"><span>Downloading an Engine Template</span></a></li><li 
class="level-2"><a class="final" href="/start/deploy/"><span>Deploying Your 
First Engine</span></a></li><li class="level-2"><a class="final" 
href="/start/customize/"><span>Customizing the 
Engine</span></a></li></ul></li><li class="l
 evel-1"><a class="expandible" href="#"><span>Integrating with Your 
App</span></a><ul><li class="level-2"><a class="final" 
href="/appintegration/"><span>App Integration Overview</span></a></li><li 
class="level-2"><a class="expandible" href="/sdk/"><span>List of 
SDKs</span></a><ul><li class="level-3"><a class="final" 
href="/sdk/java/"><span>Java & Android SDK</span></a></li><li 
class="level-3"><a class="final" href="/sdk/php/"><span>PHP 
SDK</span></a></li><li class="level-3"><a class="final" 
href="/sdk/python/"><span>Python SDK</span></a></li><li class="level-3"><a 
class="final" href="/sdk/ruby/"><span>Ruby SDK</span></a></li><li 
class="level-3"><a class="final" href="/sdk/community/"><span>Community Powered 
SDKs</span></a></li></ul></li></ul></li><li class="level-1"><a 
class="expandible" href="#"><span>Deploying an Engine</span></a><ul><li 
class="level-2"><a class="final" href="/deploy/"><span>Deploying as a Web 
Service</span></a></li><li class="level-2"><a class="final" href="/cli/#
 engine-commands"><span>Engine Command-line Interface</span></a></li><li 
class="level-2"><a class="final" href="/deploy/monitoring/"><span>Monitoring 
Engine</span></a></li><li class="level-2"><a class="final" 
href="/deploy/engineparams/"><span>Setting Engine Parameters</span></a></li><li 
class="level-2"><a class="final" href="/deploy/enginevariants/"><span>Deploying 
Multiple Engine Variants</span></a></li></ul></li><li class="level-1"><a 
class="expandible" href="#"><span>Customizing an Engine</span></a><ul><li 
class="level-2"><a class="final" href="/customize/"><span>Learning 
DASE</span></a></li><li class="level-2"><a class="final" 
href="/customize/dase/"><span>Implement DASE</span></a></li><li 
class="level-2"><a class="final" 
href="/customize/troubleshooting/"><span>Troubleshooting Engine 
Development</span></a></li><li class="level-2"><a class="final" 
href="/api/current/#package"><span>Engine Scala 
APIs</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><spa
 n>Collecting and Analyzing Data</span></a><ul><li class="level-2"><a 
class="final" href="/datacollection/"><span>Event Server 
Overview</span></a></li><li class="level-2"><a class="final" 
href="/cli/#event-server-commands"><span>Event Server Command-line 
Interface</span></a></li><li class="level-2"><a class="final" 
href="/datacollection/eventapi/"><span>Collecting Data with 
REST/SDKs</span></a></li><li class="level-2"><a class="final" 
href="/datacollection/eventmodel/"><span>Events Modeling</span></a></li><li 
class="level-2"><a class="final" 
href="/datacollection/webhooks/"><span>Unifying Multichannel Data with 
Webhooks</span></a></li><li class="level-2"><a class="final" 
href="/datacollection/channel/"><span>Channel</span></a></li><li 
class="level-2"><a class="final" 
href="/datacollection/batchimport/"><span>Importing Data in 
Batch</span></a></li><li class="level-2"><a class="final" 
href="/datacollection/analytics/"><span>Using Analytics 
Tools</span></a></li></ul></li><li class="leve
 l-1"><a class="expandible" href="#"><span>Choosing an 
Algorithm(s)</span></a><ul><li class="level-2"><a class="final" 
href="/algorithm/"><span>Built-in Algorithm Libraries</span></a></li><li 
class="level-2"><a class="final" href="/algorithm/switch/"><span>Switching to 
Another Algorithm</span></a></li><li class="level-2"><a class="final" 
href="/algorithm/multiple/"><span>Combining Multiple 
Algorithms</span></a></li><li class="level-2"><a class="final" 
href="/algorithm/custom/"><span>Adding Your Own 
Algorithms</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><span>ML Tuning and Evaluation</span></a><ul><li class="level-2"><a 
class="final" href="/evaluation/"><span>Overview</span></a></li><li 
class="level-2"><a class="final" 
href="/evaluation/paramtuning/"><span>Hyperparameter Tuning</span></a></li><li 
class="level-2"><a class="final" 
href="/evaluation/evaluationdashboard/"><span>Evaluation 
Dashboard</span></a></li><li class="level-2"><a class="final" href="/
 evaluation/metricchoose/"><span>Choosing Evaluation Metrics</span></a></li><li 
class="level-2"><a class="final" href="/evaluation/metricbuild/"><span>Building 
Evaluation Metrics</span></a></li></ul></li><li class="level-1"><a 
class="expandible" href="#"><span>System Architecture</span></a><ul><li 
class="level-2"><a class="final" href="/system/"><span>Architecture 
Overview</span></a></li><li class="level-2"><a class="final" 
href="/system/anotherdatastore/"><span>Using Another Data 
Store</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><span>Engine Template Gallery</span></a><ul><li class="level-2"><a 
class="final" href="/gallery/template-gallery/"><span>Browse</span></a></li><li 
class="level-2"><a class="final" 
href="/community/submit-template/"><span>Submit your Engine as a 
Template</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><span>Demo Tutorials</span></a><ul><li class="level-2"><a 
class="final" href="/demo/tapster/"><span>
 Comics Recommendation Demo</span></a></li><li class="level-2"><a class="final" 
href="/demo/community/"><span>Community Contributed Demo</span></a></li><li 
class="level-2"><a class="final" href="/demo/textclassification/"><span>Text 
Classification Engine Tutorial</span></a></li></ul></li><li class="level-1"><a 
class="expandible" href="/community/"><span>Getting Involved</span></a><ul><li 
class="level-2"><a class="final" 
href="/community/contribute-code/"><span>Contribute Code</span></a></li><li 
class="level-2"><a class="final" 
href="/community/contribute-documentation/"><span>Contribute 
Documentation</span></a></li><li class="level-2"><a class="final" 
href="/community/contribute-sdk/"><span>Contribute a SDK</span></a></li><li 
class="level-2"><a class="final" 
href="/community/contribute-webhook/"><span>Contribute a 
Webhook</span></a></li><li class="level-2"><a class="final" 
href="/community/projects/"><span>Community 
Projects</span></a></li></ul></li><li class="level-1"><a class="expa
 ndible" href="#"><span>Getting Help</span></a><ul><li class="level-2"><a 
class="final" href="/resources/faq/"><span>FAQs</span></a></li><li 
class="level-2"><a class="final" 
href="/support/"><span>Support</span></a></li></ul></li><li class="level-1"><a 
class="expandible" href="#"><span>Resources</span></a><ul><li 
class="level-2"><a class="final" href="/resources/intellij/"><span>Developing 
Engines with IntelliJ IDEA</span></a></li><li class="level-2"><a class="final" 
href="/resources/upgrade/"><span>Upgrade Instructions</span></a></li><li 
class="level-2"><a class="final" 
href="/resources/glossary/"><span>Glossary</span></a></li></ul></li></ul></nav></div><div
 class="col-md-9 col-sm-12"><div class="content-header hidden-md 
hidden-lg"><div id="page-title"><h1>Customizing Data Preparator 
(Recommendation)</h1></div></div><div id="table-of-content-wrapper"><h5>On this 
page</h5><aside id="table-of-contents"><ul> <li> <a 
href="#the-data-preparator-component">The Data Preparator Component</a
 > </li> <li> <a href="#modify-the-preparator">Modify the Preparator</a> </li> 
 > <li> <a href="#deploy-the-modified-engine">Deploy the Modified Engine</a> 
 > </li> <li> <a href="#adding-preparator-parameters">Adding Preparator 
 > Parameters</a> </li> </ul> </aside><hr/><a id="edit-page-link" 
 > href="https://github.com/apache/incubator-predictionio/tree/livedoc/docs/manual/source/templates/recommendation/customize-data-prep.html.md";><img
 >  src="/images/icons/edit-pencil-d6c1bb3d.png"/>Edit this page</a></div><div 
 > class="content-header hidden-sm hidden-xs"><div 
 > id="page-title"><h1>Customizing Data Preparator 
 > (Recommendation)</h1></div></div><div class="content"><p>Data Preparator is 
 > where pre-processing actions occurs. For example, one may want to remove 
 > some very popular items from the training data because she thinks that these 
 > items may not help finding individual person&#39;s tastes or one may have a 
 > black list of item that she wants to remove from the training data before 
 > feeding it to the al
 gorithm.</p><p>This section assumes that you have created a 
<em>MyRecommendation</em> engine based on the <a 
href="/templates/recommendation/quickstart/">Recommendation Engine Template: 
QuickStart</a>. We will demonstrate how to add a filtering logic to exclude a 
list of items in the training data.</p><p>A sample black list file containing 
the items to be excluded is provided in 
<code>./data/sample_not_train_data.txt</code>.</p><p>A full end-to-end example 
can be found on <a 
href="https://github.com/apache/incubator-predictionio/tree/develop/examples/scala-parallel-recommendation/custom-prepartor";>GitHub</a>.</p><h2
 id='the-data-preparator-component' class='header-anchors'>The Data Preparator 
Component</h2><p>Recall <a href="/start/engines/">the DASE Architecture</a>, 
data is prepared by 2 components sequentially: <em>Data Source</em> and 
<em>Data Preparator</em>. <em>Data Source</em> reads data from the data store 
of Event Server and then <em>Data Preparator</em> prepares <code>RDD
 [Rating]</code> for the ALS algorithm.</p><p>You may modify any component in 
an engine template to fit your needs. This example shows you how to add the 
filtering logics in Data Preparator.</p><h2 id='modify-the-preparator' 
class='header-anchors'>Modify the Preparator</h2><p>The Data Preparator 
component can be found in <code>src/main/scala/Preparator.scala</code> in the 
&quot;MyRecommendation&quot; directory. The unmodified version looks like the 
following:</p><div class="highlight scala"><table style="border-spacing: 
0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre 
class="lineno">1
+2
+3
+4
+5
+6
+7</pre></td><td class="code"><pre><span class="k">class</span> <span 
class="nc">Preparator</span>
+  <span class="k">extends</span> <span class="nc">PPreparator</span><span 
class="o">[</span><span class="kt">TrainingData</span>, <span 
class="kt">PreparedData</span><span class="o">]</span> <span class="o">{</span>
+
+  <span class="k">def</span> <span class="n">prepare</span><span 
class="o">(</span><span class="n">sc</span><span class="k">:</span> <span 
class="kt">SparkContext</span><span class="o">,</span> <span 
class="n">trainingData</span><span class="k">:</span> <span 
class="kt">TrainingData</span><span class="o">)</span><span class="k">:</span> 
<span class="kt">PreparedData</span> <span class="o">=</span> <span 
class="o">{</span>
+    <span class="k">new</span> <span class="nc">PreparedData</span><span 
class="o">(</span><span class="n">ratings</span> <span class="k">=</span> <span 
class="n">trainingData</span><span class="o">.</span><span 
class="n">ratings</span><span class="o">)</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>The <code>prepare</code> method 
simply passes the ratings from <code>TrainingData</code> to 
<code>PreparedData</code>.</p><p>You can modify the <code>prepare</code> method 
to read a black list of items from a file and remove them from 
<code>TrainingData</code>, so it becomes:</p><div class="highlight 
scala"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" 
style="text-align: right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16</pre></td><td class="code"><pre><span class="k">import</span> <span 
class="nn">scala.io.Source</span> <span class="c1">// ADDED
+</span>
+<span class="k">class</span> <span class="nc">Preparator</span>
+  <span class="k">extends</span> <span class="nc">PPreparator</span><span 
class="o">[</span><span class="kt">TrainingData</span>, <span 
class="kt">PreparedData</span><span class="o">]</span> <span class="o">{</span>
+
+  <span class="k">def</span> <span class="n">prepare</span><span 
class="o">(</span><span class="n">sc</span><span class="k">:</span> <span 
class="kt">SparkContext</span><span class="o">,</span> <span 
class="n">trainingData</span><span class="k">:</span> <span 
class="kt">TrainingData</span><span class="o">)</span><span class="k">:</span> 
<span class="kt">PreparedData</span> <span class="o">=</span> <span 
class="o">{</span>
+    <span class="c1">// MODIFIED HERE
+</span>    <span class="k">val</span> <span class="n">noTrainItems</span> 
<span class="k">=</span> <span class="nc">Source</span><span 
class="o">.</span><span class="n">fromFile</span><span class="o">(</span><span 
class="s">"./data/sample_not_train_data.txt"</span><span class="o">)</span>
+      <span class="o">.</span><span class="n">getLines</span><span 
class="o">.</span><span class="n">toSet</span>
+    <span class="c1">// exclude noTrainItems from original trainingData
+</span>    <span class="k">val</span> <span class="n">ratings</span> <span 
class="k">=</span> <span class="n">trainingData</span><span 
class="o">.</span><span class="n">ratings</span><span class="o">.</span><span 
class="n">filter</span><span class="o">(</span> <span class="n">r</span> <span 
class="k">=&gt;</span>
+      <span class="o">!</span><span class="n">noTrainItems</span><span 
class="o">.</span><span class="n">contains</span><span class="o">(</span><span 
class="n">r</span><span class="o">.</span><span class="n">item</span><span 
class="o">)</span>
+    <span class="o">)</span>
+    <span class="k">new</span> <span class="nc">PreparedData</span><span 
class="o">(</span><span class="n">ratings</span><span class="o">)</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <blockquote> <p>We will show you how 
not to hardcode the path <code>./data/sample_not_train_data.txt</code> 
soon.</p></blockquote> <h2 id='deploy-the-modified-engine' 
class='header-anchors'>Deploy the Modified Engine</h2><p>Now you can deploy the 
modified engine as described in <a 
href="/templates/recommendation/quickstart/">Quick Start</a>.</p><p>Make sure 
the <code>appName</code> defined in the file <code>engine.json</code> matches 
your <em>App Name</em>:</p><div class="highlight shell"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7</pre></td><td class="code"><pre>...
+<span class="s2">"datasource"</span>: <span class="o">{</span>
+  <span class="s2">"params"</span> : <span class="o">{</span>
+    <span class="s2">"appName"</span>: <span class="s2">"YourAppName"</span>
+  <span class="o">}</span>
+<span class="o">}</span>,
+...
+</pre></td></tr></tbody></table> </div> <p>To build <em>MyRecommendation</em> 
and deploy it as a service:</p><div class="highlight shell"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2
+3</pre></td><td class="code"><pre><span class="gp">$ </span>pio build
+<span class="gp">$ </span>pio train
+<span class="gp">$ </span>pio deploy
+</pre></td></tr></tbody></table> </div> <p>This will deploy an engine that 
binds to <a href="http://localhost:8000";>http://localhost:8000</a>. You can 
visit that page in your web browser to check its status.</p><p>Now, You can try 
to retrieve predicted results. To recommend 4 movies to user whose ID is 1, 
send this JSON <code>{ &quot;user&quot;: &quot;1&quot;, &quot;num&quot;: 4 
}</code> to the deployed engine</p><div class="highlight shell"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1</pre></td><td class="code"><pre><span class="gp">$ 
</span>curl -H <span class="s2">"Content-Type: application/json"</span> -d 
<span class="s1">'{ "user": "1", "num": 4 }'</span> 
http://localhost:8000/queries.json
+</pre></td></tr></tbody></table> </div> <p>and it will return a JSON of 
recommended movies.</p><div class="highlight json"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7
+8</pre></td><td class="code"><pre><span class="p">{</span><span class="w">
+  </span><span class="s2">"itemScores"</span><span class="p">:</span><span 
class="w"> </span><span class="p">[</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"22"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">4.072304374729956</span><span class="p">},</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"62"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">4.058482414005789</span><span class="p">},</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"75"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">4.046063009943821</span><span class="p">},</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"68"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">3.8153661512945325</span><span class="p">}</span><span class="w">
+  </span><span class="p">]</span><span class="w">
+</span><span class="p">}</span><span class="w">
+</span></pre></td></tr></tbody></table> </div> <p>Congratulations! You have 
learned how to add customized logic to your Data Preparator!</p><h2 
id='adding-preparator-parameters' class='header-anchors'>Adding Preparator 
Parameters</h2><p>Optionally, you may want to take the hardcoded path 
(<code>./data/sample_not_train_data.txt</code>) away from the source 
code.</p><p>PredictionIO offers <code>PreparatorParams</code> so you can read 
variable values from <code>engine.json</code> instead.</p><p>Modify 
<code>src/main/scala/Preparator.scala</code> again in the 
<em>MyRecommendation</em> directory to:</p><div class="highlight scala"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19</pre></td><td class="code"><pre><span class="k">import</span> <span 
class="nn">org.apache.predictionio.controller.Params</span> <span class="c1">// 
ADDED
+</span>
+ <span class="c1">// ADDED CustomPreparatorParams case class
+</span><span class="k">case</span> <span class="k">class</span> <span 
class="nc">CustomPreparatorParams</span><span class="o">(</span>
+  <span class="n">filepath</span><span class="k">:</span> <span 
class="kt">String</span>
+<span class="o">)</span> <span class="k">extends</span> <span 
class="nc">Params</span>
+
+<span class="k">class</span> <span class="nc">Preparator</span><span 
class="o">(</span><span class="n">pp</span><span class="k">:</span> <span 
class="kt">CustomPreparatorParams</span><span class="o">)</span> <span 
class="c1">// ADDED CustomPreparatorParams
+</span>  <span class="k">extends</span> <span 
class="nc">PPreparator</span><span class="o">[</span><span 
class="kt">TrainingData</span>, <span class="kt">PreparedData</span><span 
class="o">]</span> <span class="o">{</span>
+
+  <span class="k">def</span> <span class="n">prepare</span><span 
class="o">(</span><span class="n">sc</span><span class="k">:</span> <span 
class="kt">SparkContext</span><span class="o">,</span> <span 
class="n">trainingData</span><span class="k">:</span> <span 
class="kt">TrainingData</span><span class="o">)</span><span class="k">:</span> 
<span class="kt">PreparedData</span> <span class="o">=</span> <span 
class="o">{</span>
+    <span class="k">val</span> <span class="n">noTrainItems</span> <span 
class="k">=</span> <span class="nc">Source</span><span class="o">.</span><span 
class="n">fromFile</span><span class="o">(</span><span class="n">pp</span><span 
class="o">.</span><span class="n">filepath</span><span class="o">).</span><span 
class="n">getLines</span><span class="o">.</span><span class="n">toSet</span> 
<span class="c1">//CHANGED
+</span>    <span class="k">val</span> <span class="n">ratings</span> <span 
class="k">=</span> <span class="n">trainingData</span><span 
class="o">.</span><span class="n">ratings</span><span class="o">.</span><span 
class="n">filter</span><span class="o">(</span> <span class="n">r</span> <span 
class="k">=&gt;</span>
+      <span class="o">!</span><span class="n">noTrainItems</span><span 
class="o">.</span><span class="n">contains</span><span class="o">(</span><span 
class="n">r</span><span class="o">.</span><span class="n">item</span><span 
class="o">)</span>
+    <span class="o">)</span>
+    <span class="k">new</span> <span class="nc">PreparedData</span><span 
class="o">(</span><span class="n">ratings</span><span class="o">)</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+
+</pre></td></tr></tbody></table> </div> <p>In <code>engine.json</code>, you 
define the parameters <code>filepath</code> for the Data Preparator:</p><div 
class="highlight json"><table style="border-spacing: 0"><tbody><tr><td 
class="gutter gl" style="text-align: right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7
+8
+9</pre></td><td class="code"><pre><span class="p">{</span><span class="w">
+  </span><span class="err">...</span><span class="w">
+  </span><span class="s2">"preparator"</span><span class="p">:</span><span 
class="w"> </span><span class="p">{</span><span class="w">
+    </span><span class="s2">"params"</span><span class="p">:</span><span 
class="w"> </span><span class="p">{</span><span class="w">
+      </span><span class="s2">"filepath"</span><span class="p">:</span><span 
class="w"> </span><span 
class="s2">"./data/sample_not_train_data.txt"</span><span class="w">
+    </span><span class="p">}</span><span class="w">
+  </span><span class="p">},</span><span class="w">
+  </span><span class="err">...</span><span class="w">
+</span><span class="err">}</span><span class="w">
+</span></pre></td></tr></tbody></table> </div> <p>Try to build 
<em>MyRecommendation</em> and deploy it again:</p><div class="highlight 
shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" 
style="text-align: right"><pre class="lineno">1
+2
+3</pre></td><td class="code"><pre><span class="gp">$ </span>pio build
+<span class="gp">$ </span>pio train
+<span class="gp">$ </span>pio deploy
+</pre></td></tr></tbody></table> </div> <p>You can change the 
<code>filepath</code> value without re-building the code next time.</p><h4 
id='<a-href="/templates/recommendation/customize-serving/">next:-customizing-serving</a>'
 class='header-anchors' ><a 
href="/templates/recommendation/customize-serving/">Next: Customizing 
Serving</a></h4></div></div></div></div><footer><div class="container"><div 
class="seperator"></div><div class="row"><div class="col-md-6 col-xs-6 
footer-link-column"><div 
class="footer-link-column-row"><h4>Community</h4><ul><li><a 
href="//docs.prediction.io/install/" target="blank">Download</a></li><li><a 
href="//docs.prediction.io/" target="blank">Docs</a></li><li><a 
href="//github.com/apache/incubator-predictionio" 
target="blank">GitHub</a></li><li><a 
href="mailto:user-subscr...@predictionio.incubator.apache.org"; 
target="blank">Subscribe to User Mailing List</a></li><li><a 
href="//stackoverflow.com/questions/tagged/predictionio" 
target="blank">Stackoverflow</a><
 /li></ul></div></div><div class="col-md-6 col-xs-6 footer-link-column"><div 
class="footer-link-column-row"><h4>Contribute</h4><ul><li><a 
href="//predictionio.incubator.apache.org/community/contribute-code/" 
target="blank">Contribute</a></li><li><a 
href="//github.com/apache/incubator-predictionio" target="blank">Source 
Code</a></li><li><a href="//issues.apache.org/jira/browse/PIO" 
target="blank">Bug Tracker</a></li><li><a 
href="mailto:dev-subscr...@predictionio.incubator.apache.org"; 
target="blank">Subscribe to Development Mailing 
List</a></li></ul></div></div></div></div><div id="footer-bottom"><div 
class="container"><div class="row"><div class="col-md-12"><div 
id="footer-logo-wrapper"><img alt="PredictionIO" 
src="/images/logos/logo-white-d1e9c6e6.png"/></div><div 
id="social-icons-wrapper"><a class="github-button" 
href="https://github.com/apache/incubator-predictionio"; data-style="mega" 
data-count-href="/apache/incubator-predictionio/stargazers" 
data-count-api="/repos/apache/incubato
 r-predictionio#stargazers_count" data-count-aria-label="# stargazers on 
GitHub" aria-label="Star apache/incubator-predictionio on GitHub">Star</a> <a 
class="github-button" 
href="https://github.com/apache/incubator-predictionio/fork"; 
data-icon="octicon-git-branch" data-style="mega" 
data-count-href="/apache/incubator-predictionio/network" 
data-count-api="/repos/apache/incubator-predictionio#forks_count" 
data-count-aria-label="# forks on GitHub" aria-label="Fork 
apache/incubator-predictionio on GitHub">Fork</a> <script id="github-bjs" 
async="" defer="" src="https://buttons.github.io/buttons.js";></script><a 
href="//www.facebook.com/predictionio" target="blank"><img alt="PredictionIO on 
Twitter" src="/images/icons/twitter-ea9dc152.png"/></a> <a 
href="//twitter.com/predictionio" target="blank"><img alt="PredictionIO on 
Facebook" src="/images/icons/facebook-5c57939c.png"/></a> 
</div></div></div></div></div></footer></div><script>(function(w,d,t,u,n,s,e){w['SwiftypeObject']=n;w[n]=w[n]||fun
 ction(){
+(w[n].q=w[n].q||[]).push(arguments);};s=d.createElement(t);
+e=d.getElementsByTagName(t)[0];s.async=1;s.src=u;e.parentNode.insertBefore(s,e);
+})(window,document,'script','//s.swiftypecdn.com/install/v1/st.js','_st');
+
+_st('install','HaUfpXXV87xoB_zzCQ45');</script><script 
src="/javascripts/application-280db181.js"></script></body></html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-predictionio-site/blob/0bdbf8fe/templates/recommendation/customize-data-prep/index.html.gz
----------------------------------------------------------------------
diff --git a/templates/recommendation/customize-data-prep/index.html.gz 
b/templates/recommendation/customize-data-prep/index.html.gz
new file mode 100644
index 0000000..7594122
Binary files /dev/null and 
b/templates/recommendation/customize-data-prep/index.html.gz differ

http://git-wip-us.apache.org/repos/asf/incubator-predictionio-site/blob/0bdbf8fe/templates/recommendation/customize-serving/index.html
----------------------------------------------------------------------
diff --git a/templates/recommendation/customize-serving/index.html 
b/templates/recommendation/customize-serving/index.html
new file mode 100644
index 0000000..07b38b4
--- /dev/null
+++ b/templates/recommendation/customize-serving/index.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html><html><head><title>Customizing Serving Component 
(Recommendation)</title><meta charset="utf-8"/><meta content="IE=edge,chrome=1" 
http-equiv="X-UA-Compatible"/><meta name="viewport" 
content="width=device-width, initial-scale=1.0"/><meta class="swiftype" 
name="title" data-type="string" content="Customizing Serving Component 
(Recommendation)"/><link rel="canonical" 
href="https://docs.prediction.io/templates/recommendation/customize-serving/"/><link
 href="/images/favicon/normal-b330020a.png" rel="shortcut icon"/><link 
href="/images/favicon/apple-c0febcf2.png" rel="apple-touch-icon"/><link 
href="//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800"
 rel="stylesheet"/><link 
href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" 
rel="stylesheet"/><link href="/stylesheets/application-a2a2f408.css" 
rel="stylesheet" type="text/css"/><script 
src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/htm
 l5shiv.min.js"></script><script 
src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script><script
 src="//use.typekit.net/pqo0itb.js"></script><script>try{Typekit.load({ async: 
true });}catch(e){}</script></head><body><div id="global"><header><div 
class="container" id="header-wrapper"><div class="row"><div 
class="col-sm-12"><div id="logo-wrapper"><span id="drawer-toggle"></span><a 
href="#"></a><a href="http://predictionio.incubator.apache.org/";><img 
alt="PredictionIO" id="logo" 
src="/images/logos/logo-ee2b9bb3.png"/></a></div><div id="menu-wrapper"><div 
id="pill-wrapper"><a class="pill left" 
href="/gallery/template-gallery">TEMPLATES</a> <a class="pill right" 
href="//github.com/apache/incubator-predictionio/">OPEN 
SOURCE</a></div></div><img class="mobile-search-bar-toggler hidden-md 
hidden-lg" 
src="/images/icons/search-glass-704bd4ff.png"/></div></div></div></header><div 
id="search-bar-row-wrapper"><div class="container-fluid" 
id="search-bar-row"><div cl
 ass="row"><div class="col-md-9 col-sm-11 col-xs-11"><div class="hidden-md 
hidden-lg" id="mobile-page-heading-wrapper"><p>PredictionIO 
Docs</p><h4>Customizing Serving Component (Recommendation)</h4></div><h4 
class="hidden-sm hidden-xs">PredictionIO Docs</h4></div><div class="col-md-3 
col-sm-1 col-xs-1 hidden-md hidden-lg"><img id="left-menu-indicator" 
src="/images/icons/down-arrow-dfe9f7fe.png"/></div><div class="col-md-3 
col-sm-12 col-xs-12 swiftype-wrapper"><div class="swiftype"><form 
class="search-form"><img class="search-box-toggler hidden-xs hidden-sm" 
src="/images/icons/search-glass-704bd4ff.png"/><div class="search-box"><img 
src="/images/icons/search-glass-704bd4ff.png"/><input type="text" 
id="st-search-input" class="st-search-input" placeholder="Search 
Doc..."/></div><img class="swiftype-row-hider hidden-md hidden-lg" 
src="/images/icons/drawer-toggle-active-fcbef12a.png"/></form></div></div><div 
class="mobile-left-menu-toggler hidden-md 
hidden-lg"></div></div></div></div><div
  id="page" class="container-fluid"><div class="row"><div 
id="left-menu-wrapper" class="col-md-3"><nav id="nav-main"><ul><li 
class="level-1"><a class="expandible" href="/"><span>Apache PredictionIO 
(incubating) Documentation</span></a><ul><li class="level-2"><a class="final" 
href="/"><span>Welcome to Apache PredictionIO 
(incubating)</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><span>Getting Started</span></a><ul><li class="level-2"><a 
class="final" href="/start/"><span>A Quick Intro</span></a></li><li 
class="level-2"><a class="final" href="/install/"><span>Installing Apache 
PredictionIO (incubating)</span></a></li><li class="level-2"><a class="final" 
href="/start/download/"><span>Downloading an Engine Template</span></a></li><li 
class="level-2"><a class="final" href="/start/deploy/"><span>Deploying Your 
First Engine</span></a></li><li class="level-2"><a class="final" 
href="/start/customize/"><span>Customizing the 
Engine</span></a></li></ul></li><li clas
 s="level-1"><a class="expandible" href="#"><span>Integrating with Your 
App</span></a><ul><li class="level-2"><a class="final" 
href="/appintegration/"><span>App Integration Overview</span></a></li><li 
class="level-2"><a class="expandible" href="/sdk/"><span>List of 
SDKs</span></a><ul><li class="level-3"><a class="final" 
href="/sdk/java/"><span>Java & Android SDK</span></a></li><li 
class="level-3"><a class="final" href="/sdk/php/"><span>PHP 
SDK</span></a></li><li class="level-3"><a class="final" 
href="/sdk/python/"><span>Python SDK</span></a></li><li class="level-3"><a 
class="final" href="/sdk/ruby/"><span>Ruby SDK</span></a></li><li 
class="level-3"><a class="final" href="/sdk/community/"><span>Community Powered 
SDKs</span></a></li></ul></li></ul></li><li class="level-1"><a 
class="expandible" href="#"><span>Deploying an Engine</span></a><ul><li 
class="level-2"><a class="final" href="/deploy/"><span>Deploying as a Web 
Service</span></a></li><li class="level-2"><a class="final" href="/c
 li/#engine-commands"><span>Engine Command-line Interface</span></a></li><li 
class="level-2"><a class="final" href="/deploy/monitoring/"><span>Monitoring 
Engine</span></a></li><li class="level-2"><a class="final" 
href="/deploy/engineparams/"><span>Setting Engine Parameters</span></a></li><li 
class="level-2"><a class="final" href="/deploy/enginevariants/"><span>Deploying 
Multiple Engine Variants</span></a></li></ul></li><li class="level-1"><a 
class="expandible" href="#"><span>Customizing an Engine</span></a><ul><li 
class="level-2"><a class="final" href="/customize/"><span>Learning 
DASE</span></a></li><li class="level-2"><a class="final" 
href="/customize/dase/"><span>Implement DASE</span></a></li><li 
class="level-2"><a class="final" 
href="/customize/troubleshooting/"><span>Troubleshooting Engine 
Development</span></a></li><li class="level-2"><a class="final" 
href="/api/current/#package"><span>Engine Scala 
APIs</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#">
 <span>Collecting and Analyzing Data</span></a><ul><li class="level-2"><a 
class="final" href="/datacollection/"><span>Event Server 
Overview</span></a></li><li class="level-2"><a class="final" 
href="/cli/#event-server-commands"><span>Event Server Command-line 
Interface</span></a></li><li class="level-2"><a class="final" 
href="/datacollection/eventapi/"><span>Collecting Data with 
REST/SDKs</span></a></li><li class="level-2"><a class="final" 
href="/datacollection/eventmodel/"><span>Events Modeling</span></a></li><li 
class="level-2"><a class="final" 
href="/datacollection/webhooks/"><span>Unifying Multichannel Data with 
Webhooks</span></a></li><li class="level-2"><a class="final" 
href="/datacollection/channel/"><span>Channel</span></a></li><li 
class="level-2"><a class="final" 
href="/datacollection/batchimport/"><span>Importing Data in 
Batch</span></a></li><li class="level-2"><a class="final" 
href="/datacollection/analytics/"><span>Using Analytics 
Tools</span></a></li></ul></li><li class="
 level-1"><a class="expandible" href="#"><span>Choosing an 
Algorithm(s)</span></a><ul><li class="level-2"><a class="final" 
href="/algorithm/"><span>Built-in Algorithm Libraries</span></a></li><li 
class="level-2"><a class="final" href="/algorithm/switch/"><span>Switching to 
Another Algorithm</span></a></li><li class="level-2"><a class="final" 
href="/algorithm/multiple/"><span>Combining Multiple 
Algorithms</span></a></li><li class="level-2"><a class="final" 
href="/algorithm/custom/"><span>Adding Your Own 
Algorithms</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><span>ML Tuning and Evaluation</span></a><ul><li class="level-2"><a 
class="final" href="/evaluation/"><span>Overview</span></a></li><li 
class="level-2"><a class="final" 
href="/evaluation/paramtuning/"><span>Hyperparameter Tuning</span></a></li><li 
class="level-2"><a class="final" 
href="/evaluation/evaluationdashboard/"><span>Evaluation 
Dashboard</span></a></li><li class="level-2"><a class="final" hre
 f="/evaluation/metricchoose/"><span>Choosing Evaluation 
Metrics</span></a></li><li class="level-2"><a class="final" 
href="/evaluation/metricbuild/"><span>Building Evaluation 
Metrics</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><span>System Architecture</span></a><ul><li class="level-2"><a 
class="final" href="/system/"><span>Architecture Overview</span></a></li><li 
class="level-2"><a class="final" href="/system/anotherdatastore/"><span>Using 
Another Data Store</span></a></li></ul></li><li class="level-1"><a 
class="expandible" href="#"><span>Engine Template Gallery</span></a><ul><li 
class="level-2"><a class="final" 
href="/gallery/template-gallery/"><span>Browse</span></a></li><li 
class="level-2"><a class="final" 
href="/community/submit-template/"><span>Submit your Engine as a 
Template</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="#"><span>Demo Tutorials</span></a><ul><li class="level-2"><a 
class="final" href="/demo/tapster/"><s
 pan>Comics Recommendation Demo</span></a></li><li class="level-2"><a 
class="final" href="/demo/community/"><span>Community Contributed 
Demo</span></a></li><li class="level-2"><a class="final" 
href="/demo/textclassification/"><span>Text Classification Engine 
Tutorial</span></a></li></ul></li><li class="level-1"><a class="expandible" 
href="/community/"><span>Getting Involved</span></a><ul><li class="level-2"><a 
class="final" href="/community/contribute-code/"><span>Contribute 
Code</span></a></li><li class="level-2"><a class="final" 
href="/community/contribute-documentation/"><span>Contribute 
Documentation</span></a></li><li class="level-2"><a class="final" 
href="/community/contribute-sdk/"><span>Contribute a SDK</span></a></li><li 
class="level-2"><a class="final" 
href="/community/contribute-webhook/"><span>Contribute a 
Webhook</span></a></li><li class="level-2"><a class="final" 
href="/community/projects/"><span>Community 
Projects</span></a></li></ul></li><li class="level-1"><a class="
 expandible" href="#"><span>Getting Help</span></a><ul><li class="level-2"><a 
class="final" href="/resources/faq/"><span>FAQs</span></a></li><li 
class="level-2"><a class="final" 
href="/support/"><span>Support</span></a></li></ul></li><li class="level-1"><a 
class="expandible" href="#"><span>Resources</span></a><ul><li 
class="level-2"><a class="final" href="/resources/intellij/"><span>Developing 
Engines with IntelliJ IDEA</span></a></li><li class="level-2"><a class="final" 
href="/resources/upgrade/"><span>Upgrade Instructions</span></a></li><li 
class="level-2"><a class="final" 
href="/resources/glossary/"><span>Glossary</span></a></li></ul></li></ul></nav></div><div
 class="col-md-9 col-sm-12"><div class="content-header hidden-md 
hidden-lg"><div id="page-title"><h1>Customizing Serving Component 
(Recommendation)</h1></div></div><div id="table-of-content-wrapper"><h5>On this 
page</h5><aside id="table-of-contents"><ul> <li> <a 
href="#the-serving-component">The Serving Component</a> </li> <l
 i> <a href="#modify-the-serving-interface">Modify the Serving Interface</a> 
</li> <li> <a href="#deploy-the-modified-engine">Deploy the Modified Engine</a> 
</li> <li> <a href="#adding-serving-parameters">Adding Serving Parameters</a> 
</li> </ul> </aside><hr/><a id="edit-page-link" 
href="https://github.com/apache/incubator-predictionio/tree/livedoc/docs/manual/source/templates/recommendation/customize-serving.html.md";><img
 src="/images/icons/edit-pencil-d6c1bb3d.png"/>Edit this page</a></div><div 
class="content-header hidden-sm hidden-xs"><div id="page-title"><h1>Customizing 
Serving Component (Recommendation)</h1></div></div><div 
class="content"><p>Serving component is where post-processing occurs. For 
example, if you are recommending items to users, you may want to remove items 
that are not currently in stock from the list of recommendation.</p><p>This 
section is based on the <a 
href="/templates/recommendation/quickstart/">Recommendation Engine 
Template</a>.</p><p>A full end-to-end 
 example can be found on <a 
href="https://github.com/apache/incubator-predictionio/tree/develop/examples/scala-parallel-recommendation/custom-serving";>GitHub</a>.</p>
 <h2 id='the-serving-component' class='header-anchors'>The Serving 
Component</h2><p>Recall <a href="/start/engines/">the DASE Architecture</a>, a 
PredictionIO engine has 4 main components: Data Source, Data Preparator, 
Algorithm, and Serving components. When a Query comes in, it is passed to the 
Algorithm component for making Predictions.</p><p>The Engine&#39;s serving 
component can be found in <code>src/main/scala/Serving.scala</code> in the 
<em>MyRecommendation</em> directory. By default, it looks like the 
following:</p><div class="highlight scala"><table style="border-spacing: 
0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre 
class="lineno">1
+2
+3
+4
+5
+6
+7
+8</pre></td><td class="code"><pre><span class="k">class</span> <span 
class="nc">Serving</span> <span class="k">extends</span> <span 
class="nc">LServing</span><span class="o">[</span><span 
class="kt">Query</span>, <span class="kt">PredictedResult</span><span 
class="o">]</span> <span class="o">{</span>
+
+  <span class="k">override</span>
+  <span class="k">def</span> <span class="n">serve</span><span 
class="o">(</span><span class="n">query</span><span class="k">:</span> <span 
class="kt">Query</span><span class="o">,</span>
+    <span class="n">predictedResults</span><span class="k">:</span> <span 
class="kt">Seq</span><span class="o">[</span><span 
class="kt">PredictedResult</span><span class="o">])</span><span 
class="k">:</span> <span class="kt">PredictedResult</span> <span 
class="o">=</span> <span class="o">{</span>
+    <span class="n">predictedResults</span><span class="o">.</span><span 
class="n">head</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>We will customize the Serving 
component to remove temporarily disabled items from the Prediction made by 
Algorithms.</p><h2 id='modify-the-serving-interface' 
class='header-anchors'>Modify the Serving Interface</h2><p>We will use a file 
to specify a list of disabled items. When the <code>serve</code> method is 
called, it loads the file and removes items in the disabled list from 
<code>PredictedResult</code>. The following code snippet illustrates the 
logic:</p><div class="highlight scala"><table style="border-spacing: 
0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre 
class="lineno">1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17</pre></td><td class="code"><pre><span class="k">import</span> <span 
class="nn">scala.io.Source</span>  <span class="c1">// ADDED
+</span>
+<span class="k">class</span> <span class="nc">Serving</span> <span 
class="k">extends</span> <span class="nc">LServing</span><span 
class="o">[</span><span class="kt">Query</span>, <span 
class="kt">PredictedResult</span><span class="o">]</span> <span 
class="o">{</span>
+
+  <span class="k">override</span> <span class="k">def</span> <span 
class="n">serve</span><span class="o">(</span><span class="n">query</span><span 
class="k">:</span> <span class="kt">Query</span><span class="o">,</span> <span 
class="n">predictedResults</span><span class="k">:</span> <span 
class="kt">Seq</span><span class="o">[</span><span 
class="kt">PredictedResult</span><span class="o">])</span>
+  <span class="k">:</span> <span class="kt">PredictedResult</span> <span 
class="o">=</span> <span class="o">{</span>
+    <span class="c1">// Read the disabled item from file.
+</span>    <span class="k">val</span> <span 
class="n">disabledProducts</span><span class="k">:</span> <span 
class="kt">Set</span><span class="o">[</span><span 
class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span 
class="nc">Source</span>
+      <span class="o">.</span><span class="n">fromFile</span><span 
class="o">(</span><span 
class="s">"./data/sample_disabled_items.txt"</span><span class="o">)</span>
+      <span class="o">.</span><span class="n">getLines</span>
+      <span class="o">.</span><span class="n">toSet</span>
+
+    <span class="k">val</span> <span class="n">itemScores</span> <span 
class="k">=</span> <span class="n">predictedResults</span><span 
class="o">.</span><span class="n">head</span><span class="o">.</span><span 
class="n">itemScores</span>
+    <span class="c1">// Remove items from the original predictedResult
+</span>    <span class="nc">PredictedResult</span><span 
class="o">(</span><span class="n">itemScores</span><span 
class="o">.</span><span class="n">filter</span><span class="o">(</span><span 
class="n">ps</span> <span class="k">=&gt;</span> <span class="o">!</span><span 
class="n">disabledProducts</span><span class="o">(</span><span 
class="n">ps</span><span class="o">.</span><span class="n">item</span><span 
class="o">)))</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <div class="alert-message info"><p>We 
will show you how not to hardcode the path 
<code>./data/sample_disabled_items.txt</code> soon.</p></div><div 
class="alert-message warning"><p>This example code uses a local relative path. 
For remote deployment, it is recommended to use a globally accessible absolute 
path.</p></div><div class="alert-message danger"><p>This example is only for 
demonstration purpose. Reading from disk for every query leads to terrible 
system performance. Use a more efficient implementation for production 
deployment.</p></div><h2 id='deploy-the-modified-engine' 
class='header-anchors'>Deploy the Modified Engine</h2><p>Now you can deploy the 
modified engine as described in the <a 
href="/templates/recommendation/quickstart/">Quick Start</a> guide.</p><p>Make 
sure the <code>appId</code> defined in the file <code>engine.json</code> match 
your <em>App ID</em>:</p><div class="highlight shell"><table 
style="border-spacing: 0"><tbody><
 tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7</pre></td><td class="code"><pre>...
+<span class="s2">"datasource"</span>: <span class="o">{</span>
+  <span class="s2">"params"</span>: <span class="o">{</span>
+    <span class="s2">"appId"</span>: 1
+  <span class="o">}</span>
+<span class="o">}</span>,
+...
+</pre></td></tr></tbody></table> </div> <p>To build <em>MyRecommendation</em> 
and deploy it as a service:</p><div class="highlight shell"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2
+3</pre></td><td class="code"><pre><span class="gp">$ </span>pio build
+<span class="gp">$ </span>pio train
+<span class="gp">$ </span>pio deploy
+</pre></td></tr></tbody></table> </div> <p>This will deploy an engine that 
binds to <a href="http://localhost:8000";>http://localhost:8000</a>. You can 
visit that page in your web browser to check its status.</p><p>Now, you can try 
to retrieve predicted results. To recommend 4 movies to user whose ID is 1, 
send this JSON <code>{ &quot;user&quot;: &quot;1&quot;, &quot;num&quot;: 4 
}</code> to the deployed engine</p><div class="highlight shell"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2</pre></td><td class="code"><pre><span class="gp">$ </span>curl -H <span 
class="s2">"Content-Type: application/json"</span> -d <span class="s1">'{ 
"user": "1", "num": 4 }'</span> <span class="se">\</span>
+  http://localhost:8000/queries.json
+</pre></td></tr></tbody></table> </div> <p>and it will return a JSON of 
recommended movies.</p><div class="highlight json"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7
+8</pre></td><td class="code"><pre><span class="p">{</span><span class="w">
+  </span><span class="s2">"itemScores"</span><span class="p">:</span><span 
class="w"> </span><span class="p">[</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"65"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">6.537168137254073</span><span class="p">},</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"69"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">6.391430405762495</span><span class="p">},</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"38"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">5.829957095096519</span><span class="p">},</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"11"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">5.5991291456974</span><span class="p">}</span><span class="w">
+  </span><span class="p">]</span><span class="w">
+</span><span class="p">}</span><span class="w">
+</span></pre></td></tr></tbody></table> </div> <p>Now, to verify the 
blacklisting logic, we add the item 69 (the second item) to the blacklisting 
file <code>data/sample_disabled_items.txt</code>. Rerun the <code>curl</code> 
query, and the change should take effect immediately as the disabled item list 
is reloaded every time the <code>serve</code> method is called.</p><div 
class="highlight shell"><table style="border-spacing: 0"><tbody><tr><td 
class="gutter gl" style="text-align: right"><pre class="lineno">1
+2
+3</pre></td><td class="code"><pre><span class="gp">$ </span><span 
class="nb">echo</span> <span class="s2">"69"</span> &gt;&gt; 
./data/sample_disabled_items.txt
+<span class="gp">$ </span>curl -H <span class="s2">"Content-Type: 
application/json"</span> -d <span class="s1">'{ "user": "1", "num": 4 }'</span> 
<span class="se">\</span>
+  http://localhost:8000/queries.json
+</pre></td></tr></tbody></table> </div> <div class="highlight json"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7</pre></td><td class="code"><pre><span class="p">{</span><span class="w">
+  </span><span class="s2">"itemScores"</span><span class="p">:</span><span 
class="w"> </span><span class="p">[</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"65"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">6.537168137254073</span><span class="p">},</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"38"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">5.829957095096519</span><span class="p">},</span><span class="w">
+    </span><span class="p">{</span><span class="s2">"item"</span><span 
class="p">:</span><span class="w"> </span><span class="s2">"11"</span><span 
class="p">,</span><span class="w"> </span><span class="s2">"score"</span><span 
class="p">:</span><span class="w"> </span><span 
class="mf">5.5991291456974</span><span class="p">}</span><span class="w">
+  </span><span class="p">]</span><span class="w">
+</span><span class="p">}</span><span class="w">
+</span></pre></td></tr></tbody></table> </div> <p>Congratulations! You have 
learned how to add customized realtime blacklisting logic to your Serving 
component!</p><h2 id='adding-serving-parameters' class='header-anchors'>Adding 
Serving Parameters</h2><p>Optionally, you may want to take the hardcoded path 
(<code>./data/sample_disabled_items.txt</code>) away from the source 
code.</p><p>PredictionIO offers <code>ServingParams</code> so you can read 
variable values from <code>engine.json</code> instead. PredictionIO transforms 
the JSON object specified in <code>engine.json</code>&#39;s 
<code>serving</code> field into the <code>ServingParams</code> 
class.</p><p>Modify <code>src/main/scala/Serving.scala</code> again in the 
<em>MyRecommendation</em> directory to:</p><div class="highlight scala"><table 
style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: 
right"><pre class="lineno">1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22</pre></td><td class="code"><pre><span class="k">import</span> <span 
class="nn">scala.io.Source</span>
+
+<span class="k">import</span> <span 
class="nn">org.apache.predictionio.controller.Params</span>  <span 
class="c1">// ADDED
+</span>
+<span class="c1">// ADDED ServingParams to specify the blacklisting file 
location.
+</span><span class="k">case</span> <span class="k">class</span> <span 
class="nc">ServingParams</span><span class="o">(</span><span 
class="n">filepath</span><span class="k">:</span> <span 
class="kt">String</span><span class="o">)</span> <span class="k">extends</span> 
<span class="nc">Params</span>
+
+<span class="k">class</span> <span class="nc">Serving</span><span 
class="o">(</span><span class="k">val</span> <span class="n">params</span><span 
class="k">:</span> <span class="kt">ServingParams</span><span class="o">)</span>
+  <span class="k">extends</span> <span class="nc">LServing</span><span 
class="o">[</span><span class="kt">Query</span>, <span 
class="kt">PredictedResult</span><span class="o">]</span> <span 
class="o">{</span>
+
+  <span class="k">override</span>
+  <span class="k">def</span> <span class="n">serve</span><span 
class="o">(</span><span class="n">query</span><span class="k">:</span> <span 
class="kt">Query</span><span class="o">,</span> <span 
class="n">predictedResults</span><span class="k">:</span> <span 
class="kt">Seq</span><span class="o">[</span><span 
class="kt">PredictedResult</span><span class="o">])</span>
+  <span class="k">:</span> <span class="kt">PredictedResult</span> <span 
class="o">=</span> <span class="o">{</span>
+    <span class="k">val</span> <span class="n">disabledProducts</span><span 
class="k">:</span> <span class="kt">Set</span><span class="o">[</span><span 
class="kt">String</span><span class="o">]</span> <span class="k">=</span> <span 
class="nc">Source</span>
+      <span class="o">.</span><span class="n">fromFile</span><span 
class="o">(</span><span class="n">params</span><span class="o">.</span><span 
class="n">filepath</span><span class="o">)</span>
+      <span class="o">.</span><span class="n">getLines</span>
+      <span class="o">.</span><span class="n">toSet</span>
+
+    <span class="k">val</span> <span class="n">itemScores</span> <span 
class="k">=</span> <span class="n">predictedResults</span><span 
class="o">.</span><span class="n">head</span><span class="o">.</span><span 
class="n">itemScores</span>
+    <span class="nc">PredictedResult</span><span class="o">(</span><span 
class="n">itemScores</span><span class="o">.</span><span 
class="n">filter</span><span class="o">(</span><span class="n">ps</span> <span 
class="k">=&gt;</span> <span class="o">!</span><span 
class="n">disabledProducts</span><span class="o">(</span><span 
class="n">ps</span><span class="o">.</span><span class="n">item</span><span 
class="o">)))</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>In <code>engine.json</code>, you 
specify the parameter <code>serving</code> for the Serving component (the 
JSON4S library automatically extract the JSON object into a Scala class under 
the hood):</p><div class="highlight json"><table style="border-spacing: 
0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre 
class="lineno">1
+2
+3
+4
+5
+6
+7
+8
+9</pre></td><td class="code"><pre><span class="p">{</span><span class="w">
+  </span><span class="err">...</span><span class="w">
+  </span><span class="s2">"serving"</span><span class="p">:</span><span 
class="w"> </span><span class="p">{</span><span class="w">
+    </span><span class="s2">"params"</span><span class="p">:</span><span 
class="w"> </span><span class="p">{</span><span class="w">
+      </span><span class="s2">"filepath"</span><span class="p">:</span><span 
class="w"> </span><span 
class="s2">"./data/sample_disabled_items.txt"</span><span class="w">
+    </span><span class="p">}</span><span class="w">
+  </span><span class="p">},</span><span class="w">
+  </span><span class="err">...</span><span class="w">
+</span><span class="err">}</span><span class="w">
+</span></pre></td></tr></tbody></table> </div> <p>Again, to build 
<em>MyRecommendation</em> and deploy it as a service:</p><div class="highlight 
shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" 
style="text-align: right"><pre class="lineno">1
+2
+3</pre></td><td class="code"><pre><span class="gp">$ </span>pio build
+<span class="gp">$ </span>pio train
+<span class="gp">$ </span>pio deploy
+</pre></td></tr></tbody></table> </div> <p>You can change the 
<code>filepath</code> value without re-building the code next time.</p><h4 
id='<a-href="/templates/recommendation/blacklist-items/">next:-filter-recommended-items-by-blacklist-in-query</a>'
 class='header-anchors' ><a 
href="/templates/recommendation/blacklist-items/">Next: Filter Recommended 
Items by Blacklist in Query</a></h4></div></div></div></div><footer><div 
class="container"><div class="seperator"></div><div class="row"><div 
class="col-md-6 col-xs-6 footer-link-column"><div 
class="footer-link-column-row"><h4>Community</h4><ul><li><a 
href="//docs.prediction.io/install/" target="blank">Download</a></li><li><a 
href="//docs.prediction.io/" target="blank">Docs</a></li><li><a 
href="//github.com/apache/incubator-predictionio" 
target="blank">GitHub</a></li><li><a 
href="mailto:user-subscr...@predictionio.incubator.apache.org"; 
target="blank">Subscribe to User Mailing List</a></li><li><a 
href="//stackoverflow.com/questions/tagg
 ed/predictionio" target="blank">Stackoverflow</a></li></ul></div></div><div 
class="col-md-6 col-xs-6 footer-link-column"><div 
class="footer-link-column-row"><h4>Contribute</h4><ul><li><a 
href="//predictionio.incubator.apache.org/community/contribute-code/" 
target="blank">Contribute</a></li><li><a 
href="//github.com/apache/incubator-predictionio" target="blank">Source 
Code</a></li><li><a href="//issues.apache.org/jira/browse/PIO" 
target="blank">Bug Tracker</a></li><li><a 
href="mailto:dev-subscr...@predictionio.incubator.apache.org"; 
target="blank">Subscribe to Development Mailing 
List</a></li></ul></div></div></div></div><div id="footer-bottom"><div 
class="container"><div class="row"><div class="col-md-12"><div 
id="footer-logo-wrapper"><img alt="PredictionIO" 
src="/images/logos/logo-white-d1e9c6e6.png"/></div><div 
id="social-icons-wrapper"><a class="github-button" 
href="https://github.com/apache/incubator-predictionio"; data-style="mega" 
data-count-href="/apache/incubator-predictionio/
 stargazers" 
data-count-api="/repos/apache/incubator-predictionio#stargazers_count" 
data-count-aria-label="# stargazers on GitHub" aria-label="Star 
apache/incubator-predictionio on GitHub">Star</a> <a class="github-button" 
href="https://github.com/apache/incubator-predictionio/fork"; 
data-icon="octicon-git-branch" data-style="mega" 
data-count-href="/apache/incubator-predictionio/network" 
data-count-api="/repos/apache/incubator-predictionio#forks_count" 
data-count-aria-label="# forks on GitHub" aria-label="Fork 
apache/incubator-predictionio on GitHub">Fork</a> <script id="github-bjs" 
async="" defer="" src="https://buttons.github.io/buttons.js";></script><a 
href="//www.facebook.com/predictionio" target="blank"><img alt="PredictionIO on 
Twitter" src="/images/icons/twitter-ea9dc152.png"/></a> <a 
href="//twitter.com/predictionio" target="blank"><img alt="PredictionIO on 
Facebook" src="/images/icons/facebook-5c57939c.png"/></a> 
</div></div></div></div></div></footer></div><script>(function(w
 ,d,t,u,n,s,e){w['SwiftypeObject']=n;w[n]=w[n]||function(){
+(w[n].q=w[n].q||[]).push(arguments);};s=d.createElement(t);
+e=d.getElementsByTagName(t)[0];s.async=1;s.src=u;e.parentNode.insertBefore(s,e);
+})(window,document,'script','//s.swiftypecdn.com/install/v1/st.js','_st');
+
+_st('install','HaUfpXXV87xoB_zzCQ45');</script><script 
src="/javascripts/application-280db181.js"></script></body></html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-predictionio-site/blob/0bdbf8fe/templates/recommendation/customize-serving/index.html.gz
----------------------------------------------------------------------
diff --git a/templates/recommendation/customize-serving/index.html.gz 
b/templates/recommendation/customize-serving/index.html.gz
new file mode 100644
index 0000000..e254a2d
Binary files /dev/null and 
b/templates/recommendation/customize-serving/index.html.gz differ

Reply via email to