Class: Rumale::KernelApproximation::Nystroem

Inherits:
Base::Estimator show all
Includes:
Base::Transformer
Defined in:
rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb

Overview

Nystroem is a class that implements feature mapping with Nystroem method.

Reference

  • 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.

Examples:

require 'numo/linalg/autoloader'
require 'rumale/kernel_approximation/nystroem'

transformer = Rumale::KernelApproximation::Nystroem.new(kernel: 'rbf', gamma: 1, n_components: 128, random_seed: 1)
new_training_samples = transformer.fit_transform(training_samples)
new_testing_samples = transformer.transform(testing_samples)

Instance Attribute Summary collapse

Attributes inherited from Base::Estimator

#params

Instance Method Summary collapse

Constructor Details

#initialize(kernel: 'rbf', gamma: 1, degree: 3, coef: 1, n_components: 100, random_seed: nil) ⇒ Nystroem

Create a new transformer for mapping to kernel feature space with Nystrom method.

Parameters:

  • kernel (String) (defaults to: 'rbf')

    The type of kernel function (‘rbf’, ‘linear’, ‘poly’, and ‘sigmoid)

  • gamma (Float) (defaults to: 1)

    The gamma parameter in rbf/poly/sigmoid kernel function.

  • degree (Integer) (defaults to: 3)

    The degree parameter in polynomial kernel function.

  • coef (Float) (defaults to: 1)

    The coefficient in poly/sigmoid kernel function.

  • n_components (Integer) (defaults to: 100)

    The number of dimensions of the kernel feature space.

  • random_seed (Integer) (defaults to: nil)

    The seed value using to initialize the random generator.



49
50
51
52
53
54
55
56
57
58
59
60
# File 'rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb', line 49

def initialize(kernel: 'rbf', gamma: 1, degree: 3, coef: 1, n_components: 100, random_seed: nil)
  super()
  @params = {
    kernel: kernel,
    gamma: gamma,
    degree: degree,
    coef: coef,
    n_components: n_components,
    random_seed: random_seed || srand
  }
  @rng = Random.new(@params[:random_seed])
end

Instance Attribute Details

#component_indicesNumo::Int32 (readonly)

Returns the indices sampled training data.

Returns:

  • (Numo::Int32)

    (shape: [n_components])



31
32
33
# File 'rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb', line 31

def component_indices
  @component_indices
end

#componentsNumo::DFloat (readonly)

Returns the randomly sampled training data for feature mapping.

Returns:

  • (Numo::DFloat)

    (shape: n_components, n_features])



27
28
29
# File 'rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb', line 27

def components
  @components
end

#normalizerNumo::DFloat (readonly)

Returns the normalizing factors.

Returns:

  • (Numo::DFloat)

    (shape: [n_components, n_components])



35
36
37
# File 'rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb', line 35

def normalizer
  @normalizer
end

#rngRandom (readonly)

Return the random generator for transformation.

Returns:

  • (Random)


39
40
41
# File 'rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb', line 39

def rng
  @rng
end

Instance Method Details

#fit(x) ⇒ Nystroem

Fit the model with given training data.

Returns The learned transformer itself.

Parameters:

  • x (Numo::NArray)

    (shape: [n_samples, n_features]) The training data to be used for fitting the model.

Returns:

  • (Nystroem)

    The learned transformer itself.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb', line 67

def fit(x, _y = nil)
  x = ::Rumale::Validation.check_convert_sample_array(x)
  raise 'Nystroem#fit requires Numo::Linalg but that is not loaded.' unless enable_linalg?(warning: false)

  # initialize some variables.
  sub_rng = @rng.dup
  n_samples = x.shape[0]
  n_components = [1, [@params[:n_components], n_samples].min].max # rubocop:disable Style/ComparableClamp

  # random sampling.
  @component_indices = Numo::Int32.cast(Array(0...n_samples).shuffle(random: sub_rng)[0...n_components])
  @components = x[@component_indices, true].dup

  # calculate normalizing factor.
  kernel_mat = kernel_mat(@components)
  eig_vals, eig_vecs = Numo::Linalg.eigh(kernel_mat)
  la = eig_vals.class.maximum(eig_vals.reverse, 1e-12)
  u = eig_vecs.reverse(1)
  @normalizer = u.dot((1.0 / Numo::NMath.sqrt(la)).diag)

  self
end

#fit_transform(x) ⇒ Numo::DFloat

Fit the model with training data, and then transform them with the learned model.

Returns (shape: [n_samples, n_components]) The transformed data.

Parameters:

  • x (Numo::DFloat)

    (shape: [n_samples, n_features]) The training data to be used for fitting the model.

Returns:

  • (Numo::DFloat)

    (shape: [n_samples, n_components]) The transformed data



95
96
97
98
99
# File 'rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb', line 95

def fit_transform(x, _y = nil)
  x = ::Rumale::Validation.check_convert_sample_array(x)

  fit(x).transform(x)
end

#transform(x) ⇒ Numo::DFloat

Transform the given data with the learned model.

Parameters:

  • x (Numo::DFloat)

    (shape: [n_samples, n_features]) The data to be transformed with the learned model.

Returns:

  • (Numo::DFloat)

    (shape: [n_samples, n_components]) The transformed data.



105
106
107
108
109
110
# File 'rumale-kernel_approximation/lib/rumale/kernel_approximation/nystroem.rb', line 105

def transform(x)
  x = ::Rumale::Validation.check_convert_sample_array(x)

  z = kernel_mat(x, @components)
  z.dot(@normalizer)
end