Last active
August 29, 2015 14:13
-
-
Save praeclarum/a777511207495f01e3ca to your computer and use it in GitHub Desktop.
Markov Chain that learns by observing data.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Markov chain that learns by observing data. | |
/// Let it observe a sequence of states. | |
/// Then you can ask it, given a state, | |
/// what are the probabilities of the next states occuring? | |
/// This chain can remember history to make better predictions. | |
type MarkovChain (numStates : int, memory : int) = | |
let numPrevious = 1 + memory | |
let matrixSize = int (System.Math.Pow (float numStates, float numPrevious)) | |
let mutable matrix = Array2D.create matrixSize matrixSize (0, 0) | |
let previousStatesToIndex ps = ps |> Seq.take numPrevious |> Seq.fold (fun i x -> i*numStates + x) 0 | |
let approx (n : int, d : int) = | |
if d > 0 then float n / float d | |
else 0.0 | |
member this.TransitionProbabilities = matrix |> Array2D.map approx | |
member this.PredictNextState (previousStates : int seq) = | |
let prevIndex = previousStatesToIndex previousStates | |
let s = previousStates |> Seq.nth (numPrevious - 1) | |
Array.init numStates (fun i -> approx matrix.[prevIndex, s*numStates + i]) | |
member this.Learn (states : int seq) = | |
let rec learn s = | |
let pIndex = previousStatesToIndex s | |
let nIndex = previousStatesToIndex (s |> Seq.skip 1) | |
for i = 0 to (matrixSize - 1) do | |
let s, c = matrix.[pIndex, i] | |
let a = if i = nIndex then 1 else 0 | |
matrix.[pIndex, i] <- (s + a, c + 1) | |
if Seq.length s > numPrevious + 1 then | |
learn (s |> Seq.skip 1) | |
learn states | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example: