test/unit/multiple_linear_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 { MultipleLinearRegression, } from '../../index.mjs';
const expect = chai.expect;
const independentVariables = ['sqft', 'bedrooms', ];
const dependentVariables = ['price',];
let housingDataCSV;
let input_x;
let DataSet;
let x_matrix;
let y_matrix;
let trainedMLR;
let trainedMLRModel;
chai.use(sinonChai);
chai.use(chaiAsPromised);
function scaleColumnMap(columnName) {
return {
name: columnName,
options: {
strategy: 'scale',
scaleOptions: {
strategy:'standard',
},
},
};
}
/** @test {MultipleLinearRegression} */
describe('MultipleLinearRegression', function () {
this.timeout(20000);
before(async function () {
housingDataCSV = await ms.csv.loadCSV('./test/mock/data/portland_housing_data.csv');
/*
housingdataCSV = [
{ sqft: 2104, bedrooms: 3, price: 399900 },
{ sqft: 1600, bedrooms: 3, price: 329900 },
...
{ sqft: 1203, bedrooms: 3, price: 239500 }
]
*/
DataSet = new ms.DataSet(housingDataCSV);
DataSet.fitColumns({
columns: independentVariables.concat(dependentVariables).map(scaleColumnMap),
returnData:false,
});
x_matrix = DataSet.columnMatrix(independentVariables);
y_matrix = DataSet.columnMatrix(dependentVariables);
// const y_vector = ms.util.pivotVector(y_matrix)[ 0 ];// not used but just illustrative
/* x_matrix = [
[2014, 3],
[1600, 3],
]
y_matrix = [
[399900],
[329900],
]
y_vector = [ 399900, 329900]
*/
trainedMLR = new MultipleLinearRegression({
fit: {
epochs: 100,
batchSize: 5,
},
});
trainedMLRModel = await trainedMLR.train(x_matrix, y_matrix);
input_x = [
[
DataSet.scalers.get('sqft').scale(4215),
DataSet.scalers.get('bedrooms').scale(4),
], //549000
[
DataSet.scalers.get('sqft').scale(852),
DataSet.scalers.get('bedrooms').scale(2),
], //179900
];
return true;
});
/** @test {MultipleLinearRegression#constructor} */
describe('constructor', () => {
it('should export a named module class', () => {
const MLR = new MultipleLinearRegression({
fit: {
epochs: 200,
batchSize: 5,
},
});
const MLRConfigured = new MultipleLinearRegression({ test: 'prop', }, {});
expect(MultipleLinearRegression).to.be.a('function');
expect(MLR).to.be.instanceOf(MultipleLinearRegression);
expect(MLRConfigured.settings.test).to.eql('prop');
});
});
/** @test {MultipleLinearRegression#generateLayers} */
describe('generateLayers', () => {
it('should generate a classification network', async () => {
const predictions = await trainedMLR.predict(input_x);
const shape = trainedMLR.getInputShape(predictions);
// console.log('nnLR.layers', nnLR.layers);
// console.log({
// predictions,
// shape,
// });
expect(predictions).to.have.lengthOf(input_x.length);
expect(trainedMLR.layers).to.have.lengthOf(1);
const descaledPredictions = predictions.map(DataSet.scalers.get('price').descale);
expect(descaledPredictions[ 0 ]).to.be.closeTo(630000, 20000);
expect(descaledPredictions[ 1 ]).to.be.closeTo(190000, 10000);
return true;
});
it('should generate a network from layers', async () => {
const nnLRCustom = new MultipleLinearRegression({
type: 'custom',
fit: {
epochs: 10,
batchSize: 5,
},
});
await nnLRCustom.train(x_matrix, y_matrix, trainedMLR.layers);
expect(nnLRCustom.layers).to.have.lengthOf(1);
return true;
});
});
});