You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@predictionio.apache.org by do...@apache.org on 2016/07/20 19:09:43 UTC

[08/51] [partial] incubator-predictionio-site git commit: Initial doc site

http://git-wip-us.apache.org/repos/asf/incubator-predictionio-site/blob/92a45fa4/templates/classification/add-algorithm/index.html
----------------------------------------------------------------------
diff --git a/templates/classification/add-algorithm/index.html b/templates/classification/add-algorithm/index.html
new file mode 100644
index 0000000..fb7cb4a
--- /dev/null
+++ b/templates/classification/add-algorithm/index.html
@@ -0,0 +1,196 @@
+<!DOCTYPE html><html><head><title>Using Alternative Algorithm</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="Using Alternative Algorithm"/><link rel="canonical" href="https://docs.prediction.io/templates/classification/add-algorithm/"/><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-3598c7d7.css" rel="stylesheet" type="text/css"/><!--[if lt IE 9]><script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5shiv.min.js"></script><
 ![endif]--><script src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ga('create', 'UA-38306178-1', 'auto');
+ga('require', 'linkid', 'linkid.js');
+ga('send', 'pageview');</script><script>!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.0.1";
+  analytics.load("YlF3updaI3DR96hnNgSGpR3PPBUGDzt8");
+  analytics.page()
+  }}();</script><script>RCX_CUSTOM_LIB="https://cdn.recontext.com/staging/rcx.min.js";
+(function(b,d,a){b.RCX_OBJECT=a;a=b[a]||[];if(!a.snipV&&!a.libV){b.rcx=a;a.snipV="0.2.0";var g=function(a,b,c,d){a[b]=a[b]||function(){c.push([d].concat(Array.prototype.slice.call(arguments)))}};b="init page track identify link setUserProperty unsetUserProperty".split(" ");for(var f=0;f<b.length;f++){var e,c;e=b[f];c=e.split(".");2==c.length?(a[c[0]]=a[c[0]]||[],g(a[c[0]],c[1],a,e)):g(a,e,a,e)}a=d.createElement("script");a.type="text/javascript";a.async=!0;a.src="undefined"!==typeof RCX_CUSTOM_LIB?
+RCX_CUSTOM_LIB:"https://cdn.recontext.com/rcx.min.js";d=d.getElementsByTagName("script")[0];d.parentNode.insertBefore(a,d)}})(window,document,"rcx");
+rcx.init("kTxFcI3IWdXYfRsh6uuYuej4qYl8m8LVMePM2hdIkM9YjHqkAFC6mqdqO9fpp8p9");
+rcx.page();</script><script>function t(e){analytics.identify(e); analytics.track("newsletter signup");
+  rcx.track("newsletter signup", { '_email': e });}</script><script>!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
+n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
+n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
+t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
+document,'script','//connect.facebook.net/en_US/fbevents.js');
+
+fbq('init', '1073028432707778');
+fbq('track', "PageView");</script><script src="//use.typekit.net/mut4mjx.js"></script><script>try{Typekit.load();}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://prediction.io/"><img alt="PredictionIO" id="logo" src="/images/logos/logo-ee2b9bb3.png"/></a></div><div id="menu-wrapper"><div id="header-nav-options-wrapper"><ul><li><a href="/">Install & Doc</a></li> <li><a href="/support">Support</a></li> </ul></div><div id="pill-wrapper"><a class="pill left" href="//templates.prediction.io/">TEMPLATES</a> <a class="pill right" href="//github.com/PredictionIO/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 class="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>Using Alternative Algorithm</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" c
 lass="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="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="/cli/#engine-c
 ommands"><span>Engine Command-line Interface</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/"><spa
 n>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" 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="http://templates.prediction.io"><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/"><spa
 n>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>Community Support</span></a></li><li class="level-2"><a class="final" href="/support/#enterprise-support"><span>Enterprise 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>Using Alternative Algorithm</h1></div></div><div id="table-of-content-wrapper"><h5>On this page</h5><aside id="table-of-contents"><ul> <li> <a href="#create-a-new-file-randomforestalgorithm-scala">Create a new file
  RandomForestAlgorithm.scala</a> </li> <li> <a href="#define-the-algorithm-class-and-parameters">Define the algorithm class and parameters</a> </li> <li> <a href="#update-engine-scala">Update Engine.scala</a> </li> <li> <a href="#update-engine-json">Update engine.json</a> </li> </ul> </aside><hr/><a id="edit-page-link" href="https://github.com/apache/incubator-predictionio/tree/livedoc/docs/manual/source/templates/classification/add-algorithm.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>Using Alternative Algorithm</h1></div></div><div class="content"><p>The classification template uses the Naive Bayes algorithm by default. You can easily add and use other MLlib classification algorithms. The following will demonstrate how to add the <a href="https://spark.apache.org/docs/latest/mllib-ensembles.html">MLlib Random Forests algorithm</a> into the engine.</p><h2 id='create-a-ne
 w-file-randomforestalgorithm.scala' class='header-anchors'>Create a new file RandomForestAlgorithm.scala</h2><p>Locate <code>src/main/scala/NaiveBayesAlgorithm.scala</code> under your engine directory, which should be /MyClassification if you are following the <a href="/templates/classification/quickstart/">Classification QuickStart</a>. Copy <code>NaiveBayesAlgorithm.scala</code> and create a new file <code>RandomForestAlgorithm.scala</code>. You will modify this file and follow the instructions below to define a new RandomForestAlgorithm class.</p><h2 id='define-the-algorithm-class-and-parameters' class='header-anchors'>Define the algorithm class and parameters</h2><p>In &#39;RandomForestAlgorithm.scala&#39;, import the MLlib Random Forests algorithm by changing the following lines:</p><p>Original</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</pre></td><td class="code"><pre><span class="k">import</span> <span class="nn">org.apache.spark.mllib.classification.NaiveBayes</span>
