Skip to content

Commit

Permalink
Merge pull request #180 from kalimdorjs/refactor/uninstall
Browse files Browse the repository at this point in the history
Refactor/uninstall mathjs
  • Loading branch information
JasonShin committed Dec 24, 2018
2 parents d3eda77 + 87506ac commit da6f5f9
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 136 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
"isomorphic-fetch": "^2.2.1",
"libsvm-js": "^0.2.0",
"lodash": "^4.17.10",
"mathjs": "5.1.0",
"numeric": "^1.2.6",
"random-js": "^1.0.8",
"stopword": "^0.1.10"
Expand Down
4 changes: 2 additions & 2 deletions src/lib/cluster/k_means.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ export class KMeans implements IMlModel<number> {
const distanceType = _.get(options, 'distance', 'euclidean');
switch (distanceType) {
case 'euclidean':
this.distance = math.contrib.euclideanDistance;
this.distance = math.euclideanDistance;
break;
case 'manhattan':
this.distance = math.contrib.manhattanDistance;
this.distance = math.manhattanDistance;
break;
default:
throw new Error(`Unknown distance type ${distanceType}`);
Expand Down
10 changes: 5 additions & 5 deletions src/lib/linear_model/linear_regression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* References:
* - https://machinelearningmastery.com/implement-simple-linear-regression-scratch-python/
*/
import * as tf from '@tensorflow/tfjs';
import { size } from 'lodash';
import { validateMatrix1D } from '../ops';
import { Type1DMatrix } from '../types';
Expand Down Expand Up @@ -94,11 +95,10 @@ export class LinearRegression {
* @param y - y targets
*/
private coefficients(X, y): void {
const xMean = math.mean(X);
const yMean = math.mean(y);
this.b1 =
math.contrib.covariance(X, xMean, y, yMean) /
math.contrib.variance(X, xMean);
// TODO: Fix the typing
const xMean: any = tf.mean(X).dataSync();
const yMean: any = tf.mean(y).dataSync();
this.b1 = math.covariance(X, xMean, y, yMean) / math.variance(X, xMean);
this.b0 = yMean - this.b1 * xMean;
}
}
2 changes: 1 addition & 1 deletion src/lib/neighbors/classification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { inferShape, validateFitInputs } from '../ops';
import { IMlModel, Type1DMatrix, Type2DMatrix } from '../types';
import math from '../utils/MathExtra';
import KDTree from './KDTree';
const { euclideanDistance, manhattanDistance } = math.contrib;
const { euclideanDistance, manhattanDistance } = math;
const DIST_EUC = 'euclidean';
const DIST_MAN = 'manhattan';
const TYPE_KD = 'kdtree';
Expand Down
10 changes: 5 additions & 5 deletions src/lib/preprocessing/Imputer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ export class Imputer {
validateMatrix2D(X);

const _X = this.copy ? _.clone(X) : X;
const rowLen = math.contrib.size(_X, 0);
const colLen = math.contrib.size(_X, 1);
const rowRange = math.contrib.range(0, rowLen);
const colRange = math.contrib.range(0, colLen);
const rowLen = math.size(_X, 0);
const colLen = math.size(_X, 1);
const rowRange = math.range(0, rowLen);
const colRange = math.range(0, colLen);
if (this.strategy === 'mean') {
if (this.axis === 0) {
const colNumbers: any = _.map(colRange, col =>
math.contrib.subset(_X, rowRange, [col])
math.subset(_X, rowRange, [col])
);
this.means = this.calcArrayMean(colNumbers, [
'flatten',
Expand Down
4 changes: 2 additions & 2 deletions src/lib/preprocessing/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ export class PolynomialFeatures {
const colsRange = Array.isArray(c) ? c : [c];
// Retrieves column values from X using the index of the indexCombination in the loop
const srcColValues: any =
c !== null ? math.contrib.subset(X, rowRange, colsRange) : [];
c !== null ? math.subset(X, rowRange, colsRange) : [];
let xc = null;
if (srcColValues.length === 0) {
xc = _.fill(rowRange.slice(), 1);
Expand All @@ -612,7 +612,7 @@ export class PolynomialFeatures {
.prod(1)
.dataSync();
}
result = math.contrib.subset(result, rowRange, [i], xc);
result = math.subset(result, rowRange, [i], xc);
}
return result as number[][];
}
Expand Down
7 changes: 2 additions & 5 deletions src/lib/utils/MathExtra.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as _ from 'lodash';
import * as math from 'mathjs';

/**
* Return the number of elements along a given axis.
Expand Down Expand Up @@ -328,7 +327,7 @@ const inner = (a, b) => {
throw new Error(`Cannot process with the invalid inputs ${a} and ${b}`);
};

const contrib = {
const math = {
covariance,
euclideanDistance,
hstack,
Expand All @@ -344,6 +343,4 @@ const contrib = {
variance
};

// Exporting merged result
// { contrib } because we want users to access contrib API like math.contrib.xx
export default _.merge(math, { contrib });
export default math;
38 changes: 19 additions & 19 deletions test/linear_model/linear_regression.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,40 @@ describe('linear_model:LinearRegression', () => {
lr.fit(X1, y1);

const result1 = lr.predict([1, 2]);
const expected1 = [1.1999999999999995, 1.9999999999999996];
expect(isEqual(result1, expected1)).toBe(true);
const expected1 = [1.1999999523162839, 1.999999952316284];
expect(result1).toEqual(expected1);

const result2 = lr.predict([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
const expected2 = [
1.1999999999999995,
1.9999999999999996,
2.8,
3.5999999999999996,
4.3999999999999995,
5.2,
6,
6.8,
7.6,
8.399999999999999
1.1999999523162839,
1.999999952316284,
2.799999952316284,
3.599999952316284,
4.399999952316284,
5.1999999523162845,
5.999999952316284,
6.799999952316284,
7.599999952316284,
8.399999952316284
];
expect(isEqual(result2, expected2)).toBe(true);
expect(result2).toEqual(expected2);
});

it('should reload and predict the same result', () => {
const expected1 = [1.1999999999999995, 1.9999999999999996];
const expected1 = [1.1999999523162839, 1.999999952316284];
const lr = new LinearRegression();
lr.fit(X1, y1);

// Experimenting before saving the checkpoint
const result1 = lr.predict([1, 2]);
expect(isEqual(result1, expected1)).toBe(true);
expect(result1).toEqual(expected1);

// Experimenting after saving the checkpoint
const checkpoint = lr.toJSON();
const lr2 = new LinearRegression();
lr2.fromJSON(checkpoint);
const result2 = lr2.predict([1, 2]);
expect(isEqual(result2, expected1)).toBe(true);
expect(result2).toEqual(expected1);
});

it('should test NaNs', () => {
Expand All @@ -51,11 +51,11 @@ describe('linear_model:LinearRegression', () => {

const result1 = lr.predict([NaN, NaN]);
const expected1 = [NaN, NaN];
expect(isEqual(result1, expected1)).toBe(true);
expect(result1).toEqual(expected1);

const result2 = lr.predict([NaN, 123]);
const expected2 = [NaN, 98.80000000000001];
expect(isEqual(result2, expected2)).toBe(true);
const expected2 = [NaN, 98.79999995231628];
expect(result2).toEqual(expected2);
});

it('should throw an exception when invalid data is given to the fit function', () => {
Expand Down
Loading

0 comments on commit da6f5f9

Please sign in to comment.