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



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