rumale 0.23.3 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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