rumale-manifold 2.0.2 → 2.1.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: '03336967df86e91e4f85e07fd666a6306722295788dc7120b7adadeb8b6bbbfd'
4
- data.tar.gz: 7f53c35ce75e885cc00aba1acbd29527af155013126a31b4ec244df31e4eeb28
3
+ metadata.gz: a9f79f7bac08279335c170df40c94436b6cfd8b0e08ab40600ec89ef9c6409ef
4
+ data.tar.gz: 145928e79f5d26247c143685f6269b026165ef14d6f3f8f22cb701e58353ba8c
5
5
  SHA512:
6
- metadata.gz: 63357865d0442fe9004edbe5cf3ba4f41e3cd4bd1de6364a6cf52c20cf5a756d61c21207ad1104a53738a5cb5b2b215065b43e262409ce5c6a61da5adf13baf0
7
- data.tar.gz: 96f2c15001f60d0b3eeaf20f57f4286c39956377b163db90f788ade3f5a5282eca0191cd73b63784ca1e30c0acf629cbf234a4edfd5071dd52ea1a02c6707d55
6
+ metadata.gz: f79a976e69ed3c885c6a4d13fda81a080738c09b0206b956168d16b3fa692cf19c474ce09adfa4ed56b6f5e16ddb99ad24b6d442f358fa826e7d6115b95ec78a
7
+ data.tar.gz: e4188e655dac58b6135148c29444d1b407cfea856773de81c0c6d2312a4d6908d210493eccc08d12c027eee32914c5f2be0762ab73212f5a52160c7dcf433037
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2022-2024 Atsushi Tatsuma
1
+ Copyright (c) 2022-2026 Atsushi Tatsuma
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rumale/base/estimator'
4
+ require 'rumale/base/transformer'
5
+ require 'rumale/utils'
6
+ require 'rumale/validation'
7
+ require 'rumale/pairwise_metric'
8
+
9
+ module Rumale
10
+ module Manifold
11
+ # ClassicalMDS is a class that implements classical multi-dimensional scaling.
12
+ #
13
+ # @example
14
+ # require 'rumale/manifold/classical_mds'
15
+ #
16
+ # mds = Rumale::Manifold::ClassicalMDS.new(n_components: 2)
17
+ # representations = mds.fit_transform(data)
18
+ #
19
+ class ClassicalMDS < Rumale::Base::Estimator
20
+ include Rumale::Base::Transformer
21
+
22
+ # Return the data in representation space.
23
+ # @return [Numo::DFloat] (shape: [n_samples, n_components])
24
+ attr_reader :embedding
25
+
26
+ # Create a new transformer with Classical MDS.
27
+ #
28
+ # @param n_components [Integer] The number of dimensions on representation space.
29
+ # @param metric [String] The metric to calculate the distances in original space.
30
+ # If metric is 'euclidean', Euclidean distance is calculated for distance in original space.
31
+ # If metric is 'precomputed', the fit and fit_transform methods expect to be given a distance matrix.
32
+ def initialize(n_components: 2, metric: 'euclidean')
33
+ super()
34
+ @params = {
35
+ n_components: n_components,
36
+ metric: metric
37
+ }
38
+ end
39
+
40
+ # Fit the model with given training data.
41
+ #
42
+ # @overload fit(x) -> ClassicalMDS
43
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
44
+ # If the metric is 'precomputed', x must be a square distance matrix (shape: [n_samples, n_samples]).
45
+ # @return [ClassicalMDS] The learned transformer itself.
46
+ def fit(x, _not_used = nil)
47
+ raise 'ClassicalMDS#fit requires Numo::Linalg but that is not loaded' unless enable_linalg?(warning: false)
48
+
49
+ x = ::Rumale::Validation.check_convert_sample_array(x)
50
+ if @params[:metric] == 'precomputed' && x.shape[0] != x.shape[1]
51
+ raise ArgumentError, 'Expect the input distance matrix to be square.'
52
+ end
53
+
54
+ n_samples = x.shape[0]
55
+ distance_mat = @params[:metric] == 'precomputed' ? x : ::Rumale::PairwiseMetric.euclidean_distance(x)
56
+
57
+ centering_mat = Numo::DFloat.eye(n_samples) - Numo::DFloat.new(n_samples, n_samples).fill(1.fdiv(n_samples))
58
+ kernel_mat = -0.5 * centering_mat.dot(distance_mat * distance_mat).dot(centering_mat)
59
+ eig_vals, eig_vecs = Numo::Linalg.eigh(kernel_mat, vals_range: (n_samples - @params[:n_components])...n_samples)
60
+ eig_vals = eig_vals.reverse
61
+ eig_vecs = eig_vecs.reverse(1)
62
+ @embedding = eig_vecs.dot(Numo::NMath.sqrt(eig_vals.abs).diag)
63
+
64
+ @embedding = @embedding.flatten.dup if @params[:n_components] == 1
65
+
66
+ self
67
+ end
68
+
69
+ # Fit the model with training data, and then transform them with the learned model.
70
+ #
71
+ # @overload fit_transform(x) -> Numo::DFloat
72
+ # @param x [Numo::DFloat] (shape: [n_samples, n_features]) The training data to be used for fitting the model.
73
+ # If the metric is 'precomputed', x must be a square distance matrix (shape: [n_samples, n_samples]).
74
+ # @return [Numo::DFloat] (shape: [n_samples, n_components]) The transformed data
75
+ def fit_transform(x, _not_used = nil)
76
+ raise 'ClassicalMDS#fit_transform requires Numo::Linalg but that is not loaded' unless enable_linalg?(warning: false)
77
+
78
+ x = ::Rumale::Validation.check_convert_sample_array(x)
79
+ fit(x)
80
+ @embedding.dup
81
+ end
82
+ end
83
+ end
84
+ end
@@ -5,6 +5,6 @@ module Rumale
5
5
  # Module for data embedding algorithms.
