Comparing version 1.0.1 to 1.0.2
@@ -1,1 +0,1 @@ | ||
var jssvm=jssvm||{};!function(t){t.small=function(){for(var t=.5,r=1*t+1;r>1;)r=1*(t/=2)+1;return 2*t*2},t.quickSort=function(r,s){t._quickSort(r,0,r.length-1,s)},t._quickSort=function(r,s,i,a){if(!(s>=i)){var h=t._partition(r,s,i,a);t._quickSort(r,s,h-1,a),t._quickSort(r,h+1,i,a)}},t._partition=function(r,s,i,a){for(var h=r[s],o=s,e=i+1;;){for(;a(h,r[++o])>0&&!(o>=i););for(;a(h,r[--e])<0&&!(e<=s););if(o>=e)break;t._exchange(r,o,e)}return t._exchange(r,s,e),e},t._exchange=function(t,r,s){var i=t[r];t[r]=t[s],t[s]=i},t.deltaStep=function(t){var r=Math.sqrt(this.small()),s=Math.max(1,Math.abs(t)),i=Math.max(0,Math.abs(r*s));return t<0&&(i=-i),i},t.dotProduct=function(t,r){for(var s=0,i=r.length,a=0;a<i;++a)s+=t[a]*r[a];return s};var r=function(t){(t=t||{}).iterations||(t.iterations=100),t.alpha||(t.alpha=1e-4),t.C||(t.C=1),t.trace||(t.trace=!1),this.iterations=t.iterations,this.alpha=t.alpha,this.C=t.C,this.trace=t.trace};r.prototype.fit=function(t){this.dim=t[0].length;for(var r=t.length,s=[],i=[],a=0;a<r;++a){var h=t[a],o=[],e=h[h.length-1];o.push(1);for(var n=0;n<h.length-1;++n)o.push(h[n]);s.push(o),i.push(e)}this.theta=[];for(c=0;c<this.dim;++c)this.theta.push(0);for(var f=0;f<this.iterations;++f){for(var l=this.grad(s,i,this.theta),c=0;c<this.dim;++c)this.theta[c]=this.theta[c]-this.alpha*l[c];this.trace&&console.log("cost: "+this.cost(s,i,this.theta))}var u=this.transform(t);this.threshold=null;for(var r=t.length,a=0;a<r;++a)1==t[a][this.dim-1]&&(null==this.threshold||this.threshold>u[a])&&(this.threshold=u[a]);return{theta:this.theta,cost:this.cost(s,i,this.theta),threshold:this.threshold,config:{alpha:this.alpha,C:this.C,iterations:this.iterations,trace:this.trace}}},r.prototype.smallStep=function(r,s){return t.deltaStep(r[s])},r.prototype.grad=function(t,r,s){for(var i=[],a=this.cost(t,r,s),h=0;h<this.dim;++h){var o=this.smallStep(s,h),e=s[h];s[h]+=o;var n=this.cost(t,r,s);s[h]=e,i.push((n-a)/2)}return i},r.prototype.cost=function(r,s,i){for(var a=r.length,h=0,o=0;o<a;++o){var e=r[o],n=s[o];h+=this.C*(n*this.cost1(e,n,i)+(1-n)*this.cost0(e,n,i))}return h+=t.dotProduct(i,i)/2,h/=a},r.prototype.cost1=function(r,s,i){var a=t.dotProduct(r,i);return a>1?0:1-a},r.prototype.cost0=function(r,s,i){var a=t.dotProduct(r,i);return a<-1?0:1+a},r.prototype.transform=function(r){if(r[0].length){for(var s=[],i=0;i<r.length;++i){var a=this.transform(r[i]);s.push(a)}return s}var h=[];h.push(1);for(var o=0;o<r.length;++o)h.push(r[o]);return t.dotProduct(h,this.theta)},t.LinearSvm=r;var s=function(r){this.classifier=new t.LinearSvm(r)};s.prototype.fit=function(t){return this.classifier.fit(t)},s.prototype.transform=function(t){return this.classifier.transform(t)>this.threshold?1:0},t.BinarySvmClassifier=s;var i=function(t){(t=t||{}).alpha||(t.alpha=.001),t.iterations||(t.iterations=100),t.C||(t.C=C),this.alpha=t.alpha,this.C=t.C,this.iterations=t.iterations};i.prototype.fit=function(r,s){this.dim=r[0].length;var i=r.length;if(!s){s=[];for(c=0;c<i;++c){for(var a=!1,h=r[c][this.dim-1],o=0;o<s.length;++o)if(h==s[o]){a=!0;break}a||s.push(h)}}this.classes=s,this.classifiers={};for(var e={},n=0;n<this.classes.length;++n){var f=this.classes[n];this.classifiers[f]=new t.LinearSvm({alpha:this.alpha,C:this.C,iterations:this.iterations});for(var l=[],c=0;c<i;++c){for(var u=[],o=0;o<this.dim-1;++o)u.push(r[c][o]);u.push(r[c][this.dim-1]==f?1:0),l.push(u)}e[f]=this.classifiers[f].fit(l)}return e},i.prototype.transform=function(t){if(t[0].length){for(var r=[],s=0;s<t.length;++s){var i=this.transform(t[s]);r.push(i)}return r}for(var a=0,h="",o=0;o<this.classes.length;++o){var e=this.classes[o],n=this.classifiers[e].transform(t)-this.classifiers[e].threshold;a<n&&(a=n,h=e)}return h},t.MultiClassSvmClassifier=i}(jssvm),module&&(module.exports=jssvm); | ||
var jssvm=jssvm||{};!function(t){t.small=function(){for(var t=.5,s=1*t+1;s>1;)s=1*(t/=2)+1;return 2*t*2},t.quickSort=function(s,i){t._quickSort(s,0,s.length-1,i)},t._quickSort=function(s,i,r,a){if(!(i>=r)){var h=t._partition(s,i,r,a);t._quickSort(s,i,h-1,a),t._quickSort(s,h+1,r,a)}},t._partition=function(s,i,r,a){for(var h=s[i],e=i,n=r+1;;){for(;a(h,s[++e])>0&&!(e>=r););for(;a(h,s[--n])<0&&!(n<=i););if(e>=n)break;t._exchange(s,e,n)}return t._exchange(s,i,n),n},t._exchange=function(t,s,i){var r=t[s];t[s]=t[i],t[i]=r},t.deltaStep=function(t){var s=Math.sqrt(this.small()),i=Math.max(1,Math.abs(t)),r=Math.max(0,Math.abs(s*i));return t<0&&(r=-r),r},t.dotProduct=function(t,s){for(var i=0,r=s.length,a=0;a<r;++a)i+=t[a]*s[a];return i},t.gaussian=function(s,i,r,a){for(var h=i.length,e=0,n=0;n<h;++n){var o=r[n];e+=i[n]*t._gaussian(s,o,a,h)}return e},t._gaussian=function(s,i,r,a){for(var h=[],e=0;e<a;++e)h.push(s[e]-i[e]);var n=t.dotProduct(h,h);return Math.exp(-n/(r*r))};var s=function(t){(t=t||{}).iterations||(t.iterations=1e3),t.alpha||(t.alpha=.01),t.C||(t.C=5),t.trace||(t.trace=!1),this.iterations=t.iterations,this.alpha=t.alpha,this.C=t.C,this.trace=t.trace};s.prototype.fit=function(t){this.dim=t[0].length;for(var s=t.length,i=[],r=[],a=0;a<s;++a){var h=t[a],e=[],n=h[h.length-1];e.push(1);for(var o=0;o<h.length-1;++o)e.push(h[o]);i.push(e),r.push(n)}this.theta=[];for(f=0;f<this.dim;++f)this.theta.push(0);for(var l=0;l<this.iterations;++l){for(var u=this.grad(i,r,this.theta),f=0;f<this.dim;++f)this.theta[f]=this.theta[f]-this.alpha*u[f];this.trace&&console.log("cost: "+this.cost(i,r,this.theta))}var c=this.transform(t);this.threshold=null;for(var s=t.length,a=0;a<s;++a)1==t[a][this.dim-1]&&(null==this.threshold||this.threshold>c[a])&&(this.threshold=c[a]);return{theta:this.theta,cost:this.cost(i,r,this.theta),threshold:this.threshold,config:{alpha:this.alpha,C:this.C,iterations:this.iterations,trace:this.trace}}},s.prototype.smallStep=function(s,i){return t.deltaStep(s[i])},s.prototype.grad=function(t,s,i){for(var r=[],a=this.cost(t,s,i),h=0;h<this.dim;++h){var e=this.smallStep(i,h),n=i[h];i[h]+=e;var o=this.cost(t,s,i);i[h]=n,r.push((o-a)/2)}return r},s.prototype.cost=function(s,i,r){for(var a=s.length,h=0,e=0;e<a;++e){var n=s[e],o=i[e];h+=this.C*(o*this.cost1(n,o,r)+(1-o)*this.cost0(n,o,r))}return h+=t.dotProduct(r,r)/2,h/=a},s.prototype.cost1=function(s,i,r){var a=t.dotProduct(s,r);return a>1?0:1-a},s.prototype.cost0=function(s,i,r){var a=t.dotProduct(s,r);return a<-1?0:1+a},s.prototype.transform=function(s){if(s[0].length){for(var i=[],r=0;r<s.length;++r){var a=this.transform(s[r]);i.push(a)}return i}var h=[];h.push(1);for(var e=0;e<s.length;++e)h.push(s[e]);return t.dotProduct(h,this.theta)},t.LinearSvm=s;var i=function(t){(t=t||{}).iterations||(t.iterations=1e3),t.alpha||(t.alpha=.01),t.C||(t.C=5),t.trace||(t.trace=!1),t.sigma||(t.sigma=1),this.iterations=t.iterations,this.alpha=t.alpha,this.C=t.C,this.trace=t.trace,this.sigma=t.sigma};i.prototype.fit=function(t){this.dim=t[0].length;for(var s=t.length,i=[],r=[],a=0;a<s;++a){var h=t[a],e=[],n=h[h.length-1];e.push(1);for(var o=0;o<h.length-1;++o)e.push(h[o]);i.push(e),r.push(n)}this.theta=[],this.L=[];for(f=0;f<this.dim;++f)this.theta.push(0),this.L.push(i[f]);for(var l=0;l<this.iterations;++l){for(var u=this.grad(i,r,this.theta),f=0;f<this.dim;++f)this.theta[f]=this.theta[f]-this.alpha*u[f];this.trace&&console.log("cost: "+this.cost(i,r,this.theta))}var c=this.transform(t);this.threshold=null;for(var s=t.length,a=0;a<s;++a)1==t[a][this.dim-1]&&(null==this.threshold||this.threshold>c[a])&&(this.threshold=c[a]);return{theta:this.theta,L:this.L,cost:this.cost(i,r,this.theta),threshold:this.threshold,config:{alpha:this.alpha,C:this.C,iterations:this.iterations,trace:this.trace,sigma:this.sigma}}},i.prototype.smallStep=function(s,i){return t.deltaStep(s[i])},i.prototype.grad=function(t,s,i){for(var r=[],a=this.cost(t,s,i),h=0;h<this.dim;++h){var e=this.smallStep(i,h),n=i[h];i[h]+=e;var o=this.cost(t,s,i);i[h]=n,r.push((o-a)/2)}return r},i.prototype.cost=function(s,i,r){for(var a=s.length,h=0,e=0;e<a;++e){var n=s[e],o=i[e];h+=this.C*(o*this.cost1(n,o,r)+(1-o)*this.cost0(n,o,r))}return h+=t.dotProduct(r,r)/2,h/=a},i.prototype.cost1=function(s,i,r){var a=t.gaussian(s,r,this.L,this.sigma);return a>1?0:1-a},i.prototype.cost0=function(s,i,r){var a=t.gaussian(s,r,this.L,this.sigma);return a<-1?0:1+a},i.prototype.transform=function(s){if(s[0].length){for(var i=[],r=0;r<s.length;++r){var a=this.transform(s[r]);i.push(a)}return i}var h=[];h.push(1);for(var e=1;e<this.dim;++e)h.push(s[e-1]);return t.gaussian(h,this.theta,this.L,this.sigma)},t.KernelSvm=i;var r=function(s){(s=s||{}).kernel||(s.kernel="linear"),s.sigma||(s.sigma=1),this.kernel=s.kernel,"linear"==s.kernel?this.classifier=new t.LinearSvm(s):"gaussian"==s.kernel?this.classifier=new t.KernelSvm(s):this.classifier=new t.LinearSvm(s)};r.prototype.fit=function(t){var s=this.classifier.fit(t);return s.kernel=this.kernel,s},r.prototype.transform=function(t){return this.classifier.transform(t)>this.classifier.threshold?1:0},t.BinarySvmClassifier=r;var a=function(t){(t=t||{}).alpha||(t.alpha=.01),t.iterations||(t.iterations=1e3),t.C||(t.C=5),t.kernel||(t.kernel="linear"),t.sigma||(t.sigma=1),this.alpha=t.alpha,this.C=t.C,this.iterations=t.iterations,this.sigma=t.sigma,this.kernel=t.kernel};a.prototype.fit=function(s,i){this.dim=s[0].length;var r=s.length;if(!i){i=[];for(f=0;f<r;++f){for(var a=!1,h=s[f][this.dim-1],e=0;e<i.length;++e)if(h==i[e]){a=!0;break}a||i.push(h)}}this.classes=i,this.classifiers={};for(var n={},o=0;o<this.classes.length;++o){var l=this.classes[o];"linear"==this.kernel?this.classifiers[l]=new t.LinearSvm({alpha:this.alpha,C:this.C,iterations:this.iterations}):"gaussian"==this.kernel?this.classifiers[l]=new t.KernelSvm({alpha:this.alpha,C:this.C,iterations:this.iterations,sigma:this.sigma}):this.classifiers[l]=new t.LinearSvm({alpha:this.alpha,C:this.C,iterations:this.iterations});for(var u=[],f=0;f<r;++f){for(var c=[],e=0;e<this.dim-1;++e)c.push(s[f][e]);c.push(s[f][this.dim-1]==l?1:0),u.push(c)}n[l]=this.classifiers[l].fit(u)}return n.kernel=this.kernel,n},a.prototype.transform=function(t){if(t[0].length){for(var s=[],i=0;i<t.length;++i){var r=this.transform(t[i]);s.push(r)}return s}for(var a=0,h="",e=0;e<this.classes.length;++e){var n,o=this.classes[e];a<=(n=this.classifiers[o].transform(t)-this.classifiers[o].threshold)&&(a=n,h=o)}return h},t.MultiClassSvmClassifier=a}(jssvm),module&&(module.exports=jssvm); |
{ | ||
"name": "js-svm", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "Package implements linear svm and kernel svm that supports binary and mult-class classification", | ||
@@ -5,0 +5,0 @@ "author": "Xianshun Chen", |
@@ -25,8 +25,3 @@ # js-svm | ||
var svm = new jssvm.BinarySvmClassifier({ | ||
alpha: 0.01, | ||
iterations: 1000, | ||
C: 5.0, | ||
trace: false | ||
}); | ||
var svm = new jssvm.BinarySvmClassifier(); | ||
@@ -63,2 +58,13 @@ iris.shuffle(); | ||
To configure the BinarySvmClassifier, use the following code when it is created: | ||
```javascript | ||
var svm = new jssvm.BinarySvmClassifier({ | ||
alpha: 0.01, // learning rate | ||
iterations: 1000, // maximum iterations | ||
C: 5.0, // panelty term | ||
trace: false // debug tracing | ||
}); | ||
``` | ||
### Multi-Class Classification using One-vs-All Logistic Regression | ||
@@ -72,7 +78,3 @@ | ||
var classifier = new jssvm.MultiClassSvmClassifier({ | ||
alpha: 0.001, | ||
iterations: 1000, | ||
C: 5.0 | ||
}); | ||
var classifier = new jssvm.MultiClassSvmClassifier(); | ||
@@ -109,3 +111,39 @@ iris.shuffle(); | ||
To configure the MultiClassSvmClassifier, use the following code when it is created: | ||
```javascript | ||
var classifier = new jssvm.MultiClassSvmClassifier({ | ||
alpha: 0.01, // learning rate | ||
iterations: 1000, // maximum iterations | ||
C: 5.0 // panelty term | ||
sigma: 1.0 // the standard deviation for the gaussian kernel | ||
}); | ||
``` | ||
### Switch between linear and guassian kernel | ||
By default the kernel used by the binary and multi-class classifier is "linear" which can be printed by: | ||
```javascript | ||
console.log(classifier.kernel); | ||
``` | ||
To switch to use gaussian kernel, put the property 'kernel: "gaussian"' in the config data when the classifier is created: | ||
```javascript | ||
var svm = new jssvm.BinarySvmClassifier({ | ||
..., | ||
kernel: 'gaussian' | ||
}); | ||
.... | ||
var svm = new jssvm.MultiClassSvmClassifier({ | ||
..., | ||
kernel: 'gaussian' | ||
}); | ||
``` | ||
### Usage In HTML | ||
@@ -112,0 +150,0 @@ |
263
src/jssvm.js
@@ -73,2 +73,23 @@ var jssvm = jssvm || {}; | ||
jsr.gaussian = function(x_i, theta, L, sigma) { | ||
var dim = theta.length; | ||
var sum = 0; | ||
for(var d = 0; d < dim; ++d){ | ||
var l_d = L[d]; | ||
sum += theta[d] * jsr._gaussian(x_i, l_d, sigma, dim); | ||
} | ||
return sum; | ||
}; | ||
jsr._gaussian = function(x_i, l_d, sigma, dim){ | ||
var dx = []; | ||
for(var d = 0; d < dim; ++d){ | ||
dx.push(x_i[d] - l_d[d]); | ||
} | ||
var z = jsr.dotProduct(dx, dx); | ||
return Math.exp(-z / (sigma * sigma)); | ||
} | ||
var LinearSvm = function(config) { | ||
@@ -78,9 +99,9 @@ config = config || {}; | ||
if(!config.iterations){ | ||
config.iterations = 100; | ||
config.iterations = 1000; | ||
} | ||
if(!config.alpha){ | ||
config.alpha = 0.0001; | ||
config.alpha = 0.01; | ||
} | ||
if(!config.C){ | ||
config.C = 1.0; | ||
config.C = 5.0; | ||
} | ||
@@ -233,4 +254,185 @@ if(!config.trace){ | ||
var KernelSvm = function(config) { | ||
config = config || {}; | ||
if(!config.iterations){ | ||
config.iterations = 1000; | ||
} | ||
if(!config.alpha){ | ||
config.alpha = 0.01; | ||
} | ||
if(!config.C){ | ||
config.C = 5.0; | ||
} | ||
if(!config.trace){ | ||
config.trace = false; | ||
} | ||
if(!config.sigma) { | ||
config.sigma = 1.0; | ||
} | ||
this.iterations = config.iterations; | ||
this.alpha = config.alpha; | ||
this.C = config.C; | ||
this.trace = config.trace; | ||
this.sigma = config.sigma; | ||
}; | ||
KernelSvm.prototype.fit = function(data) { | ||
this.dim = data[0].length; | ||
var N = data.length; | ||
var X = []; | ||
var Y = []; | ||
for(var i=0; i < N; ++i){ | ||
var row = data[i]; | ||
var x_i = []; | ||
var y_i = row[row.length-1]; | ||
x_i.push(1.0); | ||
for(var j=0; j < row.length-1; ++j){ | ||
x_i.push(row[j]); | ||
} | ||
X.push(x_i); | ||
Y.push(y_i); | ||
} | ||
this.theta = []; | ||
this.L = []; | ||
for(var d = 0; d < this.dim; ++d){ | ||
this.theta.push(0.0); | ||
this.L.push(X[d]); | ||
} | ||
for(var iter = 0; iter < this.iterations; ++iter){ | ||
var theta_delta = this.grad(X, Y, this.theta); | ||
for(var d = 0; d < this.dim; ++d){ | ||
this.theta[d] = this.theta[d] - this.alpha * theta_delta[d]; | ||
} | ||
if(this.trace){ | ||
console.log('cost: ' + this.cost(X, Y, this.theta)); | ||
} | ||
} | ||
var scores = this.transform(data); | ||
this.threshold = null; | ||
var N = data.length; | ||
for(var i=0; i < N; ++i){ | ||
var label = data[i][this.dim-1]; | ||
if(label == 1){ | ||
if(this.threshold == null || this.threshold > scores[i]){ | ||
this.threshold = scores[i]; | ||
} | ||
} | ||
} | ||
return { | ||
theta: this.theta, | ||
L: this.L, | ||
cost: this.cost(X, Y, this.theta), | ||
threshold: this.threshold, | ||
config: { | ||
alpha: this.alpha, | ||
C: this.C, | ||
iterations: this.iterations, | ||
trace: this.trace, | ||
sigma: this.sigma | ||
} | ||
} | ||
}; | ||
KernelSvm.prototype.smallStep = function(theta, d) { | ||
return jsr.deltaStep(theta[d]); | ||
}; | ||
KernelSvm.prototype.grad = function(X, Y, theta) { | ||
var delta = []; | ||
var cost_now = this.cost(X, Y, theta); | ||
for(var d = 0; d < this.dim; ++d) { | ||
var small_step = this.smallStep(theta, d); | ||
var theta_d = theta[d]; | ||
theta[d] += small_step; | ||
var cost_d = this.cost(X, Y, theta); | ||
theta[d] = theta_d; | ||
delta.push((cost_d - cost_now) / 2.0); | ||
} | ||
return delta; | ||
}; | ||
KernelSvm.prototype.cost = function(X, Y, theta) { | ||
var N = X.length; | ||
var sum = 0; | ||
for(var i=0; i < N; ++i) { | ||
var x_i = X[i]; | ||
var y_i = Y[i]; | ||
sum += this.C * (y_i * this.cost1(x_i, y_i, theta) + (1-y_i) * this.cost0(x_i, y_i, theta)); | ||
} | ||
sum += jsr.dotProduct(theta, theta) / 2.0; | ||
sum /= N; | ||
return sum; | ||
}; | ||
KernelSvm.prototype.cost1 = function(x_i, y_i, theta) { | ||
var z = jsr.gaussian(x_i, theta, this.L, this.sigma); | ||
if(z > 1){ | ||
return 0; | ||
} | ||
return 1 - z; | ||
}; | ||
KernelSvm.prototype.cost0 = function(x_i, y_i, theta) { | ||
var z = jsr.gaussian(x_i, theta, this.L, this.sigma); | ||
if(z < -1) { | ||
return 0; | ||
} | ||
return 1 + z; | ||
}; | ||
KernelSvm.prototype.transform = function(x) { | ||
if(x[0].length){ // x is a matrix | ||
var predicted_array = []; | ||
for(var i=0; i < x.length; ++i){ | ||
var predicted = this.transform(x[i]); | ||
predicted_array.push(predicted); | ||
} | ||
return predicted_array; | ||
} | ||
var x_i = []; | ||
x_i.push(1.0); | ||
for(var d = 1; d < this.dim; ++d){ | ||
x_i.push(x[d-1]); | ||
} | ||
return jsr.gaussian(x_i, this.theta, this.L, this.sigma); | ||
}; | ||
jsr.KernelSvm = KernelSvm; | ||
var BinarySvmClassifier = function(config){ | ||
this.classifier = new jsr.LinearSvm(config); | ||
var config = config || {}; | ||
if(!config.kernel){ | ||
config.kernel = 'linear'; | ||
} | ||
if(!config.sigma) { | ||
config.sigma = 1.0; | ||
} | ||
this.kernel = config.kernel; | ||
if(config.kernel == 'linear'){ | ||
this.classifier = new jsr.LinearSvm(config); | ||
} else if(config.kernel == 'gaussian') { | ||
this.classifier = new jsr.KernelSvm(config); | ||
} else { | ||
this.classifier = new jsr.LinearSvm(config); | ||
} | ||
}; | ||
@@ -241,2 +443,3 @@ | ||
result.kernel = this.kernel; | ||
@@ -248,3 +451,3 @@ | ||
BinarySvmClassifier.prototype.transform = function(x) { | ||
return this.classifier.transform(x) > this.threshold ? 1 : 0; | ||
return this.classifier.transform(x) > this.classifier.threshold ? 1 : 0; | ||
}; | ||
@@ -257,13 +460,22 @@ | ||
if(!config.alpha){ | ||
config.alpha = 0.001; | ||
config.alpha = 0.01; | ||
} | ||
if(!config.iterations) { | ||
config.iterations = 100; | ||
config.iterations = 1000; | ||
} | ||
if(!config.C) { | ||
config.C = C; | ||
config.C = 5.0; | ||
} | ||
if(!config.kernel) { | ||
config.kernel = 'linear'; | ||
} | ||
if(!config.sigma) { | ||
config.sigma = 1.0; | ||
} | ||
this.alpha = config.alpha; | ||
this.C = config.C; | ||
this.iterations = config.iterations; | ||
this.sigma = config.sigma; | ||
this.kernel = config.kernel; | ||
}; | ||
@@ -298,7 +510,23 @@ | ||
var c = this.classes[k]; | ||
this.classifiers[c] = new jsr.LinearSvm({ | ||
alpha: this.alpha, | ||
C: this.C, | ||
iterations: this.iterations | ||
}); | ||
if(this.kernel == 'linear'){ | ||
this.classifiers[c] = new jsr.LinearSvm({ | ||
alpha: this.alpha, | ||
C: this.C, | ||
iterations: this.iterations | ||
}); | ||
} else if(this.kernel == 'gaussian'){ | ||
this.classifiers[c] = new jsr.KernelSvm({ | ||
alpha: this.alpha, | ||
C: this.C, | ||
iterations: this.iterations, | ||
sigma: this.sigma | ||
}); | ||
} else { | ||
this.classifiers[c] = new jsr.LinearSvm({ | ||
alpha: this.alpha, | ||
C: this.C, | ||
iterations: this.iterations | ||
}); | ||
} | ||
var data_c = []; | ||
@@ -315,2 +543,4 @@ for(var i=0; i < N; ++i){ | ||
} | ||
result.kernel = this.kernel; | ||
return result; | ||
@@ -335,4 +565,7 @@ }; | ||
var c = this.classes[k]; | ||
var prob_c = this.classifiers[c].transform(x) - this.classifiers[c].threshold; | ||
if(max_prob < prob_c){ | ||
var prob_c; | ||
prob_c = this.classifiers[c].transform(x) - this.classifiers[c].threshold; | ||
if(max_prob <= prob_c){ | ||
max_prob = prob_c; | ||
@@ -339,0 +572,0 @@ best_c = c; |
@@ -7,3 +7,3 @@ var expect = require("chai").expect; | ||
describe("solve the binary classification problem of iris data for which species class == Iris-virginica", function(){ | ||
describe("Use linear svm to solve the binary classification problem of iris data for which species class == Iris-virginica", function(){ | ||
var svm = new jssvm.BinarySvmClassifier({ | ||
@@ -42,7 +42,46 @@ alpha: 0.01, | ||
var predicted = svm.transform(testingData[i]); | ||
console.log("actual: " + testingData[i][4] + " predicted: " + predicted); | ||
console.log("linear svm binary classifier testing: actual: " + testingData[i][4] + " predicted: " + predicted); | ||
} | ||
}); | ||
describe("Use kernel svm to solve the binary classification problem of iris data for which species class == Iris-virginica", function(){ | ||
var svm = new jssvm.BinarySvmClassifier({ | ||
alpha: 0.01, | ||
iterations: 1000, | ||
C: 5.0, | ||
trace: false, | ||
kernel: 'gaussian' | ||
}); | ||
iris.shuffle(); | ||
var trainingDataSize = Math.round(iris.rowCount * 0.9); | ||
var trainingData = []; | ||
var testingData = []; | ||
for(var i=0; i < iris.rowCount ; ++i) { | ||
var row = []; | ||
row.push(iris.data[i][0]); // sepalLength; | ||
row.push(iris.data[i][1]); // sepalWidth; | ||
row.push(iris.data[i][2]); // petalLength; | ||
row.push(iris.data[i][3]); // petalWidth; | ||
row.push(iris.data[i][4] == "Iris-virginica" ? 1.0 : 0.0); // output which is 1 if species is Iris-virginica; 0 otherwise | ||
if(i < trainingDataSize){ | ||
trainingData.push(row); | ||
} else { | ||
testingData.push(row); | ||
} | ||
} | ||
var result = svm.fit(trainingData); | ||
console.log(result); | ||
for(var i=0; i < testingData.length; ++i){ | ||
var predicted = svm.transform(testingData[i]); | ||
console.log("kernel svm binary classifier testing: actual: " + testingData[i][4] + " predicted: " + predicted); | ||
} | ||
}); | ||
}); | ||
@@ -41,3 +41,3 @@ var expect = require("chai").expect; | ||
var probabilityOfSpeciesBeingIrisVirginica = svm.transform(testingData[i]); | ||
console.log("actual: " + testingData[i][4] + " probability of being Iris-virginica: " + probabilityOfSpeciesBeingIrisVirginica); | ||
console.log("linear svm test: actual: " + testingData[i][4] + " probability of being Iris-virginica: " + probabilityOfSpeciesBeingIrisVirginica); | ||
} | ||
@@ -44,0 +44,0 @@ |
@@ -6,3 +6,3 @@ var expect = require("chai").expect; | ||
describe("Test multi-class classification using logistic regression", function(){ | ||
describe("solve the multi-class classification problem of iris data", function(){ | ||
describe("Use linear svm to solve the multi-class classification problem of iris data", function(){ | ||
var classifier = new jssvm.MultiClassSvmClassifier({ | ||
@@ -40,6 +40,44 @@ alpha: 0.001, | ||
var predicted = classifier.transform(testingData[i]); | ||
console.log("svm prediction testing: actual: " + testingData[i][4] + " predicted: " + predicted); | ||
console.log("linear svm multi-class prediction testing: actual: " + testingData[i][4] + " predicted: " + predicted); | ||
} | ||
}); | ||
describe("Use kernel svm solve the multi-class classification problem of iris data", function(){ | ||
var classifier = new jssvm.MultiClassSvmClassifier({ | ||
alpha: 0.001, | ||
iterations: 1000, | ||
C: 5.0 | ||
}); | ||
iris.shuffle(); | ||
var trainingDataSize = Math.round(iris.rowCount * 0.9); | ||
var trainingData = []; | ||
var testingData = []; | ||
for(var i=0; i < iris.rowCount ; ++i) { | ||
var row = []; | ||
row.push(iris.data[i][0]); // sepalLength; | ||
row.push(iris.data[i][1]); // sepalWidth; | ||
row.push(iris.data[i][2]); // petalLength; | ||
row.push(iris.data[i][3]); // petalWidth; | ||
row.push(iris.data[i][4]); // output is species | ||
if(i < trainingDataSize){ | ||
trainingData.push(row); | ||
} else { | ||
testingData.push(row); | ||
} | ||
} | ||
var result = classifier.fit(trainingData); | ||
console.log(result); | ||
for(var i=0; i < testingData.length; ++i){ | ||
var predicted = classifier.transform(testingData[i]); | ||
console.log("kernel svm multi-class prediction testing: actual: " + testingData[i][4] + " predicted: " + predicted); | ||
} | ||
}); | ||
}); |
40882
14
747
155