Skip to content

Commit 44037e4

Browse files
committed
code refactoring
1 parent ea74439 commit 44037e4

7 files changed

Lines changed: 59 additions & 67 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## Unreleased
8+
### Modified
9+
- code refactoring
10+
711
## [0.1.5] - 2018-12-18
812
### Added
913
- preprocessing normalization for data set

lib/learn_kit/knn.ex

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ defmodule LearnKit.Knn do
2626
"""
2727
@spec new() :: %Knn{data_set: []}
2828

29-
def new do
30-
Knn.new([])
31-
end
29+
def new, do: Knn.new([])
3230

3331
@doc """
3432
Creates classifier with data_set
@@ -45,9 +43,7 @@ defmodule LearnKit.Knn do
4543
"""
4644
@spec new(data_set) :: %Knn{data_set: data_set}
4745

48-
def new(data_set) when is_list(data_set) do
49-
%Knn{data_set: data_set}
50-
end
46+
def new(data_set) when is_list(data_set), do: %Knn{data_set: data_set}
5147

5248
@doc """
5349
Add train data to classifier
@@ -66,7 +62,7 @@ defmodule LearnKit.Knn do
6662
@spec add_train_data(%Knn{data_set: data_set}, point) :: %Knn{data_set: data_set}
6763

6864
def add_train_data(%Knn{data_set: data_set}, {key, value}) when is_atom(key) and is_list(value) do
69-
features = if Keyword.has_key?(data_set, key), do: Keyword.get(data_set, key), else: []
65+
features = if Keyword.has_key?(data_set, key), do: data_set[key], else: []
7066
data_set = Keyword.put(data_set, key, [value | features])
7167
%Knn{data_set: data_set}
7268
end
@@ -100,10 +96,10 @@ defmodule LearnKit.Knn do
10096
!Keyword.has_key?(options, :feature) ->
10197
{:error, "Feature option is required"}
10298

103-
!is_list(Keyword.get(options, :feature)) ->
99+
!is_list(options[:feature]) ->
104100
{:error, "Feature option must be presented as array"}
105101

106-
Keyword.has_key?(options, :k) && (!is_integer(Keyword.get(options, :k)) || Keyword.get(options, :k) <= 0) ->
102+
Keyword.has_key?(options, :k) && (!is_integer(options[:k]) || options[:k] <= 0) ->
107103
{:error, "K option must be positive integer"}
108104

109105
true ->

lib/learn_kit/knn/classify.ex

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule LearnKit.Knn.Classify do
99
quote do
1010
defp prediction(data_set, options) do
1111
data_set
12-
|> filter_features_by_size(Keyword.get(options, :feature))
12+
|> filter_features_by_size(options[:feature])
1313
|> check_normalization(options)
1414
|> calc_distances_for_features(options)
1515
|> sort_distances()
@@ -29,7 +29,7 @@ defmodule LearnKit.Knn.Classify do
2929

3030
# normalize features
3131
defp check_normalization(data_set, options) do
32-
type = Keyword.get(options, :normalization)
32+
type = options[:normalization]
3333
case type do
3434
t when t in ["minimax", "z_normalization"] -> normalize(data_set, type)
3535
_ -> data_set
@@ -38,7 +38,7 @@ defmodule LearnKit.Knn.Classify do
3838

3939
# select algorithm for prediction
4040
defp calc_distances_for_features(data_set, options) do
41-
case Keyword.get(options, :algorithm) do
41+
case options[:algorithm] do
4242
"brute" -> brute_algorithm(data_set, options)
4343
_ -> []
4444
end
@@ -51,7 +51,7 @@ defmodule LearnKit.Knn.Classify do
5151

5252
# take closest features
5353
defp select_closest_features(features, options) do
54-
Enum.take(features, Keyword.get(options, :k))
54+
Enum.take(features, options[:k])
5555
end
5656

5757
# check existeness of current feature in data set
@@ -92,7 +92,7 @@ defmodule LearnKit.Knn.Classify do
9292

9393
defp calc_feature_weights(features, options) do
9494
Enum.map(features, fn feature ->
95-
Tuple.append(feature, calc_feature_weight(Keyword.get(options, :weight), elem(feature, 0)))
95+
Tuple.append(feature, calc_feature_weight(options[:weight], elem(feature, 0)))
9696
end)
9797
end
9898

