Skip to content

Commit

Permalink
Merge pull request #182 from kalimdorjs/feature/v2-fix-docs
Browse files Browse the repository at this point in the history
fix/v2 fix docs
  • Loading branch information
JasonShin committed Dec 28, 2018
2 parents da6f5f9 + c475fda commit 3245414
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 214 deletions.
1 change: 1 addition & 0 deletions docs/processor/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const tagTypeIgnore = 'ignore';
export const refKindInterface = 'Interface';
export const refKindTypeAlias = 'Type alias';
export const refTypeArgTypeUnion = 'union';
export const refTypeTypeParameter = 'typeParameter';
export const refTypeArgTypeIntrinsic = 'intrinsic';

// Matrix Types
Expand Down
15 changes: 12 additions & 3 deletions docs/processor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,9 @@ export function constructParamTable(parameters): string {
if (typeArg.type === consts.refTypeArgTypeUnion) {
const types = typeArg.types;
typeList.push(constructMatrixType(refName, types));
} else if (typeArg.type === consts.refTypeTypeParameter) {
const types = typeArg.constraint.types;
typeList.push(constructMatrixType(refName, types));
} else if (typeArg.type === consts.refTypeArgTypeIntrinsic) {
typeList.push(constructMatrixType(refName, [typeArg]));
} else {
Expand All @@ -344,9 +347,15 @@ export function constructParamTable(parameters): string {
} else if (consts.paramTypeUnion === paramType) {
// 5. Handles any union types.
// e.g. string[] | string[][]
const unionTypes = _.map(param.type.types, singleType =>
renderParamType(singleType)
);
const unionTypes = _.map(param.type.types, singleType => {
if (singleType.type === consts.paramTypeReference) {
return constructMatrixType(
singleType.name,
singleType.typeArguments
);
}
return renderParamType(singleType);
});
const unionTypesStr = unionTypes.join(' or ');
sum.push([
param.name,
Expand Down
43 changes: 22 additions & 21 deletions src/lib/cluster/k_means.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,9 @@ import { IMlModel, Type1DMatrix, Type2DMatrix } from '../types';
import math from '../utils/MathExtra';

export interface KMeansOptions {
/**
* Number of clusters
*/
k: number;
/**
* Choice of distance method. Defaulting to euclidean
*/
distance?: 'euclidean' | 'manhattan';
/**
* Relative tolerance with regards to inertia to declare convergence
*/
maxIteration?: number;
/**
* Random state value for sorting centroids during the getInitialCentroid phase
*/
randomState?: number;
}

Expand All @@ -44,16 +32,29 @@ export class KMeans implements IMlModel<number> {
private randomState: number;
private maxIteration: number;

/**
*
* @param distance - Choice of distance method. Defaulting to euclidean
* @param k - Number of clusters
* @param maxIteration - Relative tolerance with regards to inertia to declare convergence
* @param randomState - Random state value for sorting centroids during the getInitialCentroid phase
*/
constructor(
options: KMeansOptions = {
{
distance = 'euclidean',
k = 3,
maxIteration = 300,
randomState = 0
}: KMeansOptions = {
distance: 'euclidean',
k: 3,
maxIteration: 300
maxIteration: 300,
randomState: 0
}
) {
this.k = _.get(options, 'k', 3);
this.k = k;
// Assigning a distance method
const distanceType = _.get(options, 'distance', 'euclidean');
const distanceType = distance;
switch (distanceType) {
case 'euclidean':
this.distance = math.euclideanDistance;
Expand All @@ -64,8 +65,8 @@ export class KMeans implements IMlModel<number> {
default:
throw new Error(`Unknown distance type ${distanceType}`);
}
this.randomState = _.get(options, 'randomState', 0);
this.maxIteration = _.get(options, 'maxIteration', 300);
this.randomState = randomState;
this.maxIteration = maxIteration;
this.centroids = [];
}

Expand All @@ -74,7 +75,7 @@ export class KMeans implements IMlModel<number> {
* @param {any} X - array-like or sparse matrix of shape = [n_samples, n_features]
* @returns {{centroids: number[]; clusters: number[]}}
*/
public fit(X: Type2DMatrix<number> = []): void {
public fit(X: Type2DMatrix<number> = null): void {
validateMatrix2D(X);
this.assignment = new Array(_.size(X));
this.centroids = this.getInitialCentroids(X, this.k);
Expand Down Expand Up @@ -134,10 +135,10 @@ export class KMeans implements IMlModel<number> {

/**
* Predicts the cluster index with the given X
* @param {any} X
* @param {any} X - array-like or sparse matrix of shape = [n_samples, n_features]
* @returns {number[]}
*/
public predict(X: Type2DMatrix<number>): number[] {
public predict(X: Type2DMatrix<number> = null): number[] {
validateMatrix2D(X);
return _.map(X, data => {
return this.getClosestCentroids(data, this.centroids, this.distance);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/linear_model/coordinate_descent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class Ridge extends SGDRegressor {
*/
constructor(
{
l2,
l2 = null,
epochs = 1000,
learning_rate = 0.001
}: {
Expand Down
7 changes: 5 additions & 2 deletions src/lib/linear_model/linear_regression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ export class LinearRegression {
* @param {any} X - training values
* @param {any} y - target values
*/
public fit(X: Type1DMatrix<number>, y: Type1DMatrix<number>): void {
public fit(
X: Type1DMatrix<number> = null,
y: Type1DMatrix<number> = null
): void {
const xShape = validateMatrix1D(X);
const yShape = validateMatrix1D(y);
if (xShape.length === 1 && yShape.length === 1 && xShape[0] === yShape[0]) {
Expand All @@ -46,7 +49,7 @@ export class LinearRegression {
* @param {number} X - Values to predict.
* @returns {number}
*/
public predict(X: Type1DMatrix<number>): number[] {
public predict(X: Type1DMatrix<number> = null): number[] {
validateMatrix1D(X);
const preds = [];
for (let i = 0; i < size(X); i++) {
Expand Down
124 changes: 65 additions & 59 deletions src/lib/metrics/classification.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as tf from '@tensorflow/tfjs';
import * as _ from 'lodash';
import { reshape } from '../ops';
import { Type1DMatrix } from '../types';
import { checkArray } from '../utils/validation';

/**
Expand Down Expand Up @@ -86,24 +87,29 @@ export const validateInitialInputs = (y_true, y_pred, labels, options = {}) => {
* @example
* import { accuracyScore } from 'kalimdor/metrics';
*
* const accResult = accuracyScore({
* y_true: [0, 1, 2, 3],
* y_pred: [0, 2, 1, 3]
* });
* const accResult = accuracyScore(
* [0, 1, 2, 3],
* [0, 2, 1, 3]
* );
*
* // accuracy result: 0.5
*
* @param {any} y_true
* @param {any} y_pred
* @param {any} normalize
* @param y_true - 1d array-like, or label indicator array / sparse matrix
* @param y_pred - 1d array-like, or label indicator array / sparse matrix
* @param normalize
*/
export function accuracyScore({
y_true,
y_pred,
normalize = true
// sample_weight = null
}): // TODO: Fix any array type
number {
export function accuracyScore(
y_true: Type1DMatrix<number | string> = null,
y_pred: Type1DMatrix<number | string> = null,
{
normalize = true
}: // sample_weight = null
{
normalize: boolean;
} = {
normalize: true
}
): number {
validateInitialInputs(y_true, y_pred, null, { multiclass: true });

const yTrueRange = _.range(0, _.size(y_true));
Expand All @@ -128,47 +134,38 @@ number {
* @example
* import { zeroOneLoss } from 'kalimdor/metrics';
*
* const loss_zero_one_result = zeroOneLoss({
* y_true: [1, 2, 3, 4],
* y_pred: [2, 2, 3, 5]
* });
* const loss_zero_one_result = zeroOneLoss(
* [1, 2, 3, 4],
* [2, 2, 3, 5]
* );
* console.log(loss_zero_one_result); // 0.5
*
* @param {any} y_true
* @param {any} y_pred
* @param {any} y_true - Ground truth (correct) labels.
* @param {any} y_pred - Predicted labels, as returned by a classifier.
* @param {any} normalize
* @returns {number}
*/
export function zeroOneLoss({
y_true,
y_pred,
normalize = true
// sample_weight = null
}): number {
export function zeroOneLoss(
y_true = null,
y_pred = null,
{
/**
* If False, return the number of misclassifications. Otherwise, return the fraction of misclassifications.
*/
normalize = true
}: {
normalize: boolean;
} = {
normalize: true
}
): number {
if (normalize) {
return 1 - accuracyScore({ y_true, y_pred });
return 1 - accuracyScore(y_true, y_pred);
}
// TODO: Fix return 0; implement when normalize === false
return 0;
}

export interface ConfusionMatrixOptions {
/**
* Ground truth (correct) target values.
*/
y_true: any[];
/**
* Estimated targets as returned by a classifier.
*/
y_pred: any[];
/**
* List of labels to index the matrix. This may be used to reorder or
* select a subset of labels. If none is given, those that appear
* at least once in y_true or y_pred are used in sorted order.
*/
labels?: any[];
}

/**
* A confusion matrix is a technique for summarizing the performance of a classification algorithm.
*
Expand All @@ -179,26 +176,35 @@ export interface ConfusionMatrixOptions {
* @example
* import { confusion_matrix } from 'kalimdor/metrics';
*
* const matrix1 = confusion_matrix({
* y_true: [1, 2, 3],
* y_pred: [1, 2, 3]
* });
* const matrix1 = confusion_matrix([1, 2, 3], [1, 2, 3]);
* console.log(matrix1); // [ [ 1, 0, 0 ], [ 0, 1, 0 ], [ 0, 0, 1 ] ]
*
* const matrix2 = confusion_matrix({
* y_true: ['cat', 'ant', 'cat', 'cat', 'ant', 'bird'],
* y_pred: ['ant', 'ant', 'cat', 'cat', 'ant', 'cat']
* });
* const matrix2 = confusion_matrix(
* ['cat', 'ant', 'cat', 'cat', 'ant', 'bird'],
* ['ant', 'ant', 'cat', 'cat', 'ant', 'cat']
* );
* console.log(matrix2); // [ [ 1, 2, 0 ], [ 2, 0, 0 ], [ 0, 1, 0 ] ]
*
* @param {ConfusionMatrixOptions} options
* @returns {number[]}
* @param y_true - Ground truth (correct) target values.
* @param y_pred - Estimated targets as returned by a classifier.
* @param labels
*/
export function confusion_matrix(options: ConfusionMatrixOptions): number[] {
const y_true = _.get(options, 'y_true', null);
const y_pred = _.get(options, 'y_pred', null);
const labels = _.get(options, 'labels', null);

export function confusion_matrix(
y_true: Type1DMatrix<string | number> = null,
y_pred: Type1DMatrix<string | number> = null,
{
/**
* List of labels to index the matrix. This may be used to reorder or
* select a subset of labels. If none is given, those that appear
* at least once in y_true or y_pred are used in sorted order.
*/
labels = null
}: {
labels?: any[];
} = {
labels: null
}
): number[] {
validateInitialInputs(y_true, y_pred, labels);

// TODO: Sorting if set by options
Expand Down
32 changes: 9 additions & 23 deletions src/lib/metrics/index.repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,30 @@

import { accuracyScore, zeroOneLoss, confusion_matrix } from './classification';

const accResult = accuracyScore({
y_true: [0, 1, 2, 3],
y_pred: [0, 2, 1, 3]
});
const accResult = accuracyScore([0, 1, 2, 3], [0, 2, 1, 3]);

console.log('accuracy result ', accResult);

const accResultNorm = accuracyScore({
y_true: [0, 1, 2, 3],
y_pred: [0, 2, 1, 3],
const accResultNorm = accuracyScore([0, 1, 2, 3], [0, 2, 1, 3], {
normalize: false
});

console.log('accuracy result with norm false ', accResultNorm);

const loss_zero_one_result = zeroOneLoss({
y_true: [1, 2, 3, 4],
y_pred: [2, 2, 3, 5]
});
const loss_zero_one_result = zeroOneLoss([1, 2, 3, 4], [2, 2, 3, 5]);

console.log('loss zero one ', loss_zero_one_result);

const matrix1 = confusion_matrix({
y_true: [1, 2, 3],
y_pred: [1, 2, 3]
});
const matrix1 = confusion_matrix([1, 2, 3], [1, 2, 3]);
console.log(matrix1);

const matrix2 = confusion_matrix({
y_true: [2, 0, 2, 2, 0, 1],
y_pred: [0, 0, 2, 2, 0, 2]
});
const matrix2 = confusion_matrix([2, 0, 2, 2, 0, 1], [0, 0, 2, 2, 0, 2]);
console.log(matrix2);

const matrix3 = confusion_matrix({
y_true: ['cat', 'ant', 'cat', 'cat', 'ant', 'bird'],
y_pred: ['ant', 'ant', 'cat', 'cat', 'ant', 'cat']
});
const matrix3 = confusion_matrix(
['cat', 'ant', 'cat', 'cat', 'ant', 'bird'],
['ant', 'ant', 'cat', 'cat', 'ant', 'cat']
);

console.log(matrix3);

Expand Down

0 comments on commit 3245414

Please sign in to comment.