Class: LightGBM::Booster

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/lightgbm/booster.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params: nil, train_set: nil, model_file: nil, model_str: nil) ⇒ Booster

Returns a new instance of Booster.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/lightgbm/booster.rb', line 7

def initialize(params: nil, train_set: nil, model_file: nil, model_str: nil)
  if model_str
    model_from_string(model_str)
  elsif model_file
    out_num_iterations = ::FFI::MemoryPointer.new(:int)
    create_handle do |handle|
      safe_call FFI.LGBM_BoosterCreateFromModelfile(model_file, out_num_iterations, handle)
    end
    @pandas_categorical = load_pandas_categorical(file_name: model_file)
    if params
      warn "[lightgbm] Ignoring params argument, using parameters from model file."
    end
    @params = loaded_param
  else
    params ||= {}
    set_verbosity(params)
    create_handle do |handle|
      safe_call FFI.LGBM_BoosterCreate(train_set.handle, params_str(params), handle)
    end
  end

  self.best_iteration = -1

  # TODO get names when loaded from file
  @name_valid_sets = []
end

Instance Attribute Details

#best_iterationObject

Returns the value of attribute best_iteration.



5
6
7
# File 'lib/lightgbm/booster.rb', line 5

def best_iteration
  @best_iteration
end

#paramsObject

Returns the value of attribute params.



5
6
7
# File 'lib/lightgbm/booster.rb', line 5

def params
  @params
end

#train_data_nameObject

Returns the value of attribute train_data_name.



5
6
7
# File 'lib/lightgbm/booster.rb', line 5

def train_data_name
  @train_data_name
end

Instance Method Details

#add_valid(data, name) ⇒ Object



34
35
36
37
38
# File 'lib/lightgbm/booster.rb', line 34

def add_valid(data, name)
  safe_call FFI.LGBM_BoosterAddValidData(@handle, data.handle)
  @name_valid_sets << name
  self # consistent with Python API
end

#current_iterationObject



40
41
42
43
44
# File 'lib/lightgbm/booster.rb', line 40

def current_iteration
  out = ::FFI::MemoryPointer.new(:int)
  safe_call FFI.LGBM_BoosterGetCurrentIteration(@handle, out)
  out.read_int
end

#dump_model(num_iteration: nil, start_iteration: 0, importance_type: "split") ⇒ Object Also known as: to_json



46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/lightgbm/booster.rb', line 46

def dump_model(num_iteration: nil, start_iteration: 0, importance_type: "split")
  num_iteration ||= best_iteration
  importance_type_int = feature_importance_type_mapper(importance_type)
  buffer_len = 1 << 20
  out_len = ::FFI::MemoryPointer.new(:int64)
  out_str = ::FFI::MemoryPointer.new(:char, buffer_len)
  safe_call FFI.LGBM_BoosterDumpModel(@handle, start_iteration, num_iteration, importance_type_int, buffer_len, out_len, out_str)
  actual_len = out_len.read_int64
  if actual_len > buffer_len
    out_str = ::FFI::MemoryPointer.new(:char, actual_len)
    safe_call FFI.LGBM_BoosterDumpModel(@handle, start_iteration, num_iteration, importance_type_int, actual_len, out_len, out_str)
  end
  out_str.read_string
end

#eval_trainObject



66
67
68
# File 'lib/lightgbm/booster.rb', line 66

def eval_train
  inner_eval(train_data_name, 0)
end

#eval_validObject



62
63
64
# File 'lib/lightgbm/booster.rb', line 62

def eval_valid
  @name_valid_sets.each_with_index.flat_map { |n, i| inner_eval(n, i + 1) }
end

#feature_importance(iteration: nil, importance_type: "split") ⇒ Object



70
71
72
73
74
75
76
77
# File 'lib/lightgbm/booster.rb', line 70

def feature_importance(iteration: nil, importance_type: "split")
  iteration ||= best_iteration
  importance_type_int = feature_importance_type_mapper(importance_type)
  num_feature = self.num_feature
  out_result = ::FFI::MemoryPointer.new(:double, num_feature)
  safe_call FFI.LGBM_BoosterFeatureImportance(@handle, iteration, importance_type_int, out_result)
  out_result.read_array_of_double(num_feature).map(&:to_i)
end

#feature_nameObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/lightgbm/booster.rb', line 79

