Class: Rumale::Decomposition::FastICA

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

Overview

FastICA is a class that implments Fast Independent Component Analaysis.

Reference

  • Hyvarinen, A., “Fast and Robust Fixed-Point Algorithms for Independent Component Analysis,” IEEE Trans. Neural Networks, Vol. 10 (3), pp. 626–634, 1999.

  • Hyvarinen, A., and Oja, E., “Independent Component Analysis: Algorithms and Applications,” Neural Networks, Vol. 13 (4-5), pp. 411–430, 2000.

Examples:

require 'numo/linalg/autoloader'
require 'rumale/decomposition/fast_ica'

transformer = Rumale::Decomposition::FastICA.new(n_components: 2, random_seed: 1)
source_data = transformer.fit_transform(observed_data)

Instance Attribute Summary collapse

Attributes inherited from Base::Estimator

#params

Instance Method Summary collapse

Constructor Details

#initialize(n_components: 2, whiten: true, fun: 'logcosh', alpha: 1.0, max_iter: 200, tol: 1e-4, random_seed: nil) ⇒ FastICA

Create a new transformer with FastICA.

Parameters:

  • n_components (Integer) (defaults to: 2)

    The number of independent components.

  • whiten (Boolean) (defaults to: true)

    The flag indicating whether to perform whitening.

  • fun (String) (defaults to: 'logcosh')

    The type of contrast function (‘logcosh’, ‘exp’, or ‘cube’).

  • alpha (Float) (defaults to: 1.0)

    The parameter of contrast function for ‘logcosh’ and ‘exp’. If fun = ‘cube’, this parameter is ignored.

  • max_iter (Integer) (defaults to: 200)

    The maximum number of iterations.

  • tol (Float) (defaults to: 1e-4)

    The tolerance of termination criterion.

  • random_seed (Integer) (defaults to: nil)

    The seed value using to initialize the random generator.



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 51

def initialize(n_components: 2, whiten: true, fun: 'logcosh', alpha: 1.0, max_iter: 200, tol: 1e-4, random_seed: nil)
  super()
  @params = {
    n_components: n_components,
    whiten: whiten,
    fun: fun,
    alpha: alpha,
    max_iter: max_iter,
    tol: tol,
    random_seed: random_seed || srand
  }
  @rng = Random.new(@params[:random_seed])
end

Instance Attribute Details

#componentsNumo::DFloat (readonly)

Returns the unmixing matrix.

Returns:

  • (Numo::DFloat)

    (shape: [n_components, n_features])



27
28
29
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 27

def components
  @components
end

#mixingNumo::DFloat (readonly)

Returns the mixing matrix.

Returns:

  • (Numo::DFloat)

    (shape: [n_features, n_components])



31
32
33
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 31

def mixing
  @mixing
end

#n_iterInteger (readonly)

Returns the number of iterations when converged.

Returns:

  • (Integer)


35
36
37
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 35

def n_iter
  @n_iter
end

#rngRandom (readonly)

Return the random generator.

Returns:

  • (Random)


39
40
41
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 39

def rng
  @rng
end

Instance Method Details

#fit(x) ⇒ FastICA

Fit the model with given training data.

Parameters:

  • x (Numo::DFloat)

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

Returns:

  • (FastICA)

    The learned transformer itself.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 70

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

  @mean, whiten_mat = whitening(x, @params[:n_components]) if @params[:whiten]
  wx = @params[:whiten] ? (x - @mean).dot(whiten_mat.transpose) : x
  unmixing, @n_iter = ica(wx, @params[:fun], @params[:max_iter], @params[:tol], @rng.dup)
  @components = @params[:whiten] ? unmixing.dot(whiten_mat) : unmixing
  @mixing = Numo::Linalg.pinv(@components).dup
  if @params[:n_components] == 1
    @components = @components.flatten.dup
    @mixing = @mixing.flatten.dup
  end
  self
end

#fit_transform(x) ⇒ Numo::DFloat

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

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



91
92
93
94
95
96
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 91

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

  fit(x).transform(x)
end

#inverse_transform(z) ⇒ Numo::DFloat

Inverse transform the given transformed data with the learned model.

Parameters:

  • z (Numo::DFloat)

    (shape: [n_samples, n_components]) The source data reconstructed to the mixed data.

Returns:

  • (Numo::DFloat)

    (shape: [n_samples, n_featuress]) The mixed data.



113
114
115
116
117
118
119
120
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 113

def inverse_transform(z)
  z = ::Rumale::Validation.check_convert_sample_array(z)

  m = @mixing.shape[1].nil? ? @mixing.expand_dims(0).transpose : @mixing
  x = z.dot(m.transpose)
  x += @mean if @params[:whiten]
  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.



102
103
104
105
106
107
# File 'rumale-decomposition/lib/rumale/decomposition/fast_ica.rb', line 102

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

  cx = @params[:whiten] ? (x - @mean) : x
  cx.dot(@components.transpose)
end