## 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:

 ``` [] let point (x: float) (a: float) (b: float) (invNoise: float): float * float =    let y = random(GaussianFromMeanAndPrecision(a * x + b, invNoise))   x, y [] 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 [] 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```