+<span class="k">import</span> <span class="nn">org.apache.spark.mllib.classification.NaiveBayesModel</span>
+</pre></td></tr></tbody></table> </div> <p>Change 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</pre></td><td class="code"><pre><span class="k">import</span> <span class="nn">org.apache.spark.mllib.tree.RandomForest</span> <span class="c1">// CHANGED
+</span><span class="k">import</span> <span class="nn">org.apache.spark.mllib.tree.model.RandomForestModel</span> <span class="c1">// CHANGED
+</span></pre></td></tr></tbody></table> </div> <p>These are the necessary classes in order to use the MLLib&#39;s Random Forest algporithm.</p><p>Modify the <code>AlgorithmParams</code> class for the Random Forest algorithm:</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</pre></td><td class="code"><pre><span class="c1">// CHANGED
+</span><span class="k">case</span> <span class="k">class</span> <span class="nc">RandomForestAlgorithmParams</span><span class="o">(</span>
+  <span class="n">numClasses</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span>
+  <span class="n">numTrees</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span>
+  <span class="n">featureSubsetStrategy</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span>
+  <span class="n">impurity</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span>
+  <span class="n">maxDepth</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span>
+  <span class="n">maxBins</span><span class="k">:</span> <span class="kt">Int</span>
+<span class="o">)</span> <span class="k">extends</span> <span class="nc">Params</span>
+</pre></td></tr></tbody></table> </div> <p>This class defines the parameters of the Random Forest algorithm (which later you can specify the value in engine.json). Please refer to <a href="https://spark.apache.org/docs/latest/mllib-ensembles.html">MLlib documentation</a> for the description and usage of these parameters.</p><p>Modify the <code>NaiveBayesAlgorithm</code> class to <code>RandomForestAlgorithm</code>. The changes are:</p> <ul> <li>The new <code>RandomForestAlgorithmParams</code> class is used as parameter.</li> <li><code>RandomForestModel</code> is used in type parameter. This is the model returned by the Random Forest algorithm.</li> <li>the <code>train()</code> function is modified and it returns the <code>RandomForestModel</code> instead of <code>NaiveBayesModel</code>.</li> <li>the <code>predict()</code> function takes the <code>RandomForestModel</code> as input.</li> </ul> <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
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33</pre></td><td class="code"><pre><span class="c1">// extends P2LAlgorithm because the MLlib's RandomForestModel doesn't
+// contain RDD.
+</span><span class="k">class</span> <span class="nc">RandomForestAlgorithm</span><span class="o">(</span><span class="k">val</span> <span class="n">ap</span><span class="k">:</span> <span class="kt">RandomForestAlgorithmParams</span><span class="o">)</span> <span class="c1">// CHANGED
+</span>  <span class="k">extends</span> <span class="n">P2LAlgorithm</span><span class="o">[</span><span class="kt">PreparedData</span>, <span class="kt">RandomForestModel</span>, <span class="kt">//</span> <span class="kt">CHANGED</span>
+  <span class="kt">Query</span>, <span class="kt">PredictedResult</span><span class="o">]</span> <span class="o">{</span>
+
+  <span class="c1">// CHANGED
+</span>  <span class="k">def</span> <span class="n">train</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">data</span><span class="k">:</span> <span class="kt">PreparedData</span><span class="o">)</span><span class="k">:</span> <span class="kt">RandomForestModel</span> <span class="o">=</span> <span class="o">{</span>
+    <span class="c1">// CHANGED
+</span>    <span class="c1">// Empty categoricalFeaturesInfo indicates all features are continuous.
+</span>    <span class="k">val</span> <span class="n">categoricalFeaturesInfo</span> <span class="k">=</span> <span class="nc">Map</span><span class="o">[</span><span class="kt">Int</span>, <span class="kt">Int</span><span class="o">]()</span>
+    <span class="nc">RandomForest</span><span class="o">.</span><span class="n">trainClassifier</span><span class="o">(</span>
+      <span class="n">data</span><span class="o">.</span><span class="n">labeledPoints</span><span class="o">,</span>
+      <span class="n">ap</span><span class="o">.</span><span class="n">numClasses</span><span class="o">,</span>
+      <span class="n">categoricalFeaturesInfo</span><span class="o">,</span>
+      <span class="n">ap</span><span class="o">.</span><span class="n">numTrees</span><span class="o">,</span>
+      <span class="n">ap</span><span class="o">.</span><span class="n">featureSubsetStrategy</span><span class="o">,</span>
+      <span class="n">ap</span><span class="o">.</span><span class="n">impurity</span><span class="o">,</span>
+      <span class="n">ap</span><span class="o">.</span><span class="n">maxDepth</span><span class="o">,</span>
+      <span class="n">ap</span><span class="o">.</span><span class="n">maxBins</span><span class="o">)</span>
+  <span class="o">}</span>
+
+  <span class="k">def</span> <span class="n">predict</span><span class="o">(</span>
+    <span class="n">model</span><span class="k">:</span> <span class="kt">RandomForestModel</span><span class="o">,</span> <span class="c1">// CHANGED
+</span>    <span class="n">query</span><span class="k">:</span> <span class="kt">Query</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">label</span> <span class="k">=</span> <span class="n">model</span><span class="o">.</span><span class="n">predict</span><span class="o">(</span><span class="nc">Vectors</span><span class="o">.</span><span class="n">dense</span><span class="o">(</span>
+        <span class="n">query</span><span class="o">.</span><span class="n">attr0</span><span class="o">,</span> <span class="n">query</span><span class="o">.</span><span class="n">attr1</span><span class="o">,</span> <span class="n">query</span><span class="o">.</span><span class="n">attr2</span>
+    <span class="o">))</span>
+    <span class="k">new</span> <span class="nc">PredictedResult</span><span class="o">(</span><span class="n">label</span><span class="o">)</span>
+  <span class="o">}</span>
+
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>Note that the MLlib Random Forest algorithm takes the same training data as the Navie Bayes algoithm (ie, RDD[LabeledPoint]) so you don&#39;t need to modify the <code>DataSource</code>, <code>TrainigData</code> and <code>PreparedData</code> classes. If the new algoritm to be added requires different types of training data, then you need to modify these classes accordingly to accomodate your new algorithm.</p><h2 id='update-engine.scala' class='header-anchors'>Update Engine.scala</h2><p>Modify the EngineFactory to add the new algorithm class <code>RandomForestAlgorithm</code> you just defined and give it a name <code>&quot;randomforest&quot;</code>. The name will be used in <code>engne.json</code> to specify which algorithm to use.</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</pre></td><td class="code"><pre><span class="k">object</span> <span class="nc">ClassificationEngine</span> <span class="k">extends</span> <span class="nc">IEngineFactory</span> <span class="o">{</span>
+  <span class="k">def</span> <span class="n">apply</span><span class="o">()</span> <span class="k">=</span> <span class="o">{</span>
+    <span class="k">new</span> <span class="nc">Engine</span><span class="o">(</span>
+      <span class="n">classOf</span><span class="o">[</span><span class="kt">DataSource</span><span class="o">],</span>
+      <span class="n">classOf</span><span class="o">[</span><span class="kt">Preparator</span><span class="o">],</span>
+      <span class="nc">Map</span><span class="o">(</span><span class="s">"naive"</span> <span class="o">-&gt;</span> <span class="n">classOf</span><span class="o">[</span><span class="kt">NaiveBayesAlgorithm</span><span class="o">],</span>
+        <span class="s">"randomforest"</span> <span class="o">-&gt;</span> <span class="n">classOf</span><span class="o">[</span><span class="kt">RandomForestAlgorithm</span><span class="o">]),</span> <span class="c1">// ADDED
+</span>      <span class="n">classOf</span><span class="o">[</span><span class="kt">Serving</span><span class="o">])</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>This engine factory now returns an engine with two algorithms and they are named as <code>&quot;naive&quot;</code> and <code>&quot;randomforest&quot;</code> respectively.</p><h2 id='update-engine.json' class='header-anchors'>Update engine.json</h2><p>In order to use the new algorithm, you need to modify <code>engine.json</code> to specify the name of the algorithm and the parameters.</p><p>Update the engine.json to use <strong>randomforest</strong>:</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
+10
+11
+12
+13
+14
+15</pre></td><td class="code"><pre><span class="err">...</span><span class="w">
+</span><span class="s2">"algorithms"</span><span class="err">:</span><span class="w"> </span><span class="p">[</span><span class="w">
+  </span><span class="p">{</span><span class="w">
+    </span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"randomforest"</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">"numClasses"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w">
+      </span><span class="s2">"numTrees"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w">
+      </span><span class="s2">"featureSubsetStrategy"</span><span class="p">:</span><span class="w"> </span><span class="s2">"auto"</span><span class="p">,</span><span class="w">
+      </span><span class="s2">"impurity"</span><span class="p">:</span><span class="w"> </span><span class="s2">"gini"</span><span class="p">,</span><span class="w">
+      </span><span class="s2">"maxDepth"</span><span class="p">:</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w">
+      </span><span class="s2">"maxBins"</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="w">
+    </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><span class="err">...</span><span class="w">
+</span></pre></td></tr></tbody></table> </div> <p>The engine now uses <strong>MLlib Random Forests algorithm</strong> instead of the default Naive Bayes algorithm. You are ready to build, train and deploy the engine as described in <a href="/templates/classification/quickstart/">quickstart</a>.</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> <div class="alert-message info"><p>To switch back using Naive Bayes algorithm, simply modify engine.json.</p></div></div></div></div></div><footer><div class="container"><div class="seperator"></div><div class="row"><div class="col-md-4 col-md-push-8 col-xs-12"><div class="subscription-form-wrapper"><h4>Subscribe to our Newsletter</h4><form class="ajax-form" id="subscribe-form" method="POST" action="https://script.google.com/macros/s/AKfycbwhzeKCQJjQ52eVAqNT_vcklH07OITUO7wzOMDXvK6EGAWgaZgF/exec"><input class="required underlined-input" type="email" placeholder="Your email address" name="subscription_email" id="subscription_email"/><input class="pill-button" value="SUBSCRIBE" type="submit" data-state-normal="SUBSCRIBE" data-state-sucess="SUBSCRIBED!" data-state-loading="SENDING..." onclick="t($('#subscription_email').val());"/><p class="result"></p></form></div></div><div class="col-md-2 col-md-pull-4 col-xs-6 footer-link-column"><div class="fo
 oter-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/PredictionIO/PredictionIO" target="blank">GitHub</a></li><li><a href="//groups.google.com/forum/#!forum/predictionio-user" target="blank">Support Forum</a></li><li><a href="//stackoverflow.com/questions/tagged/predictionio" target="blank">Stackoverflow</a></li><li><a href="mailto:&#x73;&#x75;&#x70;&#x70;&#x6F;&#x72;&#x74;&#x40;&#x70;&#x72;&#x65;&#x64;&#x69;&#x63;&#x74;&#x69;&#x6F;&#x6E;&#x2E;&#x69;&#x6F;" target="blank">Contact Us</a></li></ul></div></div><div class="col-md-2 col-md-pull-4 col-xs-6 footer-link-column"><div class="footer-link-column-row"><h4>Contribute</h4><ul><li><a href="//docs.prediction.io/community/contribute-code/" target="blank">Contribute</a></li><li><a href="//github.com/PredictionIO/PredictionIO" target="blank">Source Code</a></li><li><a href="//predi
 ctionio.atlassian.net/secure/Dashboard.jspa" target="blank">Bug Tracker</a></li><li><a href="//groups.google.com/forum/#!forum/predictionio-dev" target="blank">Contributors&#146; Forum</a></li><li><a href="//prediction.io/cla">Contributor Agreement</a></li><li><a href="//predictionio.uservoice.com/forums/219398-general/filters/top">Request Features</a></li></ul></div></div><div class="col-md-2 col-md-pull-4 col-xs-6 footer-link-column"><div class="footer-link-column-row"><h4>Enterprise</h4><ul><li><a href="//docs.prediction.io/support/" target="blank">Support</a></li><li><a href="//prediction.io/enterprise">Enterprise</a></li><li><a href="//prediction.io/products/predictionio-enterprise">Services</a></li></ul></div><div class="footer-link-column-row"><h4>Connect</h4><ul><li><a href="//blog.prediction.io/" target="blank">Blog</a></li><li><a href="//predictionio.theresumator.com/" target="blank">Careers</a></li></ul></div></div><div class="col-md-2 col-md-pull-4 col-xs-6 footer-link-c
 olumn"><div class="footer-link-column-row"><h4>Partnership</h4><ul><li><a href="//prediction.io/partners/program">Partner Program</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/PredictionIO/PredictionIO" data-style="mega" data-count-href="/PredictionIO/PredictionIO/stargazers" data-count-api="/repos/PredictionIO/PredictionIO#stargazers_count" data-count-aria-label="# stargazers on GitHub" aria-label="Star PredictionIO/PredictionIO on GitHub">Star</a> <a class="github-button" href="https://github.com/PredictionIO/PredictionIO/fork" data-icon="octicon-git-branch" data-style="mega" data-count-href="/PredictionIO/PredictionIO/network" data-count-api="/repos/PredictionIO/PredictionIO#forks_count" data-count-aria-label="# forks on
  GitHub" aria-label="Fork PredictionIO/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>var _qevents = _qevents || [];
+(function() {
+var elem = document.createElement('script');
+elem.src = (document.location.protocol == "https:" ? "https://secure" : "http://edge") + ".quantserve.com/quant.js";
+elem.async = true;
+elem.type = "text/javascript";
+var scpt = document.getElementsByTagName('script')[0];
+scpt.parentNode.insertBefore(elem, scpt);
+})();
+_qevents.push({
+qacct:"p-stVMxuw8H5EPX"
+});</script><noscript><div style="display:none;"><img src="//pixel.quantserve.com/pixel/p-stVMxuw8H5EPX.gif" border="0" height="1" width="1" alt="Quantcast"/></div></noscript><script>adroll_adv_id = "CPSSMJFFZ5DDHITC2STA54";
+adroll_pix_id = "UWX4N2WIMJADVHJGOFTM44";
+(function () {
+    var _onload = function(){
+        if (document.readyState && !/loaded|complete/.test(document.readyState)){setTimeout(_onload, 10);return}
+        if (!window.__adroll_loaded){__adroll_loaded=true;setTimeout(_onload, 50);return}
+        var scr = document.createElement("script");
+        var host = (("https:" == document.location.protocol) ? "https://s.adroll.com" : "http://a.adroll.com");
+        scr.setAttribute('async', 'true');
+        scr.type = "text/javascript";
+        scr.src = host + "/j/roundtrip.js";
+        ((document.getElementsByTagName('head') || [null])[0] ||
+            document.getElementsByTagName('script')[0].parentNode).appendChild(scr);
+    };
+    if (window.addEventListener) {window.addEventListener('load', _onload, false);}
+    else {window.attachEvent('onload', _onload)}
+}());</script><script src="/javascripts/application-5a24945b.js"></script></body></html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-predictionio-site/blob/92a45fa4/templates/classification/add-algorithm/index.html.gz
----------------------------------------------------------------------
diff --git a/templates/classification/add-algorithm/index.html.gz b/templates/classification/add-algorithm/index.html.gz
new file mode 100644
index 0000000..70c3af3
Binary files /dev/null and b/templates/classification/add-algorithm/index.html.gz differ

http://git-wip-us.apache.org/repos/asf/incubator-predictionio-site/blob/92a45fa4/templates/classification/dase/index.html
----------------------------------------------------------------------
diff --git a/templates/classification/dase/index.html b/templates/classification/dase/index.html
new file mode 100644
index 0000000..e4a6706
--- /dev/null
+++ b/templates/classification/dase/index.html
@@ -0,0 +1,267 @@
+<!DOCTYPE html><html><head><title>DASE Components Explained (Classification)</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="DASE Components Explained (Classification)"/><link rel="canonical" href="https://docs.prediction.io/templates/classification/dase/"/><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-3598c7d7.css" rel="stylesheet" type="text/css"/><!--[if lt IE 9]><script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.2/html5sh
 iv.min.js"></script><![endif]--><script src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ga('create', 'UA-38306178-1', 'auto');
+ga('require', 'linkid', 'linkid.js');
+ga('send', 'pageview');</script><script>!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","group","track","ready","alias","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="3.0.1";
+  analytics.load("YlF3updaI3DR96hnNgSGpR3PPBUGDzt8");
+  analytics.page()
+  }}();</script><script>RCX_CUSTOM_LIB="https://cdn.recontext.com/staging/rcx.min.js";
+(function(b,d,a){b.RCX_OBJECT=a;a=b[a]||[];if(!a.snipV&&!a.libV){b.rcx=a;a.snipV="0.2.0";var g=function(a,b,c,d){a[b]=a[b]||function(){c.push([d].concat(Array.prototype.slice.call(arguments)))}};b="init page track identify link setUserProperty unsetUserProperty".split(" ");for(var f=0;f<b.length;f++){var e,c;e=b[f];c=e.split(".");2==c.length?(a[c[0]]=a[c[0]]||[],g(a[c[0]],c[1],a,e)):g(a,e,a,e)}a=d.createElement("script");a.type="text/javascript";a.async=!0;a.src="undefined"!==typeof RCX_CUSTOM_LIB?
+RCX_CUSTOM_LIB:"https://cdn.recontext.com/rcx.min.js";d=d.getElementsByTagName("script")[0];d.parentNode.insertBefore(a,d)}})(window,document,"rcx");
+rcx.init("kTxFcI3IWdXYfRsh6uuYuej4qYl8m8LVMePM2hdIkM9YjHqkAFC6mqdqO9fpp8p9");
+rcx.page();</script><script>function t(e){analytics.identify(e); analytics.track("newsletter signup");
+  rcx.track("newsletter signup", { '_email': e });}</script><script>!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
+n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
+n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
+t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
+document,'script','//connect.facebook.net/en_US/fbevents.js');
+
+fbq('init', '1073028432707778');
+fbq('track', "PageView");</script><script src="//use.typekit.net/mut4mjx.js"></script><script>try{Typekit.load();}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://prediction.io/"><img alt="PredictionIO" id="logo" src="/images/logos/logo-ee2b9bb3.png"/></a></div><div id="menu-wrapper"><div id="header-nav-options-wrapper"><ul><li><a href="/">Install & Doc</a></li> <li><a href="/support">Support</a></li> </ul></div><div id="pill-wrapper"><a class="pill left" href="//templates.prediction.io/">TEMPLATES</a> <a class="pill right" href="//github.com/PredictionIO/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 class="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>DASE Components Explained (Classification)</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 c
 lass="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=
 "/cli/#engine-commands"><span>Engine Command-line Interface</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="/dataco
 llection/"><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="leve
 l-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="http://templates.prediction.io"><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/c
 ommunity/"><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>Community Support</span></a></li><li class="level-2"><a class="final" href="/support/#enterprise-support"><span>Enterprise 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>DASE Components Explained (Classification)</h1></div></div><div id="table-of-content-wrapper"><h5>On this page</h5><aside id="table-of-contents"><ul> <li> <a href="#the-engine-design">The Engine Desi
 gn</a> </li> <li> <a href="#data">Data</a> </li> <li> <a href="#algorithm">Algorithm</a> </li> <li> <a href="#serving">Serving</a> </li> </ul> </aside><hr/><a id="edit-page-link" href="https://github.com/apache/incubator-predictionio/tree/livedoc/docs/manual/source/templates/classification/dase.html.md.erb"><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>DASE Components Explained (Classification)</h1></div></div><div class="content"><p>PredictionIO&#39;s DASE architecture brings the separation-of-concerns design principle to predictive engine development. DASE stands for the following components of an engine:</p> <ul> <li><strong>D</strong>ata - includes Data Source and Data Preparator</li> <li><strong>A</strong>lgorithm(s)</li> <li><strong>S</strong>erving</li> <li><strong>E</strong>valuator</li> </ul> <p><p>Let&#39;s look at the code and see how you can customize the engine you buil
 t from the Classification Engine Template.</p><div class="alert-message note"><p>Evaluator will not be covered in this tutorial. Please visit <a href="/evaluation/paramtuning/">evaluation explained</a> for using evaluation.</p></div></p><h2 id='the-engine-design' class='header-anchors'>The Engine Design</h2><p>As you can see from the Quick Start, <em>MyClassification</em> takes a JSON prediction query, e.g. <code>{ &quot;attr0&quot;:4, &quot;attr1&quot;:3, &quot;attr2&quot;:8 }</code>, and return a JSON predicted result.</p><div class="alert-message warning"><p>for version &lt; v0.3.1, it is array of features values: <code>{ &quot;features&quot;: [4, 3, 8] }</code></p></div><p>In MyClassification/src/main/scala/<strong><em>Engine.scala</em></strong>, the <code>Query</code> case class defines the format of <strong>query</strong>, such as <code>{ &quot;attr0&quot;:4, &quot;attr1&quot;:3, &quot;attr2&quot;:8 }</code>:</p><div class="highlight scala"><table style="border-spacing: 0"><tb
 ody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