def feature_name
  len = self.num_feature
  out_len = ::FFI::MemoryPointer.new(:size_t)
  buffer_len = 255
  out_buffer_len = ::FFI::MemoryPointer.new(:size_t)
  out_strs = ::FFI::MemoryPointer.new(:pointer, num_feature)
  str_ptrs = len.times.map { ::FFI::MemoryPointer.new(:char, buffer_len) }
  out_strs.write_array_of_pointer(str_ptrs)
  safe_call FFI.LGBM_BoosterGetFeatureNames(@handle, len, out_len, buffer_len, out_buffer_len, out_strs)

  actual_len = out_buffer_len.read(:size_t)
  if actual_len > buffer_len
    str_ptrs = len.times.map { ::FFI::MemoryPointer.new(:char, actual_len) }
    out_strs.write_array_of_pointer(str_ptrs)
    safe_call FFI.LGBM_BoosterGetFeatureNames(@handle, len, out_len, actual_len, out_buffer_len, out_strs)
  end

  str_ptrs[0, out_len.read(:size_t)].map(&:read_string)
end

#model_from_string(model_str) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/lightgbm/booster.rb', line 99

def model_from_string(model_str)
  out_num_iterations = ::FFI::MemoryPointer.new(:int)
  create_handle do |handle|
    safe_call FFI.LGBM_BoosterLoadModelFromString(model_str, out_num_iterations, handle)
  end
  @pandas_categorical = load_pandas_categorical(model_str: model_str)
  @params = loaded_param
  @cached_feature_name = nil
  self
end

#model_to_string(num_iteration: nil, start_iteration: 0, importance_type: "split") ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/lightgbm/booster.rb', line 110

def model_to_string(num_iteration: nil, start_iteration: 0, importance_type: "split")
  num_iteration ||= best_iteration
  importance_type_int = feature_importance_type_mapper(importance_type)
  buffer_len = 1 << 20
  out_len = ::FFI::MemoryPointer.new(:int64)
  out_str = ::FFI::MemoryPointer.new(:char, buffer_len)
  safe_call FFI.LGBM_BoosterSaveModelToString(@handle, start_iteration, num_iteration, importance_type_int, buffer_len, out_len, out_str)
  actual_len = out_len.read_int64
  if actual_len > buffer_len
    out_str = ::FFI::MemoryPointer.new(:char, actual_len)
    safe_call FFI.LGBM_BoosterSaveModelToString(@handle, start_iteration, num_iteration, importance_type_int, actual_len, out_len, out_str)
  end
  out_str.read_string
end

#num_featureObject Also known as: num_features



125
126
127
128
129
# File 'lib/lightgbm/booster.rb', line 125

def num_feature
  out = ::FFI::MemoryPointer.new(:int)
  safe_call FFI.LGBM_BoosterGetNumFeature(@handle, out)
  out.read_int
end

#num_model_per_iterationObject



132
133
134
135
136
# File 'lib/lightgbm/booster.rb', line 132

def num_model_per_iteration
  out = ::FFI::MemoryPointer.new(:int)
  safe_call FFI.LGBM_BoosterNumModelPerIteration(@handle, out)
  out.read_int
end

#num_treesObject



138
139
140
141
142
# File 'lib/lightgbm/booster.rb', line 138

def num_trees
  out = ::FFI::MemoryPointer.new(:int)
  safe_call FFI.LGBM_BoosterNumberOfTotalModel(@handle, out)
  out.read_int
end

#predict(data, start_iteration: 0, num_iteration: nil, raw_score: false, pred_leaf: false, pred_contrib: false, **kwargs) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/lightgbm/booster.rb', line 144

def predict(data, start_iteration: 0, num_iteration: nil, raw_score: false, pred_leaf: false, pred_contrib: false, **kwargs)
  predictor = InnerPredictor.from_booster(self, kwargs.transform_values(&:dup))
  if num_iteration.nil?
    if start_iteration <= 0
      num_iteration = best_iteration
    else
      num_iteration = -1
    end
  end
  predictor.predict(
    data,
    start_iteration: start_iteration,
    num_iteration: num_iteration,
    raw_score: raw_score,
    pred_leaf: pred_leaf,
    pred_contrib: pred_contrib
  )
end

#save_model(filename, num_iteration: nil, start_iteration: 0, importance_type: "split") ⇒ Object



163
164
165
166
167
168
# File 'lib/lightgbm/booster.rb', line 163

def save_model(filename, num_iteration: nil, start_iteration: 0, importance_type: "split")
  num_iteration ||= best_iteration
  importance_type_int = feature_importance_type_mapper(importance_type)
  safe_call FFI.LGBM_BoosterSaveModel(@handle, start_iteration, num_iteration, importance_type_int, filename)
  self # consistent with Python API
end

#updateObject



170
171
172
173
174
# File 'lib/lightgbm/booster.rb', line 170

def update
  finished = ::FFI::MemoryPointer.new(:int)
  safe_call FFI.LGBM_BoosterUpdateOneIter(@handle, finished)
  finished.read_int == 1
end