Class: SVMKit::LinearModel::PegasosSVC
- Inherits:
-
Object
- Object
- SVMKit::LinearModel::PegasosSVC
- Includes:
- Base::BaseEstimator, Base::Classifier
- Defined in:
- lib/svmkit/linear_model/pegasos_svc.rb
Overview
PegasosSVC is a class that implements Support Vector Classifier with the Pegasos algorithm.
estimator =
SVMKit::LinearModel::PegasosSVC.new(reg_param: 1.0, max_iter: 100, batch_size: 20, random_seed: 1)
estimator.fit(training_samples, traininig_labels)
results = estimator.predict(testing_samples)
-
Reference:
-
Shalev-Shwartz and Y. Singer, “Pegasos: Primal Estimated sub-GrAdient SOlver for SVM,” Proc. ICML’07, pp. 807–814, 2007.
-
Constant Summary collapse
- DEFAULT_PARAMS =
:nodoc:
{ # :nodoc: reg_param: 1.0, max_iter: 100, batch_size: 50, random_seed: nil }.freeze
Instance Attribute Summary collapse
-
#rng ⇒ Object
readonly
The random generator for performing random sampling in the Pegasos algorithm.
-
#weight_vec ⇒ Object
readonly
The weight vector for SVC.
Attributes included from Base::BaseEstimator
Instance Method Summary collapse
-
#decision_function(x) ⇒ Object
Calculate confidence scores for samples.
-
#fit(x, y) ⇒ Object
Fit the model with given training data.
-
#initialize(params = {}) ⇒ PegasosSVC
constructor
Create a new classifier with Support Vector Machine by the Pegasos algorithm.
-
#marshal_dump ⇒ Object
Serializes object through Marshal#dump.
-
#marshal_load(obj) ⇒ Object
Deserialize object through Marshal#load.
-
#predict(x) ⇒ Object
Predict class labels for samples.
-
#score(x, y) ⇒ Object
Claculate the mean accuracy of the given testing data.
Constructor Details
#initialize(params = {}) ⇒ PegasosSVC
Create a new classifier with Support Vector Machine by the Pegasos algorithm.
:call-seq:
new(reg_param: 1.0, max_iter: 100, batch_size: 50, random_seed: 1) -> PegasosSVC
-
Arguments :
-
:reg_param(Float) (defaults to: 1.0) – The regularization parameter. -
:max_iter(Integer) (defaults to: 100) – The maximum number of iterations. -
:batch_size(Integer) (defaults to: 50) – The size of the mini batches. -
:random_seed(Integer) (defaults to: nil) – The seed value using to initialize the random generator.
-
44 45 46 47 48 49 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 44 def initialize(params = {}) self.params = DEFAULT_PARAMS.merge(Hash[params.map { |k, v| [k.to_sym, v] }]) self.params[:random_seed] ||= srand @weight_vec = nil @rng = Random.new(self.params[:random_seed]) end |
Instance Attribute Details
#rng ⇒ Object (readonly)
The random generator for performing random sampling in the Pegasos algorithm.
32 33 34 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 32 def rng @rng end |
#weight_vec ⇒ Object (readonly)
The weight vector for SVC.
29 30 31 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 29 def weight_vec @weight_vec end |
Instance Method Details
#decision_function(x) ⇒ Object
Calculate confidence scores for samples.
:call-seq:
decision_function(x) -> NMatrix, shape: [1, n_samples]
-
Arguments :
-
x(NMatrix, shape: [n_samples, n_features]) – The samples to compute the scores.
-
-
Returns :
-
Confidence score per sample.
-
101 102 103 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 101 def decision_function(x) @weight_vec.dot(x.transpose) end |
#fit(x, y) ⇒ Object
Fit the model with given training data.
:call-seq:
fit(x, y) -> PegasosSVC
-
Arguments :
-
x(NMatrix, shape: [n_samples, n_features]) – The training data to be used for fitting the model. -
y(NMatrix, shape: [1, n_samples]) – The labels to be used for fitting the model.
-
-
Returns :
-
The learned classifier itself.
-
61 62 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 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 61 def fit(x, y) # Generate binary labels negative_label = y.uniq.sort.shift bin_y = y.to_flat_a.map { |l| l != negative_label ? 1 : -1 } # Initialize some variables. n_samples, n_features = x.shape rand_ids = [*0..n_samples - 1].shuffle(random: @rng) @weight_vec = NMatrix.zeros([1, n_features]) # Start optimization. params[:max_iter].times do |t| # random sampling subset_ids = rand_ids.shift(params[:batch_size]) rand_ids.concat(subset_ids) target_ids = subset_ids.map do |n| n if @weight_vec.dot(x.row(n).transpose) * bin_y[n] < 1 end n_subsamples = target_ids.size next if n_subsamples.zero? # update the weight vector. eta = 1.0 / (params[:reg_param] * (t + 1)) mean_vec = NMatrix.zeros([1, n_features]) target_ids.each { |n| mean_vec += x.row(n) * bin_y[n] } mean_vec *= eta / n_subsamples @weight_vec = @weight_vec * (1.0 - eta * params[:reg_param]) + mean_vec # scale the weight vector. scaler = (1.0 / params[:reg_param]**0.5) / @weight_vec.norm2 @weight_vec *= [1.0, scaler].min end self end |
#marshal_dump ⇒ Object
Serializes object through Marshal#dump.
135 136 137 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 135 def marshal_dump # :nodoc: { params: params, weight_vec: Utils.dump_nmatrix(@weight_vec), rng: @rng } end |
#marshal_load(obj) ⇒ Object
Deserialize object through Marshal#load.
140 141 142 143 144 145 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 140 def marshal_load(obj) # :nodoc: self.params = obj[:params] @weight_vec = Utils.restore_nmatrix(obj[:weight_vec]) @rng = obj[:rng] nil end |
#predict(x) ⇒ Object
Predict class labels for samples.
:call-seq:
predict(x) -> NMatrix, shape: [1, n_samples]
-
Arguments :
-
x(NMatrix, shape: [n_samples, n_features]) – The samples to predict the labels.
-
-
Returns :
-
Predicted class label per sample.
-
114 115 116 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 114 def predict(x) decision_function(x).map { |v| v >= 0 ? 1 : -1 } end |
#score(x, y) ⇒ Object
Claculate the mean accuracy of the given testing data.
:call-seq:
predict(x, y) -> Float
-
Arguments :
-
x(NMatrix, shape: [n_samples, n_features]) – Testing data. -
y(NMatrix, shape: [1, n_samples]) – True labels for testing data.
-
-
Returns :
-
Mean accuracy
-
128 129 130 131 132 |
# File 'lib/svmkit/linear_model/pegasos_svc.rb', line 128 def score(x, y) p = predict(x) n_hits = (y.to_flat_a.map.with_index { |l, n| l == p[n] ? 1 : 0 }).inject(:+) n_hits / y.size.to_f end |