Class: XLearn::Model

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/xlearn/model.rb

Direct Known Subclasses

FFM, FM, Linear

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**options) ⇒ Model

Returns a new instance of Model.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/xlearn/model.rb', line 5

def initialize(**options)
  @handle = ::FFI::MemoryPointer.new(:pointer)
  check_call FFI.XLearnCreate(@model_type, @handle)
  ObjectSpace.define_finalizer(self, self.class.finalize(@handle))

  options = {
    task: "binary",
    quiet: true,
    bin_out: false
  }.merge(options)

  if options[:task] == "binary" && !options.key?(:sigmoid)
    options[:sigmoid] = true
  end

  set_params(options)
end

Class Method Details

.finalize(pointer) ⇒ Object



110
111
112
113
# File 'lib/xlearn/model.rb', line 110

def self.finalize(pointer)
  # must use proc instead of stabby lambda
  proc { FFI.XLearnHandleFree(pointer) }
end

.finalize_file(file) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/xlearn/model.rb', line 115

def self.finalize_file(file)
  # must use proc instead of stabby lambda
  proc do
    file.close
    file.unlink
  end
end

Instance Method Details

#bias_termObject



92
93
94
95
96
# File 'lib/xlearn/model.rb', line 92

def bias_term
  read_txt do |line|
    return line.split(":").last.to_f if line.start_with?("bias:")
  end
end

#cv(x, y = nil, folds: nil) ⇒ Object



70
71
72
73
74
# File 'lib/xlearn/model.rb', line 70

def cv(x, y = nil, folds: nil)
  set_params(fold: folds) if folds
  set_train_set(x, y)
  check_call FFI.XLearnCV(@handle)
end

#fit(x, y = nil, eval_set: nil) ⇒ Object



23
24
25
26
# File 'lib/xlearn/model.rb', line 23

def fit(x, y = nil, eval_set: nil)
  @model_path = nil
  partial_fit(x, y, eval_set: eval_set)
end

#linear_termObject



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/xlearn/model.rb', line 98

def linear_term
  term = []
  read_txt do |line|
    if line.start_with?("i_")
      term << line.split(":").last.to_f
    elsif line.start_with?("v_")
      break
    end
  end
  term
end

#load_model(path) ⇒ Object



86
87
88
89
90
# File 'lib/xlearn/model.rb', line 86

def load_model(path)
  @model_file ||= create_tempfile
  # TODO ensure tempfile is still cleaned up
  FileUtils.cp(path, @model_file.path)
end

#partial_fit(x, y = nil, eval_set: nil) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/xlearn/model.rb', line 28

def partial_fit(x, y = nil, eval_set: nil)
  check_call FFI.XLearnSetPreModel(@handle, @model_path || "")

  set_train_set(x, y)

  if eval_set
    if eval_set.is_a?(String)
      check_call FFI.XLearnSetValidate(@handle, eval_set)
    else
      valid_set = DMatrix.new(x, label: y)
      check_call FFI.XLearnSetDMatrix(@handle, "validate", valid_set)
    end
  end

  @txt_file ||= create_tempfile
  check_call FFI.XLearnSetTXTModel(@handle, @txt_file.path)

  @model_file ||= create_tempfile
  check_call FFI.XLearnFit(@handle, @model_file.path)
  @model_path = @model_file.path
end

#predict(x, out_path: nil) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/xlearn/model.rb', line 50

def predict(x, out_path: nil)
  if x.is_a?(String)
    check_call FFI.XLearnSetTest(@handle, x)
    check_call FFI.XLearnSetBool(@handle, "from_file", true)
  else
    test_set = DMatrix.new(x)
    check_call FFI.XLearnSetDMatrix(@handle, "test", test_set)
    check_call FFI.XLearnSetBool(@handle, "from_file", false)
  end

  if out_path
    check_call FFI.XLearnPredictForFile(@handle, @model_file.path, out_path)
  else
    length = ::FFI::MemoryPointer.new(:uint64)
    out_arr = ::FFI::MemoryPointer.new(:pointer)
    check_call FFI.XLearnPredictForMat(@handle, @model_file.path, length, out_arr)
    out_arr.read_pointer.read_array_of_float(length.read_uint64)
  end
end

#save_model(path) ⇒ Object

Raises:



76
77
78
79
# File 'lib/xlearn/model.rb', line 76

def save_model(path)
  raise Error, "Not trained" unless @model_file
  FileUtils.cp(@model_file.path, path)
end

#save_txt(path) ⇒ Object

Raises:



81
82
83
84
# File 'lib/xlearn/model.rb', line 81

def save_txt(path)
  raise Error, "Not trained" unless @txt_file
  FileUtils.cp(@txt_file.path, path)
end