Comparing version 2.3.4 to 3.0.0
@@ -0,1 +1,5 @@ | ||
# [3.0.0](https://github.com/mljs/kernel/compare/v2.3.4...v3.0.0) (2019-06-29) | ||
<a name="2.3.4"></a> | ||
@@ -2,0 +6,0 @@ ## [2.3.4](https://github.com/mljs/kernel/compare/v2.3.3...v2.3.4) (2017-07-21) |
{ | ||
"name": "ml-kernel", | ||
"version": "2.3.4", | ||
"version": "3.0.0", | ||
"description": "A factory for kernel functions", | ||
@@ -12,4 +12,5 @@ "main": "./src/kernel.js", | ||
"eslint-fix": "npm run eslint -- --fix", | ||
"test": "npm run test-mocha && npm run eslint", | ||
"test-mocha": "mocha --require should --reporter mocha-better-spec-reporter" | ||
"test": "npm run test-coverage && npm run eslint", | ||
"test-only": "jest", | ||
"test-coverage": "jest --coverage" | ||
}, | ||
@@ -40,16 +41,15 @@ "repository": { | ||
"devDependencies": { | ||
"eslint": "^4.2.0", | ||
"eslint-config-cheminfo": "^1.1.2", | ||
"eslint-plugin-no-only-tests": "^2.0.0", | ||
"mocha": "^3.0.0", | ||
"mocha-better-spec-reporter": "^3.0.2", | ||
"should": "^11.1.0" | ||
"eslint": "^6.0.1", | ||
"eslint-config-cheminfo": "^1.20.1", | ||
"eslint-plugin-import": "^2.18.0", | ||
"eslint-plugin-jest": "^22.7.1", | ||
"jest": "^24.8.0" | ||
}, | ||
"dependencies": { | ||
"ml-distance-euclidean": "^1.0.0", | ||
"ml-kernel-gaussian": "^2.0.1", | ||
"ml-kernel-polynomial": "^2.0.0", | ||
"ml-kernel-sigmoid": "^1.0.0", | ||
"ml-matrix": "^5.0.0" | ||
"ml-distance-euclidean": "^2.0.0", | ||
"ml-kernel-gaussian": "^2.0.2", | ||
"ml-kernel-polynomial": "^2.0.1", | ||
"ml-kernel-sigmoid": "^1.0.1", | ||
"ml-matrix": "^6.1.2" | ||
} | ||
} |
# ml-kernel | ||
[![NPM version][npm-image]][npm-url] | ||
[![build status][travis-image]][travis-url] | ||
[![David deps][david-image]][david-url] | ||
[![npm download][download-image]][download-url] | ||
[![NPM version][npm-image]][npm-url] | ||
[![build status][travis-image]][travis-url] | ||
[![npm download][download-image]][download-url] | ||
A factory for kernel functions | ||
A factory for kernel functions. | ||
## Installation | ||
`$ npm install ml-kernel` | ||
`$ npm i ml-kernel` | ||
@@ -18,18 +17,19 @@ ## Usage | ||
This function can be called with a matrix of input vectors | ||
This function can be called with a matrix of input vectors. | ||
and optional landmarks. If no landmark is provided, the input vectors will be used. | ||
__Available kernels__ | ||
* `linear` - Linear kernel | ||
* `gaussian` or `rbf` - [Gaussian (radial basis function) kernel](https://github.com/mljs/kernel-gaussian) | ||
* `polynomial` or `poly` - [Polynomial kernel](https://github.com/mljs/kernel-polynomial) | ||
* `exponential` - [Exponential kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#exponential) | ||
* `laplacian` - [Laplacian kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#laplacian) | ||
* `anova` - [ANOVA kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#anova) | ||
* `rational` - [Rational Quadratic kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#rational) | ||
* `multiquadratic` - [Multiquadratic kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#multiquadric) | ||
* `cauchy` - [Cauchy kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#cauchy) | ||
* `histogram` or `min` - [Histogram Intersection kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#histogram) | ||
* `sigmoid` or `mlp' - [Sigmoid (hyperbolic tangent) kernel](https://github.com/mljs/kernel-sigmoid) | ||
**Available kernels**: | ||
- `linear` - Linear kernel | ||
- `gaussian` or `rbf` - [Gaussian (radial basis function) kernel](https://github.com/mljs/kernel-gaussian) | ||
- `polynomial` or `poly` - [Polynomial kernel](https://github.com/mljs/kernel-polynomial) | ||
- `exponential` - [Exponential kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#exponential) | ||
- `laplacian` - [Laplacian kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#laplacian) | ||
- `anova` - [ANOVA kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#anova) | ||
- `rational` - [Rational Quadratic kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#rational) | ||
- `multiquadratic` - [Multiquadratic kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#multiquadric) | ||
- `cauchy` - [Cauchy kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#cauchy) | ||
- `histogram` or `min` - [Histogram Intersection kernel](http://crsouza.com/2010/03/kernel-functions-for-machine-learning-applications/#histogram) | ||
- `sigmoid` or `mlp' - [Sigmoid (hyperbolic tangent) kernel](https://github.com/mljs/kernel-sigmoid) | ||
### kernel.compute(inputs, landmarks) | ||
@@ -43,3 +43,3 @@ | ||
[MIT](./LICENSE) | ||
[MIT](./LICENSE) | ||
@@ -50,5 +50,3 @@ [npm-image]: https://img.shields.io/npm/v/ml-kernel.svg?style=flat-square | ||
[travis-url]: https://travis-ci.org/mljs/kernel | ||
[david-image]: https://img.shields.io/david/mljs/kernel.svg?style=flat-square | ||
[david-url]: https://david-dm.org/mljs/kernel | ||
[download-image]: https://img.shields.io/npm/dm/ml-kernel.svg?style=flat-square | ||
[download-url]: https://npmjs.org/package/ml-kernel |
'use strict'; | ||
const Matrix = require('ml-matrix').Matrix; | ||
const { Matrix, MatrixTransposeView } = require('ml-matrix'); | ||
const GaussianKernel = require('ml-kernel-gaussian'); | ||
const PolynomialKernel = require('ml-kernel-polynomial'); | ||
const SigmoidKernel = require('ml-kernel-sigmoid'); | ||
const ANOVAKernel = require('./kernels/anova-kernel'); | ||
@@ -14,71 +15,82 @@ const CauchyKernel = require('./kernels/cauchy-kernel'); | ||
const RationalKernel = require('./kernels/rational-quadratic-kernel'); | ||
const SigmoidKernel = require('ml-kernel-sigmoid'); | ||
const kernelType = { | ||
gaussian: GaussianKernel, | ||
rbf: GaussianKernel, | ||
polynomial: PolynomialKernel, | ||
poly: PolynomialKernel, | ||
anova: ANOVAKernel, | ||
cauchy: CauchyKernel, | ||
exponential: ExponentialKernel, | ||
histogram: HistogramKernel, | ||
min: HistogramKernel, | ||
laplacian: LaplacianKernel, | ||
multiquadratic: MultiquadraticKernel, | ||
rational: RationalKernel, | ||
sigmoid: SigmoidKernel, | ||
mlp: SigmoidKernel | ||
gaussian: GaussianKernel, | ||
rbf: GaussianKernel, | ||
polynomial: PolynomialKernel, | ||
poly: PolynomialKernel, | ||
anova: ANOVAKernel, | ||
cauchy: CauchyKernel, | ||
exponential: ExponentialKernel, | ||
histogram: HistogramKernel, | ||
min: HistogramKernel, | ||
laplacian: LaplacianKernel, | ||
multiquadratic: MultiquadraticKernel, | ||
rational: RationalKernel, | ||
sigmoid: SigmoidKernel, | ||
mlp: SigmoidKernel | ||
}; | ||
class Kernel { | ||
constructor(type, options) { | ||
this.kernelType = type; | ||
if (type === 'linear') return; | ||
constructor(type, options) { | ||
this.kernelType = type; | ||
if (type === 'linear') return; | ||
if (typeof type === 'string') { | ||
type = type.toLowerCase(); | ||
if (typeof type === 'string') { | ||
type = type.toLowerCase(); | ||
var KernelConstructor = kernelType[type]; | ||
if (KernelConstructor) { | ||
this.kernelFunction = new KernelConstructor(options); | ||
} else { | ||
throw new Error('unsupported kernel type: ' + type); | ||
} | ||
} else if (typeof type === 'object' && typeof type.compute === 'function') { | ||
this.kernelFunction = type; | ||
} else { | ||
throw new TypeError('first argument must be a valid kernel type or instance'); | ||
} | ||
var KernelConstructor = kernelType[type]; | ||
if (KernelConstructor) { | ||
this.kernelFunction = new KernelConstructor(options); | ||
} else { | ||
throw new Error(`unsupported kernel type: ${type}`); | ||
} | ||
} else if (typeof type === 'object' && typeof type.compute === 'function') { | ||
this.kernelFunction = type; | ||
} else { | ||
throw new TypeError( | ||
'first argument must be a valid kernel type or instance' | ||
); | ||
} | ||
} | ||
compute(inputs, landmarks) { | ||
if (landmarks === undefined) { | ||
landmarks = inputs; | ||
} | ||
compute(inputs, landmarks) { | ||
inputs = Matrix.checkMatrix(inputs); | ||
if (landmarks === undefined) { | ||
landmarks = inputs; | ||
} else { | ||
landmarks = Matrix.checkMatrix(landmarks); | ||
} | ||
if (this.kernelType === 'linear') { | ||
return inputs.mmul(new MatrixTransposeView(landmarks)); | ||
} | ||
if (this.kernelType === 'linear') { | ||
var matrix = new Matrix(inputs); | ||
return matrix.mmul(new Matrix(landmarks).transposeView()); | ||
const kernelMatrix = new Matrix(inputs.rows, landmarks.rows); | ||
if (inputs === landmarks) { | ||
// fast path, matrix is symmetric | ||
for (let i = 0; i < inputs.rows; i++) { | ||
for (let j = i; j < inputs.rows; j++) { | ||
const value = this.kernelFunction.compute( | ||
inputs.getRow(i), | ||
inputs.getRow(j) | ||
); | ||
kernelMatrix.set(i, j, value); | ||
kernelMatrix.set(j, i, value); | ||
} | ||
const kernelMatrix = new Matrix(inputs.length, landmarks.length); | ||
var i, j; | ||
if (inputs === landmarks) { // fast path, matrix is symmetric | ||
for (i = 0; i < inputs.length; i++) { | ||
for (j = i; j < inputs.length; j++) { | ||
kernelMatrix[i][j] = kernelMatrix[j][i] = this.kernelFunction.compute(inputs[i], inputs[j]); | ||
} | ||
} | ||
} else { | ||
for (i = 0; i < inputs.length; i++) { | ||
for (j = 0; j < landmarks.length; j++) { | ||
kernelMatrix[i][j] = this.kernelFunction.compute(inputs[i], landmarks[j]); | ||
} | ||
} | ||
} | ||
} else { | ||
for (let i = 0; i < inputs.rows; i++) { | ||
for (let j = 0; j < landmarks.rows; j++) { | ||
kernelMatrix.set( | ||
i, | ||
j, | ||
this.kernelFunction.compute(inputs.getRow(i), landmarks.getRow(j)) | ||
); | ||
} | ||
return kernelMatrix; | ||
} | ||
} | ||
return kernelMatrix; | ||
} | ||
} | ||
module.exports = Kernel; |
'use strict'; | ||
const defaultOptions = { | ||
sigma: 1, | ||
degree: 1 | ||
sigma: 1, | ||
degree: 1 | ||
}; | ||
class ANOVAKernel { | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.sigma = options.sigma; | ||
this.degree = options.degree; | ||
} | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.sigma = options.sigma; | ||
this.degree = options.degree; | ||
} | ||
compute(x, y) { | ||
var sum = 0; | ||
var len = Math.min(x.length, y.length); | ||
for (var i = 1; i <= len; ++i) { | ||
sum += Math.pow(Math.exp(-this.sigma * Math.pow(Math.pow(x[i - 1], i) - | ||
Math.pow(y[i - 1], i), 2)), this.degree); | ||
} | ||
return sum; | ||
compute(x, y) { | ||
var sum = 0; | ||
var len = Math.min(x.length, y.length); | ||
for (var i = 1; i <= len; ++i) { | ||
sum += Math.pow( | ||
Math.exp( | ||
-this.sigma * | ||
Math.pow(Math.pow(x[i - 1], i) - Math.pow(y[i - 1], i), 2) | ||
), | ||
this.degree | ||
); | ||
} | ||
return sum; | ||
} | ||
} | ||
module.exports = ANOVAKernel; |
'use strict'; | ||
const squaredEuclidean = require('ml-distance-euclidean').squared; | ||
const { squaredEuclidean } = require('ml-distance-euclidean'); | ||
const defaultOptions = { | ||
sigma: 1 | ||
sigma: 1 | ||
}; | ||
class CauchyKernel { | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.sigma = options.sigma; | ||
} | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.sigma = options.sigma; | ||
} | ||
compute(x, y) { | ||
return 1 / (1 + squaredEuclidean(x, y) / (this.sigma * this.sigma)); | ||
} | ||
compute(x, y) { | ||
return 1 / (1 + squaredEuclidean(x, y) / (this.sigma * this.sigma)); | ||
} | ||
} | ||
module.exports = CauchyKernel; |
'use strict'; | ||
const euclidean = require('ml-distance-euclidean'); | ||
const { euclidean } = require('ml-distance-euclidean'); | ||
const defaultOptions = { | ||
sigma: 1 | ||
sigma: 1 | ||
}; | ||
class ExponentialKernel { | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.sigma = options.sigma; | ||
this.divisor = 2 * options.sigma * options.sigma; | ||
} | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.sigma = options.sigma; | ||
this.divisor = 2 * options.sigma * options.sigma; | ||
} | ||
compute(x, y) { | ||
const distance = euclidean(x, y); | ||
return Math.exp(-distance / this.divisor); | ||
} | ||
compute(x, y) { | ||
const distance = euclidean(x, y); | ||
return Math.exp(-distance / this.divisor); | ||
} | ||
} | ||
module.exports = ExponentialKernel; |
'use strict'; | ||
class HistogramIntersectionKernel { | ||
compute(x, y) { | ||
var min = Math.min(x.length, y.length); | ||
var sum = 0; | ||
for (var i = 0; i < min; ++i) { | ||
sum += Math.min(x[i], y[i]); | ||
} | ||
compute(x, y) { | ||
var min = Math.min(x.length, y.length); | ||
var sum = 0; | ||
for (var i = 0; i < min; ++i) { | ||
sum += Math.min(x[i], y[i]); | ||
} | ||
return sum; | ||
} | ||
return sum; | ||
} | ||
} | ||
module.exports = HistogramIntersectionKernel; |
'use strict'; | ||
const euclidean = require('ml-distance-euclidean'); | ||
const { euclidean } = require('ml-distance-euclidean'); | ||
const defaultOptions = { | ||
sigma: 1 | ||
sigma: 1 | ||
}; | ||
class LaplacianKernel { | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.sigma = options.sigma; | ||
} | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.sigma = options.sigma; | ||
} | ||
compute(x, y) { | ||
const distance = euclidean(x, y); | ||
return Math.exp(-distance / this.sigma); | ||
} | ||
compute(x, y) { | ||
const distance = euclidean(x, y); | ||
return Math.exp(-distance / this.sigma); | ||
} | ||
} | ||
module.exports = LaplacianKernel; |
'use strict'; | ||
const squaredEuclidean = require('ml-distance-euclidean').squared; | ||
const { squaredEuclidean } = require('ml-distance-euclidean'); | ||
const defaultOptions = { | ||
constant: 1 | ||
constant: 1 | ||
}; | ||
class MultiquadraticKernel { | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.constant = options.constant; | ||
} | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.constant = options.constant; | ||
} | ||
compute(x, y) { | ||
return Math.sqrt(squaredEuclidean(x, y) + this.constant * this.constant); | ||
} | ||
compute(x, y) { | ||
return Math.sqrt(squaredEuclidean(x, y) + this.constant * this.constant); | ||
} | ||
} | ||
module.exports = MultiquadraticKernel; |
'use strict'; | ||
const squaredEuclidean = require('ml-distance-euclidean').squared; | ||
const { squaredEuclidean } = require('ml-distance-euclidean'); | ||
const defaultOptions = { | ||
constant: 1 | ||
constant: 1 | ||
}; | ||
class RationalQuadraticKernel { | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.constant = options.constant; | ||
} | ||
constructor(options) { | ||
options = Object.assign({}, defaultOptions, options); | ||
this.constant = options.constant; | ||
} | ||
compute(x, y) { | ||
const distance = squaredEuclidean(x, y); | ||
return 1 - (distance / (distance + this.constant)); | ||
} | ||
compute(x, y) { | ||
const distance = squaredEuclidean(x, y); | ||
return 1 - distance / (distance + this.constant); | ||
} | ||
} | ||
module.exports = RationalQuadraticKernel; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5
204
11779
50
+ Addedml-matrix@6.12.0(transitive)
- Removedml-distance-euclidean@1.0.0(transitive)
- Removedml-matrix@5.3.0(transitive)
Updatedml-distance-euclidean@^2.0.0
Updatedml-kernel-gaussian@^2.0.2
Updatedml-kernel-polynomial@^2.0.1
Updatedml-kernel-sigmoid@^1.0.1
Updatedml-matrix@^6.1.2