Skip to content

Commit 9766e3b

Browse files
committed
add Math functions, add Fit method for LinearRegression
1 parent ddad829 commit 9766e3b

3 files changed

Lines changed: 135 additions & 14 deletions

File tree

lib/learn_kit/math.ex

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +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 ->
69-
list_mean - x
70-
|> :math.pow(2)
71-
end)
68+
|> Enum.map(fn x -> pow(list_mean - x, 2) end)
7269
|> mean
7370
end
7471

@@ -132,4 +129,84 @@ defmodule LearnKit.Math do
132129
others = Enum.map(rows, fn(x) -> tl(x) end)
133130
[firsts | swap_rows_cols(others)]
134131
end
132+
133+
@doc """
134+
Division for 2 elements
135+
136+
## Examples
137+
138+
iex> LearnKit.Math.division(10, 2)
139+
5
140+
141+
"""
142+
@spec division(number, number) :: number
143+
144+
def division(x, y) when y != 0 do
145+
x / y
146+
end
147+
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+
163+
@doc """
164+
Calculate the covariance of two lists
165+
166+
## Examples
167+
168+
iex> LearnKit.Math.covariance([1, 2, 3], [14, 17, 25])
169+
5.5
170+
171+
"""
172+
@spec covariance(list,list) :: number
173+
174+
def covariance(x, y) when length(x) == length(y) do
175+
mean_x = mean(x)
176+
mean_y = mean(y)
177+
size = length(x)
178+
179+
Enum.zip(x, y)
180+
|> Enum.map(fn {xi, yi} -> (xi - mean_x) * (yi - mean_y) end)
181+
|> Enum.sum
182+
|> division(size - 1)
183+
end
184+
185+
@doc """
186+
Correlation of two lists
187+
188+
## Examples
189+
190+
iex> LearnKit.Math.correlation([1, 2, 3], [14, 17, 25])
191+
0.9672471299049061
192+
193+
"""
194+
@spec correlation(list, list) :: number
195+
196+
def correlation(x, y) when length(x) == length(y) do
197+
mean_x = mean(x)
198+
mean_y = mean(y)
199+
200+
divider = Enum.zip(x, y)
201+
|> Enum.map(fn {xi, yi} -> (xi - mean_x) * (yi - mean_y) end)
202+
|> Enum.sum
203+
denom_x = x
204+
|> Enum.map(fn xi -> pow(xi - mean_x, 2) end)
205+
|> Enum.sum
206+
denom_y = y
207+
|> Enum.map(fn yi -> pow(yi - mean_y, 2) end)
208+
|> Enum.sum
209+
210+
divider / :math.sqrt(denom_x * denom_y)
211+
end
135212
end

lib/learn_kit/regression/linear.ex

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,71 @@ defmodule LearnKit.Regression.Linear do
33
Module for Linear Regression algorithm
44
"""
55

6-
defstruct factors: [], results: []
6+
defstruct factors: [], results: [], coefficients: []
77

88
alias LearnKit.Regression.Linear
99

10+
use Linear.Fit
11+
1012
@type factors :: [number]
1113
@type results :: [number]
14+
@type coefficients :: [number]
1215

1316
@doc """
14-
Creates classificator with empty data_set
17+
Creates predictor with empty data_set
1518
1619
## Examples
1720
18-
iex> classificator = LearnKit.Regression.Linear.new
19-
%LearnKit.Regression.Linear{factors: [], results: []}
21+
iex> predictor = LearnKit.Regression.Linear.new
22+
%LearnKit.Regression.Linear{factors: [], results: [], coefficients: []}
2023
2124
"""
22-
@spec new() :: %LearnKit.Regression.Linear{factors: [], results: []}
25+
@spec new() :: %LearnKit.Regression.Linear{factors: [], results: [], coefficients: []}
2326

2427
def new do
2528
Linear.new([], [])
2629
end
2730

2831
@doc """
29-
Creates classificator with data_set
32+
Creates predictor with data_set
3033
3134
## Parameters
3235
33-
- data_set: Keyword list with labels and features in tuples
36+
- factors: Array of predictor variables
37+
- results: Array of criterion variables
3438
3539
## Examples
3640
37-
iex> classificator = LearnKit.Regression.Linear.new([1, 2, 3, 4], [2, 3, 4, 5])
38-
%LearnKit.Regression.Linear{factors: [1, 2, 3, 4], results: [2, 3, 4, 5]}
41+
iex> predictor = LearnKit.Regression.Linear.new([1, 2, 3, 4], [2, 3, 4, 5])
42+
%LearnKit.Regression.Linear{factors: [1, 2, 3, 4], results: [2, 3, 4, 5], coefficients: []}
3943
4044
"""
41-
@spec new(factors, results) :: %LearnKit.Regression.Linear{factors: factors, results: results}
45+
@spec new(factors, results) :: %LearnKit.Regression.Linear{factors: factors, results: results, coefficients: []}
4246

4347
def new(factors, results) do
4448
%Linear{factors: factors, results: results}
4549
end
50+
51+
@doc """
52+
Fit train data
53+
54+
## Parameters
55+
56+
- predictor: %LearnKit.Regression.Linear{}
57+
58+
## Examples
59+
60+
iex> predictor |> LearnKit.Regression.Linear.fit
61+
%LearnKit.Regression.Linear{
62+
coefficients: [1.0, 1.0],
63+
factors: [1, 2, 3, 4],
64+
results: [2, 3, 4, 5]
65+
}
66+
67+
"""
68+
@spec fit(%LearnKit.Regression.Linear{factors: factors, results: results}) :: %LearnKit.Regression.Linear{factors: factors, results: results, coefficients: coefficients}
69+
70+
def fit(%Linear{factors: factors, results: results}) do
71+
%Linear{factors: factors, results: results, coefficients: fit_data(factors, results)}
72+
end
4673
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
defmodule LearnKit.Regression.Linear.Fit do
2+
@moduledoc """
3+
Module for fit functions
4+
"""
5+
6+
alias LearnKit.Math
7+
8+
defmacro __using__(_opts) do
9+
quote do
10+
defp fit_data(factors, results) do
11+
beta = Math.correlation(factors, results) * Math.standard_deviation(results) / Math.standard_deviation(factors)
12+
alpha = Math.mean(results) - beta * Math.mean(factors)
13+
[alpha, beta]
14+
end
15+
end
16+
end
17+
end

0 commit comments

Comments
 (0)