rumale 0.17.3 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
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