Class: Rumale::LinearModel::NNLS

Inherits:
BaseEstimator show all
Includes:
Base::Regressor
Defined in:
rumale-linear_model/lib/rumale/linear_model/nnls.rb

Overview

NNLS is a class that implements non-negative least squares regression. NNLS solves least squares problem under non-negative constraints on the coefficient using L-BFGS-B method.

Examples:

require 'rumale/linear_model/nnls'

estimator = Rumale::LinearModel::NNLS.new(reg_param: 0.01)
estimator.fit(training_samples, traininig_values)
results = estimator.predict(testing_samples)

Instance Attribute Summary collapse

Attributes inherited from BaseEstimator

#bias_term, #weight_vec

Attributes inherited from Base::Estimator

#params

Instance Method Summary collapse

Methods included from Base::Regressor

#score

Constructor Details

#initialize(reg_param: 1.0, fit_bias: true, bias_scale: 1.0, max_iter: 1000, tol: 1e-4, verbose: false) ⇒ NNLS

Create a new regressor with non-negative least squares method.

Parameters:

  • reg_param (Float) (defaults to: 1.0)

    The regularization parameter for L2 regularization term.

  • fit_bias (Boolean) (defaults to: true)

    The flag indicating whether to fit the bias term.

  • bias_scale (Float) (defaults to: 1.0)

    The scale of the bias term.

  • max_iter (Integer) (defaults to: 1000)

    The maximum number of epochs that indicates how many times the whole data is given to the training process.

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

    The tolerance of loss for terminating optimization. If solver = ‘svd’, this parameter is ignored.

  • verbose (Boolean) (defaults to: false)

    The flag indicating whether to output loss during iteration.



39
40
41
42
43
44
45
46
47
48
49
# File 'rumale-linear_model/lib/rumale/linear_model/nnls.rb', line 39

def initialize(reg_param: 1.0, fit_bias: true, bias_scale: 1.0, max_iter: 1000, tol: 1e-4, verbose: false)
  super()
  @params = {
    reg_param: reg_param,
    fit_bias: fit_bias,
    bias_scale: bias_scale,
    max_iter: max_iter,
    tol: tol,
    verbose: verbose
  }
end

Instance Attribute Details

#n_iterInteger (readonly)

Returns the number of iterations when converged.

Returns:

  • (Integer)


27
28
29
# File 'rumale-linear_model/lib/rumale/linear_model/nnls.rb', line 27

def n_iter
  @n_iter
end

Instance Method Details

#fit(x, y) ⇒ NonneagtiveLeastSquare

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.

  • y (Numo::DFloat)

    (shape: [n_samples, n_outputs]) The target values to be used for fitting the model.

Returns:

  • (NonneagtiveLeastSquare)

    The learned regressor itself.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'rumale-linear_model/lib/rumale/linear_model/nnls.rb', line 56

def fit(x, y)
  x = Rumale::Validation.check_convert_sample_array(x)
  y = Rumale::Validation.check_convert_target_value_array(y)
  Rumale::Validation.check_sample_size(x, y)

  x = expand_feature(x) if fit_bias?

  n_features = x.shape[1]
  n_outputs = single_target?(y) ? 1 : y.shape[1]

  w_init = Numo::DFloat.zeros(n_outputs * n_features)
  bounds = Numo::DFloat.zeros(n_outputs * n_features, 2)
  bounds.shape[0].times { |n| bounds[n, 1] = Float::INFINITY }

  res = Lbfgsb.minimize(
    fnc: method(:nnls_fnc), jcb: true, x_init: w_init, args: [x, y, @params[:reg_param]], bounds: bounds,
    maxiter: @params[:max_iter], factr: @params[:tol] / Lbfgsb::DBL_EPSILON, verbose: @params[:verbose] ? 1 : -1
  )

  @n_iter = res[:n_iter]
  w = single_target?(y) ? res[:x] : res[:x].reshape(n_outputs, n_features)
  @weight_vec, @bias_term = split_weight(w)

  self
end

#predict(x) ⇒ Numo::DFloat

Predict values for samples.

Parameters:

  • x (Numo::DFloat)

    (shape: [n_samples, n_features]) The samples to predict the values.

Returns:

  • (Numo::DFloat)

    (shape: [n_samples, n_outputs]) Predicted values per sample.



86
87
88
89
90
# File 'rumale-linear_model/lib/rumale/linear_model/nnls.rb', line 86

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

  x.dot(@weight_vec.transpose) + @bias_term
end