Skip to content

Commit

Permalink
Refactor SVC implementation and templates
Browse files Browse the repository at this point in the history
  • Loading branch information
nok committed Oct 22, 2017
1 parent c483d25 commit cd8f52e
Show file tree
Hide file tree
Showing 19 changed files with 450 additions and 306 deletions.
223 changes: 151 additions & 72 deletions examples/estimator/classifier/SVC/js/basics.ipynb

Large diffs are not rendered by default.

207 changes: 143 additions & 64 deletions examples/estimator/classifier/SVC/js/basics.py

Large diffs are not rendered by default.

Expand Up @@ -120,7 +120,7 @@ public int {method_name}(double[] features) {{
classIdx= i;
}}
}}
return classes[classIdx];
return this.classes[classIdx];

}}
}}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

35 changes: 29 additions & 6 deletions sklearn_porter/estimator/classifier/SVC/templates/js/class.txt
@@ -1,16 +1,39 @@
// Array.prototype.fill polyfill:
[].fill||(Array.prototype.fill=function(a){{for(var b=Object(this),c=parseInt(b.length,10),d=arguments[1],e=parseInt(d,10)||0,f=0>e?Math.max(c+e,0):Math.min(e,c),g=arguments[2],h=void 0===g?c:parseInt(g)||0,i=0>h?Math.max(c+h,0):Math.min(h,c);i>f;f++)b[f]=a;return b}});
var {class_name} = function(nClasses, vectors, coefficients, intercepts, weights, kernel, gamma, coef0, degree) {{

var {class_name} = function() {{
this.nClasses = nClasses;
this.classes = new Array(nClasses);
for (var i = 0; i < nClasses; i++) {{
this.classes[i] = i;
}}
this.vectors = vectors;
this.coefficients = coefficients;
this.intercepts = intercepts;
this.weights = weights;
this.kernel = kernel.toUpperCase();
this.gamma = gamma;
this.coef0 = coef0;
this.degree = degree;

{method}

}};

if (typeof process !== 'undefined' && typeof process.argv !== 'undefined') {{
if (process.argv.length - 2 == {n_features}) {{
var argv = process.argv.slice(2);
var prediction = new {class_name}().{method_name}(argv);
if (process.argv.length - 2 === {n_features}) {{

// Features:
var features = process.argv.slice(2);

// Parameters:
{vectors}
{coefficients}
{intercepts}
{weights}

// Prediction:
var clf = new {class_name}({n_classes}, vectors, coefficients, intercepts, weights, "{kernel}", {gamma}, {coef0}, {degree});
var prediction = clf.{method_name}(features);
console.log(prediction);

}}
}}
4 changes: 0 additions & 4 deletions sklearn_porter/estimator/classifier/SVC/templates/js/ends.txt

This file was deleted.

130 changes: 126 additions & 4 deletions sklearn_porter/estimator/classifier/SVC/templates/js/method.txt
@@ -1,4 +1,126 @@
this.{method_name} = function(atts) {{
var i, j, k, d, l;
{decicion}
}};
this.{method_name} = function(features) {{

var kernels = new Array(vectors.length);
var kernel;
switch (this.kernel) {{
case 'LINEAR':
// <x,x'>
for (var i = 0; i < this.vectors.length; i++) {{
kernel = 0.;
for (var j = 0; j < this.vectors[i].length; j++) {{
kernel += this.vectors[i][j] * features[j];
}}
kernels[i] = kernel;
}}
break;
case 'POLY':
// (y<x,x'>+r)^d
for (var i = 0; i < this.vectors.length; i++) {{
kernel = 0.;
for (var j = 0; j < this.vectors[i].length; j++) {{
kernel += this.vectors[i][j] * features[j];
}}
kernels[i] = Math.pow((this.gamma * kernel) + this.coef0, this.degree);
}}
break;
case 'RBF':
// exp(-y|x-x'|^2)
for (var i = 0; i < this.vectors.length; i++) {{
kernel = 0.;
for (var j = 0; j < this.vectors[i].length; j++) {{
kernel += Math.pow(this.vectors[i][j] - features[j], 2);
}}
kernels[i] = Math.exp(-this.gamma * kernel);
}}
break;
case 'SIGMOID':
// tanh(y<x,x'>+r)
for (var i = 0; i < this.vectors.length; i++) {{
kernel = 0.;
for (var j = 0; j < this.vectors[i].length; j++) {{
kernel += this.vectors[i][j] * features[j];
}}
kernels[i] = Math.tanh((this.gamma * kernel) + this.coef0);
}}
break;
}}

var starts = new Array(this.nClasses);
for (var i = 0; i < this.nClasses; i++) {{
if (i != 0) {{
var start = 0;
for (var j = 0; j < i; j++) {{
start += this.weights[j];
}}
starts[i] = start;
}} else {{
starts[0] = 0;
}}
}}

var ends = new Array(this.nClasses);
for (var i = 0; i < this.nClasses; i++) {{
ends[i] = this.weights[i] + starts[i];
}}

if (this.nClasses == 2) {{

for (var i = 0; i < kernels.length; i++) {{
kernels[i] = -kernels[i];
}}

var decision = 0.;
for (var k = starts[1]; k < ends[1]; k++) {{
decision += kernels[k] * this.coefficients[0][k];
}}
for (var k = starts[0]; k < ends[0]; k++) {{
decision += kernels[k] * this.coefficients[0][k];
}}
decision += this.intercepts[0];

if (decision > 0) {{
return 0;
}}
return 1;

}} else {{

var decisions = new Array(this.nClasses);
for (var i = 0, d = 0, l = this.nClasses; i < l; i++) {{
for (var j = i + 1; j < l; j++) {{
var tmp = 0.;
for (var k = starts[j]; k < ends[j]; k++) {{
tmp += this.coefficients[i][k] * kernels[k];
}}
for (var k = starts[i]; k < ends[i]; k++) {{
tmp += this.coefficients[j - 1][k] * kernels[k];
}}
decisions[d] = tmp + this.intercepts[d];
d++;
}}
}}

var votes = new Array(this.intercepts.length);
for (var i = 0, d = 0, l = this.nClasses; i < l; i++) {{
for (var j = i + 1; j < l; j++) {{
votes[d] = decisions[d] > 0 ? i : j;
d++;
}}
}}

var amounts = new Array(this.nClasses).fill(0);
for (var i = 0, l = votes.length; i < l; i++) {{
amounts[votes[i]] += 1;
}}

var classVal = -1, classIdx = -1;
for (var i = 0, l = amounts.length; i < l; i++) {{
if (amounts[i] > classVal) {{
classVal = amounts[i];
classIdx= i;
}}
}}
return this.classes[classIdx];

}}
}}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

12 changes: 0 additions & 12 deletions sklearn_porter/estimator/classifier/SVC/templates/js/starts.txt

This file was deleted.

0 comments on commit cd8f52e

Please sign in to comment.