Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nearform/node-hidden-markov-model-tf
A trainable Hidden Markov Model with Gaussian emissions using TensorFlow.js
https://github.com/nearform/node-hidden-markov-model-tf
Last synced: 10 days ago
JSON representation
A trainable Hidden Markov Model with Gaussian emissions using TensorFlow.js
- Host: GitHub
- URL: https://github.com/nearform/node-hidden-markov-model-tf
- Owner: nearform
- License: other
- Archived: true
- Created: 2018-08-15T10:01:00.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-07T19:43:00.000Z (almost 2 years ago)
- Last Synced: 2024-10-13T15:10:40.832Z (about 1 month ago)
- Language: JavaScript
- Size: 544 KB
- Stars: 30
- Watchers: 64
- Forks: 7
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# hidden-markov-model-tf
[![Greenkeeper badge](https://badges.greenkeeper.io/nearform/node-hidden-markov-model-tf.svg)](https://greenkeeper.io/)
**A trainable Hidden Markov Model with Gaussian emissions using TensorFlow.js**
## Install
```
$ npm install hidden-markov-model-tf
```Require: Node v12+
## Usage
```js
const assert = require('assert'):
require('@tensorflow/tfjs-node'); // Optional, enable native TensorFlow backend
const tf = require('@tensorflow/tfjs');
const HMM = require('hidden-markov-model-tf');const [observations, time, states, dimensions] = [5, 7, 3, 2];
// Configure model
const hmm = new HMM({
states: states,
dimensions: dimensions
});// Set parameters
await hmm.setParameters({
pi: tf.tensor([0.15, 0.20, 0.65]),
A: tf.tensor([
[0.55, 0.15, 0.30],
[0.45, 0.45, 0.10],
[0.15, 0.20, 0.65]
]),
mu: tf.tensor([
[-7.0, -8.0],
[-1.5, 3.7],
[-1.7, 1.2]
]),
Sigma: tf.tensor([
[[ 0.12, -0.01],
[-0.01, 0.50]],
[[ 0.21, 0.05],
[ 0.05, 0.03]],
[[ 0.37, 0.35],
[ 0.35, 0.44]]
])
});// Sample data
const sample = hmm.sample({observations, time});
assert.deepEqual(sample.states.shape, [observations, time]);
assert.deepEqual(sample.emissions.shape, [observations, time, dimensions]);// Your data must be a tf.tensor with shape [observations, time, dimensions]
const data = sample.emissions;// Fit model with data
const results = await hmm.fit(data);
assert(results.converged);// Predict hidden state indices
const inference = hmm.inference(data);
assert.deepEqual(inference.shape, [observations, time]);
states.print();// Compute log-likelihood
const logLikelihood = hmm.logLikelihood(data);
assert.deepEqual(logLikelihood.shape, [observations]);
logLikelihood.print();// Get parameters
const {pi, A, mu, Sigma} = hmm.getParameters();
pi.print();
A.print();
mu.print();
Sigma.print();
```## Documentation
`hidden-markov-model-tf` is TensorFlow.js based, therefore your input must
be povided as a `tf.tensor`. Likewise most outputs are also provided as a
`tf.tensor`. You can always get a `TypedArray` with `await tensor.data()`.### hmm = new HMM({states, dimensions})
The constructor takes two integer arguments. The number of hidden `states` and
the number of `dimensions` in the Gaussian emissions.### result = await hmm.fit(tensor, {maxIterations = 100, tolerance = 0.001, seed})
The `fit` method, takes an required `tf.tensor` object. That must have the
shape `[observations, time, dimensions]`. If you only have one observation
it should have the shape `[1, time, dimensions]`.The `fit` method, returns a `Promise` for the `results`. The `results` is
an object with the following properties:```js
const {
// the number of iterations used, will at most be `maxIterations`
iterations,// if the training coverged, given the `tolerance`,
// before `maxIterations` was reached
converged,// The achived tolerance, after the number of iterations. This can be
// useful if the optimizer did not converge, but you want to know how
// good the fit is.
tolerance
} = await hmm.fit(tensor);
```The `fit` method uses a KMeans initialization. This initialization algorithm is
random but can be seeded with the optional `seed` parameter.After initialization, the model is optimized using an EM-algorithm called
the [Baum–Welch algorithm](https://en.wikipedia.org/wiki/Baum%E2%80%93Welch_algorithm).### states = hmm.inference(tensor)
The `inference` method, takes an required `tf.tensor` object. That must have
the shape `[observations, time, dimensions]`.It uses the [Viterbi algorithm](https://en.wikipedia.org/wiki/Viterbi_algorithm)
for infering the hidden state. Which is returned as `tf.tensor` with the
shape `[observations, time]`.```js
const states = hmm.inference(tensor);
states.print();
console.log(await states.data());
```### logLikelihood = hmm.logLikelihood(tensor)
The `inference` method, takes an required `tf.tensor` object. That must have
the shape `[observations, time, dimensions]`.It uses the forward procedure of the
[Baum–Welch algorithm](https://en.wikipedia.org/wiki/Baum%E2%80%93Welch_algorithm)
to compute the logLikelihood for each observation. This is returned as a
`tf.tensor` with the shape `[observations]`.### {states, emissions} = hmm.sample({ observations, time, seed })
The `sample` method, samples data from the Hidden Markov Model distribution
and returns both the sampled states and Gaussian emissions, as two `tf.tensor`
objects.the `states` tensor has the shape `[observations, time]`. While the `emissions`
tensor has the `shape` [observations, time, dimensions].The sampling can be seed with the optional `seed` parameter.
### {pi, A, mu, Sigma} = hmm.getParameters()
Return the underlying parameters:
* `pi`: the hidden state prior distribution. `shape = [states]`
* `A`: the hidden state transfer distribution. `shape = [states, states]`
* `mu`: the mean of the Gaussian emission distribution. `shape = [states, dimensions]`
* `Sigma`: the covariance matrix of the Gaussian emission distribution. `shape = [states, dimensions, dimensions]`### await hmm.setParameters({pi, A, mu, Sigma})
Set the underlying parameters of the Hidden Markov Model. Note that some
internal properties related to the Gaussian distribution will be precomputed.
Therefore this returns a `Promise`. Be sure to wait for the promise to
resolve before calling any other method.