Class: Rumale::Decomposition::FactorAnalysis
- Inherits:
-
Base::Estimator
- Object
- Base::Estimator
- Rumale::Decomposition::FactorAnalysis
- Includes:
- Base::Transformer
- Defined in:
- rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb
Overview
FactorAnalysis is a class that implements fator analysis with EM algorithm.
Reference
-
Barber, D., “Bayesian Reasoning and Machine Learning,” Cambridge University Press, 2012.
Instance Attribute Summary collapse
-
#components ⇒ Numo::DFloat
readonly
Returns the components with maximum variance.
-
#loglike ⇒ Numo::DFloat
readonly
Returns the log likelihood at each iteration.
-
#mean ⇒ Numo::DFloat
readonly
Returns the mean vector.
-
#n_iter ⇒ Integer
readonly
Return the number of iterations run for optimization.
-
#noise_variance ⇒ Numo::DFloat
readonly
Returns the estimated noise variance for each feature.
Attributes inherited from Base::Estimator
Instance Method Summary collapse
-
#fit(x) ⇒ FactorAnalysis
Fit the model with given training data.
-
#fit_transform(x) ⇒ Numo::DFloat
Fit the model with training data, and then transform them with the learned model.
-
#initialize(n_components: 2, max_iter: 100, tol: 1e-8) ⇒ FactorAnalysis
constructor
Create a new transformer with factor analysis.
-
#transform(x) ⇒ Numo::DFloat
Transform the given data with the learned model.
Constructor Details
#initialize(n_components: 2, max_iter: 100, tol: 1e-8) ⇒ FactorAnalysis
Create a new transformer with factor analysis.
49 50 51 52 53 54 55 56 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 49 def initialize(n_components: 2, max_iter: 100, tol: 1e-8) super() @params = { n_components: n_components, max_iter: max_iter, tol: tol } end |
Instance Attribute Details
#components ⇒ Numo::DFloat (readonly)
Returns the components with maximum variance.
33 34 35 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 33 def components @components end |
#loglike ⇒ Numo::DFloat (readonly)
Returns the log likelihood at each iteration.
37 38 39 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 37 def loglike @loglike end |
#mean ⇒ Numo::DFloat (readonly)
Returns the mean vector.
25 26 27 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 25 def mean @mean end |
#n_iter ⇒ Integer (readonly)
Return the number of iterations run for optimization
41 42 43 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 41 def n_iter @n_iter end |
#noise_variance ⇒ Numo::DFloat (readonly)
Returns the estimated noise variance for each feature.
29 30 31 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 29 def noise_variance @noise_variance end |
Instance Method Details
#fit(x) ⇒ FactorAnalysis
Fit the model with given training data.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 63 def fit(x, _y = nil) x = ::Rumale::Validation.check_convert_sample_array(x) raise 'FactorAnalysis#fit requires Numo::Linalg but that is not loaded' unless enable_linalg?(warning: false) # initialize some variables. n_samples, n_features = x.shape @mean = x.mean(0) centered_x = x - @mean cov_mat = centered_x.transpose.dot(centered_x) / n_samples sample_vars = x.var(0) sqrt_n_samples = Math.sqrt(n_samples) @noise_variance = Numo::DFloat.ones(n_features) # run optimization. old_loglike = 0.0 @n_iter = 0 @loglike = [] unless @params[:tol].nil? @params[:max_iter].times do |t| @n_iter = t + 1 sqrt_noise_variance = Numo::NMath.sqrt(@noise_variance) scaled_x = centered_x / (sqrt_noise_variance * sqrt_n_samples + 1e-12) s, u = truncate_svd(scaled_x, @params[:n_components]) scaler = Numo::NMath.sqrt(Numo::DFloat.maximum(s**2 - 1.0, 0.0)) @components = (sqrt_noise_variance.diag.dot(u) * scaler).transpose.dup @noise_variance = Numo::DFloat.maximum(sample_vars - @components.transpose.dot(@components).diagonal, 1e-12) next if @params[:tol].nil? new_loglike = log_likelihood(cov_mat, @components, @noise_variance) @loglike.push(new_loglike) break if (old_loglike - new_loglike).abs <= @params[:tol] old_loglike = new_loglike end @loglike = Numo::DFloat.cast(@loglike) unless @params[:tol].nil? @components = @components[0, true].dup if @params[:n_components] == 1 self end |
#fit_transform(x) ⇒ Numo::DFloat
Fit the model with training data, and then transform them with the learned model.
107 108 109 110 111 112 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 107 def fit_transform(x, _y = nil) x = ::Rumale::Validation.check_convert_sample_array(x) raise 'FactorAnalysis#fit_transform requires Numo::Linalg but that is not loaded' unless enable_linalg?(warning: false) fit(x).transform(x) end |
#transform(x) ⇒ Numo::DFloat
Transform the given data with the learned model.
118 119 120 121 122 123 124 125 126 127 |
# File 'rumale-decomposition/lib/rumale/decomposition/factor_analysis.rb', line 118 def transform(x) x = ::Rumale::Validation.check_convert_sample_array(x) raise 'FactorAnalysis#transform requires Numo::Linalg but that is not loaded' unless enable_linalg?(warning: false) factors = @params[:n_components] == 1 ? @components.(0) : @components centered_x = x - @mean beta = Numo::Linalg.inv(Numo::DFloat.eye(factors.shape[0]) + (factors / @noise_variance).dot(factors.transpose)) z = centered_x.dot((beta.dot(factors) / @noise_variance).transpose) @params[:n_components] == 1 ? z[true, 0].dup : z end |