Using Arrays -
Linear Regression
(See file Samples\Fun\LinearRegression\LinearRegression.fs.)
Suppose you have data that you believe to be distributed along a line with
parameters a and b with some additional gaussian
noise, that is, the points of the data are of the form (x, y)
y = a*x + b + Gaussian(0.0, noise). Having observed some data points you
would like to learn the distribution of a b, and
noise We start by setting up a model:
[<ReflectedDefinition>]
let point (x: float) (a: float) (b: float) (invNoise: float): float * float =
let y = random(GaussianFromMeanAndPrecision(a * x + b, invNoise))
x, y
[<ReflectedDefinition>]
let parameters() =
let a = random(GaussianFromMeanAndPrecision(0.0, 1.0))
let b = random(GaussianFromMeanAndPrecision(5.0, 0.3))
let invNoise = random (GammaFromShapeAndScale(1.0, 1.0))
a, b, invNoise
[<ReflectedDefinition>]
let model (data: (float * float)[]) =
let a, b, invNoise = parameters ()
observe (data = [| for (x, _) in data -> point x a b invNoise |])
a, b, invNoise
|
The function point describes how we believe the data points to
be generated; the function parameters describes our prior
beliefs regarding the parameters of the line; and the function model
uses an observation to state that we believe the actual concrete data to be
generated by our model. In model we can use the array
comprehension syntax to generate a whole range of points at once.
For
testing purposes we can use the model itself to generate sample data points:
let nPoints = 10
let aTrue, bTrue, invNoiseTrue = parameters()
let data =
[| for x in 1 .. nPoints -> point (float x) aTrue bTrue invNoiseTrue |] |
We can now run inference to compute the parameters based on the generated
points. The inference returns a distribution of the parameters, in order to get
the most likely values we can ask for the mean of the distribution:
open
MicrosoftResearch.Infer.Distributions
printf "true a: %A\n" aTrue
printf "true b: %A\n" bTrue
printf "true noise (inverse): %A\n"
invNoiseTrue
let (aD: Gaussian),
(bD: Gaussian),
(noiseD: Gamma) = infer <@ model @> data
printf "inferred a: %A\n" aD
printf "inferred b: %A\n" bD
printf "inferred noise (inverse): %A\n"
noiseD
let aMean = aD.GetMean()
let bMean = bD.GetMean()
printf "mean a: %A\n" aMean
printf "mean b: %A\n" bMean |