Class: Model

Inherits:
Object
  • Object
show all
Defined in:
lib/svm.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arg1, arg2 = nil) ⇒ Model

Returns a new instance of Model.



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/svm.rb', line 186

def initialize(arg1,arg2=nil)
  if arg2 == nil
    # create model from file
    filename = arg1
    @model = svm_load_model(filename)
  else
    # create model from problem and parameter
    prob,param = arg1,arg2
    @prob = prob
    if param.gamma == 0
      param.gamma = 1.0/prob.maxlen
    end
    msg = svm_check_parameter(prob.prob,param.param)
    raise ::ArgumentError, msg if msg
    @model = svm_train(prob.prob,param.param)
  end
  
  #setup some classwide variables
  @nr_class = svm_get_nr_class(@model)
  @svm_type = svm_get_svm_type(@model)
  #create labels(classes)
  intarr = new_int(@nr_class)
  svm_get_labels(@model,intarr)
  @labels = _int_array_to_list(intarr, @nr_class)
  delete_int(intarr)
  #check if valid probability model
  @probability = svm_check_probability_model(@model)

end

Instance Attribute Details

#modelObject

Returns the value of attribute model.



184
185
186
# File 'lib/svm.rb', line 184

def model
  @model
end

Instance Method Details

#destroyObject



317
318
319
# File 'lib/svm.rb', line 317

def destroy
  svm_destroy_model(@model)
end

#get_labelsObject



228
229
230
231
232
233
# File 'lib/svm.rb', line 228

def get_labels
  if @svm_type == NU_SVR or @svm_type == EPSILON_SVR or @svm_type == ONE_CLASS
    raise TypeError, "Unable to get label from a SVR/ONE_CLASS model"
  end
  return @labels
end

#get_nr_classObject



224
225
226
# File 'lib/svm.rb', line 224

def get_nr_class
  return @nr_class
end

#get_svr_pdfObject



307
308
309
310
311
# File 'lib/svm.rb', line 307

def get_svr_pdf
  #get_svr_probability will handle error checking
  sigma = get_svr_probability()
  return Proc.new{|z| exp(-z.abs/sigma)/(2*sigma)}  # TODO: verify this works
end

#get_svr_probabilityObject



298
299
300
301
302
303
304
305
# File 'lib/svm.rb', line 298

def get_svr_probability
  #leave the Error checking to svm.cpp code
  ret = svm_get_svr_probability(@model)
  if ret == 0
    raise TypeError, "not a regression model or probability information not available"
  end
  return ret
end

#predict(x) ⇒ Object



216
217
218
219
220
221
# File 'lib/svm.rb', line 216

def predict(x)
  data = _convert_to_svm_node_array(x)
  ret = svm_predict(@model,data)
  svm_node_array_destroy(data)
  return ret
end

#predict_probability(x) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/svm.rb', line 272

def predict_probability(x)
  #c code will do nothing on wrong type, so we have to check ourself
  if @svm_type == NU_SVR or @svm_type == EPSILON_SVR
    raise TypeError, "call get_svr_probability or get_svr_pdf for probability output of regression"
  elsif @svm_type == ONE_CLASS
    raise TypeError, "probability not supported yet for one-class problem"
  end
  #only C_SVC,NU_SVC goes in
  if not @probability
    raise TypeError, "model does not support probabiliy estimates"
  end
  
  #convert x into svm_node, alloc a double array to receive probabilities
  data = _convert_to_svm_node_array(x)
  dblarr = new_double(@nr_class)
  pred = svm_predict_probability(@model, data, dblarr)
  pv = _double_array_to_list(dblarr, @nr_class)
  delete_double(dblarr)
  svm_node_array_destroy(data)
  p = {}
  for i in (0..@labels.size-1)
    p[@labels[i]] = pv[i]
  end
  return pred, p
end

#predict_values(x) ⇒ Object



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/svm.rb', line 247

def predict_values(x)
  v=predict_values_raw(x)
  #puts v.inspect
  if @svm_type == NU_SVR or @svm_type == EPSILON_SVR or @svm_type == ONE_CLASS
    return v[0]
  else #self.svm_type == C_SVC or self.svm_type == NU_SVC
    count = 0
    
    # create a width x height array
    width = @labels.size
    height = @labels.size
    d = Array.new(width)
    d.map! { Array.new(height) }
    
    for i in (0..@labels.size-1)
      for j in (i+1..@labels.size-1)
        d[@labels[i]][@labels[j]] = v[count]
        d[@labels[j]][@labels[i]] = -v[count]
        count += 1
      end
    end
    return d
  end
end

#predict_values_raw(x) ⇒ Object



235
236
237
238
239
240
241
242
243
244
245
# File 'lib/svm.rb', line 235

def predict_values_raw(x)
  #convert x into svm_node, allocate a double array for return
  n = (@nr_class*(@nr_class-1)/2).floor
  data = _convert_to_svm_node_array(x)
  dblarr = new_double(n)
  svm_predict_values(@model, data, dblarr)
  ret = _double_array_to_list(dblarr, n)
  delete_double(dblarr)
  svm_node_array_destroy(data)
  return ret
end

#save(filename) ⇒ Object



313
314
315
# File 'lib/svm.rb', line 313

def save(filename)
  svm_save_model(filename,@model)
end