@@ -106,14 +106,13 @@ defmodule LearnKit.Knn.Classify do
106106
defp brute_algorithm(data_set, options) do
107107
data_set
108108
|> Keyword.keys()
109-
|> handle_features_in_label(data_set, Keyword.get(options, :feature))
109+
|> handle_features_in_label(data_set, options[:feature])
110110
|> List.flatten()
111111
end
112112

113113
defp handle_features_in_label(keys, data_set, current_feature) do
114114
Enum.map(keys, fn key ->
115-
data_set
116-
|> Keyword.get(key)
115+
data_set[key]
117116
|> calc_distances_in_label(current_feature, key)
118117
end)
119118
end
@@ -152,7 +151,7 @@ defmodule LearnKit.Knn.Classify do
152151
end
153152

154153
defp accumulate_weight_of_labels([{_, key, weight} | tail], acc) do
155-
previous = if Keyword.has_key?(acc, key), do: Keyword.get(acc, key), else: 0
154+
previous = if Keyword.has_key?(acc, key), do: acc[key], else: 0
156155
acc = Keyword.put(acc, key, previous + weight)
157156
accumulate_weight_of_labels(tail, acc)
158157
end

lib/learn_kit/math.ex

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,20 @@ defmodule LearnKit.Math do
1717
"""
1818
@spec summ(number, number) :: number
1919

20-
def summ(a, b) do
21-
a + b
22-
end
20+
def summ(a, b), do: a + b
21+
22+
@doc """
23+
Division for 2 elements
24+
25+
## Examples
26+
27+
iex> LearnKit.Math.division(10, 2)
28+
5.0
29+
30+
"""
31+
@spec division(number, number) :: number
32+
33+
def division(x, y) when y != 0, do: x / y
2334

2435
@doc """
2536
Calculate the mean from a list of numbers
@@ -35,14 +46,14 @@ defmodule LearnKit.Math do
3546
"""
3647
@spec mean(list) :: number
3748

38-
def mean(list) when is_list(list), do: mean(list, 0, 0)
49+
def mean(list) when is_list(list), do: do_mean(list, 0, 0)
3950

40-
defp mean([], 0, 0), do: nil
51+
defp do_mean([], 0, 0), do: nil
4152

42-
defp mean([], sum, number), do: sum / number
53+
defp do_mean([], sum, number), do: sum / number
4354

44-
defp mean([head | tail], sum, number) do
45-
mean(tail, sum + head, number + 1)
55+
defp do_mean([head | tail], sum, number) do
56+
do_mean(tail, sum + head, number + 1)
4657
end
4758

4859
@doc """
@@ -131,16 +142,14 @@ defmodule LearnKit.Math do
131142
"""
132143
@spec transpose(matrix) :: matrix
133144

134-
def transpose(m) do
135-
swap_rows_cols(m)
136-
end
145+
def transpose(m), do: do_transpose(m)
137146

138-
defp swap_rows_cols([head | _]) when head == [], do: []
147+
defp do_transpose([head | _]) when head == [], do: []
139148

140-
defp swap_rows_cols(rows) do
149+
defp do_transpose(rows) do
141150
firsts = Enum.map(rows, fn x -> hd(x) end)
142151
others = Enum.map(rows, fn x -> tl(x) end)
143-
[firsts | swap_rows_cols(others)]
152+
[firsts | do_transpose(others)]
144153
end
145154

146155
@doc """
@@ -169,26 +178,11 @@ defmodule LearnKit.Math do
169178
"""
170179
@spec vector_subtraction(list, list) :: list
171180

172-
def vector_subtraction(x, y) when is_list(x) and is_list(y) and length(x) == length(y) do
181+
def vector_subtraction(x, y) when length(x) == length(y) do
173182
Enum.zip(x, y)
174183
|> Enum.map(fn {xi, yi} -> xi - yi end)
175184
end
176185

177-
@doc """
178-
Division for 2 elements
179-
180-
## Examples
181-
182-
iex> LearnKit.Math.division(10, 2)
183-
5.0
184-
185-
"""
186-
@spec division(number, number) :: number
187-
188-
def division(x, y) when y != 0 do
189-
x / y
190-
end
191-
192186
@doc """
193187
Calculate the covariance of two lists
194188

