@@ -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