rumale 0.23.3 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +5 -1
  3. data/README.md +3 -288
  4. data/lib/rumale/version.rb +1 -1
  5. data/lib/rumale.rb +20 -131
  6. metadata +252 -150
  7. data/CHANGELOG.md +0 -643
  8. data/CODE_OF_CONDUCT.md +0 -74
  9. data/ext/rumale/extconf.rb +0 -37
  10. data/ext/rumale/rumaleext.c +0 -545
  11. data/ext/rumale/rumaleext.h +0 -12
  12. data/lib/rumale/base/base_estimator.rb +0 -49
  13. data/lib/rumale/base/classifier.rb +0 -36
  14. data/lib/rumale/base/cluster_analyzer.rb +0 -31
  15. data/lib/rumale/base/evaluator.rb +0 -17
  16. data/lib/rumale/base/regressor.rb +0 -36
  17. data/lib/rumale/base/splitter.rb +0 -21
  18. data/lib/rumale/base/transformer.rb +0 -22
  19. data/lib/rumale/clustering/dbscan.rb +0 -123
  20. data/lib/rumale/clustering/gaussian_mixture.rb +0 -218
  21. data/lib/rumale/clustering/hdbscan.rb +0 -291
  22. data/lib/rumale/clustering/k_means.rb +0 -122
  23. data/lib/rumale/clustering/k_medoids.rb +0 -141
  24. data/lib/rumale/clustering/mini_batch_k_means.rb +0 -139
  25. data/lib/rumale/clustering/power_iteration.rb +0 -127
  26. data/lib/rumale/clustering/single_linkage.rb +0 -203
  27. data/lib/rumale/clustering/snn.rb +0 -76
  28. data/lib/rumale/clustering/spectral_clustering.rb +0 -115
  29. data/lib/rumale/dataset.rb +0 -246
  30. data/lib/rumale/decomposition/factor_analysis.rb +0 -150
  31. data/lib/rumale/decomposition/fast_ica.rb +0 -188
  32. data/lib/rumale/decomposition/nmf.rb +0 -124
  33. data/lib/rumale/decomposition/pca.rb +0 -159
  34. data/lib/rumale/ensemble/ada_boost_classifier.rb +0 -179
  35. data/lib/rumale/ensemble/ada_boost_regressor.rb +0 -160
  36. data/lib/rumale/ensemble/extra_trees_classifier.rb +0 -139
  37. data/lib/rumale/ensemble/extra_trees_regressor.rb +0 -125
  38. data/lib/rumale/ensemble/gradient_boosting_classifier.rb +0 -306
  39. data/lib/rumale/ensemble/gradient_boosting_regressor.rb +0 -237
  40. data/lib/rumale/ensemble/random_forest_classifier.rb +0 -189
  41. data/lib/rumale/ensemble/random_forest_regressor.rb +0 -153
  42. data/lib/rumale/ensemble/stacking_classifier.rb +0 -215
  43. data/lib/rumale/ensemble/stacking_regressor.rb +0 -163
  44. data/lib/rumale/ensemble/voting_classifier.rb +0 -126
  45. data/lib/rumale/ensemble/voting_regressor.rb +0 -82
  46. data/lib/rumale/evaluation_measure/accuracy.rb +0 -29
  47. data/lib/rumale/evaluation_measure/adjusted_rand_score.rb +0 -74
  48. data/lib/rumale/evaluation_measure/calinski_harabasz_score.rb +0 -56
  49. data/lib/rumale/evaluation_measure/davies_bouldin_score.rb +0 -53
  50. data/lib/rumale/evaluation_measure/explained_variance_score.rb +0 -39
  51. data/lib/rumale/evaluation_measure/f_score.rb +0 -50
  52. data/lib/rumale/evaluation_measure/function.rb +0 -147
  53. data/lib/rumale/evaluation_measure/log_loss.rb +0 -45
  54. data/lib/rumale/evaluation_measure/mean_absolute_error.rb +0 -29
  55. data/lib/rumale/evaluation_measure/mean_squared_error.rb +0 -29
  56. data/lib/rumale/evaluation_measure/mean_squared_log_error.rb +0 -29
  57. data/lib/rumale/evaluation_measure/median_absolute_error.rb +0 -30
  58. data/lib/rumale/evaluation_measure/mutual_information.rb +0 -49
  59. data/lib/rumale/evaluation_measure/normalized_mutual_information.rb +0 -53
  60. data/lib/rumale/evaluation_measure/precision.rb +0 -50
  61. data/lib/rumale/evaluation_measure/precision_recall.rb +0 -96
  62. data/lib/rumale/evaluation_measure/purity.rb +0 -40
  63. data/lib/rumale/evaluation_measure/r2_score.rb +0 -43
  64. data/lib/rumale/evaluation_measure/recall.rb +0 -50
  65. data/lib/rumale/evaluation_measure/roc_auc.rb +0 -130
  66. data/lib/rumale/evaluation_measure/silhouette_score.rb +0 -82
  67. data/lib/rumale/feature_extraction/feature_hasher.rb +0 -110
  68. data/lib/rumale/feature_extraction/hash_vectorizer.rb +0 -155
  69. data/lib/rumale/feature_extraction/tfidf_transformer.rb +0 -113
  70. data/lib/rumale/kernel_approximation/nystroem.rb +0 -126
  71. data/lib/rumale/kernel_approximation/rbf.rb +0 -102
  72. data/lib/rumale/kernel_machine/kernel_fda.rb +0 -120
  73. data/lib/rumale/kernel_machine/kernel_pca.rb +0 -97
  74. data/lib/rumale/kernel_machine/kernel_ridge.rb +0 -82
  75. data/lib/rumale/kernel_machine/kernel_ridge_classifier.rb +0 -92
  76. data/lib/rumale/kernel_machine/kernel_svc.rb +0 -193
  77. data/lib/rumale/linear_model/base_sgd.rb +0 -285
  78. data/lib/rumale/linear_model/elastic_net.rb +0 -119
  79. data/lib/rumale/linear_model/lasso.rb +0 -115
  80. data/lib/rumale/linear_model/linear_regression.rb +0 -201
  81. data/lib/rumale/linear_model/logistic_regression.rb +0 -275
  82. data/lib/rumale/linear_model/nnls.rb +0 -137
  83. data/lib/rumale/linear_model/ridge.rb +0 -209
  84. data/lib/rumale/linear_model/svc.rb +0 -213
  85. data/lib/rumale/linear_model/svr.rb +0 -132
  86. data/lib/rumale/manifold/mds.rb +0 -155
  87. data/lib/rumale/manifold/tsne.rb +0 -222
  88. data/lib/rumale/metric_learning/fisher_discriminant_analysis.rb +0 -113
  89. data/lib/rumale/metric_learning/mlkr.rb +0 -161
  90. data/lib/rumale/metric_learning/neighbourhood_component_analysis.rb +0 -167
  91. data/lib/rumale/model_selection/cross_validation.rb +0 -125
  92. data/lib/rumale/model_selection/function.rb +0 -42
  93. data/lib/rumale/model_selection/grid_search_cv.rb +0 -225
  94. data/lib/rumale/model_selection/group_k_fold.rb +0 -93
  95. data/lib/rumale/model_selection/group_shuffle_split.rb +0 -115
  96. data/lib/rumale/model_selection/k_fold.rb +0 -81
  97. data/lib/rumale/model_selection/shuffle_split.rb +0 -90
  98. data/lib/rumale/model_selection/stratified_k_fold.rb +0 -99
  99. data/lib/rumale/model_selection/stratified_shuffle_split.rb +0 -118
  100. data/lib/rumale/model_selection/time_series_split.rb +0 -91
  101. data/lib/rumale/multiclass/one_vs_rest_classifier.rb +0 -83
  102. data/lib/rumale/naive_bayes/base_naive_bayes.rb +0 -47
  103. data/lib/rumale/naive_bayes/bernoulli_nb.rb +0 -82
  104. data/lib/rumale/naive_bayes/complement_nb.rb +0 -85
  105. data/lib/rumale/naive_bayes/gaussian_nb.rb +0 -69
  106. data/lib/rumale/naive_bayes/multinomial_nb.rb +0 -74
  107. data/lib/rumale/naive_bayes/negation_nb.rb +0 -71
  108. data/lib/rumale/nearest_neighbors/k_neighbors_classifier.rb +0 -133
  109. data/lib/rumale/nearest_neighbors/k_neighbors_regressor.rb +0 -108
  110. data/lib/rumale/nearest_neighbors/vp_tree.rb +0 -132
  111. data/lib/rumale/neural_network/adam.rb +0 -56
  112. data/lib/rumale/neural_network/base_mlp.rb +0 -248
  113. data/lib/rumale/neural_network/mlp_classifier.rb +0 -120
  114. data/lib/rumale/neural_network/mlp_regressor.rb +0 -90
  115. data/lib/rumale/pairwise_metric.rb +0 -152
  116. data/lib/rumale/pipeline/feature_union.rb +0 -69
  117. data/lib/rumale/pipeline/pipeline.rb +0 -175
  118. data/lib/rumale/preprocessing/bin_discretizer.rb +0 -93
  119. data/lib/rumale/preprocessing/binarizer.rb +0 -60
  120. data/lib/rumale/preprocessing/kernel_calculator.rb +0 -92
  121. data/lib/rumale/preprocessing/l1_normalizer.rb +0 -62
  122. data/lib/rumale/preprocessing/l2_normalizer.rb +0 -63
  123. data/lib/rumale/preprocessing/label_binarizer.rb +0 -89
  124. data/lib/rumale/preprocessing/label_encoder.rb +0 -79
  125. data/lib/rumale/preprocessing/max_abs_scaler.rb +0 -61
  126. data/lib/rumale/preprocessing/max_normalizer.rb +0 -62
  127. data/lib/rumale/preprocessing/min_max_scaler.rb +0 -76
  128. data/lib/rumale/preprocessing/one_hot_encoder.rb +0 -100
  129. data/lib/rumale/preprocessing/ordinal_encoder.rb +0 -109
  130. data/lib/rumale/preprocessing/polynomial_features.rb +0 -109
  131. data/lib/rumale/preprocessing/standard_scaler.rb +0 -71
  132. data/lib/rumale/probabilistic_output.rb +0 -114
  133. data/lib/rumale/tree/base_decision_tree.rb +0 -150
  134. data/lib/rumale/tree/decision_tree_classifier.rb +0 -150
  135. data/lib/rumale/tree/decision_tree_regressor.rb +0 -116
  136. data/lib/rumale/tree/extra_tree_classifier.rb +0 -107
  137. data/lib/rumale/tree/extra_tree_regressor.rb +0 -94
  138. data/lib/rumale/tree/gradient_tree_regressor.rb +0 -202
  139. data/lib/rumale/tree/node.rb +0 -39
  140. data/lib/rumale/utils.rb +0 -42
  141. data/lib/rumale/validation.rb +0 -128
  142. data/lib/rumale/values.rb +0 -13
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rumale/validation'
4
- require 'rumale/pairwise_metric'
5
- require 'rumale/base/base_estimator'
6
-
7
- module Rumale
8
- module NearestNeighbors
9
- # VPTree is a class that implements the nearest neigbor searcher based on vantage point tree.
10
- # This implementation, unlike the paper, does not perform random sampling with vantage point selection.
11
- # This class is used internally for k-nearest neighbor estimators.
12
- #
13
- # @deprecated This class will be removed in ver. 0.24.0. The author recommends to use the annoy-rb gem instead.
14
- #
15
- # *Reference*
16
- # - Yianilos, P N., "Data Structures and Algorithms for Nearest Neighbor Search in General Metric Spaces," Proc. SODA'93, pp. 311--321, 1993.
17
- class VPTree
18
- include Validation
19
- include Base::BaseEstimator
20
-
21
- # Return the training data.
22
- # @return [Numo::DFloat] (shape: [n_samples, n_features])
23
- attr_reader :data
24
-
25
- # Create a search index with vantage point tree algorithm.
26
- #
27
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The data to used generating search index.
28
- # @param min_samples_leaf [Integer] The minimum number of samples at a leaf node.
29
- def initialize(x, min_samples_leaf: 1)
30
- check_params_numeric(min_samples_leaf: min_samples_leaf)
31
- check_params_positive(min_samples_leaf: min_samples_leaf)
32
- @params = {}
33
- @params[:min_samples_leaf] = min_samples_leaf
34
- @data = x
35
- @tree = build_tree(Numo::Int32.cast(Array(0...@data.shape[0])))
36
- end
37
-
38
- # Search k-nearest neighbors of given query point.
39
- #
40
- # @param x [Numo::DFloat] (shape: [n_samples, n_features])
41
- # @param k [Integer] The samples to be query points.
42
- # @return [Array<Array<Numo::Int32, Numo::DFloat>>] The indices and distances of retrieved k-nearest neighbors.
43
- def query(x, k = 1)
44
- x = check_convert_sample_array(x)
45
- check_params_numeric(k: k)
46
- check_params_positive(k: k)
47
-
48
- n_samples = x.shape[0]
49
- rel_ids = []
50
- rel_dists = []
51
-
52
- n_samples.times do |n|
53
- q = x[n, true]
54
- rel_node = search(q, @tree, k)
55
- dist_arr = calc_distances(q, @data[rel_node.sample_ids, true])
56
- rank_ids = dist_arr.sort_index[0...k]
57
- rel_ids.push(rel_node.sample_ids[rank_ids].dup)
58
- rel_dists.push(dist_arr[rank_ids].dup)
59
- end
60
-
61
- [Numo::Int32.cast(rel_ids), Numo::DFloat.cast(rel_dists)]
62
- end
63
-
64
- private
65
-
66
- Node = Struct.new(:sample_ids, :n_samples, :vantage_point_id, :threshold, :left, :right) do
67
- def leaf?
68
- vantage_point_id.nil?
69
- end
70
- end
71
-
72
- private_constant :Node
73
-
74
- def search(q, node, k, tau = Float::INFINITY)
75
- return node if node.leaf?
76
-
77
- dist = Math.sqrt(((q - @data[node.vantage_point_id, true])**2).sum)
78
- tau = dist if dist < tau
79
-
80
- # :nocov:
81
- if dist < node.threshold
82
- if dist - tau <= node.threshold
83
- node.left.n_samples < k ? node : search(q, node.left, k, tau)
84
- elsif dist + tau >= node.threshold
85
- node.right.n_samples < k ? node : search(q, node.right, k, tau)
86
- else
87
- node
88
- end
89
- elsif dist + tau >= node.threshold
90
- node.right.n_samples < k ? node : search(q, node.right, k, tau)
91
- elsif dist - tau <= node.threshold
92
- node.left.n_samples < k ? node : search(q, node.left, k, tau)
93
- else
94
- node
95
- end
96
- # :nocov:
97
- end
98
-
99
- def build_tree(sample_ids)
100
- n_samples = sample_ids.size
101
- node = Node.new
102
- node.n_samples = n_samples
103
- node.sample_ids = sample_ids
104
- return node if n_samples <= @params[:min_samples_leaf]
105
-
106
- vantage_point_id = select_vantage_point_id(sample_ids)
107
- distance_arr = calc_distances(@data[vantage_point_id, true], @data[sample_ids, true])
108
- threshold = distance_arr.median
109
- left_flgs = distance_arr.lt(threshold)
110
- right_flgs = distance_arr.ge(threshold)
111
- return node if left_flgs.count < @params[:min_samples_leaf] || right_flgs.count < @params[:min_samples_leaf]
112
-
113
- node.left = build_tree(sample_ids[left_flgs])
114
- node.right = build_tree(sample_ids[right_flgs])
115
- node.vantage_point_id = vantage_point_id
116
- node.threshold = threshold
117
- node
118
- end
119
-
120
- def select_vantage_point_id(sample_ids)
121
- dist_mat = Rumale::PairwiseMetric.euclidean_distance(@data[sample_ids, true])
122
- means = dist_mat.mean(0)
123
- vars = ((dist_mat - means)**2).mean(0)
124
- sample_ids[vars.max_index]
125
- end
126
-
127
- def calc_distances(q, x)
128
- Rumale::PairwiseMetric.euclidean_distance(q.expand_dims(0), x).flatten.dup
129
- end
130
- end
131
- end
132
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rumale/base/base_estimator'
4
-
5
- module Rumale
6
- module NeuralNetwork
7
- # @!visibility private
8
- # This module consists of the classes that implement optimizers adaptively tuning learning rate.
9
- module Optimizer
10
- # @!visibility private
11
- # Adam is a class that implements Adam optimizer.
12
- #
13
- # *Reference*
14
- # - Kingma, D P., and Ba, J., "Adam: A Method for Stochastic Optimization," Proc. ICLR'15, 2015.
15
- class Adam
16
- include Base::BaseEstimator
17
-
18
- # @!visibility private
19
- # Create a new optimizer with Adam
20
- #
21
- # @param learning_rate [Float] The initial value of learning rate.
22
- # @param decay1 [Float] The smoothing parameter for the first moment.
23
- # @param decay2 [Float] The smoothing parameter for the second moment.
24
- def initialize(learning_rate: 0.001, decay1: 0.9, decay2: 0.999)
25
- @params = {}
26
- @params[:learning_rate] = learning_rate
27
- @params[:decay1] = decay1
28
- @params[:decay2] = decay2
29
- @fst_moment = nil
30
- @sec_moment = nil
31
- @iter = 0
32
- end
33
-
34
- # @!visibility private
35
- # Calculate the updated weight with Adam adaptive learning rate.
36
- #
37
- # @param weight [Numo::DFloat] (shape: [n_features]) The weight to be updated.
38
- # @param gradient [Numo::DFloat] (shape: [n_features]) The gradient for updating the weight.
39
- # @return [Numo::DFloat] (shape: [n_feautres]) The updated weight.
40
- def call(weight, gradient)
41
- @fst_moment ||= Numo::DFloat.zeros(weight.shape)
42
- @sec_moment ||= Numo::DFloat.zeros(weight.shape)
43
-
44
- @iter += 1
45
-
46
- @fst_moment = @params[:decay1] * @fst_moment + (1.0 - @params[:decay1]) * gradient
47
- @sec_moment = @params[:decay2] * @sec_moment + (1.0 - @params[:decay2]) * gradient**2
48
- nm_fst_moment = @fst_moment / (1.0 - @params[:decay1]**@iter)
49
- nm_sec_moment = @sec_moment / (1.0 - @params[:decay2]**@iter)
50
-
51
- weight - @params[:learning_rate] * nm_fst_moment / (nm_sec_moment**0.5 + 1e-8)
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,248 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rumale/base/base_estimator'
4
-
5
- module Rumale
6
- # This module consists of the modules and classes for implementation multi-layer perceptron estimator.
7
- module NeuralNetwork
8
- # @!visibility private
9
- # This module consists of the classes that implement layer functions of neural network.
10
- module Layer
11
- # @!visibility private
12
- # Affine is a class that calculates the linear transform.
13
- # This class is used internally.
14
- class Affine
15
- # @!visibility private
16
- def initialize(n_inputs: nil, n_outputs: nil, optimizer: nil, rng: nil)
17
- @weight = 0.01 * Rumale::Utils.rand_normal([n_inputs, n_outputs], rng)
18
- @bias = Numo::DFloat.zeros(n_outputs)
19
- @optimizer_weight = optimizer.dup
20
- @optimizer_bias = optimizer.dup
21
- end
22
-
23
- # @!visibility private
24
- def forward(x)
25
- out = x.dot(@weight) + @bias
26
-
27
- backward = proc do |dout|
28
- dx = dout.dot(@weight.transpose)
29
- dw = x.transpose.dot(dout)
30
- db = dout.sum(0)
31
-
32
- @weight = @optimizer_weight.call(@weight, dw)
33
- @bias = @optimizer_bias.call(@bias, db)
34
-
35
- dx
36
- end
37
-
38
- [out, backward]
39
- end
40
- end
41
-
42
- # @!visibility private
43
- # Dropout is a class that performs dropout regularization.
44
- # This class is used internally.
45
- class Dropout
46
- # @!visibility private
47
- def initialize(rate: 0.3, rng: nil)
48
- @rate = rate
49
- @rng = rng
50
- end
51
-
52
- # @!visibility private
53
- def forward(x)
54
- rand_mat = Rumale::Utils.rand_uniform(x.shape, @rng)
55
- mask = rand_mat.ge(@rate)
56
- out = x * mask
57
- out *= 1.fdiv(1 - @rate) if @rate < 1.0
58
-
59
- backward = proc { |dout| dout * mask }
60
-
61
- [out, backward]
62
- end
63
- end
64
-
65
- # @!visibility private
66
- # ReLU is a class that calculates rectified linear function.
67
- # This class is used internally.
68
- class Relu
69
- # @!visibility private
70
- def forward(x)
71
- mask = x.gt(0)
72
- out = x * mask
73
-
74
- backward = proc { |dout| dout * mask }
75
-
76
- [out, backward]
77
- end
78
- end
79
- end
80
-
81
- # @!visibility private
82
- # This module consists of the classes that implement loss function for neural network.
83
- module Loss
84
- # @!visibility private
85
- # MeanSquaredError is a class that calculates mean squared error for regression task.
86
- # This class is used internally.
87
- class MeanSquaredError
88
- # @!visibility private
89
- def call(out, y)
90
- sz_batch = y.shape[0]
91
- diff = out - y
92
- loss = (diff**2).sum.fdiv(sz_batch)
93
- dout = 2.fdiv(sz_batch) * diff
94
- [loss, dout]
95
- end
96
- end
97
-
98
- # @!visibility private
99
- # SoftmaxCrossEntropy is a class that calculates softmax cross-entropy for classification task.
100
- # This class is used internally.
101
- class SoftmaxCrossEntropy
102
- # @!visibility private
103
- def call(out, y)
104
- sz_batch = y.shape[0]
105
- z = softmax(out)
106
- loss = -(y * Numo::NMath.log(z + 1e-8)).sum.fdiv(sz_batch)
107
- dout = (z - y) / sz_batch
108
- [loss, dout]
109
- end
110
-
111
- private
112
-
113
- def softmax(x)
114
- clip = x.max(-1).expand_dims(-1)
115
- exp_x = Numo::NMath.exp(x - clip)
116
- exp_x / exp_x.sum(-1).expand_dims(-1)
117
- end
118
- end
119
- end
120
-
121
- # @!visibility private
122
- # This module consists of the classes for implementing neural network model.
123
- module Model
124
- # @!visibility private
125
- attr_reader :layers
126
-
127
- # @!visibility private
128
- # Sequential is a class that implements linear stack model.
129
- # This class is used internally.
130
- class Sequential
131
- # @!visibility private
132
- def initialize
133
- @layers = []
134
- end
135
-
136
- # @!visibility private
137
- def push(ops)
138
- @layers.push(ops)
139
- self
140
- end
141
-
142
- # @!visibility private
143
- def delete_dropout
144
- @layers.delete_if { |node| node.is_a?(Layer::Dropout) }
145
- self
146
- end
147
-
148
- # @!visibility private
149
- def forward(x)
150
- backprops = []
151
- out = x.dup
152
-
153
- @layers.each do |l|
154
- out, bw = l.forward(out)
155
- backprops.push(bw)
156
- end
157
-
158
- backward = proc do |dout|
159
- backprops.reverse_each { |bw| dout = bw.call(dout) }
160
- dout
161
- end
162
-
163
- [out, backward]
164
- end
165
- end
166
- end
167
-
168
- # BaseMLP is an abstract class for implementation of multi-layer peceptron estimator.
169
- # This class is used internally.
170
- class BaseMLP
171
- include Base::BaseEstimator
172
-
173
- # Create a multi-layer perceptron estimator.
174
- #
175
- # @param hidden_units [Array] The number of units in the i-th hidden layer.
176
- # @param dropout_rate [Float] The rate of the units to drop.
177
- # @param learning_rate [Float] The initial value of learning rate in Adam optimizer.
178
- # @param decay1 [Float] The smoothing parameter for the first moment in Adam optimizer.
179
- # @param decay2 [Float] The smoothing parameter for the second moment in Adam optimizer.
180
- # @param max_iter [Integer] The maximum number of epochs that indicates
181
- # how many times the whole data is given to the training process.
182
- # @param batch_size [Intger] The size of the mini batches.
183
- # @param tol [Float] The tolerance of loss for terminating optimization.
184
- # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
185
- # @param random_seed [Integer] The seed value using to initialize the random generator.
186
- def initialize(hidden_units: [128, 128], dropout_rate: 0.4, learning_rate: 0.001, decay1: 0.9, decay2: 0.999,
187
- max_iter: 200, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
188
- @params = {}
189
- @params[:hidden_units] = hidden_units
190
- @params[:dropout_rate] = dropout_rate
191
- @params[:learning_rate] = learning_rate
192
- @params[:decay1] = decay1
193
- @params[:decay2] = decay2
194
- @params[:max_iter] = max_iter
195
- @params[:batch_size] = batch_size
196
- @params[:tol] = tol
197
- @params[:verbose] = verbose
198
- @params[:random_seed] = random_seed
199
- @params[:random_seed] ||= srand
200
- @n_iter = nil
201
- @rng = Random.new(@params[:random_seed])
202
- end
203
-
204
- private
205
-
206
- def buld_network(n_inputs, n_outputs, srng = nil)
207
- adam = Rumale::NeuralNetwork::Optimizer::Adam.new(
208
- learning_rate: @params[:learning_rate], decay1: @params[:decay1], decay2: @params[:decay2]
209
- )
210
- model = Model::Sequential.new
211
- n_units = [n_inputs, *@params[:hidden_units]]
212
- n_units.each_cons(2) do |n_in, n_out|
213
- model.push(Layer::Affine.new(n_inputs: n_in, n_outputs: n_out, optimizer: adam, rng: srng))
214
- model.push(Layer::Relu.new)
215
- model.push(Layer::Dropout.new(rate: @params[:dropout_rate], rng: srng))
216
- end
217
- model.push(Layer::Affine.new(n_inputs: n_units[-1], n_outputs: n_outputs, optimizer: adam, rng: srng))
218
- end
219
-
220
- def train(x, y, network, loss_func, srng = nil)
221
- class_name = self.class.to_s.split('::').last
222
- n_samples = x.shape[0]
223
-
224
- @params[:max_iter].times do |t|
225
- sample_ids = Array(0...n_samples)
226
- sample_ids.shuffle!(random: srng)
227
- until (subset_ids = sample_ids.shift(@params[:batch_size])).empty?
228
- # random sampling
229
- sub_x = x[subset_ids, true].dup
230
- sub_y = y[subset_ids, true].dup
231
- # forward
232
- out, backward = network.forward(sub_x)
233
- # calc loss function
234
- loss, dout = loss_func.call(out, sub_y)
235
- break if loss < @params[:tol]
236
-
237
- # backward
238
- backward.call(dout)
239
- end
240
- @n_iter = t + 1
241
- puts "[#{class_name}] Loss after #{@n_iter} epochs: #{loss}" if @params[:verbose]
242
- end
243
-
244
- network
245
- end
246
- end
247
- end
248
- end
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rumale/base/classifier'
4
- require 'rumale/neural_network/base_mlp'
5
- require 'rumale/preprocessing/label_binarizer'
6
-
7
- module Rumale
8
- module NeuralNetwork
9
- # MLPClassifier is a class that implements classifier based on multi-layer perceptron.
10
- # MLPClassifier use ReLu as the activation function and Adam as the optimization method
11
- # and softmax cross entropy as the loss function.
12
- #
13
- # @example
14
- # estimator = Rumale::NeuralNetwork::MLPClassifier.new(hidden_units: [100, 100], dropout_rate: 0.3)
15
- # estimator.fit(training_samples, traininig_labels)
16
- # results = estimator.predict(testing_samples)
17
- class MLPClassifier < BaseMLP
18
- include Base::Classifier
19
-
20
- # Return the network.
21
- # @return [Rumale::NeuralNetwork::Model::Sequential]
22
- attr_reader :network
23
-
24
- # Return the class labels.
25
- # @return [Numo::Int32] (size: n_classes)
26
- attr_reader :classes
27
-
28
- # Return the number of iterations run for optimization
29
- # @return [Integer]
30
- attr_reader :n_iter
31
-
32
- # Return the random generator.
33
- # @return [Random]
34
- attr_reader :rng
35
-
36
- # Create a new classifier with multi-layer preceptron.
37
- #
38
- # @param hidden_units [Array] The number of units in the i-th hidden layer.
39
- # @param dropout_rate [Float] The rate of the units to drop.
40
- # @param learning_rate [Float] The initial value of learning rate in Adam optimizer.
41
- # @param decay1 [Float] The smoothing parameter for the first moment in Adam optimizer.
42
- # @param decay2 [Float] The smoothing parameter for the second moment in Adam optimizer.
43
- # @param max_iter [Integer] The maximum number of epochs that indicates
44
- # how many times the whole data is given to the training process.
45
- # @param batch_size [Intger] The size of the mini batches.
46
- # @param tol [Float] The tolerance of loss for terminating optimization.
47
- # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
48
- # @param random_seed [Integer] The seed value using to initialize the random generator.
49
- def initialize(hidden_units: [128, 128], dropout_rate: 0.4, learning_rate: 0.001, decay1: 0.9, decay2: 0.999,
50
- max_iter: 200, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
51
- check_params_type(Array, hidden_units: hidden_units)
52
- check_params_numeric(dropout_rate: dropout_rate, learning_rate: learning_rate, decay1: decay1, decay2: decay2,
53
- max_iter: max_iter, batch_size: batch_size, tol: tol)
54
- check_params_boolean(verbose: verbose)
55
- check_params_numeric_or_nil(random_seed: random_seed)
56
- super
57
- @classes = nil
58
- @network = nil
59
- end
60
-
61
- # Fit the model with given training data.
62
- #
63
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
64
- # @param y [Numo::Int32] (shape: [n_samples]) The labels to be used for fitting the model.
65
- # @return [MLPClassifier] The learned classifier itself.
66
- def fit(x, y)
67
- x = check_convert_sample_array(x)
68
- y = check_convert_label_array(y)
69
- check_sample_label_size(x, y)
70
-
71
- @classes = Numo::Int32[*y.to_a.uniq.sort]
72
- n_labels = @classes.size
73
- n_features = x.shape[1]
74
- sub_rng = @rng.dup
75
-
76
- loss = Loss::SoftmaxCrossEntropy.new
77
- @network = buld_network(n_features, n_labels, sub_rng)
78
- @network = train(x, one_hot_encode(y), @network, loss, sub_rng)
79
- @network.delete_dropout
80
-
81
- self
82
- end
83
-
84
- # Predict class labels for samples.
85
- #
86
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to predict the labels.
87
- # @return [Numo::Int32] (shape: [n_samples]) Predicted class label per sample.
88
- def predict(x)
89
- x = check_convert_sample_array(x)
90
- n_samples = x.shape[0]
91
- decision_values = predict_proba(x)
92
- predicted = Array.new(n_samples) { |n| @classes[decision_values[n, true].max_index] }
93
- Numo::Int32.asarray(predicted)
94
- end
95
-
96
- # Predict probability for samples.
97
- #
98
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to predict the probailities.
99
- # @return [Numo::DFloat] (shape: [n_samples, n_classes]) Predicted probability of each class per sample.
100
- def predict_proba(x)
101
- x = check_convert_sample_array(x)
102
- out, = @network.forward(x)
103
- softmax(out)
104
- end
105
-
106
- private
107
-
108
- def one_hot_encode(y)
109
- encoder = Rumale::Preprocessing::LabelBinarizer.new
110
- encoder.fit_transform(y)
111
- end
112
-
113
- def softmax(x)
114
- clip = x.max(-1).expand_dims(-1)
115
- exp_x = Numo::NMath.exp(x - clip)
116
- exp_x / exp_x.sum(-1).expand_dims(-1)
117
- end
118
- end
119
- end
120
- end
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rumale/base/regressor'
4
- require 'rumale/neural_network/base_mlp'
5
-
6
- module Rumale
7
- module NeuralNetwork
8
- # MLPRegressor is a class that implements regressor based on multi-layer perceptron.
9
- # MLPRegressor use ReLu as the activation function and Adam as the optimization method
10
- # and mean squared error as the loss function.
11
- #
12
- # @example
13
- # estimator = Rumale::NeuralNetwork::MLPRegressor.new(hidden_units: [100, 100], dropout_rate: 0.3)
14
- # estimator.fit(training_samples, traininig_labels)
15
- # results = estimator.predict(testing_samples)
16
- class MLPRegressor < BaseMLP
17
- include Base::Regressor
18
-
19
- # Return the network.
20
- # @return [Rumale::NeuralNetwork::Model::Sequential]
21
- attr_reader :network
22
-
23
- # Return the number of iterations run for optimization
24
- # @return [Integer]
25
- attr_reader :n_iter
26
-
27
- # Return the random generator.
28
- # @return [Random]
29
- attr_reader :rng
30
-
31
- # Create a new regressor with multi-layer perceptron.
32
- #
33
- # @param hidden_units [Array] The number of units in the i-th hidden layer.
34
- # @param dropout_rate [Float] The rate of the units to drop.
35
- # @param learning_rate [Float] The initial value of learning rate in Adam optimizer.
36
- # @param decay1 [Float] The smoothing parameter for the first moment in Adam optimizer.
37
- # @param decay2 [Float] The smoothing parameter for the second moment in Adam optimizer.
38
- # @param max_iter [Integer] The maximum number of epochs that indicates
39
- # how many times the whole data is given to the training process.
40
- # @param batch_size [Intger] The size of the mini batches.
41
- # @param tol [Float] The tolerance of loss for terminating optimization.
42
- # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
43
- # @param random_seed [Integer] The seed value using to initialize the random generator.
44
- def initialize(hidden_units: [128, 128], dropout_rate: 0.4, learning_rate: 0.001, decay1: 0.9, decay2: 0.999,
45
- max_iter: 200, batch_size: 50, tol: 1e-4, verbose: false, random_seed: nil)
46
- check_params_type(Array, hidden_units: hidden_units)
47
- check_params_numeric(dropout_rate: dropout_rate, learning_rate: learning_rate, decay1: decay1, decay2: decay2,
48
- max_iter: max_iter, batch_size: batch_size, tol: tol)
49
- check_params_boolean(verbose: verbose)
50
- check_params_numeric_or_nil(random_seed: random_seed)
51
- super
52
- @network = nil
53
- end
54
-
55
- # Fit the model with given training data.
56
- #
57
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
58
- # @param y [Numo::DFloat] (shape: [n_samples, n_outputs]) The taget values to be used for fitting the model.
59
- # @return [MLPRegressor] The learned regressor itself.
60
- def fit(x, y)
61
- x = check_convert_sample_array(x)
62
- y = check_convert_tvalue_array(y)
63
- check_sample_tvalue_size(x, y)
64
-
65
- y = y.expand_dims(1) if y.ndim == 1
66
- n_targets = y.shape[1]
67
- n_features = x.shape[1]
68
- sub_rng = @rng.dup
69
-
70
- loss = Loss::MeanSquaredError.new
71
- @network = buld_network(n_features, n_targets, sub_rng)
72
- @network = train(x, y, @network, loss, sub_rng)
73
- @network.delete_dropout
74
-
75
- self
76
- end
77
-
78
- # Predict values for samples.
79
- #
80
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to predict the values.
81
- # @return [Numo::DFloat] (shape: [n_samples, n_outputs]) Predicted values per sample.
82
- def predict(x)
83
- x = check_convert_sample_array(x)
84
- out, = @network.forward(x)
85
- out = out[true, 0] if out.shape[1] == 1
86
- out
87
- end
88
- end
89
- end
90
- end