@@ -3,13 +3,11 @@ defmodule LearnKit.Regression.Linear.Calculations do
33 Module for fit functions
44 """
55
6- alias LearnKit.Math
7- alias LearnKit.Regression.Linear
6+ alias LearnKit . { Math , Regression.Linear }
87
98 defmacro __using__ ( _opts ) do
109 quote do
11- defp do_fit ( method , % Linear { factors: factors , results: results } )
12- when method == "gradient descent" do
10+ defp do_fit ( "gradient descent" , % Linear { factors: factors , results: results } ) do
1311 gradient_descent_iteration (
1412 [ :rand . uniform ( ) , :rand . uniform ( ) ] ,
1513 0.0001 ,
@@ -21,10 +19,7 @@ defmodule LearnKit.Regression.Linear.Calculations do
2119 end
2220
2321 defp do_fit ( _ , % Linear { factors: factors , results: results } ) do
24- beta =
25- Math . correlation ( factors , results ) * Math . standard_deviation ( results ) /
26- Math . standard_deviation ( factors )
27-
22+ beta = calc_beta ( factors , results )
2823 alpha = Math . mean ( results ) - beta * Math . mean ( factors )
2924 [ alpha , beta ]
3025 end
@@ -36,66 +31,54 @@ defmodule LearnKit.Regression.Linear.Calculations do
3631 end )
3732 end
3833
34+ defp calc_beta ( factors , results ) do
35+ Math . correlation ( factors , results ) * Math . standard_deviation ( results ) / Math . standard_deviation ( factors )
36+ end
37+
3938 defp squared_error_gradient ( linear , x , y ) do
4039 error_variable = prediction_error ( linear , x , y )
41-
4240 [
4341 - 2 * error_variable ,
4442 - 2 * error_variable * x
4543 ]
4644 end
4745
48- defp gradient_descent_iteration ( _ , _ , min_theta , _ , _ , iterations_with_no_improvement )
49- when iterations_with_no_improvement >= 100 ,
50- do: min_theta
46+ defp gradient_descent_iteration ( _ , _ , min_theta , _ , _ , no_improve_step ) when no_improve_step >= 100 , do: min_theta
5147
52- defp gradient_descent_iteration (
53- theta ,
54- alpha ,
55- min_theta ,
56- min_value ,
57- data ,
58- iterations_with_no_improvement
59- ) do
48+ defp gradient_descent_iteration ( theta , alpha , min_theta , min_value , data , no_improve_step ) do
6049 [
6150 min_theta ,
6251 min_value ,
63- iterations_with_no_improvement ,
52+ no_improve_step ,
6453 alpha
65- ] = check_value ( data , min_value , theta , min_theta , iterations_with_no_improvement , alpha )
54+ ] = check_value ( data , min_value , theta , min_theta , no_improve_step , alpha )
6655
67- theta =
68- data
69- |> Enum . shuffle ( )
70- |> Enum . reduce ( theta , fn { xi , yi } , acc ->
71- gradient_i = squared_error_gradient ( % Linear { coefficients: theta } , xi , yi )
72- acc |> Math . vector_subtraction ( alpha |> Math . scalar_multiply ( gradient_i ) )
73- end )
74-
75- gradient_descent_iteration (
76- theta ,
77- alpha ,
78- min_theta ,
79- min_value ,
80- data ,
81- iterations_with_no_improvement
82- )
56+ calc_new_theta ( data , theta , alpha )
57+ |> gradient_descent_iteration ( alpha , min_theta , min_value , data , no_improve_step )
8358 end
8459
85- defp check_value ( data , min_value , theta , min_theta , iterations_with_no_improvement , alpha ) do
86- value =
87- Enum . reduce ( data , 0 , fn { xi , yi } , acc ->
88- acc + squared_prediction_error ( % Linear { coefficients: theta } , xi , yi )
89- end )
60+ defp calc_new_theta ( data , theta , alpha ) do
61+ data
62+ |> Enum . shuffle ( )
63+ |> Enum . reduce ( theta , fn { xi , yi } , acc ->
64+ gradient_i = squared_error_gradient ( % Linear { coefficients: theta } , xi , yi )
65+ acc |> Math . vector_subtraction ( alpha |> Math . scalar_multiply ( gradient_i ) )
66+ end )
67+ end
9068
69+ defp check_value ( data , min_value , theta , min_theta , no_improve_step , alpha ) do
70+ value = calc_new_value ( data , theta )
9171 cond do
92- value < min_value ->
93- [ theta , value , 0 , 0.0001 ]
94-
95- true ->
96- [ min_theta , min_value , iterations_with_no_improvement + 1 , alpha * 0.9 ]
72+ value < min_value -> [ theta , value , 0 , 0.0001 ]
73+ true -> [ min_theta , min_value , no_improve_step + 1 , alpha * 0.9 ]
9774 end
9875 end
76+
77+ defp calc_new_value ( data , theta ) do
78+ Enum . reduce ( data , 0 , fn { xi , yi } , acc ->
79+ acc + squared_prediction_error ( % Linear { coefficients: theta } , xi , yi )
80+ end )
81+ end
9982 end
10083 end
10184end
0 commit comments