test/unit/logistic_regression_spec.mjs
import chai from 'chai';
// import sinon from 'sinon';
import * as ms from 'modelscript';
import sinonChai from 'sinon-chai';
import chaiAsPromised from 'chai-as-promised';
import 'babel-polyfill';
import { LogisticRegression, } from '../../index.mjs';
const expect = chai.expect;
const independentVariables = [
'Age',
'EstimatedSalary',
];
const dependentVariables = [
'Purchased',
];
let CSVData;
let DataSet;
let x_matrix;
let y_matrix;
let nnLR;
let nnLRClass;
let nnLRReg;
let nnLRModel;
let nnLRClassModel;
let nnLRRegModel;
const encodedAnswers = {
'yes': [1,],
'no': [0,],
};
const fit = {
epochs: 10,
batchSize: 5,
};
const input_x = [
[-0.062482849427819266, 0.30083326827486173, ], //0
[0.7960601198093905, -1.1069168538010206, ], //1
[0.7960601198093905, 0.12486450301537644, ], //0
[0.4144854668150751, -0.49102617539282206, ], //0
[0.3190918035664962, 0.5061301610775946, ], //1
];
chai.use(sinonChai);
chai.use(chaiAsPromised);
function scaleColumnMap(columnName) {
return {
name: columnName,
options: {
strategy: 'scale',
scaleOptions: {
strategy:'standard',
},
},
};
}
/** @test {LogisticRegression} */
describe('LogisticRegression', function () {
this.timeout(120000);
before(async function () {
CSVData = await ms.csv.loadCSV('./test/mock/data/social_network_ads.csv');
DataSet = new ms.DataSet(CSVData);
const scaledData = DataSet.fitColumns({
columns: independentVariables.map(scaleColumnMap),
returnData:true,
});
/*
scaledData = [
{ 'User ID': 15624510,
Gender: 'Male',
Age: -1.7795687879022388,
EstimatedSalary: -1.4881825118632386,
Purchased: 0 },
{ 'User ID': 15810944,
Gender: 'Male',
Age: -0.253270175924977,
EstimatedSalary: -1.458854384319991,
Purchased: 0 },
...
];
*/
x_matrix = DataSet.columnMatrix(independentVariables);
y_matrix = DataSet.columnMatrix(dependentVariables);
/*
x_matrix = [
[ -1.7795687879022388, -1.4881825118632386 ],
[ -0.253270175924977, -1.458854384319991 ],
...
];
y_matrix = [
[ 0 ],
[ 0 ],
...
]
*/
// console.log({ x_matrix, y_matrix, });
nnLR = new LogisticRegression({ fit, });
nnLRClass = new LogisticRegression({ type: 'class', fit, });
nnLRReg = new LogisticRegression({ type: 'l1l2', fit, });
const models = await Promise.all([
nnLR.train(x_matrix, y_matrix),
nnLRClass.train(x_matrix, y_matrix),
nnLRReg.train(x_matrix, y_matrix),
]);
nnLRModel = models[ 0 ];
nnLRClassModel = models[ 1 ];
nnLRRegModel = models[ 2 ];
});
/** @test {LogisticRegression#constructor} */
describe('constructor', () => {
it('should export a named module class', () => {
const NN = new LogisticRegression();
const NNConfigured = new LogisticRegression({ test: 'prop', });
expect(LogisticRegression).to.be.a('function');
expect(NN).to.be.instanceOf(LogisticRegression);
expect(NNConfigured.settings.test).to.eql('prop');
});
});
/** @test {LogisticRegression#generateLayers} */
describe('generateLayers', () => {
it('should generate a classification network', async () => {
const predictions = await nnLR.predict(input_x);
const answers = await nnLR.predict(input_x, {
probability:false,
});
const shape = nnLR.getInputShape(predictions);
expect(predictions).to.have.lengthOf(input_x.length);
expect(nnLR.layers).to.have.lengthOf(1);
expect(shape).to.eql([5, 1, ]);
// expect(answers[ 0 ]).to.eql(encodedAnswers[ 'Iris-setosa' ]);
return true;
});
it('should generate a network from layers', async () => {
const nnLRCustom = new LogisticRegression({ type:'custom', fit, });
await nnLRCustom.train(x_matrix, y_matrix, nnLR.layers);
expect(nnLRCustom.layers).to.have.lengthOf(1);
});
// it('should validate trainning data', async () => {
// const nnLRCustom = new LogisticRegression({ type:'custom', fit, });
// await nnLRCustom.train(x_matrix, y_matrix, nnLR.layers, x_matrix, y_matrix);
// expect(nnLRCustom.layers).to.have.lengthOf(1);
// });
});
});