Packages

A collection of useful mathematical functions in Elixir with a slant towards statistics, linear algebra and machine learning

Current section

Files

Jump to
numerix lib linear_regression.ex
Raw

lib/linear_regression.ex

defmodule Numerix.LinearRegression do
@moduledoc """
Linear regression functions.
"""
import Numerix.Statistics
alias Numerix.Correlation
@doc """
Least squares best fit for points `{x, y}` to a line `y:x↦a+bx`
where `x` is the predictor and `y` the response.
Returns a tuple containing the intercept `a` and slope `b`.
"""
@spec fit([number], [number]) :: {float, float}
def fit([], _), do: nil
def fit(_, []), do: nil
def fit(xs, ys) when length(xs) != length(ys), do: nil
def fit(xs, ys) do
x_mean = xs |> mean
y_mean = ys |> mean
variance = xs |> variance
covariance = xs |> covariance(ys)
slope = covariance / variance
intercept = y_mean - (slope * x_mean)
{intercept, slope}
end
@doc """
Estimates a response `y` given a predictor `x`
and a set of predictors and responses, i.e.
it calculates `y` in `y:x↦a+bx`.
"""
def predict(x, xs, ys) do
{intercept, slope} = fit(xs, ys)
intercept + slope * x
end
@doc """
Measures how close the observed data are to
the fitted regression line, i.e. how accurate
the prediction is given the actual data.
Returns a value between 0 and 1 where 0 indicates
a prediction that is worse than the mean and 1
indicates a perfect prediction.
"""
@spec r_squared([number], [number]) :: float
def r_squared(predicted, actual) do
predicted
|> Correlation.pearson(actual)
|> squared
end
defp squared(nil), do: nil
defp squared(correlation), do: correlation |> :math.pow(2)
end