rumale 0.18.5 → 0.19.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +15 -3
- data/.travis.yml +3 -3
- data/CHANGELOG.md +44 -0
- data/Gemfile +9 -0
- data/README.md +6 -44
- data/lib/rumale.rb +3 -0
- data/lib/rumale/base/base_estimator.rb +2 -0
- data/lib/rumale/clustering/dbscan.rb +5 -1
- data/lib/rumale/clustering/gaussian_mixture.rb +2 -0
- data/lib/rumale/clustering/hdbscan.rb +5 -3
- data/lib/rumale/clustering/k_means.rb +2 -1
- data/lib/rumale/clustering/k_medoids.rb +5 -1
- data/lib/rumale/clustering/mini_batch_k_means.rb +139 -0
- data/lib/rumale/clustering/power_iteration.rb +3 -1
- data/lib/rumale/clustering/single_linkage.rb +3 -1
- data/lib/rumale/clustering/snn.rb +2 -2
- data/lib/rumale/clustering/spectral_clustering.rb +2 -2
- data/lib/rumale/dataset.rb +2 -0
- data/lib/rumale/decomposition/factor_analysis.rb +3 -1
- data/lib/rumale/decomposition/fast_ica.rb +2 -2
- data/lib/rumale/decomposition/nmf.rb +1 -1
- data/lib/rumale/decomposition/pca.rb +25 -6
- data/lib/rumale/ensemble/ada_boost_classifier.rb +4 -1
- data/lib/rumale/ensemble/ada_boost_regressor.rb +4 -2
- data/lib/rumale/ensemble/extra_trees_classifier.rb +1 -1
- data/lib/rumale/ensemble/extra_trees_regressor.rb +1 -1
- data/lib/rumale/ensemble/gradient_boosting_classifier.rb +4 -4
- data/lib/rumale/ensemble/gradient_boosting_regressor.rb +4 -4
- data/lib/rumale/evaluation_measure/adjusted_rand_score.rb +1 -1
- data/lib/rumale/evaluation_measure/calinski_harabasz_score.rb +1 -1
- data/lib/rumale/evaluation_measure/davies_bouldin_score.rb +1 -1
- data/lib/rumale/evaluation_measure/function.rb +2 -1
- data/lib/rumale/evaluation_measure/mutual_information.rb +1 -1
- data/lib/rumale/evaluation_measure/normalized_mutual_information.rb +4 -2
- data/lib/rumale/evaluation_measure/precision_recall.rb +5 -0
- data/lib/rumale/evaluation_measure/purity.rb +1 -1
- data/lib/rumale/evaluation_measure/roc_auc.rb +3 -0
- data/lib/rumale/evaluation_measure/silhouette_score.rb +3 -1
- data/lib/rumale/feature_extraction/feature_hasher.rb +14 -1
- data/lib/rumale/feature_extraction/hash_vectorizer.rb +1 -0
- data/lib/rumale/feature_extraction/tfidf_transformer.rb +113 -0
- data/lib/rumale/kernel_approximation/nystroem.rb +1 -1
- data/lib/rumale/kernel_approximation/rbf.rb +1 -1
- data/lib/rumale/kernel_machine/kernel_fda.rb +1 -1
- data/lib/rumale/kernel_machine/kernel_pca.rb +1 -1
- data/lib/rumale/kernel_machine/kernel_ridge.rb +2 -0
- data/lib/rumale/kernel_machine/kernel_svc.rb +1 -1
- data/lib/rumale/linear_model/base_linear_model.rb +2 -0
- data/lib/rumale/linear_model/elastic_net.rb +3 -3
- data/lib/rumale/linear_model/lasso.rb +3 -3
- data/lib/rumale/linear_model/linear_regression.rb +2 -1
- data/lib/rumale/linear_model/logistic_regression.rb +3 -3
- data/lib/rumale/linear_model/ridge.rb +2 -1
- data/lib/rumale/linear_model/svc.rb +3 -3
- data/lib/rumale/linear_model/svr.rb +3 -3
- data/lib/rumale/manifold/mds.rb +3 -1
- data/lib/rumale/manifold/tsne.rb +6 -2
- data/lib/rumale/metric_learning/neighbourhood_component_analysis.rb +14 -1
- data/lib/rumale/model_selection/grid_search_cv.rb +1 -0
- data/lib/rumale/naive_bayes/bernoulli_nb.rb +1 -1
- data/lib/rumale/naive_bayes/multinomial_nb.rb +1 -1
- data/lib/rumale/nearest_neighbors/k_neighbors_classifier.rb +1 -0
- data/lib/rumale/nearest_neighbors/k_neighbors_regressor.rb +2 -0
- data/lib/rumale/nearest_neighbors/vp_tree.rb +1 -1
- data/lib/rumale/neural_network/adam.rb +2 -2
- data/lib/rumale/neural_network/base_mlp.rb +1 -0
- data/lib/rumale/optimizer/ada_grad.rb +4 -1
- data/lib/rumale/optimizer/adam.rb +4 -1
- data/lib/rumale/optimizer/nadam.rb +6 -1
- data/lib/rumale/optimizer/rmsprop.rb +5 -2
- data/lib/rumale/optimizer/sgd.rb +3 -0
- data/lib/rumale/optimizer/yellow_fin.rb +4 -1
- data/lib/rumale/pipeline/pipeline.rb +3 -0
- data/lib/rumale/polynomial_model/base_factorization_machine.rb +5 -0
- data/lib/rumale/polynomial_model/factorization_machine_classifier.rb +7 -2
- data/lib/rumale/polynomial_model/factorization_machine_regressor.rb +7 -2
- data/lib/rumale/preprocessing/l1_normalizer.rb +62 -0
- data/lib/rumale/preprocessing/l2_normalizer.rb +2 -1
- data/lib/rumale/preprocessing/one_hot_encoder.rb +3 -0
- data/lib/rumale/preprocessing/ordinal_encoder.rb +2 -0
- data/lib/rumale/preprocessing/polynomial_features.rb +1 -0
- data/lib/rumale/probabilistic_output.rb +4 -2
- data/lib/rumale/tree/base_decision_tree.rb +2 -0
- data/lib/rumale/tree/decision_tree_classifier.rb +1 -0
- data/lib/rumale/tree/extra_tree_classifier.rb +1 -1
- data/lib/rumale/tree/extra_tree_regressor.rb +1 -1
- data/lib/rumale/tree/gradient_tree_regressor.rb +5 -5
- data/lib/rumale/utils.rb +1 -0
- data/lib/rumale/validation.rb +7 -0
- data/lib/rumale/version.rb +1 -1
- data/rumale.gemspec +1 -13
- metadata +10 -133
@@ -12,7 +12,7 @@ module Rumale
|
|
12
12
|
# puts evaluator.score(x, predicted)
|
13
13
|
#
|
14
14
|
# *Reference*
|
15
|
-
# - P J
|
15
|
+
# - Rousseuw, P J., "Silhouettes: A graphical aid to the interpretation and validation of cluster analysis," Journal of Computational and Applied Mathematics, Vol. 20, pp. 53--65, 1987.
|
16
16
|
class SilhouetteScore
|
17
17
|
include Base::Evaluator
|
18
18
|
|
@@ -47,6 +47,7 @@ module Rumale
|
|
47
47
|
cls_pos = y.eq(labels[n])
|
48
48
|
sz_cluster = cls_pos.count
|
49
49
|
next unless sz_cluster > 1
|
50
|
+
|
50
51
|
cls_dist_mat = dist_mat[cls_pos, cls_pos].dup
|
51
52
|
cls_dist_mat[cls_dist_mat.diag_indices] = 0.0
|
52
53
|
intra_dists[cls_pos] = cls_dist_mat.sum(0) / (sz_cluster - 1)
|
@@ -57,6 +58,7 @@ module Rumale
|
|
57
58
|
cls_pos = y.eq(labels[m])
|
58
59
|
n_clusters.times do |n|
|
59
60
|
next if m == n
|
61
|
+
|
60
62
|
not_cls_pos = y.eq(labels[n])
|
61
63
|
inter_dists[cls_pos] = Numo::DFloat.minimum(
|
62
64
|
inter_dists[cls_pos], dist_mat[cls_pos, not_cls_pos].mean(1)
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'mmh3'
|
4
3
|
require 'rumale/base/base_estimator'
|
5
4
|
require 'rumale/base/transformer'
|
6
5
|
|
@@ -11,11 +10,15 @@ module Rumale
|
|
11
10
|
# This encoder employs signed 32-bit Murmurhash3 as the hash function.
|
12
11
|
#
|
13
12
|
# @example
|
13
|
+
# require 'mmh3'
|
14
|
+
# require 'rumale'
|
15
|
+
#
|
14
16
|
# encoder = Rumale::FeatureExtraction::FeatureHasher.new(n_features: 10)
|
15
17
|
# x = encoder.transform([
|
16
18
|
# { dog: 1, cat: 2, elephant: 4 },
|
17
19
|
# { dog: 2, run: 5 }
|
18
20
|
# ])
|
21
|
+
#
|
19
22
|
# # > pp x
|
20
23
|
# # Numo::DFloat#shape=[2,10]
|
21
24
|
# # [[0, 0, -4, -1, 0, 0, 0, 0, 0, 2],
|
@@ -62,6 +65,8 @@ module Rumale
|
|
62
65
|
# @param x [Array<Hash>] (shape: [n_samples]) The array of hash consisting of feature names and values.
|
63
66
|
# @return [Numo::DFloat] (shape: [n_samples, n_features]) The encoded sample array.
|
64
67
|
def transform(x)
|
68
|
+
raise 'FeatureHasher#transform requires Mmh3 but that is not loaded.' unless enable_mmh3?
|
69
|
+
|
65
70
|
x = [x] unless x.is_a?(Array)
|
66
71
|
n_samples = x.size
|
67
72
|
|
@@ -85,6 +90,14 @@ module Rumale
|
|
85
90
|
|
86
91
|
private
|
87
92
|
|
93
|
+
def enable_mmh3?
|
94
|
+
if defined?(Mmh3).nil?
|
95
|
+
warn('FeatureHasher#transform requires Mmh3 but that is not loaded. You should intall and load mmh3 gem in advance.')
|
96
|
+
return false
|
97
|
+
end
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
88
101
|
def n_features
|
89
102
|
@params[:n_features]
|
90
103
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rumale/base/base_estimator'
|
4
|
+
require 'rumale/base/transformer'
|
5
|
+
require 'rumale/preprocessing/l1_normalizer'
|
6
|
+
require 'rumale/preprocessing/l2_normalizer'
|
7
|
+
|
8
|
+
module Rumale
|
9
|
+
module FeatureExtraction
|
10
|
+
# Transform sample matrix with term frequecy (tf) to a normalized tf-idf (inverse document frequency) reprensentation.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# encoder = Rumale::FeatureExtraction::HashVectorizer.new
|
14
|
+
# x = encoder.fit_transform([
|
15
|
+
# { foo: 1, bar: 2 },
|
16
|
+
# { foo: 3, baz: 1 }
|
17
|
+
# ])
|
18
|
+
#
|
19
|
+
# # > pp x
|
20
|
+
# # Numo::DFloat#shape=[2,3]
|
21
|
+
# # [[2, 0, 1],
|
22
|
+
# # [0, 1, 3]]
|
23
|
+
#
|
24
|
+
# transformer = Rumale::FeatureExtraction::TfidfTransformer.new
|
25
|
+
# x_tfidf = transformer.fit_transform(x)
|
26
|
+
#
|
27
|
+
# # > pp x_tfidf
|
28
|
+
# # Numo::DFloat#shape=[2,3]
|
29
|
+
# # [[0.959056, 0, 0.283217],
|
30
|
+
# # [0, 0.491506, 0.870874]]
|
31
|
+
#
|
32
|
+
# *Reference*
|
33
|
+
# - Manning, C D., Raghavan, P., and Schutze, H., "Introduction to Information Retrieval," Cambridge University Press., 2008.
|
34
|
+
class TfidfTransformer
|
35
|
+
include Base::BaseEstimator
|
36
|
+
include Base::Transformer
|
37
|
+
|
38
|
+
# Return the vector consists of inverse document frequency.
|
39
|
+
# @return [Numo::DFloat] (shape: [n_features])
|
40
|
+
attr_reader :idf
|
41
|
+
|
42
|
+
# Create a new transfomer for converting tf vectors to tf-idf vectors.
|
43
|
+
#
|
44
|
+
# @param norm [String] The normalization method to be used ('l1', 'l2' and 'none').
|
45
|
+
# @param use_idf [Boolean] The flag indicating whether to use inverse document frequency weighting.
|
46
|
+
# @param smooth_idf [Boolean] The flag indicating whether to apply idf smoothing by log((n_samples + 1) / (df + 1)) + 1.
|
47
|
+
# @param sublinear_tf [Boolean] The flag indicating whether to perform subliner tf scaling by 1 + log(tf).
|
48
|
+
def initialize(norm: 'l2', use_idf: true, smooth_idf: false, sublinear_tf: false)
|
49
|
+
check_params_string(norm: norm)
|
50
|
+
check_params_boolean(use_idf: use_idf, smooth_idf: smooth_idf, sublinear_tf: sublinear_tf)
|
51
|
+
@params = {}
|
52
|
+
@params[:norm] = norm
|
53
|
+
@params[:use_idf] = use_idf
|
54
|
+
@params[:smooth_idf] = smooth_idf
|
55
|
+
@params[:sublinear_tf] = sublinear_tf
|
56
|
+
@idf = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
# Calculate the inverse document frequency for weighting.
|
60
|
+
#
|
61
|
+
# @overload fit(x) -> TfidfTransformer
|
62
|
+
#
|
63
|
+
# @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to calculate the idf values.
|
64
|
+
# @return [TfidfTransformer]
|
65
|
+
def fit(x, _y = nil)
|
66
|
+
return self unless @params[:use_idf]
|
67
|
+
|
68
|
+
x = check_convert_sample_array(x)
|
69
|
+
|
70
|
+
n_samples = x.shape[0]
|
71
|
+
df = x.class.cast(x.gt(0.0).count(0))
|
72
|
+
|
73
|
+
if @params[:smooth_idf]
|
74
|
+
df += 1
|
75
|
+
n_samples += 1
|
76
|
+
end
|
77
|
+
|
78
|
+
@idf = Numo::NMath.log(n_samples / df) + 1
|
79
|
+
|
80
|
+
self
|
81
|
+
end
|
82
|
+
|
83
|
+
# Calculate the idf values, and then transfrom samples to the tf-idf representation.
|
84
|
+
#
|
85
|
+
# @overload fit_transform(x) -> Numo::DFloat
|
86
|
+
#
|
87
|
+
# @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to calculate idf and be transformed to tf-idf representation.
|
88
|
+
# @return [Numo::DFloat] The transformed samples.
|
89
|
+
def fit_transform(x, _y = nil)
|
90
|
+
fit(x).transform(x)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Perform transforming the given samples to the tf-idf representation.
|
94
|
+
#
|
95
|
+
# @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to be transformed.
|
96
|
+
# @return [Numo::DFloat] The transformed samples.
|
97
|
+
def transform(x)
|
98
|
+
x = check_convert_sample_array(x)
|
99
|
+
z = x.dup
|
100
|
+
|
101
|
+
z[z.ne(0)] = Numo::NMath.log(z[z.ne(0)]) + 1 if @params[:sublinear_tf]
|
102
|
+
z *= @idf if @params[:use_idf]
|
103
|
+
case @params[:norm]
|
104
|
+
when 'l2'
|
105
|
+
z = Rumale::Preprocessing::L2Normalizer.new.fit_transform(z)
|
106
|
+
when 'l1'
|
107
|
+
z = Rumale::Preprocessing::L1Normalizer.new.fit_transform(z)
|
108
|
+
end
|
109
|
+
z
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -16,7 +16,7 @@ module Rumale
|
|
16
16
|
# new_testing_samples = transformer.transform(testing_samples)
|
17
17
|
#
|
18
18
|
# *Reference*
|
19
|
-
#
|
19
|
+
# - Yang, T., Li, Y., Mahdavi, M., Jin, R., and Zhou, Z-H., "Nystrom Method vs Random Fourier Features: A Theoretical and Empirical Comparison," Advances in NIPS'12, Vol. 1, pp. 476--484, 2012.
|
20
20
|
class Nystroem
|
21
21
|
include Base::BaseEstimator
|
22
22
|
include Base::Transformer
|
@@ -15,7 +15,7 @@ module Rumale
|
|
15
15
|
# new_testing_samples = transformer.transform(testing_samples)
|
16
16
|
#
|
17
17
|
# *Refernce*:
|
18
|
-
#
|
18
|
+
# - Rahimi, A., and Recht, B., "Random Features for Large-Scale Kernel Machines," Proc. NIPS'07, pp.1177--1184, 2007.
|
19
19
|
class RBF
|
20
20
|
include Base::BaseEstimator
|
21
21
|
include Base::Transformer
|
@@ -18,7 +18,7 @@ module Rumale
|
|
18
18
|
# mapped_test_samples = kfda.transform(kernel_mat_test)
|
19
19
|
#
|
20
20
|
# *Reference*
|
21
|
-
# - Baudat, G
|
21
|
+
# - Baudat, G., and Anouar, F., "Generalized Discriminant Analysis using a Kernel Approach," Neural Computation, vol. 12, pp. 2385--2404, 2000.
|
22
22
|
class KernelFDA
|
23
23
|
include Base::BaseEstimator
|
24
24
|
include Base::Transformer
|
@@ -18,7 +18,7 @@ module Rumale
|
|
18
18
|
# mapped_test_samples = kpca.transform(kernel_mat_test)
|
19
19
|
#
|
20
20
|
# *Reference*
|
21
|
-
# -
|
21
|
+
# - Scholkopf, B., Smola, A., and Muller, K-R., "Nonlinear Component Analysis as a Kernel Eigenvalue Problem," Neural Computation, Vol. 10 (5), pp. 1299--1319, 1998.
|
22
22
|
class KernelPCA
|
23
23
|
include Base::BaseEstimator
|
24
24
|
include Base::Transformer
|
@@ -30,6 +30,7 @@ module Rumale
|
|
30
30
|
def initialize(reg_param: 1.0)
|
31
31
|
raise TypeError, 'Expect class of reg_param to be Float or Numo::DFloat' unless reg_param.is_a?(Float) || reg_param.is_a?(Numo::DFloat)
|
32
32
|
raise ArgumentError, 'Expect reg_param array to be 1-D arrray' if reg_param.is_a?(Numo::DFloat) && reg_param.shape.size != 1
|
33
|
+
|
33
34
|
@params = {}
|
34
35
|
@params[:reg_param] = reg_param
|
35
36
|
@weight_vec = nil
|
@@ -55,6 +56,7 @@ module Rumale
|
|
55
56
|
@weight_vec = Numo::Linalg.solve(reg_kernel_mat, y, driver: 'sym')
|
56
57
|
else
|
57
58
|
raise ArgumentError, 'Expect y and reg_param to have the same number of elements.' unless y.shape[1] == @params[:reg_param].shape[0]
|
59
|
+
|
58
60
|
n_outputs = y.shape[1]
|
59
61
|
@weight_vec = Numo::DFloat.zeros(n_samples, n_outputs)
|
60
62
|
n_outputs.times do |n|
|
@@ -24,7 +24,7 @@ module Rumale
|
|
24
24
|
# results = estimator.predict(testing_kernel_matrix)
|
25
25
|
#
|
26
26
|
# *Reference*
|
27
|
-
#
|
27
|
+
# - Shalev-Shwartz, S., Singer, Y., Srebro, N., and Cotter, A., "Pegasos: Primal Estimated sub-GrAdient SOlver for SVM," Mathematical Programming, vol. 127 (1), pp. 3--30, 2011.
|
28
28
|
class KernelSVC
|
29
29
|
include Base::BaseEstimator
|
30
30
|
include Base::Classifier
|
@@ -8,6 +8,7 @@ module Rumale
|
|
8
8
|
# @note
|
9
9
|
# In version 0.17.0, a new linear model abstract class called BaseSGD is introduced.
|
10
10
|
# BaseLienarModel is deprecated and will be removed in the future.
|
11
|
+
# @deprecated Use BaseSGD class instead. This class will be deleted in version 0.20.0.
|
11
12
|
#
|
12
13
|
# BaseLinearModel is an abstract class for implementation of linear estimator
|
13
14
|
# with mini-batch stochastic gradient descent optimization.
|
@@ -68,6 +69,7 @@ module Rumale
|
|
68
69
|
# Update weight.
|
69
70
|
loss_gradient = calc_loss_gradient(sub_samples, sub_targets, weight)
|
70
71
|
next if loss_gradient.ne(0.0).count.zero?
|
72
|
+
|
71
73
|
weight = calc_new_weight(optimizer, sub_samples, weight, loss_gradient)
|
72
74
|
end
|
73
75
|
split_weight(weight)
|
@@ -15,9 +15,9 @@ module Rumale
|
|
15
15
|
# results = estimator.predict(testing_samples)
|
16
16
|
#
|
17
17
|
# *Reference*
|
18
|
-
# -
|
19
|
-
# -
|
20
|
-
# -
|
18
|
+
# - Shalev-Shwartz, S., and Singer, Y., "Pegasos: Primal Estimated sub-GrAdient SOlver for SVM," Proc. ICML'07, pp. 807--814, 2007.
|
19
|
+
# - 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.
|
20
|
+
# - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
|
21
21
|
class ElasticNet < BaseSGD
|
22
22
|
include Base::Regressor
|
23
23
|
|
@@ -15,9 +15,9 @@ module Rumale
|
|
15
15
|
# results = estimator.predict(testing_samples)
|
16
16
|
#
|
17
17
|
# *Reference*
|
18
|
-
# -
|
19
|
-
# -
|
20
|
-
# -
|
18
|
+
# - Shalev-Shwartz, S., and Singer, Y., "Pegasos: Primal Estimated sub-GrAdient SOlver for SVM," Proc. ICML'07, pp. 807--814, 2007.
|
19
|
+
# - 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.
|
20
|
+
# - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
|
21
21
|
class Lasso < BaseSGD
|
22
22
|
include Base::Regressor
|
23
23
|
|
@@ -21,7 +21,7 @@ module Rumale
|
|
21
21
|
# results = estimator.predict(testing_samples)
|
22
22
|
#
|
23
23
|
# *Reference*
|
24
|
-
# -
|
24
|
+
# - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
|
25
25
|
class LinearRegression < BaseSGD
|
26
26
|
include Base::Regressor
|
27
27
|
|
@@ -162,6 +162,7 @@ module Rumale
|
|
162
162
|
def load_linalg?
|
163
163
|
return false if defined?(Numo::Linalg).nil?
|
164
164
|
return false if Numo::Linalg::VERSION < '0.1.4'
|
165
|
+
|
165
166
|
true
|
166
167
|
end
|
167
168
|
end
|
@@ -20,9 +20,9 @@ module Rumale
|
|
20
20
|
# results = estimator.predict(testing_samples)
|
21
21
|
#
|
22
22
|
# *Reference*
|
23
|
-
# -
|
24
|
-
# -
|
25
|
-
# -
|
23
|
+
# - Shalev-Shwartz, S., Singer, Y., Srebro, N., and Cotter, A., "Pegasos: Primal Estimated sub-GrAdient SOlver for SVM," Mathematical Programming, vol. 127 (1), pp. 3--30, 2011.
|
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
26
|
class LogisticRegression < BaseSGD
|
27
27
|
include Base::Classifier
|
28
28
|
|
@@ -21,7 +21,7 @@ module Rumale
|
|
21
21
|
# results = estimator.predict(testing_samples)
|
22
22
|
#
|
23
23
|
# *Reference*
|
24
|
-
# -
|
24
|
+
# - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
|
25
25
|
class Ridge < BaseSGD
|
26
26
|
include Base::Regressor
|
27
27
|
|
@@ -164,6 +164,7 @@ module Rumale
|
|
164
164
|
def load_linalg?
|
165
165
|
return false if defined?(Numo::Linalg).nil?
|
166
166
|
return false if Numo::Linalg::VERSION < '0.1.4'
|
167
|
+
|
167
168
|
true
|
168
169
|
end
|
169
170
|
end
|
@@ -22,9 +22,9 @@ module Rumale
|
|
22
22
|
# results = estimator.predict(testing_samples)
|
23
23
|
#
|
24
24
|
# *Reference*
|
25
|
-
# -
|
26
|
-
# -
|
27
|
-
# -
|
25
|
+
# - Shalev-Shwartz, S., and Singer, Y., "Pegasos: Primal Estimated sub-GrAdient SOlver for SVM," Proc. ICML'07, pp. 807--814, 2007.
|
26
|
+
# - 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.
|
27
|
+
# - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
|
28
28
|
class SVC < BaseSGD
|
29
29
|
include Base::Classifier
|
30
30
|
|
@@ -19,9 +19,9 @@ module Rumale
|
|
19
19
|
# results = estimator.predict(testing_samples)
|
20
20
|
#
|
21
21
|
# *Reference*
|
22
|
-
# -
|
23
|
-
# -
|
24
|
-
# -
|
22
|
+
# - Shalev-Shwartz, S., and Singer, Y., "Pegasos: Primal Estimated sub-GrAdient SOlver for SVM," Proc. ICML'07, pp. 807--814, 2007.
|
23
|
+
# - 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.
|
24
|
+
# - Bottou, L., "Large-Scale Machine Learning with Stochastic Gradient Descent," Proc. COMPSTAT'10, pp. 177--186, 2010.
|
25
25
|
class SVR < BaseSGD
|
26
26
|
include Base::Regressor
|
27
27
|
|
data/lib/rumale/manifold/mds.rb
CHANGED
@@ -16,7 +16,7 @@ module Rumale
|
|
16
16
|
# representations = mds.fit_transform(samples)
|
17
17
|
#
|
18
18
|
# *Reference*
|
19
|
-
# - P J. F.
|
19
|
+
# - Groenen, P J. F. and van de Velden, M., "Multidimensional Scaling by Majorization: A Review," J. of Statistical Software, Vol. 73 (8), 2016.
|
20
20
|
class MDS
|
21
21
|
include Base::BaseEstimator
|
22
22
|
include Base::Transformer
|
@@ -83,6 +83,7 @@ module Rumale
|
|
83
83
|
def fit(x, _not_used = nil)
|
84
84
|
x = check_convert_sample_array(x)
|
85
85
|
raise ArgumentError, 'Expect the input distance matrix to be square.' if @params[:metric] == 'precomputed' && x.shape[0] != x.shape[1]
|
86
|
+
|
86
87
|
# initialize some varibales.
|
87
88
|
n_samples = x.shape[0]
|
88
89
|
hi_distance_mat = @params[:metric] == 'precomputed' ? x : Rumale::PairwiseMetric.euclidean_distance(x)
|
@@ -142,6 +143,7 @@ module Rumale
|
|
142
143
|
def terminate?(old_stress, new_stress)
|
143
144
|
return false if @params[:tol].nil?
|
144
145
|
return false if old_stress.nil?
|
146
|
+
|
145
147
|
(old_stress - new_stress).abs <= @params[:tol]
|
146
148
|
end
|
147
149
|
|
data/lib/rumale/manifold/tsne.rb
CHANGED
@@ -19,8 +19,8 @@ module Rumale
|
|
19
19
|
# representations = tsne.fit_transform(samples)
|
20
20
|
#
|
21
21
|
# *Reference*
|
22
|
-
# -
|
23
|
-
# -
|
22
|
+
# - van der Maaten, L., and Hinton, G., "Visualizing data using t-SNE," J. of Machine Learning Research, vol. 9, pp. 2579--2605, 2008.
|
23
|
+
# - Yang, Z., King, I., Xu, Z., and Oja, E., "Heavy-Tailed Symmetric Stochastic Neighbor Embedding," Proc. NIPS'09, pp. 2169--2177, 2009.
|
24
24
|
class TSNE
|
25
25
|
include Base::BaseEstimator
|
26
26
|
include Base::Transformer
|
@@ -89,6 +89,7 @@ module Rumale
|
|
89
89
|
def fit(x, _not_used = nil)
|
90
90
|
x = check_convert_sample_array(x)
|
91
91
|
raise ArgumentError, 'Expect the input distance matrix to be square.' if @params[:metric] == 'precomputed' && x.shape[0] != x.shape[1]
|
92
|
+
|
92
93
|
# initialize some varibales.
|
93
94
|
@n_iter = 0
|
94
95
|
distance_mat = @params[:metric] == 'precomputed' ? x**2 : Rumale::PairwiseMetric.squared_error(x)
|
@@ -99,6 +100,7 @@ module Rumale
|
|
99
100
|
one_vec = Numo::DFloat.ones(x.shape[0]).expand_dims(1)
|
100
101
|
@params[:max_iter].times do |t|
|
101
102
|
break if terminate?(hi_prob_mat, lo_prob_mat)
|
103
|
+
|
102
104
|
a = hi_prob_mat * lo_prob_mat
|
103
105
|
b = lo_prob_mat * lo_prob_mat
|
104
106
|
y = (b.dot(one_vec) * y + (a - b).dot(y)) / a.dot(one_vec)
|
@@ -170,6 +172,7 @@ module Rumale
|
|
170
172
|
entropy, probs = gaussian_distributed_probability_vector(sample_id, distance_vec, beta)
|
171
173
|
diff_entropy = entropy - init_entropy
|
172
174
|
break if diff_entropy.abs <= 1e-5
|
175
|
+
|
173
176
|
if diff_entropy.positive?
|
174
177
|
betamin = beta
|
175
178
|
if betamax == Float::MAX
|
@@ -211,6 +214,7 @@ module Rumale
|
|
211
214
|
|
212
215
|
def terminate?(p, q)
|
213
216
|
return false if @params[:tol].nil?
|
217
|
+
|
214
218
|
cost(p, q) <= @params[:tol]
|
215
219
|
end
|
216
220
|
end
|
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
require 'rumale/base/base_estimator'
|
4
4
|
require 'rumale/base/transformer'
|
5
|
-
require 'mopti/scaled_conjugate_gradient'
|
6
5
|
|
7
6
|
module Rumale
|
8
7
|
module MetricLearning
|
9
8
|
# NeighbourhoodComponentAnalysis is a class that implements Neighbourhood Component Analysis.
|
10
9
|
#
|
11
10
|
# @example
|
11
|
+
# require 'mopti'
|
12
|
+
# require 'rumale'
|
13
|
+
#
|
12
14
|
# transformer = Rumale::MetricLearning::NeighbourhoodComponentAnalysis.new
|
13
15
|
# transformer.fit(training_samples, traininig_labels)
|
14
16
|
# low_samples = transformer.transform(testing_samples)
|
@@ -63,6 +65,8 @@ module Rumale
|
|
63
65
|
# @param y [Numo::Int32] (shape: [n_samples]) The labels to be used for fitting the model.
|
64
66
|
# @return [NeighbourhoodComponentAnalysis] The learned classifier itself.
|
65
67
|
def fit(x, y)
|
68
|
+
raise 'NeighbourhoodComponentAnalysis#fit requires Mopti but that is not loaded.' unless enable_mopti?
|
69
|
+
|
66
70
|
x = check_convert_sample_array(x)
|
67
71
|
y = check_convert_label_array(y)
|
68
72
|
check_sample_label_size(x, y)
|
@@ -98,6 +102,14 @@ module Rumale
|
|
98
102
|
|
99
103
|
private
|
100
104
|
|
105
|
+
def enable_mopti?
|
106
|
+
if defined?(Mopti).nil?
|
107
|
+
warn('NeighbourhoodComponentAnalysis#fit requires Mopti but that is not loaded. You should intall and load mopti gem in advance.')
|
108
|
+
return false
|
109
|
+
end
|
110
|
+
true
|
111
|
+
end
|
112
|
+
|
101
113
|
def init_components(x, n_features, n_components)
|
102
114
|
if @params[:init] == 'pca'
|
103
115
|
pca = Rumale::Decomposition::PCA.new(n_components: n_components, solver: 'evd')
|
@@ -126,6 +138,7 @@ module Rumale
|
|
126
138
|
res = prm
|
127
139
|
puts "[NeighbourhoodComponentAnalysis] The value of objective function after #{res[:n_iter]} epochs: #{x.shape[0] - res[:fnc]}" if @params[:verbose]
|
128
140
|
break if (fold - res[:fnc]).abs <= @params[:tol] && (dold - res[:jcb]).abs <= @params[:tol]
|
141
|
+
|
129
142
|
fold = res[:fnc]
|
130
143
|
dold = res[:jcb]
|
131
144
|
end
|