rumale 0.17.3 → 0.18.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68b01301c9e7b9aa9d98f0a252e87fc0c5e5e888379e347660a76a63ae7f86a4
4
- data.tar.gz: dd464110ff410705a20fa2446c884ed039b9f0ea3febfc4cd12ef8d6b542b736
3
+ metadata.gz: 7caefe8d0715984980daede523f1944460bcff7dd782c431b7e95d851ddfbf82
4
+ data.tar.gz: 05ba1863410dcaabd31dc281c921011a9625f75980c137ab8c88f302c33042b5
5
5
  SHA512:
6
- metadata.gz: d95cf5140e5846431b812867a64927f51ede6f6a925ffdc3a43f3ae1add1ce33756ad6481ca7645edeed56084fe0f8d294f5032364ff664cae19e9edcdaac57e
7
- data.tar.gz: 620bd2099ddd5ce14ff9525062938740835fe9714f1c42023f7782e963a96b423bba4921e35d134877aada0d05189d5213b90e5556b50799dadfebdeeaf59eba
6
+ metadata.gz: 06a95f1fda83e546954e235f06c5b487cc393a340c48b1316b9ef2d0fafbb5be4bb4de02681c6b7b013915695ecd06a04a8692c9df2ba9822e3ba4e01925c0df
7
+ data.tar.gz: 0e5e1ae19fbb420cba2914f251b8ba44de29f4eb9feed31d5bcdb0dc4003a9221053bedddc3214faf8803282965c9dbd51c1e3e81df94fe6bb4fa8c6afbfe277
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 0.18.0
2
+ - Add transformer class for [FisherDiscriminantAnalysis](https://yoshoku.github.io/rumale/doc/Rumale/MetricLearning/FisherDiscriminantAnalysis.html).
3
+ - Add transformer class for [NeighbourhoodComponentAnalysis](https://yoshoku.github.io/rumale/doc/Rumale/MetricLearning/NeighbourhoodComponentAnalysis.html).
4
+ - Add [module function](https://yoshoku.github.io/rumale/doc/Rumale/ModelSelection.html#train_test_split-class_method) for hold-out validation.
5
+
1
6
  # 0.17.3
2
7
  - Add pipeline class for [FeatureUnion](https://yoshoku.github.io/rumale/doc/Rumale/Pipeline/FeatureUnion.html).
3
8
  - Fix to use mmh3 gem for generating hash value on [FeatureHasher](https://yoshoku.github.io/rumale/doc/Rumale/FeatureExtraction/FeatureHasher.html).
data/README.md CHANGED
@@ -15,12 +15,11 @@ Logistic Regression, Ridge, Lasso, Factorization Machine,
15
15
  Multi-layer Perceptron,
16
16
  Naive Bayes, Decision Tree, Gradient Tree Boosting, Random Forest,
17
17
  K-Means, Gaussian Mixture Model, DBSCAN, Spectral Clustering,
18
- Mutidimensional Scaling, t-SNE, Principal Component Analysis, Non-negative Matrix Factorization,
18
+ Mutidimensional Scaling, t-SNE,
19
+ Fisher Discriminant Analysis, Neighbourhood Component Analysis,
20
+ Principal Component Analysis, Non-negative Matrix Factorization,
19
21
  and many other algorithms.
20
22
 
21
- This project was formerly known as "SVMKit".
22
- If you are using SVMKit, please install Rumale and replace `SVMKit` constants with `Rumale`.
23
-
24
23
  ## Installation
25
24
 
26
25
  Add this line to your application's Gemfile:
data/lib/rumale.rb CHANGED
@@ -78,6 +78,8 @@ require 'rumale/decomposition/factor_analysis'
78
78
  require 'rumale/decomposition/fast_ica'
79
79
  require 'rumale/manifold/tsne'
80
80
  require 'rumale/manifold/mds'
81
+ require 'rumale/metric_learning/fisher_discriminant_analysis'
82
+ require 'rumale/metric_learning/neighbourhood_component_analysis.rb'
81
83
  require 'rumale/neural_network/adam'
82
84
  require 'rumale/neural_network/base_mlp'
83
85
  require 'rumale/neural_network/mlp_regressor'
@@ -100,6 +102,7 @@ require 'rumale/model_selection/shuffle_split'
100
102
  require 'rumale/model_selection/stratified_shuffle_split'
101
103
  require 'rumale/model_selection/cross_validation'
102
104
  require 'rumale/model_selection/grid_search_cv'
105
+ require 'rumale/model_selection/function'
103
106
  require 'rumale/evaluation_measure/accuracy'
104
107
  require 'rumale/evaluation_measure/precision'
105
108
  require 'rumale/evaluation_measure/recall'
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rumale/base/base_estimator'
4
+ require 'rumale/base/transformer'
5
+
6
+ module Rumale
7
+ # Module for metric learning algorithms.
8
+ module MetricLearning
9
+ # FisherDiscriminantAnalysis is a class that implements Fisher Discriminant Analysis.
10
+ #
11
+ # @example
12
+ # transformer = Rumale::MetricLearning::FisherDiscriminantAnalysis.new
13
+ # transformer.fit(training_samples, traininig_labels)
14
+ # low_samples = transformer.transform(testing_samples)
15
+ #
16
+ # *Reference*
17
+ # - Fisher, R. A., "The use of multiple measurements in taxonomic problems," Annals of Eugenics, vol. 7, pp. 179--188, 1936.
18
+ # - Sugiyama, M., "Local Fisher Discriminant Analysis for Supervised Dimensionality Reduction," Proc. ICML'06, pp. 905--912, 2006.
19
+ class FisherDiscriminantAnalysis
20
+ include Base::BaseEstimator
21
+ include Base::Transformer
22
+
23
+ # Returns the transform matrix.
24
+ # @return [Numo::DFloat] (shape: [n_components, n_features])
25
+ attr_reader :components
26
+
27
+ # Returns the mean vector.
28
+ # @return [Numo::DFloat] (shape: [n_features])
29
+ attr_reader :mean
30
+
31
+ # Returns the class mean vectors.
32
+ # @return [Numo::DFloat] (shape: [n_classes, n_features])
33
+ attr_reader :class_means
34
+
35
+ # Return the class labels.
36
+ # @return [Numo::Int32] (shape: [n_classes])
37
+ attr_reader :classes
38
+
39
+ # Create a new transformer with FisherDiscriminantAnalysis.
40
+ #
41
+ # @param n_components [Integer] The number of components.
42
+ # If nil is given, the number of components will be set to [n_features, n_classes - 1].min
43
+ def initialize(n_components: nil)
44
+ check_params_numeric_or_nil(n_components: n_components)
45
+ @params = {}
46
+ @params[:n_components] = n_components
47
+ end
48
+
49
+ # Fit the model with given training data.
50
+ #
51
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
52
+ # @param y [Numo::Int32] (shape: [n_samples]) The labels to be used for fitting the model.
53
+ # @return [FisherDiscriminantAnalysis] The learned classifier itself.
54
+ def fit(x, y)
55
+ x = check_convert_sample_array(x)
56
+ y = check_convert_label_array(y)
57
+ check_sample_label_size(x, y)
58
+ raise 'FisherDiscriminatAnalysis#fit requires Numo::Linalg but that is not loaded.' unless enable_linalg?
59
+
60
+ # initialize some variables.
61
+ n_features = x.shape[1]
62
+ @classes = Numo::Int32[*y.to_a.uniq.sort]
63
+ n_classes = @classes.size
64
+ n_components = if @params[:n_components].nil?
65
+ [n_features, n_classes - 1].min
66
+ else
67
+ [n_features, @params[:n_components]].min
68
+ end
69
+
70
+ # calculate within and between scatter matricies.
71
+ within_mat = Numo::DFloat.zeros(n_features, n_features)
72
+ between_mat = Numo::DFloat.zeros(n_features, n_features)
73
+ @class_means = Numo::DFloat.zeros(n_classes, n_features)
74
+ @mean = x.mean(0)
75
+ @classes.each_with_index do |label, i|
76
+ mask_vec = y.eq(label)
77
+ sz_class = mask_vec.count
78
+ class_samples = x[mask_vec, true]
79
+ class_mean = class_samples.mean(0)
80
+ within_mat += (class_samples - class_mean).transpose.dot(class_samples - class_mean)
81
+ between_mat += sz_class * (class_mean - @mean).expand_dims(1) * (class_mean - @mean)
82
+ @class_means[i, true] = class_mean
83
+ end
84
+
85
+ # calculate components.
86
+ _, evecs = Numo::Linalg.eigh(between_mat, within_mat, vals_range: (n_features - n_components)...n_features)
87
+ comps = evecs.reverse(1).transpose.dup
88
+ @components = n_components == 1 ? comps[0, true].dup : comps.dup
89
+ self
90
+ end
91
+
92
+ # Fit the model with training data, and then transform them with the learned model.
93
+ #
94
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
95
+ # @param y [Numo::Int32] (shape: [n_samples]) The labels to be used for fitting the model.
96
+ # @return [Numo::DFloat] (shape: [n_samples, n_components]) The transformed data
97
+ def fit_transform(x, y)
98
+ x = check_convert_sample_array(x)
99
+ y = check_convert_label_array(y)
100
+ fit(x, y).transform(x)
101
+ end
102
+
103
+ # Transform the given data with the learned model.
104
+ #
105
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The data to be transformed with the learned model.
106
+ # @return [Numo::DFloat] (shape: [n_samples, n_components]) The transformed data.
107
+ def transform(x)
108
+ x = check_convert_sample_array(x)
109
+ x.dot(@components.transpose)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rumale/base/base_estimator'
4
+ require 'rumale/base/transformer'
5
+ require 'mopti/scaled_conjugate_gradient'
6
+
7
+ module Rumale
8
+ module MetricLearning
9
+ # NeighbourhoodComponentAnalysis is a class that implements Neighbourhood Component Analysis.
10
+ #
11
+ # @example
12
+ # transformer = Rumale::MetricLearning::NeighbourhoodComponentAnalysis.new
13
+ # transformer.fit(training_samples, traininig_labels)
14
+ # low_samples = transformer.transform(testing_samples)
15
+ #
16
+ # *Reference*
17
+ # - Goldberger, J., Roweis, S., Hinton, G., and Salakhutdinov, R., "Neighbourhood Component Analysis," Advances in NIPS'17, pp. 513--520, 2005.
18
+ class NeighbourhoodComponentAnalysis
19
+ include Base::BaseEstimator
20
+ include Base::Transformer
21
+
22
+ # Returns the neighbourhood components.
23
+ # @return [Numo::DFloat] (shape: [n_components, n_features])
24
+ attr_reader :components
25
+
26
+ # Return the number of iterations run for optimization
27
+ # @return [Integer]
28
+ attr_reader :n_iter
29
+
30
+ # Return the random generator.
31
+ # @return [Random]
32
+ attr_reader :rng
33
+
34
+ # Create a new transformer with NeighbourhoodComponentAnalysis.
35
+ #
36
+ # @param n_components [Integer] The number of components.
37
+ # @param init [String] The initialization method for components ('random' or 'pca').
38
+ # @param max_iter [Integer] The maximum number of iterations.
39
+ # @param tol [Float] The tolerance of termination criterion.
40
+ # @param verbose [Boolean] The flag indicating whether to output loss during iteration.
41
+ # @param random_seed [Integer] The seed value using to initialize the random generator.
42
+ def initialize(n_components: nil, init: 'random', max_iter: 100, tol: 1e-6, verbose: false, random_seed: nil)
43
+ check_params_numeric_or_nil(n_components: n_components, random_seed: random_seed)
44
+ check_params_numeric(max_iter: max_iter, tol: tol)
45
+ check_params_string(init: init)
46
+ check_params_boolean(verbose: verbose)
47
+ @params = {}
48
+ @params[:n_components] = n_components
49
+ @params[:init] = init
50
+ @params[:max_iter] = max_iter
51
+ @params[:tol] = tol
52
+ @params[:verbose] = verbose
53
+ @params[:random_seed] = random_seed
54
+ @params[:random_seed] ||= srand
55
+ @components = nil
56
+ @n_iter = nil
57
+ @rng = Random.new(@params[:random_seed])
58
+ end
59
+
60
+ # Fit the model with given training data.
61
+ #
62
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
63
+ # @param y [Numo::Int32] (shape: [n_samples]) The labels to be used for fitting the model.
64
+ # @return [NeighbourhoodComponentAnalysis] The learned classifier itself.
65
+ def fit(x, y)
66
+ x = check_convert_sample_array(x)
67
+ y = check_convert_label_array(y)
68
+ check_sample_label_size(x, y)
69
+ n_features = x.shape[1]
70
+ n_components = if @params[:n_components].nil?
71
+ n_features
72
+ else
73
+ [n_features, @params[:n_components]].min
74
+ end
75
+ @components, @n_iter = optimize_components(x, y, n_features, n_components)
76
+ self
77
+ end
78
+
79
+ # Fit the model with training data, and then transform them with the learned model.
80
+ #
81
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
82
+ # @param y [Numo::Int32] (shape: [n_samples]) The labels to be used for fitting the model.
83
+ # @return [Numo::DFloat] (shape: [n_samples, n_components]) The transformed data
84
+ def fit_transform(x, y)
85
+ x = check_convert_sample_array(x)
86
+ y = check_convert_label_array(y)
87
+ fit(x, y).transform(x)
88
+ end
89
+
90
+ # Transform the given data with the learned model.
91
+ #
92
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The data to be transformed with the learned model.
93
+ # @return [Numo::DFloat] (shape: [n_samples, n_components]) The transformed data.
94
+ def transform(x)
95
+ x = check_convert_sample_array(x)
96
+ x.dot(@components.transpose)
97
+ end
98
+
99
+ private
100
+
101
+ def init_components(x, n_features, n_components)
102
+ if @params[:init] == 'pca'
103
+ pca = Rumale::Decomposition::PCA.new(n_components: n_components, solver: 'evd')
104
+ pca.fit(x).components.flatten.dup
105
+ else
106
+ Rumale::Utils.rand_normal([n_features, n_components], @rng.dup).flatten.dup
107
+ end
108
+ end
109
+
110
+ def optimize_components(x, y, n_features, n_components)
111
+ # initialize components.
112
+ comp_init = init_components(x, n_features, n_components)
113
+ # initialize optimization results.
114
+ res = {}
115
+ res[:x] = comp_init
116
+ res[:n_iter] = 0
117
+ # perform optimization.
118
+ optimizer = Mopti::ScaledConjugateGradient.new(
119
+ fnc: method(:nca_loss), jcb: method(:nca_dloss),
120
+ x_init: comp_init, args: [x, y],
121
+ max_iter: @params[:max_iter], ftol: @params[:tol]
122
+ )
123
+ fold = 0.0
124
+ dold = 0.0
125
+ optimizer.each do |prm|
126
+ res = prm
127
+ puts "[NeighbourhoodComponentAnalysis] The value of objective function after #{res[:n_iter]} epochs: #{x.shape[0] - res[:fnc]}" if @params[:verbose]
128
+ break if (fold - res[:fnc]).abs <= @params[:tol] && (dold - res[:jcb]).abs <= @params[:tol]
129
+ fold = res[:fnc]
130
+ dold = res[:jcb]
131
+ end
132
+ # return the results.
133
+ n_iter = res[:n_iter]
134
+ comps = n_components == 1 ? res[:x].dup : res[:x].reshape(n_components, n_features)
135
+ [comps, n_iter]
136
+ end
137
+
138
+ def nca_loss(w, x, y)
139
+ # initialize some variables.
140
+ n_samples, n_features = x.shape
141
+ n_components = w.size / n_features
142
+ # projection.
143
+ w = w.reshape(n_components, n_features)
144
+ z = x.dot(w.transpose)
145
+ # calculate probability matrix.
146
+ prob_mat = probability_matrix(z)
147
+ # calculate loss.
148
+ # NOTE:
149
+ # NCA attempts to maximize its objective function.
150
+ # For the minization algorithm, the objective function value is subtracted from the maixmum value (n_samples).
151
+ mask_mat = y.expand_dims(1).eq(y)
152
+ masked_prob_mat = prob_mat * mask_mat
153
+ n_samples - masked_prob_mat.sum
154
+ end
155
+
156
+ def nca_dloss(w, x, y)
157
+ # initialize some variables.
158
+ n_features = x.shape[1]
159
+ n_components = w.size / n_features
160
+ # projection.
161
+ w = w.reshape(n_components, n_features)
162
+ z = x.dot(w.transpose)
163
+ # calculate probability matrix.
164
+ prob_mat = probability_matrix(z)
165
+ # calculate gradient.
166
+ mask_mat = y.expand_dims(1).eq(y)
167
+ masked_prob_mat = prob_mat * mask_mat
168
+ weighted_prob_mat = masked_prob_mat - prob_mat * masked_prob_mat.sum(1).expand_dims(1)
169
+ weighted_prob_mat += weighted_prob_mat.transpose
170
+ weighted_prob_mat[weighted_prob_mat.diag_indices] = -weighted_prob_mat.sum(0)
171
+ gradient = 2 * z.transpose.dot(weighted_prob_mat).dot(x)
172
+ -gradient.flatten.dup
173
+ end
174
+
175
+ def probability_matrix(z)
176
+ prob_mat = Numo::NMath.exp(-Rumale::PairwiseMetric.squared_error(z))
177
+ prob_mat[prob_mat.diag_indices] = 0.0
178
+ prob_mat /= prob_mat.sum(1).expand_dims(1)
179
+ prob_mat
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rumale/model_selection/shuffle_split'
4
+ require 'rumale/model_selection/stratified_shuffle_split'
5
+
6
+ module Rumale
7
+ module ModelSelection
8
+ module_function
9
+
10
+ # Split randomly data set into test and train data.
11
+ #
12
+ # @example
13
+ # x_train, x_test, y_train, y_test = Rumale::ModelSelection.train_test_split(x, y, test_size: 0.2, stratify: true, random_seed: 1)
14
+ #
15
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The dataset to be used to generate data indices.
16
+ # @param y [Numo::Int32] (shape: [n_samples]) The labels to be used to generate data indices for stratified random permutation.
17
+ # If stratify = false, this parameter is ignored.
18
+ # @param test_size [Float] The ratio of number of samples for test data.
19
+ # @param train_size [Float] The ratio of number of samples for train data.
20
+ # If nil is given, it sets to 1 - test_size.
21
+ # @param stratify [Boolean] The flag indicating whether to perform stratify split.
22
+ # @param random_seed [Integer] The seed value using to initialize the random generator.
23
+ # @return [Array<Numo::NArray>] The set of training and testing data.
24
+ def train_test_split(x, y = nil, test_size: 0.1, train_size: nil, stratify: false, random_seed: nil)
25
+ splitter = if stratify
26
+ Rumale::ModelSelection::StratifiedShuffleSplit.new(
27
+ n_splits: 1, test_size: test_size, train_size: train_size, random_seed: random_seed
28
+ )
29
+ else
30
+ Rumale::ModelSelection::ShuffleSplit.new(
31
+ n_splits: 1, test_size: test_size, train_size: train_size, random_seed: random_seed
32
+ )
33
+ end
34
+ train_ids, test_ids = splitter.split(x, y).first
35
+ x_train = x[train_ids, true].dup
36
+ y_train = y[train_ids].dup
37
+ x_test = x[test_ids, true].dup
38
+ y_test = y[test_ids].dup
39
+ [x_train, x_test, y_train, y_test]
40
+ end
41
+ end
42
+ end
@@ -42,15 +42,16 @@ module Rumale
42
42
  # @param y [Numo::DFloat] (shape: [n_samples_y, n_features])
43
43
  # @return [Numo::DFloat] (shape: [n_samples_x, n_samples_x] or [n_samples_x, n_samples_y] if y is given)
44
44
  def squared_error(x, y = nil)
45
- y = x if y.nil?
45
+ y_not_given = y.nil?
46
+ y = x if y_not_given
46
47
  x = Rumale::Validation.check_convert_sample_array(x)
47
- y = Rumale::Validation.check_convert_sample_array(y)
48
- n_features = x.shape[1]
49
- one_vec = Numo::DFloat.ones(n_features).expand_dims(1)
50
- sum_x_vec = (x**2).dot(one_vec)
51
- sum_y_vec = (y**2).dot(one_vec).transpose
52
- dot_xy_mat = x.dot(y.transpose)
53
- dot_xy_mat * -2.0 + sum_x_vec + sum_y_vec
48
+ y = Rumale::Validation.check_convert_sample_array(y) unless y_not_given
49
+ sum_x_vec = (x**2).sum(1).expand_dims(1)
50
+ sum_y_vec = y_not_given ? sum_x_vec.transpose : (y**2).sum(1).expand_dims(1).transpose
51
+ err_mat = -2 * x.dot(y.transpose)
52
+ err_mat += sum_x_vec
53
+ err_mat += sum_y_vec
54
+ err_mat.class.maximum(err_mat, 0)
54
55
  end
55
56
 
56
57
  # Calculate the rbf kernel between x and y.
@@ -3,5 +3,5 @@
3
3
  # Rumale is a machine learning library in Ruby.
4
4
  module Rumale
5
5
  # The version of Rumale you are using.
6
- VERSION = '0.17.3'
6
+ VERSION = '0.18.0'
7
7
  end
data/rumale.gemspec CHANGED
@@ -20,7 +20,9 @@ Gem::Specification.new do |spec|
20
20
  Multi-layer Perceptron,
21
21
  Naive Bayes, Decision Tree, Gradient Tree Boosting, Random Forest,
22
22
  K-Means, Gaussian Mixture Model, DBSCAN, Spectral Clustering,
23
- Mutidimensional Scaling, t-SNE, Principal Component Analysis, Non-negative Matrix Factorization,
23
+ Mutidimensional Scaling, t-SNE,
24
+ Fisher Discriminant Analysis, Neighbourhood Component Analysis,
25
+ Principal Component Analysis, Non-negative Matrix Factorization,
24
26
  and many other algorithms.
25
27
  MSG
26
28
  spec.homepage = 'https://github.com/yoshoku/rumale'
@@ -45,13 +47,14 @@ Gem::Specification.new do |spec|
45
47
  spec.required_ruby_version = '>= 2.3'
46
48
 
47
49
  spec.add_runtime_dependency 'numo-narray', '>= 0.9.1'
50
+ spec.add_runtime_dependency 'mopti', '~> 0.1'
48
51
  spec.add_runtime_dependency 'mmh3', '~> 0.1'
49
52
 
50
53
  spec.add_development_dependency 'bundler', '~> 2.0'
51
54
  spec.add_development_dependency 'coveralls', '~> 0.8'
52
55
  spec.add_development_dependency 'numo-linalg', '>= 0.1.4'
53
56
  spec.add_development_dependency 'parallel', '>= 1.17.0'
54
- spec.add_development_dependency 'rake', '~> 10.0'
57
+ spec.add_development_dependency 'rake', '~> 12.0'
55
58
  spec.add_development_dependency 'rake-compiler', '~> 1.0'
56
59
  spec.add_development_dependency 'rspec', '~> 3.0'
57
60
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rumale
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.3
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-16 00:00:00.000000000 Z
11
+ date: 2020-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.9.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: mopti
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: mmh3
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +114,14 @@ dependencies:
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '10.0'
117
+ version: '12.0'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '10.0'
124
+ version: '12.0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: rake-compiler
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -144,7 +158,9 @@ description: |
144
158
  Multi-layer Perceptron,
145
159
  Naive Bayes, Decision Tree, Gradient Tree Boosting, Random Forest,
146
160
  K-Means, Gaussian Mixture Model, DBSCAN, Spectral Clustering,
147
- Mutidimensional Scaling, t-SNE, Principal Component Analysis, Non-negative Matrix Factorization,
161
+ Mutidimensional Scaling, t-SNE,
162
+ Fisher Discriminant Analysis, Neighbourhood Component Analysis,
163
+ Principal Component Analysis, Non-negative Matrix Factorization,
148
164
  and many other algorithms.
149
165
  email:
150
166
  - yoshoku@outlook.com
@@ -239,7 +255,10 @@ files:
239
255
  - lib/rumale/linear_model/svr.rb
240
256
  - lib/rumale/manifold/mds.rb
241
257
  - lib/rumale/manifold/tsne.rb
258
+ - lib/rumale/metric_learning/fisher_discriminant_analysis.rb
259
+ - lib/rumale/metric_learning/neighbourhood_component_analysis.rb
242
260
  - lib/rumale/model_selection/cross_validation.rb
261
+ - lib/rumale/model_selection/function.rb
243
262
  - lib/rumale/model_selection/grid_search_cv.rb
244
263
  - lib/rumale/model_selection/k_fold.rb
245
264
  - lib/rumale/model_selection/shuffle_split.rb