ensemble / ensemble.test.js
nanye's picture
support for random forest & extra trees, mlp basis for boosting, multiple class, and improve UI
6ed536f
Raw History Blame Contribute Delete
1.47 kB
const {test}=require('node:test');
const assert=require('node:assert/strict');
const E=require('./ensemble.js');
test('grid lookup respects coordinates and clamps plot edges',()=>{
const grid={size:2,grid:[-1,1,2,-1]};
assert.equal(E.predict(grid,{x:0,y:0}),-1);
assert.equal(E.predict(grid,{x:0,y:1}),2);
assert.equal(E.predict(grid,{x:2,y:2}),-1);
});
test('SAMME upweights mistakes and restores weights after removal',()=>{
const points=[{label:-1},{label:1},{label:2}];
const models=[{alpha:Math.log(4),predictions:[-1,-1,2]}];
const before=E.weightsFor(points,models);
assert.ok(Math.abs(before[1]-2/3)<1e-12);
models.push({alpha:1,predictions:[-1,1,2]});models.pop();
assert.deepEqual(E.weightsFor(points,models),before);
});
test('three-class voting and forests average probabilities across all classes',()=>{
const classes=[-1,1,2];
const models=[{classes,alpha:1,predictions:[1],tree:{size:1,grid:[1]}},{classes,alpha:2,predictions:[2],tree:{size:1,grid:[2]}}];
assert.equal(E.vote(models,{x:0,y:0}),2);assert.equal(E.trainingVote(models,0),2);
const forest=[[.45,.05,.5],[.6,.1,.3]].map(p=>({classes,forest:true,alpha:1,trainingProbabilities:[p],tree:{size:1,probabilities:[p]}}));
assert.equal(E.vote(forest,{x:0,y:0}),-1);forest.pop();assert.equal(E.trainingVote(forest,0),2);
});
test('training supports a pair of classes that excludes A',()=>{
assert.equal(E.trainingVote([{classes:[1,2],alpha:1,predictions:[2]}],0),2);
});