6
6
  module Manifold
7
7
  # @!visibility private
8
- VERSION = '2.0.2'
8
+ VERSION = '2.1.0'
9
9
  end
10
10
  end
@@ -6,6 +6,7 @@ require_relative 'manifold/laplacian_eigenmaps'
6
6
  require_relative 'manifold/locally_linear_embedding'
7
7
  require_relative 'manifold/hessian_eigenmaps'
8
8
  require_relative 'manifold/local_tangent_space_alignment'
9
+ require_relative 'manifold/classical_mds'
9
10
  require_relative 'manifold/mds'
10
11
  require_relative 'manifold/tsne'
11
12
  require_relative 'manifold/version'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rumale-manifold
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
@@ -13,44 +13,50 @@ dependencies:
13
13
  name: numo-narray-alt
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
18
  version: 0.9.10
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: 0.11.0
19
22
  type: :runtime
20
23
  prerelease: false
21
24
  version_requirements: !ruby/object:Gem::Requirement
22
25
  requirements:
23
- - - "~>"
26
+ - - ">="
24
27
  - !ruby/object:Gem::Version
25
28
  version: 0.9.10
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: 0.11.0
26
32
  - !ruby/object:Gem::Dependency
27
33
  name: rumale-core
28
34
  requirement: !ruby/object:Gem::Requirement
29
35
  requirements:
30
36
  - - "~>"
31
37
  - !ruby/object:Gem::Version
32
- version: 2.0.2
38
+ version: 2.1.0
33
39
  type: :runtime
34
40
  prerelease: false
35
41
  version_requirements: !ruby/object:Gem::Requirement
36
42
  requirements:
37
43
  - - "~>"
38
44
  - !ruby/object:Gem::Version
39
- version: 2.0.2
45
+ version: 2.1.0
40
46
  - !ruby/object:Gem::Dependency
41
47
  name: rumale-decomposition
42
48
  requirement: !ruby/object:Gem::Requirement
43
49
  requirements:
44
50
  - - "~>"
45
51
  - !ruby/object:Gem::Version
46
- version: 2.0.2
52
+ version: 2.1.0
47
53
  type: :runtime
48
54
  prerelease: false
49
55
  version_requirements: !ruby/object:Gem::Requirement
50
56
  requirements:
51
57
  - - "~>"
52
58
  - !ruby/object:Gem::Version
53
- version: 2.0.2
59
+ version: 2.1.0
54
60
  description: |
55
61
  Rumale::Manifold provides data embedding algorithms,
56
62
  such as Multi-dimensional Scaling, Locally Linear Embedding, Laplacian Eigenmaps, Hessian Eigenmaps,
@@ -65,6 +71,7 @@ files:
65
71
  - LICENSE.txt
66
72
  - README.md
67
73
  - lib/rumale/manifold.rb
74
+ - lib/rumale/manifold/classical_mds.rb
68
75
  - lib/rumale/manifold/hessian_eigenmaps.rb
69
76
  - lib/rumale/manifold/laplacian_eigenmaps.rb
70
77
  - lib/rumale/manifold/local_tangent_space_alignment.rb
@@ -94,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
101
  - !ruby/object:Gem::Version
95
102
  version: '0'
96
103
  requirements: []
97
- rubygems_version: 3.6.9
104
+ rubygems_version: 4.0.3
98
105
  specification_version: 4
99
106
  summary: Rumale::Manifold provides data embedding algorithms with Rumale interface.
100
107
  test_files: []