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 +4 -4
- data/LICENSE.txt +1 -1
- data/lib/rumale/manifold/classical_mds.rb +84 -0
- data/lib/rumale/manifold/version.rb +1 -1
- data/lib/rumale/manifold.rb +1 -0
- metadata +15 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a9f79f7bac08279335c170df40c94436b6cfd8b0e08ab40600ec89ef9c6409ef
|
|
4
|
+
data.tar.gz: 145928e79f5d26247c143685f6269b026165ef14d6f3f8f22cb701e58353ba8c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f79a976e69ed3c885c6a4d13fda81a080738c09b0206b956168d16b3fa692cf19c474ce09adfa4ed56b6f5e16ddb99ad24b6d442f358fa826e7d6115b95ec78a
|
|
7
|
+
data.tar.gz: e4188e655dac58b6135148c29444d1b407cfea856773de81c0c6d2312a4d6908d210493eccc08d12c027eee32914c5f2be0762ab73212f5a52160c7dcf433037
|
data/LICENSE.txt
CHANGED
|
@@ -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
|
data/lib/rumale/manifold.rb
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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: []
|