Skip to content

Commit ae5ded5

Browse files
committed
add function for calculating R^2 score of the prediction
1 parent c92174c commit ae5ded5

3 files changed

Lines changed: 48 additions & 19 deletions

File tree

lib/learn_kit/math.ex

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ defmodule LearnKit.Math do
6565

6666
def variance(list, list_mean) when is_list(list) do
6767
list
68-
|> Enum.map(fn x -> pow(list_mean - x, 2) end)
68+
|> Enum.map(fn x -> :math.pow(list_mean - x, 2) end)
6969
|> mean
7070
end
7171

@@ -145,21 +145,6 @@ defmodule LearnKit.Math do
145145
x / y
146146
end
147147

148-
@doc """
149-
Pow number
150-
151-
## Examples
152-
153-
iex> LearnKit.Math.pow(10, 2)
154-
100
155-
156-
"""
157-
@spec pow(number, number) :: number
158-
159-
def pow(x, y) do
160-
:math.pow(x, y)
161-
end
162-
163148
@doc """
164149
Calculate the covariance of two lists
165150
@@ -201,10 +186,10 @@ defmodule LearnKit.Math do
201186
|> Enum.map(fn {xi, yi} -> (xi - mean_x) * (yi - mean_y) end)
202187
|> Enum.sum
203188
denom_x = x
204-
|> Enum.map(fn xi -> pow(xi - mean_x, 2) end)
189+
|> Enum.map(fn xi -> :math.pow(xi - mean_x, 2) end)
205190
|> Enum.sum
206191
denom_y = y
207-
|> Enum.map(fn yi -> pow(yi - mean_y, 2) end)
192+
|> Enum.map(fn yi -> :math.pow(yi - mean_y, 2) end)
208193
|> Enum.sum
209194

210195
divider / :math.sqrt(denom_x * denom_y)

lib/learn_kit/regression/linear.ex

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,26 @@ defmodule LearnKit.Regression.Linear do
8989
@spec predict(%LearnKit.Regression.Linear{coefficients: coefficients}, list) :: list
9090

9191
def predict(%Linear{coefficients: coefficients}, samples) do
92-
IO.inspect coefficients
9392
samples
9493
|> Enum.map(fn sample -> predict_sample(sample, coefficients) end)
9594
end
95+
96+
@doc """
97+
Returns the coefficient of determination R^2 of the prediction
98+
99+
## Parameters
100+
101+
- predictor: %LearnKit.Regression.Linear{}
102+
103+
## Examples
104+
105+
iex> predictor |> LearnKit.Regression.Linear.score
106+
0.9876543209876543
107+
108+
"""
109+
@spec score(%LearnKit.Regression.Linear{factors: factors, results: results, coefficients: coefficients}) :: number
110+
111+
def score(%Linear{factors: factors, results: results, coefficients: coefficients}) do
112+
calculate_score(coefficients, factors, results)
113+
end
96114
end

lib/learn_kit/regression/linear/predict.ex

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,37 @@ defmodule LearnKit.Regression.Linear.Predict do
22
@moduledoc """
33
Module for fit functions
44
"""
5+
6+
alias LearnKit.Math
7+
58
defmacro __using__(_opts) do
69
quote do
710
defp predict_sample(sample, [alpha, beta]) do
811
sample * beta + alpha
912
end
13+
14+
defp calculate_score([], _, _), do: raise("There was no fit for model")
15+
16+
defp calculate_score(coefficients, factors, results) do
17+
1.0 - sum_of_squared_errors(coefficients, factors, results) / total_sum_of_squares(results)
18+
end
19+
20+
defp total_sum_of_squares(list) do
21+
mean_list = Math.mean(list)
22+
list
23+
|> Enum.map(fn x -> :math.pow(x - mean_list, 2) end)
24+
|> Enum.sum
25+
end
26+
27+
defp sum_of_squared_errors(coefficients, factors, results) do
28+
Enum.zip(factors, results)
29+
|> Enum.map(fn {xi, yi} -> :math.pow(prediction_error(coefficients, xi, yi), 2) end)
30+
|> Enum.sum
31+
end
32+
33+
defp prediction_error(coefficients, x, y) do
34+
y - predict_sample(x, coefficients)
35+
end
1036
end
1137
end
1238
end

0 commit comments

Comments
 (0)