+2
+3
+4
+5
+6</pre></td><td class="code"><pre><span class="k">class</span> <span class="nc">Query</span><span class="o">(</span>
+  <span class="k">val</span> <span class="n">attr0</span> <span class="k">:</span> <span class="kt">Double</span><span class="o">,</span>
+  <span class="k">val</span> <span class="n">attr1</span> <span class="k">:</span> <span class="kt">Double</span><span class="o">,</span>
+  <span class="k">val</span> <span class="n">attr2</span> <span class="k">:</span> <span class="kt">Double</span>
+<span class="o">)</span> <span class="k">extends</span> <span class="nc">Serializable</span>
+
+</pre></td></tr></tbody></table> </div> <p>The <code>PredictedResult</code> case class defines the format of <strong>predicted result</strong>, such as <code>{&quot;label&quot;:2.0}</code>:</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</pre></td><td class="code"><pre><span class="k">class</span> <span class="nc">PredictedResult</span><span class="o">(</span>
+  <span class="k">val</span> <span class="n">label</span><span class="k">:</span> <span class="kt">Double</span>
+<span class="o">)</span> <span class="k">extends</span> <span class="nc">Serializable</span>
+</pre></td></tr></tbody></table> </div> <p>Finally, <code>ClassificationEngine</code> is the Engine Factory that defines the components this engine will use: Data Source, Data Preparator, Algorithm(s) and Serving components.</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</pre></td><td class="code"><pre><span class="k">object</span> <span class="nc">ClassificationEngine</span> <span class="k">extends</span> <span class="nc">IEngineFactory</span> <span class="o">{</span>
+  <span class="k">def</span> <span class="n">apply</span><span class="o">()</span> <span class="k">=</span> <span class="o">{</span>
+    <span class="k">new</span> <span class="nc">Engine</span><span class="o">(</span>
+      <span class="n">classOf</span><span class="o">[</span><span class="kt">DataSource</span><span class="o">],</span>
+      <span class="n">classOf</span><span class="o">[</span><span class="kt">Preparator</span><span class="o">],</span>
+      <span class="nc">Map</span><span class="o">(</span><span class="s">"naive"</span> <span class="o">-&gt;</span> <span class="n">classOf</span><span class="o">[</span><span class="kt">NaiveBayesAlgorithm</span><span class="o">]),</span>
+      <span class="n">classOf</span><span class="o">[</span><span class="kt">Serving</span><span class="o">])</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <h3 id='spark-mllib' class='header-anchors'>Spark MLlib</h3><p>Spark&#39;s MLlib NaiveBayes algorithm takes training data of RDD type, i.e. <code>RDD[LabeledPoint]</code> and train a model, which is a <code>NaiveBayesModel</code> object.</p><p>PredictionIO&#39;s MLlib Classification engine template, which <em>MyClassification</em> bases on, integrates this algorithm under the DASE architecture. We will take a closer look at the DASE code below.</p> <blockquote> <p><a href="https://spark.apache.org/docs/latest/mllib-naive-bayes.html">Check this out</a> to learn more about MLlib&#39;s NaiveBayes algorithm.</p></blockquote> <h2 id='data' class='header-anchors'>Data</h2><p>In the DASE architecture, data is prepared by 2 components sequentially: <em>Data Source</em> and <em>Data Preparator</em>. <em>Data Source</em> and <em>Data Preparator</em> takes data from the data store and prepares <code>RDD[LabeledPoint]</code> for the NaiveBayes algorithm.<
 /p><h3 id='data-source' class='header-anchors'>Data Source</h3><p>In MyClassification/src/main/scala/<strong><em>DataSource.scala</em></strong>, the <code>readTraining</code> method of the class <code>DataSource</code> reads, and selects, data from datastore of EventServer and it returns <code>TrainingData</code>.</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
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38</pre></td><td class="code"><pre><span class="k">case</span> <span class="k">class</span> <span class="nc">DataSourceParams</span><span class="o">(</span><span class="n">appName</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">DataSource</span><span class="o">(</span><span class="k">val</span> <span class="n">dsp</span><span class="k">:</span> <span class="kt">DataSourceParams</span><span class="o">)</span>
+  <span class="k">extends</span> <span class="nc">PDataSource</span><span class="o">[</span><span class="kt">TrainingData</span>, <span class="kt">EmptyEvaluationInfo</span>, <span class="kt">Query</span>, <span class="kt">EmptyActualResult</span><span class="o">]</span> <span class="o">{</span>
+
+  <span class="nd">@transient</span> <span class="k">lazy</span> <span class="k">val</span> <span class="n">logger</span> <span class="k">=</span> <span class="nc">Logger</span><span class="o">[</span><span class="kt">this.</span><span class="k">type</span><span class="o">]</span>
+
+  <span class="k">override</span>
+  <span class="k">def</span> <span class="n">readTraining</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="k">:</span> <span class="kt">TrainingData</span> <span class="o">=</span> <span class="o">{</span>
+
+    <span class="k">val</span> <span class="n">labeledPoints</span><span class="k">:</span> <span class="kt">RDD</span><span class="o">[</span><span class="kt">LabeledPoint</span><span class="o">]</span> <span class="k">=</span> <span class="nc">PEventStore</span><span class="o">.</span><span class="n">aggregateProperties</span><span class="o">(</span>
+      <span class="n">appName</span> <span class="k">=</span> <span class="n">dsp</span><span class="o">.</span><span class="n">appName</span><span class="o">,</span>
+      <span class="n">entityType</span> <span class="k">=</span> <span class="s">"user"</span><span class="o">,</span>
+      <span class="c1">// only keep entities with these required properties defined
+</span>      <span class="n">required</span> <span class="k">=</span> <span class="nc">Some</span><span class="o">(</span><span class="nc">List</span><span class="o">(</span><span class="s">"plan"</span><span class="o">,</span> <span class="s">"attr0"</span><span class="o">,</span> <span class="s">"attr1"</span><span class="o">,</span> <span class="s">"attr2"</span><span class="o">)))(</span><span class="n">sc</span><span class="o">)</span>
+      <span class="c1">// aggregateProperties() returns RDD pair of
+</span>      <span class="c1">// entity ID and its aggregated properties
+</span>      <span class="o">.</span><span class="n">map</span> <span class="o">{</span> <span class="k">case</span> <span class="o">(</span><span class="n">entityId</span><span class="o">,</span> <span class="n">properties</span><span class="o">)</span> <span class="k">=&gt;</span>
+        <span class="k">try</span> <span class="o">{</span>
+          <span class="nc">LabeledPoint</span><span class="o">(</span><span class="n">properties</span><span class="o">.</span><span class="n">get</span><span class="o">[</span><span class="kt">Double</span><span class="o">](</span><span class="s">"plan"</span><span class="o">),</span>
+            <span class="nc">Vectors</span><span class="o">.</span><span class="n">dense</span><span class="o">(</span><span class="nc">Array</span><span class="o">(</span>
+              <span class="n">properties</span><span class="o">.</span><span class="n">get</span><span class="o">[</span><span class="kt">Double</span><span class="o">](</span><span class="s">"attr0"</span><span class="o">),</span>
+              <span class="n">properties</span><span class="o">.</span><span class="n">get</span><span class="o">[</span><span class="kt">Double</span><span class="o">](</span><span class="s">"attr1"</span><span class="o">),</span>
+              <span class="n">properties</span><span class="o">.</span><span class="n">get</span><span class="o">[</span><span class="kt">Double</span><span class="o">](</span><span class="s">"attr2"</span><span class="o">)</span>
+            <span class="o">))</span>
+          <span class="o">)</span>
+        <span class="o">}</span> <span class="k">catch</span> <span class="o">{</span>
+          <span class="k">case</span> <span class="n">e</span><span class="k">:</span> <span class="kt">Exception</span> <span class="o">=&gt;</span> <span class="o">{</span>
+            <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="o">(</span><span class="n">s</span><span class="s">"Failed to get properties ${properties} of"</span> <span class="o">+</span>
+              <span class="n">s</span><span class="s">" ${entityId}. Exception: ${e}."</span><span class="o">)</span>
+            <span class="k">throw</span> <span class="n">e</span>
+          <span class="o">}</span>
+        <span class="o">}</span>
+      <span class="o">}.</span><span class="n">cache</span><span class="o">()</span>
+
+    <span class="k">new</span> <span class="nc">TrainingData</span><span class="o">(</span><span class="n">labeledPoints</span><span class="o">)</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p><code>PEventStore</code> is an object which provides function to access data that is collected through the <em>Event Server</em>, and <code>PEventStore.aggregateProperties</code> aggregates the event records of the 4 properties (attr0, attr1, attr2 and plan) for each user.</p><p>PredictionIO automatically loads the parameters of <em>datasource</em> specified in MyEngine/<strong><em>engine.json</em></strong>, including <em>appName</em>, to <code>dsp</code>.</p><p>In <strong><em>engine.json</em></strong>:</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
+8
+9</pre></td><td class="code"><pre><span class="o">{</span>
+  ...
+  <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">"MyApp1"</span>
+    <span class="o">}</span>
+  <span class="o">}</span>,
+  ...
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>In this sample text data file, columns are delimited by comma (,). The first column are labels. The second column are features.</p><p>The class definition of <code>TrainingData</code> is:</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</pre></td><td class="code"><pre><span class="k">class</span> <span class="nc">TrainingData</span><span class="o">(</span>
+  <span class="k">val</span> <span class="n">labeledPoints</span><span class="k">:</span> <span class="kt">RDD</span><span class="o">[</span><span class="kt">LabeledPoint</span><span class="o">]</span>
+<span class="o">)</span> <span class="k">extends</span> <span class="nc">Serializable</span>
+</pre></td></tr></tbody></table> </div> <p>and PredictionIO passes the returned <code>TrainingData</code> object to <em>Data Preparator</em>.</p><h3 id='data-preparator' class='header-anchors'>Data Preparator</h3><p>In MyClassification/src/main/scala/<strong><em>Preparator.scala</em></strong>, the <code>prepare</code> of class <code>Preparator</code> takes <code>TrainingData</code>. It then conducts any necessary feature selection and data processing tasks. At the end, it returns <code>PreparedData</code> which should contain the data <em>Algorithm</em> needs. For MLlib NaiveBayes, it is <code>RDD[LabeledPoint]</code>.</p><p>By default, <code>prepare</code> simply copies the unprocessed <code>TrainingData</code> data to <code>PreparedData</code>:</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</pre></td><td class="code"><pre><span class="k">class</span> <span class="nc">PreparedData</span><span class="o">(</span>
+  <span class="k">val</span> <span class="n">labeledPoints</span><span class="k">:</span> <span class="kt">RDD</span><span class="o">[</span><span class="kt">LabeledPoint</span><span class="o">]</span>
+<span class="o">)</span> <span class="k">extends</span> <span class="nc">Serializable</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="k">new</span> <span class="nc">PreparedData</span><span class="o">(</span><span class="n">trainingData</span><span class="o">.</span><span class="n">labeledPoints</span><span class="o">)</span>
+  <span class="o">}</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>PredictionIO passes the returned <code>PreparedData</code> object to Algorithm&#39;s <code>train</code> function.</p><h2 id='algorithm' class='header-anchors'>Algorithm</h2><p>In MyClassification/src/main/scala/<strong><em>NaiveBayesAlgorithm.scala</em></strong>, the two methods of the algorithm class are <code>train</code> and <code>predict</code>. <code>train</code> is responsible for training a predictive model. PredictionIO will store this model and <code>predict</code> is responsible for using this model to make prediction.</p><h3 id='train(...)' class='header-anchors'>train(...)</h3><p><code>train</code> is called when you run <strong>pio train</strong>. This is where MLlib NaiveBayes algorithm, i.e. <code>NaiveBayes.train</code>, is used to train a predictive model.</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</pre></td><td class="code"><pre><span class="k">def</span> <span class="n">train</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">data</span><span class="k">:</span> <span class="kt">PreparedData</span><span class="o">)</span><span class="k">:</span> <span class="kt">NaiveBayesModel</span> <span class="o">=</span> <span class="o">{</span>
+    <span class="nc">NaiveBayes</span><span class="o">.</span><span class="n">train</span><span class="o">(</span><span class="n">data</span><span class="o">.</span><span class="n">labeledPoints</span><span class="o">,</span> <span class="n">ap</span><span class="o">.</span><span class="n">lambda</span><span class="o">)</span>
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>In addition to <code>RDD[LabeledPoint]</code> (i.e. <code>data.labeledPoints</code>), <code>NaiveBayes.train</code> takes 1 parameter: <em>lambda</em>.</p><p>The values of this parameter is specified in <em>algorithms</em> of MyClassification/<strong><em>engine.json</em></strong>:</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
+8
+9
+10
+11
+12</pre></td><td class="code"><pre><span class="o">{</span>
+  ...
+  <span class="s2">"algorithms"</span>: <span class="o">[</span>
+    <span class="o">{</span>
+      <span class="s2">"name"</span>: <span class="s2">"naive"</span>,
+      <span class="s2">"params"</span>: <span class="o">{</span>
+        <span class="s2">"lambda"</span>: 1.0
+      <span class="o">}</span>
+    <span class="o">}</span>
+  <span class="o">]</span>
+  ...
+<span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <p>PredictionIO will automatically loads these values into the constructor <code>ap</code>, which has a corresponding case case <code>AlgorithmParams</code>:</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</pre></td><td class="code"><pre><span class="k">case</span> <span class="k">class</span> <span class="nc">AlgorithmParams</span><span class="o">(</span>
+  <span class="n">lambda</span><span class="k">:</span> <span class="kt">Double</span>
+<span class="o">)</span> <span class="k">extends</span> <span class="nc">Params</span>
+</pre></td></tr></tbody></table> </div> <p><code>NaiveBayes.train</code> then returns a <code>NaiveBayesModel</code> model. PredictionIO will automatically store the returned model.</p><h3 id='predict(...)' class='header-anchors'>predict(...)</h3><p>The <code>predict</code> method is called when you send a JSON query to <a href="http://localhost:8000/queries.json">http://localhost:8000/queries.json</a>. PredictionIO converts the query, such as <code>{ &quot;attr0&quot;:4, &quot;attr1&quot;:3, &quot;attr2&quot;:8 }</code> to the <code>Query</code> class you defined previously.</p><p>The predictive model <code>NaiveBayesModel</code> of MLlib NaiveBayes offers a function called <code>predict</code>. <code>predict</code> takes a dense vector of features. It predicts the label of the item represented by this feature vector.</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</pre></td><td class="code"><pre>  <span class="k">def</span> <span class="n">predict</span><span class="o">(</span><span class="n">model</span><span class="k">:</span> <span class="kt">NaiveBayesModel</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="k">:</span> <span class="kt">PredictedResult</span> <span class="o">=</span> <span class="o">{</span>
+    <span class="k">val</span> <span class="n">label</span> <span class="k">=</span> <span class="n">model</span><span class="o">.</span><span class="n">predict</span><span class="o">(</span><span class="nc">Vectors</span><span class="o">.</span><span class="n">dense</span><span class="o">(</span>
+        <span class="n">query</span><span class="o">.</span><span class="n">attr0</span><span class="o">,</span> <span class="n">query</span><span class="o">.</span><span class="n">attr1</span><span class="o">,</span> <span class="n">query</span><span class="o">.</span><span class="n">attr2</span>
+    <span class="o">))</span>
+    <span class="k">new</span> <span class="nc">PredictedResult</span><span class="o">(</span><span class="n">label</span><span class="o">)</span>
+  <span class="o">}</span>
+</pre></td></tr></tbody></table> </div> <blockquote> <p>You have defined the class <code>PredictedResult</code> earlier in this page.</p></blockquote> <p>PredictionIO passes the returned <code>PredictedResult</code> object to <em>Serving</em>.</p><h2 id='serving' class='header-anchors'>Serving</h2><p>The <code>serve</code> method of class <code>Serving</code> processes predicted result. It is also responsible for combining multiple predicted results into one if you have more than one predictive model. <em>Serving</em> then returns the final predicted result. PredictionIO will convert it to a JSON response automatically.</p><p>In MyClassification/src/main/scala/<strong><em>Serving.scala</em></strong>,</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</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>When you send a JSON query to <a href="http://localhost:8000/queries.json">http://localhost:8000/queries.json</a>, <code>PredictedResult</code> from all models will be passed to <code>serve</code> as a sequence, i.e. <code>Seq[PredictedResult]</code>.</p> <blockquote> <p>An engine can train multiple models if you specify more than one Algorithm component in <code>object RecommendationEngine</code> inside <strong><em>Engine.scala</em></strong>. Since only one <code>NaiveBayesAlgorithm</code> is implemented by default, this <code>Seq</code> contains one element.</p></blockquote> <p>In this case, <code>serve</code> simply returns the predicted result of the first, and the only, algorithm, i.e. <code>predictedResults.head</code>.</p><p>Congratulations! You have just learned how to customize and build a production-ready engine. Have fun!</p></div></div></div></div><footer><div class="container"><div class="seperator"></div><div class="row"><div 
 class="col-md-4 col-md-push-8 col-xs-12"><div class="subscription-form-wrapper"><h4>Subscribe to our Newsletter</h4><form class="ajax-form" id="subscribe-form" method="POST" action="https://script.google.com/macros/s/AKfycbwhzeKCQJjQ52eVAqNT_vcklH07OITUO7wzOMDXvK6EGAWgaZgF/exec"><input class="required underlined-input" type="email" placeholder="Your email address" name="subscription_email" id="subscription_email"/><input class="pill-button" value="SUBSCRIBE" type="submit" data-state-normal="SUBSCRIBE" data-state-sucess="SUBSCRIBED!" data-state-loading="SENDING..." onclick="t($('#subscription_email').val());"/><p class="result"></p></form></div></div><div class="col-md-2 col-md-pull-4 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/PredictionIO/PredictionIO" target="blank">GitHub</a
 ></li><li><a href="//groups.google.com/forum/#!forum/predictionio-user" target="blank">Support Forum</a></li><li><a href="//stackoverflow.com/questions/tagged/predictionio" target="blank">Stackoverflow</a></li><li><a href="mailto:&#x73;&#x75;&#x70;&#x70;&#x6F;&#x72;&#x74;&#x40;&#x70;&#x72;&#x65;&#x64;&#x69;&#x63;&#x74;&#x69;&#x6F;&#x6E;&#x2E;&#x69;&#x6F;" target="blank">Contact Us</a></li></ul></div></div><div class="col-md-2 col-md-pull-4 col-xs-6 footer-link-column"><div class="footer-link-column-row"><h4>Contribute</h4><ul><li><a href="//docs.prediction.io/community/contribute-code/" target="blank">Contribute</a></li><li><a href="//github.com/PredictionIO/PredictionIO" target="blank">Source Code</a></li><li><a href="//predictionio.atlassian.net/secure/Dashboard.jspa" target="blank">Bug Tracker</a></li><li><a href="//groups.google.com/forum/#!forum/predictionio-dev" target="blank">Contributors&#146; Forum</a></li><li><a href="//prediction.io/cla">Contributor Agreement</a></li><li>
 <a href="//predictionio.uservoice.com/forums/219398-general/filters/top">Request Features</a></li></ul></div></div><div class="col-md-2 col-md-pull-4 col-xs-6 footer-link-column"><div class="footer-link-column-row"><h4>Enterprise</h4><ul><li><a href="//docs.prediction.io/support/" target="blank">Support</a></li><li><a href="//prediction.io/enterprise">Enterprise</a></li><li><a href="//prediction.io/products/predictionio-enterprise">Services</a></li></ul></div><div class="footer-link-column-row"><h4>Connect</h4><ul><li><a href="//blog.prediction.io/" target="blank">Blog</a></li><li><a href="//predictionio.theresumator.com/" target="blank">Careers</a></li></ul></div></div><div class="col-md-2 col-md-pull-4 col-xs-6 footer-link-column"><div class="footer-link-column-row"><h4>Partnership</h4><ul><li><a href="//prediction.io/partners/program">Partner Program</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/PredictionIO/PredictionIO" data-style="mega" data-count-href="/PredictionIO/PredictionIO/stargazers" data-count-api="/repos/PredictionIO/PredictionIO#stargazers_count" data-count-aria-label="# stargazers on GitHub" aria-label="Star PredictionIO/PredictionIO on GitHub">Star</a> <a class="github-button" href="https://github.com/PredictionIO/PredictionIO/fork" data-icon="octicon-git-branch" data-style="mega" data-count-href="/PredictionIO/PredictionIO/network" data-count-api="/repos/PredictionIO/PredictionIO#forks_count" data-count-aria-label="# forks on GitHub" aria-label="Fork PredictionIO/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>var _qevents = _qevents || [];
+(function() {
+var elem = document.createElement('script');
+elem.src = (document.location.protocol == "https:" ? "https://secure" : "http://edge") + ".quantserve.com/quant.js";
+elem.async = true;
+elem.type = "text/javascript";
+var scpt = document.getElementsByTagName('script')[0];
+scpt.parentNode.insertBefore(elem, scpt);
+})();
+_qevents.push({
+qacct:"p-stVMxuw8H5EPX"
+});</script><noscript><div style="display:none;"><img src="//pixel.quantserve.com/pixel/p-stVMxuw8H5EPX.gif" border="0" height="1" width="1" alt="Quantcast"/></div></noscript><script>adroll_adv_id = "CPSSMJFFZ5DDHITC2STA54";
+adroll_pix_id = "UWX4N2WIMJADVHJGOFTM44";
+(function () {
+    var _onload = function(){
+        if (document.readyState && !/loaded|complete/.test(document.readyState)){setTimeout(_onload, 10);return}
+        if (!window.__adroll_loaded){__adroll_loaded=true;setTimeout(_onload, 50);return}
+        var scr = document.createElement("script");
+        var host = (("https:" == document.location.protocol) ? "https://s.adroll.com" : "http://a.adroll.com");
+        scr.setAttribute('async', 'true');
+        scr.type = "text/javascript";
+        scr.src = host + "/j/roundtrip.js";
+        ((document.getElementsByTagName('head') || [null])[0] ||
+            document.getElementsByTagName('script')[0].parentNode).appendChild(scr);
+    };
+    if (window.addEventListener) {window.addEventListener('load', _onload, false);}
+    else {window.attachEvent('onload', _onload)}
+}());</script><script src="/javascripts/application-5a24945b.js"></script></body></html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-predictionio-site/blob/92a45fa4/templates/classification/dase/index.html.gz
----------------------------------------------------------------------
diff --git a/templates/classification/dase/index.html.gz b/templates/classification/dase/index.html.gz
new file mode 100644
index 0000000..a209288
Binary files /dev/null and b/templates/classification/dase/index.html.gz differ