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,209 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'lbfgsb'
4
-
5
- require 'rumale/linear_model/base_sgd'
6
- require 'rumale/base/regressor'
7
-
8
- module Rumale
9
- module LinearModel
10
- # Ridge is a class that implements Ridge Regression
11
- # with stochastic gradient descent (SGD) optimization,
12
- # singular value decomposition (SVD), or L-BFGS optimization.
13
- #
14
- # @example
15
- # estimator =
16
- # Rumale::LinearModel::Ridge.new(reg_param: 0.1, max_iter: 1000, batch_size: 20, random_seed: 1)
17
- # estimator.fit(training_samples, traininig_values)
18
- # results = estimator.predict(testing_samples)
19
- #
20
- # # If Numo::Linalg is installed, you can specify 'svd' for the solver option.
21
- # require 'numo/linalg/autoloader'
22
- # estimator = Rumale::LinearModel::Ridge.new(reg_param: 0.1, solver: 'svd')
23
- # estimator.fit(training_samples, traininig_values)
24
- # results = estimator.predict(testing_samples)
25
- #
26
- # *Reference*
27
- # - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
28
- class Ridge < BaseSGD
29
- include Base::Regressor
30
-
31
- # Return the weight vector.
32
- # @return [Numo::DFloat] (shape: [n_outputs, n_features])
33
- attr_reader :weight_vec
34
-
35
- # Return the bias term (a.k.a. intercept).
36
- # @return [Numo::DFloat] (shape: [n_outputs])
37
- attr_reader :bias_term
38
-
39
- # Return the random generator for random sampling.
40
- # @return [Random]
41
- attr_reader :rng
42
-
43
- # Create a new Ridge regressor.
44
- #
45
- # @param learning_rate [Float] The initial value of learning rate.
46
- # The learning rate decreases as the iteration proceeds according to the equation: learning_rate / (1 + decay * t).
47
- # If solver is not 'sgd', this parameter is ignored.
48
- # @param decay [Float] The smoothing parameter for decreasing learning rate as the iteration proceeds.
49
- # If nil is given, the decay sets to 'reg_param * learning_rate'.
50
- # If solver is not 'sgd', this parameter is ignored.
51
- # @param momentum [Float] The momentum factor.
52
- # If solver is not 'sgd', this parameter is ignored.
53
- # @param reg_param [Float] The regularization parameter.
54
- # @param fit_bias [Boolean] The flag indicating whether to fit the bias term.
55
- # @param bias_scale [Float] The scale of the bias term.
56
- # @param max_iter [Integer] The maximum number of epochs that indicates
57
- # how many times the whole data is given to the training process.
58
- # If solver is 'svd', this parameter is ignored.
59
- # @param batch_size [Integer] The size of the mini batches.
60
- # If solver is not 'sgd', this parameter is ignored.
61
- # @param tol [Float] The tolerance of loss for terminating optimization.
62
- # If solver is 'svd', this parameter is ignored.
63
- # @param solver [String] The algorithm to calculate weights. ('auto', 'sgd', 'svd', or 'lbfgs').
64
- # 'auto' chooses the 'svd' solver if Numo::Linalg is loaded. Otherwise, it chooses the 'lbfgs' solver.
65
- # 'sgd' uses the stochastic gradient descent optimization.
66
- # 'svd' performs singular value decomposition of samples.
67
- # 'lbfgs' uses the L-BFGS method for optimization.
68
- # @param n_jobs [Integer] The number of jobs for running the fit method in parallel.
69
- # If nil is given, the method does not execute in parallel.
70
- # If zero or less is given, it becomes equal to the number of processors.
71
- # This parameter is ignored if the Parallel gem is not loaded or solver is not 'sgd'.
72
- # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
73
- # If solver is 'svd', this parameter is ignored.
74
- # @param random_seed [Integer] The seed value using to initialize the random generator.
75
- def initialize(learning_rate: 0.01, decay: nil, momentum: 0.9,
76
- reg_param: 1.0, fit_bias: true, bias_scale: 1.0,
77
- max_iter: 1000, batch_size: 50, tol: 1e-4,
78
- solver: 'auto',
79
- n_jobs: nil, verbose: false, random_seed: nil)
80
- check_params_numeric(learning_rate: learning_rate, momentum: momentum,
81
- reg_param: reg_param, bias_scale: bias_scale,
82
- max_iter: max_iter, batch_size: batch_size, tol: tol)
83
- check_params_boolean(fit_bias: fit_bias, verbose: verbose)
84
- check_params_string(solver: solver)
85
- check_params_numeric_or_nil(decay: decay, n_jobs: n_jobs, random_seed: random_seed)
86
- check_params_positive(learning_rate: learning_rate, reg_param: reg_param, max_iter: max_iter, batch_size: batch_size)
87
- super()
88
- @params.merge!(method(:initialize).parameters.map { |_t, arg| [arg, binding.local_variable_get(arg)] }.to_h)
89
- @params[:solver] = if solver == 'auto'
90
- enable_linalg?(warning: false) ? 'svd' : 'lbfgs'
91
- else
92
- solver.match?(/^svd$|^sgd$|^lbfgs$/) ? solver : 'lbfgs'
93
- end
94
- @params[:decay] ||= @params[:reg_param] * @params[:learning_rate]
95
- @params[:random_seed] ||= srand
96
- @rng = Random.new(@params[:random_seed])
97
- @penalty_type = L2_PENALTY
98
- @loss_func = LinearModel::Loss::MeanSquaredError.new
99
- @weight_vec = nil
100
- @bias_term = nil
101
- end
102
-
103
- # Fit the model with given training data.
104
- #
105
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
106
- # @param y [Numo::DFloat] (shape: [n_samples, n_outputs]) The target values to be used for fitting the model.
107
- # @return [Ridge] The learned regressor itself.
108
- def fit(x, y)
109
- x = check_convert_sample_array(x)
110
- y = check_convert_tvalue_array(y)
111
- check_sample_tvalue_size(x, y)
112
-
113
- if @params[:solver] == 'svd' && enable_linalg?(warning: false)
114
- fit_svd(x, y)
115
- elsif @params[:solver] == 'lbfgs'
116
- fit_lbfgs(x, y)
117
- else
118
- fit_sgd(x, y)
119
- end
120
-
121
- self
122
- end
123
-
124
- # Predict values for samples.
125
- #
126
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to predict the values.
127
- # @return [Numo::DFloat] (shape: [n_samples, n_outputs]) Predicted values per sample.
128
- def predict(x)
129
- x = check_convert_sample_array(x)
130
- x.dot(@weight_vec.transpose) + @bias_term
131
- end
132
-
133
- private
134
-
135
- def fit_svd(x, y)
136
- x = expand_feature(x) if fit_bias?
137
-
138
- s, u, vt = Numo::Linalg.svd(x, driver: 'sdd', job: 'S')
139
- d = (s / (s**2 + @params[:reg_param])).diag
140
- w = vt.transpose.dot(d).dot(u.transpose).dot(y)
141
-
142
- @weight_vec, @bias_term = single_target?(y) ? split_weight(w) : split_weight_mult(w)
143
- end
144
-
145
- def fit_lbfgs(x, y)
146
- fnc = proc do |w, x, y, a| # rubocop:disable Lint/ShadowingOuterLocalVariable
147
- n_samples, n_features = x.shape
148
- w = w.reshape(y.shape[1], n_features) unless y.shape[1].nil?
149
- z = x.dot(w.transpose)
150
- d = z - y
151
- loss = (d**2).sum.fdiv(n_samples) + a * (w * w).sum
152
- gradient = 2.fdiv(n_samples) * d.transpose.dot(x) + 2.0 * a * w
153
- [loss, gradient.flatten.dup]
154
- end
155
-
156
- x = expand_feature(x) if fit_bias?
157
-
158
- n_features = x.shape[1]
159
- n_outputs = single_target?(y) ? 1 : y.shape[1]
160
-
161
- res = Lbfgsb.minimize(
162
- fnc: fnc, jcb: true, x_init: init_weight(n_features, n_outputs), args: [x, y, @params[:reg_param]],
163
- maxiter: @params[:max_iter], factr: @params[:tol] / Lbfgsb::DBL_EPSILON,
164
- verbose: @params[:verbose] ? 1 : -1
165
- )
166
-
167
- @weight_vec, @bias_term =
168
- if single_target?(y)
169
- split_weight(res[:x])
170
- else
171
- split_weight_mult(res[:x].reshape(n_outputs, n_features).transpose)
172
- end
173
- end
174
-
175
- def fit_sgd(x, y)
176
- if single_target?(y)
177
- @weight_vec, @bias_term = partial_fit(x, y)
178
- else
179
- n_outputs = y.shape[1]
180
- n_features = x.shape[1]
181
- @weight_vec = Numo::DFloat.zeros(n_outputs, n_features)
182
- @bias_term = Numo::DFloat.zeros(n_outputs)
183
- if enable_parallel?
184
- models = parallel_map(n_outputs) { |n| partial_fit(x, y[true, n]) }
185
- n_outputs.times { |n| @weight_vec[n, true], @bias_term[n] = models[n] }
186
- else
187
- n_outputs.times { |n| @weight_vec[n, true], @bias_term[n] = partial_fit(x, y[true, n]) }
188
- end
189
- end
190
- end
191
-
192
- def single_target?(y)
193
- y.ndim == 1
194
- end
195
-
196
- def init_weight(n_features, n_outputs)
197
- Rumale::Utils.rand_normal([n_outputs, n_features], @rng.dup).flatten.dup
198
- end
199
-
200
- def split_weight_mult(w)
201
- if fit_bias?
202
- [w[0...-1, true].dup, w[-1, true].dup]
203
- else
204
- [w.dup, Numo::DFloat.zeros(w.shape[1])]
205
- end
206
- end
207
- end
208
- end
209
- end
@@ -1,213 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rumale/linear_model/base_sgd'
4
- require 'rumale/base/classifier'
5
- require 'rumale/probabilistic_output'
6
-
7
- module Rumale
8
- # This module consists of the classes that implement generalized linear models.
9
- module LinearModel
10
- # SVC is a class that implements Support Vector Classifier
11
- # with stochastic gradient descent optimization.
12
- # For multiclass classification problem, it uses one-vs-the-rest strategy.
13
- #
14
- # @note
15
- # Rumale::SVM provides linear support vector classifier based on LIBLINEAR.
16
- # If you prefer execution speed, you should use Rumale::SVM::LinearSVC.
17
- # https://github.com/yoshoku/rumale-svm
18
- #
19
- # @example
20
- # estimator =
21
- # Rumale::LinearModel::SVC.new(reg_param: 1.0, max_iter: 1000, batch_size: 50, random_seed: 1)
22
- # estimator.fit(training_samples, traininig_labels)
23
- # results = estimator.predict(testing_samples)
24
- #
25
- # *Reference*
26
- # - Shalev-Shwartz, S., and Singer, Y., "Pegasos: Primal Estimated sub-GrAdient SOlver for SVM," Proc. ICML'07, pp. 807--814, 2007.
27
- # - Tsuruoka, Y., Tsujii, J., and Ananiadou, S., "Stochastic Gradient Descent Training for L1-regularized Log-linear Models with Cumulative Penalty," Proc. ACL'09, pp. 477--485, 2009.
28
- # - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
29
- class SVC < BaseSGD
30
- include Base::Classifier
31
-
32
- # Return the weight vector for SVC.
33
- # @return [Numo::DFloat] (shape: [n_classes, n_features])
34
- attr_reader :weight_vec
35
-
36
- # Return the bias term (a.k.a. intercept) for SVC.
37
- # @return [Numo::DFloat] (shape: [n_classes])
38
- attr_reader :bias_term
39
-
40
- # Return the class labels.
41
- # @return [Numo::Int32] (shape: [n_classes])
42
- attr_reader :classes
43
-
44
- # Return the random generator for performing random sampling.
45
- # @return [Random]
46
- attr_reader :rng
47
-
48
- # Create a new classifier with Support Vector Machine by the SGD optimization.
49
- #
50
- # @param learning_rate [Float] The initial value of learning rate.
51
- # The learning rate decreases as the iteration proceeds according to the equation: learning_rate / (1 + decay * t).
52
- # @param decay [Float] The smoothing parameter for decreasing learning rate as the iteration proceeds.
53
- # If nil is given, the decay sets to 'reg_param * learning_rate'.
54
- # @param momentum [Float] The momentum factor.
55
- # @param penalty [String] The regularization type to be used ('l1', 'l2', and 'elasticnet').
56
- # @param l1_ratio [Float] The elastic-net type regularization mixing parameter.
57
- # If penalty set to 'l2' or 'l1', this parameter is ignored.
58
- # If l1_ratio = 1, the regularization is similar to Lasso.
59
- # If l1_ratio = 0, the regularization is similar to Ridge.
60
- # If 0 < l1_ratio < 1, the regularization is a combination of L1 and L2.
61
- # @param reg_param [Float] The regularization parameter.
62
- # @param fit_bias [Boolean] The flag indicating whether to fit the bias term.
63
- # @param bias_scale [Float] The scale of the bias term.
64
- # @param max_iter [Integer] The maximum number of epochs that indicates
65
- # how many times the whole data is given to the training process.
66
- # @param batch_size [Integer] The size of the mini batches.
67
- # @param tol [Float] The tolerance of loss for terminating optimization.
68
- # @param probability [Boolean] The flag indicating whether to perform probability estimation.
69
- # @param n_jobs [Integer] The number of jobs for running the fit and predict methods in parallel.
70
- # If nil is given, the methods do not execute in parallel.
71
- # If zero or less is given, it becomes equal to the number of processors.
72
- # This parameter is ignored if the Parallel gem is not loaded.
73
- # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
74
- # @param random_seed [Integer] The seed value using to initialize the random generator.
75
- def initialize(learning_rate: 0.01, decay: nil, momentum: 0.9,
76
- penalty: 'l2', reg_param: 1.0, l1_ratio: 0.5,
77
- fit_bias: true, bias_scale: 1.0,
78
- max_iter: 1000, batch_size: 50, tol: 1e-4,
79
- probability: false,
80
- n_jobs: nil, verbose: false, random_seed: nil)
81
- check_params_numeric(learning_rate: learning_rate, momentum: momentum,
82
- reg_param: reg_param, l1_ratio: l1_ratio, bias_scale: bias_scale,
83
- max_iter: max_iter, batch_size: batch_size, tol: tol)
84
- check_params_boolean(fit_bias: fit_bias, verbose: verbose, probability: probability)
85
- check_params_string(penalty: penalty)
86
- check_params_numeric_or_nil(decay: decay, n_jobs: n_jobs, random_seed: random_seed)
87
- check_params_positive(learning_rate: learning_rate, reg_param: reg_param,
88
- bias_scale: bias_scale, max_iter: max_iter, batch_size: batch_size)
89
- super()
90
- @params.merge!(method(:initialize).parameters.map { |_t, arg| [arg, binding.local_variable_get(arg)] }.to_h)
91
- @params[:decay] ||= @params[:reg_param] * @params[:learning_rate]
92
- @params[:random_seed] ||= srand
93
- @rng = Random.new(@params[:random_seed])
94
- @penalty_type = @params[:penalty]
95
- @loss_func = LinearModel::Loss::HingeLoss.new
96
- @weight_vec = nil
97
- @bias_term = nil
98
- @classes = nil
99
- @prob_param = nil
100
- end
101
-
102
- # Fit the model with given training data.
103
- #
104
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
105
- # @param y [Numo::Int32] (shape: [n_samples]) The labels to be used for fitting the model.
106
- # @return [SVC] The learned classifier itself.
107
- def fit(x, y)
108
- x = check_convert_sample_array(x)
109
- y = check_convert_label_array(y)
110
- check_sample_label_size(x, y)
111
-
112
- @classes = Numo::Int32[*y.to_a.uniq.sort]
113
-
114
- if multiclass_problem?
115
- n_classes = @classes.size
116
- n_features = x.shape[1]
117
- # initialize model.
118
- @weight_vec = Numo::DFloat.zeros(n_classes, n_features)
119
- @bias_term = Numo::DFloat.zeros(n_classes)
120
- @prob_param = Numo::DFloat.zeros(n_classes, 2)
121
- # fit model.
122
- models = if enable_parallel?
123
- # :nocov:
124
- parallel_map(n_classes) do |n|
125
- bin_y = Numo::Int32.cast(y.eq(@classes[n])) * 2 - 1
126
- partial_fit(x, bin_y)
127
- end
128
- # :nocov:
129
- else
130
- Array.new(n_classes) do |n|
131
- bin_y = Numo::Int32.cast(y.eq(@classes[n])) * 2 - 1
132
- partial_fit(x, bin_y)
133
- end
134
- end
135
- # store model.
136
- models.each_with_index { |model, n| @weight_vec[n, true], @bias_term[n], @prob_param[n, true] = model }
137
- else
138
- negative_label = @classes[0]
139
- bin_y = Numo::Int32.cast(y.ne(negative_label)) * 2 - 1
140
- @weight_vec, @bias_term, @prob_param = partial_fit(x, bin_y)
141
- end
142
-
143
- self
144
- end
145
-
146
- # Calculate confidence scores for samples.
147
- #
148
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to compute the scores.
149
- # @return [Numo::DFloat] (shape: [n_samples, n_classes]) Confidence score per sample.
150
- def decision_function(x)
151
- x = check_convert_sample_array(x)
152
- x.dot(@weight_vec.transpose) + @bias_term
153
- end
154
-
155
- # Predict class labels for samples.
156
- #
157
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to predict the labels.
158
- # @return [Numo::Int32] (shape: [n_samples]) Predicted class label per sample.
159
- def predict(x)
160
- x = check_convert_sample_array(x)
161
-
162
- n_samples = x.shape[0]
163
- predicted = if multiclass_problem?
164
- decision_values = decision_function(x)
165
- if enable_parallel?
166
- parallel_map(n_samples) { |n| @classes[decision_values[n, true].max_index] }
167
- else
168
- Array.new(n_samples) { |n| @classes[decision_values[n, true].max_index] }
169
- end
170
- else
171
- decision_values = decision_function(x).ge(0.0).to_a
172
- Array.new(n_samples) { |n| @classes[decision_values[n]] }
173
- end
174
- Numo::Int32.asarray(predicted)
175
- end
176
-
177
- # Predict probability for samples.
178
- #
179
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to predict the probailities.
180
- # @return [Numo::DFloat] (shape: [n_samples, n_classes]) Predicted probability of each class per sample.
181
- def predict_proba(x)
182
- x = check_convert_sample_array(x)
183
-
184
- if multiclass_problem?
185
- probs = 1.0 / (Numo::NMath.exp(@prob_param[true, 0] * decision_function(x) + @prob_param[true, 1]) + 1.0)
186
- (probs.transpose / probs.sum(axis: 1)).transpose.dup
187
- else
188
- n_samples, = x.shape
189
- probs = Numo::DFloat.zeros(n_samples, 2)
190
- probs[true, 1] = 1.0 / (Numo::NMath.exp(@prob_param[0] * decision_function(x) + @prob_param[1]) + 1.0)
191
- probs[true, 0] = 1.0 - probs[true, 1]
192
- probs
193
- end
194
- end
195
-
196
- private
197
-
198
- def partial_fit(x, bin_y)
199
- w, b = super
200
- p = if @params[:probability]
201
- Rumale::ProbabilisticOutput.fit_sigmoid(x.dot(w.transpose) + b, bin_y)
202
- else
203
- Numo::DFloat[1, 0]
204
- end
205
- [w, b, p]
206
- end
207
-
208
- def multiclass_problem?
209
- @classes.size > 2
210
- end
211
- end
212
- end
213
- end
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rumale/linear_model/base_sgd'
4
- require 'rumale/base/regressor'
5
-
6
- module Rumale
7
- module LinearModel
8
- # SVR is a class that implements Support Vector Regressor
9
- # with stochastic gradient descent optimization.
10
- #
11
- # @note
12
- # Rumale::SVM provides linear and kernel support vector regressor based on LIBLINEAR and LIBSVM.
13
- # If you prefer execution speed, you should use Rumale::SVM::LinearSVR.
14
- # https://github.com/yoshoku/rumale-svm
15
- #
16
- # @example
17
- # estimator =
18
- # Rumale::LinearModel::SVR.new(reg_param: 1.0, epsilon: 0.1, max_iter: 1000, batch_size: 50, random_seed: 1)
19
- # estimator.fit(training_samples, traininig_target_values)
20
- # results = estimator.predict(testing_samples)
21
- #
22
- # *Reference*
23
- # - Shalev-Shwartz, S., and Singer, Y., "Pegasos: Primal Estimated sub-GrAdient SOlver for SVM," Proc. ICML'07, pp. 807--814, 2007.
24
- # - Tsuruoka, Y., Tsujii, J., and Ananiadou, S., "Stochastic Gradient Descent Training for L1-regularized Log-linear Models with Cumulative Penalty," Proc. ACL'09, pp. 477--485, 2009.
25
- # - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
26
- class SVR < BaseSGD
27
- include Base::Regressor
28
-
29
- # Return the weight vector for SVR.
30
- # @return [Numo::DFloat] (shape: [n_outputs, n_features])
31
- attr_reader :weight_vec
32
-
33
- # Return the bias term (a.k.a. intercept) for SVR.
34
- # @return [Numo::DFloat] (shape: [n_outputs])
35
- attr_reader :bias_term
36
-
37
- # Return the random generator for performing random sampling.
38
- # @return [Random]
39
- attr_reader :rng
40
-
41
- # Create a new regressor with Support Vector Machine by the SGD optimization.
42
- #
43
- # @param learning_rate [Float] The initial value of learning rate.
44
- # The learning rate decreases as the iteration proceeds according to the equation: learning_rate / (1 + decay * t).
45
- # @param decay [Float] The smoothing parameter for decreasing learning rate as the iteration proceeds.
46
- # If nil is given, the decay sets to 'reg_param * learning_rate'.
47
- # @param momentum [Float] The momentum factor.
48
- # @param penalty [String] The regularization type to be used ('l1', 'l2', and 'elasticnet').
49
- # @param l1_ratio [Float] The elastic-net type regularization mixing parameter.
50
- # If penalty set to 'l2' or 'l1', this parameter is ignored.
51
- # If l1_ratio = 1, the regularization is similar to Lasso.
52
- # If l1_ratio = 0, the regularization is similar to Ridge.
53
- # If 0 < l1_ratio < 1, the regularization is a combination of L1 and L2.
54
- # @param reg_param [Float] The regularization parameter.
55
- # @param fit_bias [Boolean] The flag indicating whether to fit the bias term.
56
- # @param bias_scale [Float] The scale of the bias term.
57
- # @param epsilon [Float] The margin of tolerance.
58
- # @param max_iter [Integer] The maximum number of epochs that indicates
59
- # how many times the whole data is given to the training process.
60
- # @param batch_size [Integer] The size of the mini batches.
61
- # @param tol [Float] The tolerance of loss for terminating optimization.
62
- # @param n_jobs [Integer] The number of jobs for running the fit method in parallel.
63
- # If nil is given, the method does not execute in parallel.
64
- # If zero or less is given, it becomes equal to the number of processors.
65
- # This parameter is ignored if the Parallel gem is not loaded.
66
- # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
67
- # @param random_seed [Integer] The seed value using to initialize the random generator.
68
- def initialize(learning_rate: 0.01, decay: nil, momentum: 0.9,
69
- penalty: 'l2', reg_param: 1.0, l1_ratio: 0.5,
70
- fit_bias: true, bias_scale: 1.0,
71
- epsilon: 0.1,
72
- max_iter: 1000, batch_size: 50, tol: 1e-4,
73
- n_jobs: nil, verbose: false, random_seed: nil)
74
- check_params_numeric(learning_rate: learning_rate, momentum: momentum,
75
- reg_param: reg_param, bias_scale: bias_scale, epsilon: epsilon,
76
- max_iter: max_iter, batch_size: batch_size, tol: tol)
77
- check_params_boolean(fit_bias: fit_bias, verbose: verbose)
78
- check_params_numeric_or_nil(decay: decay, n_jobs: n_jobs, random_seed: random_seed)
79
- check_params_positive(learning_rate: learning_rate, reg_param: reg_param,
80
- bias_scale: bias_scale, epsilon: epsilon,
81
- max_iter: max_iter, batch_size: batch_size)
82
- super()
83
- @params.merge!(method(:initialize).parameters.map { |_t, arg| [arg, binding.local_variable_get(arg)] }.to_h)
84
- @params[:decay] ||= @params[:reg_param] * @params[:learning_rate]
85
- @params[:random_seed] ||= srand
86
- @rng = Random.new(@params[:random_seed])
87
- @penalty_type = @params[:penalty]
88
- @loss_func = LinearModel::Loss::EpsilonInsensitive.new(epsilon: @params[:epsilon])
89
- @weight_vec = nil
90
- @bias_term = nil
91
- end
92
-
93
- # Fit the model with given training data.
94
- #
95
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
96
- # @param y [Numo::DFloat] (shape: [n_samples, n_outputs]) The target values to be used for fitting the model.
97
- # @return [SVR] The learned regressor itself.
98
- def fit(x, y)
99
- x = check_convert_sample_array(x)
100
- y = check_convert_tvalue_array(y)
101
- check_sample_tvalue_size(x, y)
102
-
103
- n_outputs = y.shape[1].nil? ? 1 : y.shape[1]
104
- n_features = x.shape[1]
105
-
106
- if n_outputs > 1
107
- @weight_vec = Numo::DFloat.zeros(n_outputs, n_features)
108
- @bias_term = Numo::DFloat.zeros(n_outputs)
109
- if enable_parallel?
110
- models = parallel_map(n_outputs) { |n| partial_fit(x, y[true, n]) }
111
- n_outputs.times { |n| @weight_vec[n, true], @bias_term[n] = models[n] }
112
- else
113
- n_outputs.times { |n| @weight_vec[n, true], @bias_term[n] = partial_fit(x, y[true, n]) }
114
- end
115
- else
116
- @weight_vec, @bias_term = partial_fit(x, y)
117
- end
118
-
119
- self
120
- end
121
-
122
- # Predict values for samples.
123
- #
124
- # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to predict the values.
125
- # @return [Numo::DFloat] (shape: [n_samples, n_outputs]) Predicted values per sample.
126
- def predict(x)
127
- x = check_convert_sample_array(x)
128
- x.dot(@weight_vec.transpose) + @bias_term
129
- end
130
- end
131
- end
132
- end