diff --git a/CHANGELOG.md b/CHANGELOG.md index b19b0b15..39286db6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# [1.16.0](https://github.com/javascriptdata/scikit.js/compare/v1.15.0...v1.16.0) (2022-04-19) + + +### Features + +* fixed loadBoston calls. Need to do the others ([05c9d9a](https://github.com/javascriptdata/scikit.js/commit/05c9d9af772c1d197798ea28fdd985e92b6fc5ac)) +* fixed tests ([3f6654d](https://github.com/javascriptdata/scikit.js/commit/3f6654d3aa128cfc0296cd97cb4f672cb2184bc9)) +* remove data loading logic in favor of using dfd.readCSV(url) ([3251738](https://github.com/javascriptdata/scikit.js/commit/3251738e09b9e1af9a354b225033a57b1081f573)) + # [1.15.0](https://github.com/javascriptdata/scikit.js/compare/v1.14.0...v1.15.0) (2022-04-18) diff --git a/package-lock.json b/package-lock.json index db9066e7..60bfe979 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "scikitjs", - "version": "1.15.0", + "version": "1.16.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "scikitjs", - "version": "1.15.0", + "version": "1.16.0", "hasInstallScript": true, "license": "ISC", "dependencies": { @@ -2697,6 +2697,25 @@ "node": ">= 8" } }, + "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/@mapbox/node-pre-gyp/node_modules/tar": { "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", @@ -2880,6 +2899,26 @@ "node": ">=0.10.0" } }, + "node_modules/@octokit/request/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/@octokit/rest": { "version": "18.12.0", "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", @@ -3500,6 +3539,25 @@ "yarn": ">= 1.3.2" } }, + "node_modules/@tensorflow/tfjs-core/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/@tensorflow/tfjs-core/node_modules/seedrandom": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz", @@ -3563,6 +3621,25 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/@tensorflow/tfjs/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/@tensorflow/tfjs/node_modules/seedrandom": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", @@ -5335,6 +5412,26 @@ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", "dev": true }, + "node_modules/danfojs-node/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/danfojs-node/node_modules/seedrandom": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", @@ -9704,25 +9801,6 @@ "lodash": "^4.17.21" } }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -14720,7 +14798,8 @@ }, "node_modules/tr46": { "version": "0.0.3", - "license": "MIT" + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, "node_modules/traverse": { "version": "0.6.6", @@ -15169,7 +15248,8 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" }, "node_modules/whatwg-encoding": { "version": "1.0.5", @@ -15190,7 +15270,8 @@ }, "node_modules/whatwg-url": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -17178,6 +17259,14 @@ "yallist": "^4.0.0" } }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, "tar": { "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", @@ -17323,6 +17412,15 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } } } }, @@ -17721,6 +17819,14 @@ "sprintf-js": "~1.0.2" } }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, "seedrandom": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", @@ -17799,6 +17905,14 @@ "seedrandom": "2.4.3" }, "dependencies": { + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, "seedrandom": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz", @@ -19172,6 +19286,15 @@ } } }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, "seedrandom": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", @@ -22195,14 +22318,6 @@ "lodash": "^4.17.21" } }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -25739,7 +25854,9 @@ } }, "tr46": { - "version": "0.0.3" + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, "traverse": { "version": "0.6.6", @@ -26026,7 +26143,9 @@ } }, "webidl-conversions": { - "version": "3.0.1" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" }, "whatwg-encoding": { "version": "1.0.5", @@ -26047,6 +26166,8 @@ }, "whatwg-url": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/package.json b/package.json index a9b31f52..9cd76462 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scikitjs", - "version": "1.15.0", + "version": "1.16.0", "description": "Scikit-Learn for JS", "output": { "node": "dist/node/index.js", diff --git a/src/datasets/datasets.ts b/src/datasets/datasets.ts index 60377547..88b7bead 100644 --- a/src/datasets/datasets.ts +++ b/src/datasets/datasets.ts @@ -1,101 +1,9 @@ -/** - * Loads the Boston housing dataset (regression). Samples 506, features 13. - * @example - * ```typescript - import { loadBoston } from 'scikitjs' - - let df = await loadBoston() - df.print() - ``` - */ -export function loadBoston(): string { - return 'http://scikitjs.org/data/boston.csv' -} - -/** - * Loads the Iris dataset (classification). - * This is a very easy multi-class classification dataset. Samples 150, Classes 3, Features 4. - * @example - * ```typescript - import { loadIris } from 'scikitjs' - - let df = await loadIris() - df.print() - ``` - */ -export function loadIris(): string { - return 'http://scikitjs.org/data/iris.csv' -} - -/** - * Loads the Wine dataset (classification). - * This is a very easy multi-class classification dataset. Samples 178, Classes 3, Features 13. - * @example - * ```typescript - import { loadWine } from 'scikitjs' - - let df = await loadWine() - df.print() - ``` - */ - -export function loadWine(): string { - return 'http://scikitjs.org/data/wine.csv' -} - -/** - * Loads the Diabetes dataset (regression). - * Samples 442, Features 10. - * @example - * ```typescript - import { loadDiabetes } from 'scikitjs' - - let df = await loadDiabetes() - df.print() - ``` - */ - -export function loadDiabetes(): string { - return 'http://scikitjs.org/data/diabetes.csv' -} - -/** - * Loads the Breast Cancer Wisconsin dataset (classification). - * Samples 569, Features 30. - * @example - * ```typescript - import { loadBreastCancer } from 'scikitjs' - - let df = await loadBreastCancer() - df.print() - ``` - */ - -export function loadBreastCancer(): string { - return 'http://scikitjs.org/data/breast_cancer.csv' -} - -/** - * Loads the Digit dataset (classification). - * Samples 1797, Features 64. Each sample is an 8x8 image - * @example - * ```typescript - import { loadDigits } from 'scikitjs' - - let df = await loadDigits() - df.print() - ``` - */ -export function loadDigits(): string { - return 'http://scikitjs.org/data/digits.csv' -} - -/** - * Loads the California housing dataset (regression). - * - * Samples 20640, Features 8. - */ - -export function fetchCaliforniaHousing(): string { - return 'http://scikitjs.org/data/california_housing.csv' +export const dataUrls = { + loadBoston: 'http://scikitjs.org/data/boston.csv', + loadIris: 'http://scikitjs.org/data/iris.csv', + loadWine: 'http://scikitjs.org/data/wine.csv', + loadDiabetes: 'http://scikitjs.org/data/diabetes.csv', + loadBreastCancer: 'http://scikitjs.org/data/breast_cancer.csv', + loadDigits: 'http://scikitjs.org/data/digits.csv', + fetchCaliforniaHousing: 'http://scikitjs.org/data/california_housing.csv' } diff --git a/src/index.ts b/src/index.ts index ddc10162..69172976 100644 --- a/src/index.ts +++ b/src/index.ts @@ -58,7 +58,7 @@ export { export { RobustScaler, RobustScalerParams } from './preprocessing/robustScaler' export { KMeans, KMeansParams } from './cluster/kmeans' export { Scikit1D, Scikit2D, ScikitVecOrMatrix } from './types' -export * as datasets from './datasets/datasets' +export { dataUrls } from './datasets/datasets' export { makeVotingRegressor, VotingRegressor, diff --git a/src/neighbors/kNeighborsClassifier.test.ts b/src/neighbors/kNeighborsClassifier.test.ts index 5a512e66..0226bf88 100644 --- a/src/neighbors/kNeighborsClassifier.test.ts +++ b/src/neighbors/kNeighborsClassifier.test.ts @@ -15,12 +15,7 @@ import { KNeighborsClassifier } from './kNeighborsClassifier' import { KNeighborsParams } from './kNeighborsBase' -import { - loadDigits, - loadIris, - loadWine, - loadBreastCancer -} from '../datasets/datasets' +import { dataUrls } from '../datasets/datasets' import { crossValScore } from '../model_selection/crossValScore' import { KFold } from '../model_selection/kFold' import { arrayEqual } from '../utils' @@ -31,15 +26,16 @@ type Tensor1D = tf.Tensor1D type Tensor2D = tf.Tensor2D function testWithDataset( - loadData: () => string, + loadDataUrl: string, + loadDataName: string, params: KNeighborsParams, referenceAccuracy: number ) { it( - `matches sklearn fitting ${loadData.name}`.padEnd(48) + + `matches sklearn fitting ${loadDataName}`.padEnd(48) + JSON.stringify(params), async () => { - const df = await dfd.readCSV(loadData()) + const df = await dfd.readCSV(loadDataUrl) const Xy = df.tensor as unknown as Tensor2D let [nSamples, nFeatures] = Xy.shape @@ -72,46 +68,54 @@ for (const algorithm of [ ]) { describe(`KNeighborsClassifier({ algorithm: ${algorithm} })`, () => { testWithDataset( - loadIris, + dataUrls.loadIris, + 'loadIris', { nNeighbors: 5, weights: 'distance', algorithm }, 0.0 ) testWithDataset( - loadIris, + dataUrls.loadIris, + 'loadIris', { nNeighbors: 3, weights: 'uniform', algorithm }, 0.0 ) testWithDataset( - loadWine, + dataUrls.loadWine, + 'loadWine', { nNeighbors: 5, weights: 'distance', algorithm }, 0.135 ) testWithDataset( - loadWine, + dataUrls.loadWine, + 'loadWine', { nNeighbors: 3, weights: 'uniform', algorithm }, 0.158 ) testWithDataset( - loadBreastCancer, + dataUrls.loadBreastCancer, + 'loadBreastCancer', { nNeighbors: 5, weights: 'distance', algorithm }, 0.92 ) testWithDataset( - loadBreastCancer, + dataUrls.loadBreastCancer, + 'loadBreastCancer', { nNeighbors: 3, weights: 'uniform', algorithm }, 0.916 ) if ('brute' !== algorithm) { testWithDataset( - loadDigits, + dataUrls.loadDigits, + 'loadDigits', { nNeighbors: 5, weights: 'distance', algorithm, leafSize: 256 }, 0.963 ) testWithDataset( - loadDigits, + dataUrls.loadDigits, + 'loadDigits', { nNeighbors: 3, weights: 'uniform', algorithm, leafSize: 256 }, 0.967 ) diff --git a/src/neighbors/kNeighborsRegressor.test.ts b/src/neighbors/kNeighborsRegressor.test.ts index 4b7001d2..58dd53fa 100644 --- a/src/neighbors/kNeighborsRegressor.test.ts +++ b/src/neighbors/kNeighborsRegressor.test.ts @@ -15,7 +15,7 @@ import { KNeighborsRegressor } from './kNeighborsRegressor' import { KNeighborsParams } from './kNeighborsBase' -import { fetchCaliforniaHousing, loadDiabetes } from '../datasets/datasets' +import { dataUrls } from '../datasets/datasets' import { arrayEqual } from '../utils' import { crossValScore } from '../model_selection/crossValScore' import { KFold } from '../model_selection/kFold' @@ -28,15 +28,16 @@ type Tensor1D = tf.Tensor1D type Tensor2D = tf.Tensor2D function testWithDataset( - loadData: () => string, + loadDataUrl: string, + loadDataName: string, params: KNeighborsParams, referenceError: number ) { it( - `matches sklearn fitting ${loadData.name}`.padEnd(48) + + `matches sklearn fitting ${loadDataName}`.padEnd(48) + JSON.stringify(params), async () => { - const df = await dfd.readCSV(loadData()) + const df = await dfd.readCSV(loadDataUrl) const Xy = df.tensor as unknown as Tensor2D let [nSamples, nFeatures] = Xy.shape @@ -70,32 +71,37 @@ for (const algorithm of [ ]) { describe(`KNeighborsRegressor({ algorithm: ${algorithm} })`, function () { testWithDataset( - loadDiabetes, + dataUrls.loadDiabetes, + 'loadDiabetes', { nNeighbors: 5, weights: 'distance', algorithm }, 3570 ) testWithDataset( - loadDiabetes, + dataUrls.loadDiabetes, + 'loadDiabetes', { nNeighbors: 3, weights: 'uniform', algorithm }, 3833 ) if ('kdTree' === algorithm) { testWithDataset( - fetchCaliforniaHousing, + dataUrls.fetchCaliforniaHousing, + 'fetchCaliforniaHousing', { nNeighbors: 3, weights: 'distance', algorithm }, 1.31 ) } if ('auto' === algorithm) { testWithDataset( - fetchCaliforniaHousing, + dataUrls.fetchCaliforniaHousing, + 'fetchCaliforniaHousing', { nNeighbors: 4, weights: 'uniform', algorithm, p: 1 }, 1.19 ) } if (undefined === algorithm) { testWithDataset( - fetchCaliforniaHousing, + dataUrls.fetchCaliforniaHousing, + 'fetchCaliforniaHousing', { nNeighbors: 4, weights: 'uniform', algorithm, p: Infinity }, 1.32 ) diff --git a/src/tree/decisiontree.test.ts b/src/tree/decisiontree.test.ts index 3e496508..cb500392 100644 --- a/src/tree/decisiontree.test.ts +++ b/src/tree/decisiontree.test.ts @@ -1,5 +1,5 @@ import { DecisionTreeClassifier, DecisionTreeRegressor } from './decisiontree' -import { loadBoston, loadIris } from '../datasets/datasets' +import { dataUrls } from '../datasets/datasets' import * as dfd from 'danfojs-node' describe('DecisionTree', function () { @@ -424,7 +424,7 @@ describe('DecisionTree', function () { } ] /*[[[end]]]*/ - let df = await dfd.readCSV(loadIris()) + let df = await dfd.readCSV(dataUrls.loadIris) let y = df['target'].values let X = df.drop({ columns: 'target' }).values @@ -586,7 +586,7 @@ describe('DecisionTree', function () { } ] /*[[[end]]]*/ - let df = await dfd.readCSV(loadBoston()) + let df = await dfd.readCSV(dataUrls.loadBoston) let y = df['target'].values let X = df.drop({ columns: 'target' }).values