Git Product home page Git Product logo

bayesjs's Introduction

Build Status Coverage Status npm bundle size Commitizen friendly js-standard-style semantic-release

BayesJS

A inference library for Bayesian Networks made with TypeScript.

Inferences

Currently there are three inferences algorithms:

Methods

infer(network: INetwork, nodes?: ICombinations, given?: ICombinations): number

Calculate the probability of a node's state.

This function receives a network, and will return the probability of the node having the given state subject to the given evidence.

As mentioned above, there are three inferences engines, by default the junction tree algorithm is used to execute the infer function.

If you want to perform repeated inferences from the same bayes network, you should consider instanciating an inference engine for that network.

import { infer, inferences } from 'bayesjs';

infer(network, event, evidence); // Junction tree algorithm

inferences.enumeration.infer(network, event, evidence);
inferences.variableElimination.infer(network, event, evidence);
inferences.junctionTree.infer(network, event, evidence);
Example

Given the rain-sprinkler-grasswet network. Image here.

import { infer } from 'bayesjs';

const network = // ...

// What is the probability that it is raining (RAIN = T)?
infer(network, { 'RAIN': 'T' }).toFixed(4) // 0.2000
// What is the probability that it is raining (RAIN = T), given the sprinkler is off (SPRINKLER = F)?
infer(network, { 'RAIN': 'T' }, { 'SPRINKLER': 'F' }).toFixed(4) // 0.2920

inferAll(network: INetwork, given?: ICombinations, options?: IInferAllOptions): INetworkResult)

Calculate the marginal distributions for a given network subject to some given evidence.

This method will execute the junction tree algorithm on each node's state.

Options
precision

default: 8

Rounds the network results according to this value. To round the value we are using round-to.

Some rounds examples:

  • 0.30000000000000004
    • 8 precision -> 0.3
    • 4 precision -> 0.3
    • 2 precision -> 0.3
  • 0.3333333333333333
    • 8 precision -> 0.33333333
    • 4 precision -> 0.3333
    • 2 precision -> 0.33
  • 0.9802979902088171
    • 8 precision -> 0.98029799
    • 4 precision -> 0.9803
    • 2 precision -> 0.98
Example
const network = {
  'Node 1': {
    id: 'Node 1',
    states: ['True', 'False'],
    parents: [],
    cpt: { True: 0.5, False: 0.5 },
  },
  'Node 2': {
    id: 'Node 2',
    states: ['True', 'False'],
    parents: [],
    cpt: { True: 0.5, False: 0.5 },
  },
  'Node 3': {
    id: 'Node 3',
    states: ['True', 'False'],
    parents: ['Node 2', 'Node 1'],
    cpt: [
      {
        when: { 'Node 2': 'True', 'Node 1': 'True' },
        then: { True: 0.5, False: 0.5 },
      },
      {
        when: { 'Node 2': 'False', 'Node 1': 'True' },
        then: { True: 0.5, False: 0.5 },
      },
      {
        when: { 'Node 2': 'True', 'Node 1': 'False' },
        then: { True: 0.5, False: 0.5 },
      },
      {
        when: { 'Node 2': 'False', 'Node 1': 'False' },
        then: { True: 0.5, False: 0.5 },
      },
    ],
  },
};

const evidence = { 'Node 1': 'True' }

inferAll(network, evidence)
// {
//   'Node 1': { True: 1, False: 0 },
//   'Node 2': { True: 0.5, False: 0.5 },
//   'Node 3': { True: 0.5, False: 0.5 },
// }

// Mutating the network...
network["Node 3"].cpt[0].then = { True: 0.95, False: 0.05 };

inferAll(network, evidence);
// {
//   'Node 1': { True: 1, False: 0 },
//   'Node 2': { True: 0.5, False: 0.5 },
//   'Node 3': { True: 0.725, False: 0.275 }
// }

Inference engines provide an efficient way of performing repeated inferences on the same Bayesian network. Currently there is one inference engine provided:

  • InferenceEngine) - An inference engine that uses the junction tree algorithm for infereneces, caching the network topology and potentials for efficiency.

Each engine can be ititialized by calling the constructor with the desired network. The example below shows how to perform efficient repeated inference on the Alarm bayes network.:

import { InferenceEngine } from 'bayesjs'
import { allNodes } from './models/alarm.ts'

const network = createNetwork(...allNodes )
const engine = InferenceEngine( network )

// Make multiple inferences with the network without inferences
console.log( engine.infer({ 'JOHN_CALLS': 'T' })) // 0.0521
console.log( engine.infer({ 'MARY_CALLS': 'T' })) // 0.0117
console.log( engine.getEvidence ) // { }

// inject some evidence and make multiple inferences
engine.setEvidence({ 'EARTHQUAKE': 'T' } )
console.log( engine.infer({ 'JOHN_CALLS': 'T' })) // 0.2971
console.log( engine.infer({ 'MARY_CALLS': 'T' })) // 0.2106
console.log( engine.getEvidence ) // { 'EARTHQUAKE': 'T' }

// Update the distribution for a node and make some inferences
engine.setDistribution('BURGLARY', { T: 0.05, F: 0.95 })
console.log( engine.infer({ 'JOHN_CALLS': 'T' })) // 0.3246
console.log( engine.infer({ 'MARY_CALLS': 'T' })) // 0.2329
console.log( engine.getEvidence ) // { 'EARTHQUAKE': 'T' }

// incrementally add additional evidence and make multiple inferences
engine.setEvidence({ 'ALARM': 'T' } )
console.log( engine.infer({ 'JOHN_CALLS': 'T' })) // 0.9000
console.log( engine.infer({ 'MARY_CALLS': 'T' })) // 0.7000
console.log( engine.getEvidence ) // { 'ALARM': 'T', 'EARTHQUAKE': 'T' }

// Remove all the evidence and make multiple inferences.
engine.removeAllEvidence()
console.log( engine.infer({ 'JOHN_CALLS': 'T' })) // 0.0912
console.log( engine.infer({ 'MARY_CALLS': 'T' })) // 0.0435
console.log( engine.getEvidence ) // { }

addNode(network: INetwork, node: INode): INetwork

Add a node in a Bayesian Network.

This function receives a network and a node, check if the node can be appended on the network. If something is wrong an exception will be thrown, otherwise, a new network will return with the node added.

Example
import { addNode } from 'bayesjs';

const networkWithRainAndSprinkler = // ...

const grassWet = {
  id: 'GRASS_WET',
  states: [ 'T', 'F' ],
  parents: [ 'RAIN', 'SPRINKLER' ],
  cpt: [
    { when: { 'RAIN': 'T', 'SPRINKLER': 'T' }, then: { 'T': 0.99, 'F': 0.01 } },
    { when: { 'RAIN': 'T', 'SPRINKLER': 'F' }, then: { 'T': 0.8, 'F': 0.2 } },
    { when: { 'RAIN': 'F', 'SPRINKLER': 'T' }, then: { 'T': 0.9, 'F': 0.1 } },
    { when: { 'RAIN': 'F', 'SPRINKLER': 'F' }, then: { 'T': 0, 'F': 1 } }
  ]
};

const newtwork = addNode(networkWithRainAndSprinkler, grassWet);

License

MIT

bayesjs's People

Contributors

nolleto avatar fhelwanger avatar dlewissandy avatar dependabot[bot] avatar semantic-release-bot avatar parties avatar cartucciam avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.