lib/learn_kit/preprocessing.ex

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ defmodule LearnKit.Preprocessing do
2929
"""
3030
@spec normalize(matrix) :: matrix
3131

32-
def normalize(features) when is_list(features) do
33-
normalize(features, [type: "minimax"])
34-
end
32+
def normalize(features) when is_list(features), do: normalize(features, [type: "minimax"])
3533

3634
@doc """
3735
Normalize data set
@@ -59,7 +57,7 @@ defmodule LearnKit.Preprocessing do
5957

6058
def normalize(features, options) when is_list(features) and is_list(options) do
6159
options = Keyword.merge([type: "minimax"], options)
62-
case Keyword.get(options, :type) do
60+
case options[:type] do
6361
"z_normalization" -> normalization(features, "z_normalization")
6462
_ -> normalization(features, "minimax")
6563
end

lib/learn_kit/regression/linear.ex

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ defmodule LearnKit.Regression.Linear do
2424
"""
2525
@spec new() :: %Linear{factors: [], results: [], coefficients: []}
2626

27-
def new do
28-
Linear.new([], [])
29-
end
27+
def new, do: Linear.new([], [])
3028

3129
@doc """
3230
Creates predictor with data_set
@@ -44,9 +42,7 @@ defmodule LearnKit.Regression.Linear do
4442
"""
4543
@spec new(factors, results) :: %Linear{factors: factors, results: results, coefficients: []}
4644

47-
def new(factors, results) do
48-
%Linear{factors: factors, results: results}
49-
end
45+
def new(factors, results) when is_list(factors) and is_list(results), do: %Linear{factors: factors, results: results}
5046

5147
@doc """
5248
Fit train data
@@ -79,16 +75,16 @@ defmodule LearnKit.Regression.Linear do
7975
"""
8076
@spec fit(%Linear{factors: factors, results: results}) :: %Linear{factors: factors, results: results, coefficients: coefficients}
8177

82-
def fit(%Linear{factors: factors, results: results}, options \\ []) do
78+
def fit(%Linear{factors: factors, results: results}, options \\ []) when is_list(options) do
8379
coefficients =
8480
Keyword.merge([method: ""], options)
8581
|> define_method_for_fit()
86-
|> fit_data(factors, results)
82+
|> do_fit(factors, results)
8783
%Linear{factors: factors, results: results, coefficients: coefficients}
8884
end
8985

9086
defp define_method_for_fit(options) do
91-
case Keyword.get(options, :method) do
87+
case options[:method] do
9288
"gradient descent" -> "gradient descent"
9389
_ -> ""
9490
end
@@ -110,9 +106,11 @@ defmodule LearnKit.Regression.Linear do
110106
"""
111107
@spec predict(%Linear{coefficients: coefficients}, list) :: {:ok, list}
112108

113-
def predict(%Linear{coefficients: coefficients}, samples) do
114-
result = Enum.map(samples, fn sample -> predict_sample(sample, coefficients) end)
115-
{:ok, result}
109+
def predict(%Linear{coefficients: coefficients}, samples) when is_list(samples) do
110+
{
111+
:ok,
112+
Enum.map(samples, fn sample -> predict_sample(sample, coefficients) end)
113+
}
116114
end
117115

118116
@doc """
@@ -131,6 +129,9 @@ defmodule LearnKit.Regression.Linear do
131129
@spec score(%Linear{factors: factors, results: results, coefficients: coefficients}) :: {:ok, number}
132130

133131
def score(%Linear{factors: factors, results: results, coefficients: coefficients}) do
134-
{:ok, calculate_score(coefficients, factors, results)}
132+
{
133+
:ok,
134+
calculate_score(coefficients, factors, results)
135+
}
135136
end
136137
end

lib/learn_kit/regression/linear/calculations.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ defmodule LearnKit.Regression.Linear.Calculations do
77

88
defmacro __using__(_opts) do
99
quote do
10-
defp fit_data(method, factors, results) when method == "gradient descent" do
10+
defp do_fit(method, factors, results) when method == "gradient descent" do
1111
gradient_descent_iteration([:rand.uniform, :rand.uniform], 0.0001, nil, 1000000, Enum.zip(factors, results), 0)
1212
end
1313

14-
defp fit_data(_, factors, results) do
14+
defp do_fit(_, factors, results) do
1515
beta = Math.correlation(factors, results) * Math.standard_deviation(results) / Math.standard_deviation(factors)
1616
alpha = Math.mean(results) - beta * Math.mean(factors)
1717
[alpha, beta]

0 commit comments

Comments
 (0)