Class: Xgb::Booster

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Booster.



5
6
7
8
9
10
11
12
13
14
# File 'lib/xgb/booster.rb', line 5

def initialize(params: nil, model_file: nil)
  @handle = ::FFI::MemoryPointer.new(:pointer)
  check_result FFI.XGBoosterCreate(nil, 0, @handle)
  if model_file
    check_result FFI.XGBoosterLoadModel(handle_pointer, model_file)
  end

  self.best_iteration = 0
  set_param(params)
end

Instance Attribute Details

#best_iterationObject

Returns the value of attribute best_iteration.



3
4
5
# File 'lib/xgb/booster.rb', line 3

def best_iteration
  @best_iteration
end

#feature_namesObject

Returns the value of attribute feature_names.



3
4
5
# File 'lib/xgb/booster.rb', line 3

def feature_names
  @feature_names
end

Instance Method Details

#dump(fmap: "", with_stats: false, dump_format: "text") ⇒ Object

returns an array of strings



60
61
62
63
64
65
# File 'lib/xgb/booster.rb', line 60

def dump(fmap: "", with_stats: false, dump_format: "text")
  out_len = ::FFI::MemoryPointer.new(:ulong)
  out_result = ::FFI::MemoryPointer.new(:pointer)
  check_result FFI.XGBoosterDumpModelEx(handle_pointer, fmap, with_stats ? 1 : 0, dump_format, out_len, out_result)
  out_result.read_pointer.get_array_of_string(0, out_len.read_ulong)
end

#dump_model(fout, fmap: "", with_stats: false, dump_format: "text") ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/xgb/booster.rb', line 67

def dump_model(fout, fmap: "", with_stats: false, dump_format: "text")
  ret = dump(fmap: fmap, with_stats: with_stats, dump_format: dump_format)
  File.open(fout, "wb") do |f|
    if dump_format == "json"
      f.print("[\n")
      ret.each_with_index do |r, i|
        f.print(r)
        f.print(",\n") if i < ret.size - 1
      end
      f.print("\n]")
    else
      ret.each_with_index do |r, i|
        f.print("booster[#{i}]:\n")
        f.print(r)
      end
    end
  end
end

#eval_set(evals, iteration) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/xgb/booster.rb', line 20

def eval_set(evals, iteration)
  dmats = ::FFI::MemoryPointer.new(:pointer, evals.size)
  dmats.write_array_of_pointer(evals.map { |v| v[0].handle_pointer })

  evnames = ::FFI::MemoryPointer.new(:pointer, evals.size)
  evnames.write_array_of_pointer(evals.map { |v| ::FFI::MemoryPointer.from_string(v[1]) })

  out_result = ::FFI::MemoryPointer.new(:pointer)

  check_result FFI.XGBoosterEvalOneIter(handle_pointer, iteration, dmats, evnames, evals.size, out_result)

  out_result.read_pointer.read_string
end

#fscore(fmap: "") ⇒ Object



86
87
88
89
# File 'lib/xgb/booster.rb', line 86

def fscore(fmap: "")
  # always weight
  score(fmap: fmap, importance_type: "weight")
end

#predict(data, ntree_limit: nil) ⇒ Object



44
45
46
47
48
49
50
51
52
53
# File 'lib/xgb/booster.rb', line 44

def predict(data, ntree_limit: nil)
  ntree_limit ||= 0
  out_len = ::FFI::MemoryPointer.new(:ulong)
  out_result = ::FFI::MemoryPointer.new(:pointer)
  check_result FFI.XGBoosterPredict(handle_pointer, data.handle_pointer, 0, ntree_limit, out_len, out_result)
  out = out_result.read_pointer.read_array_of_float(out_len.read_ulong)
  num_class = out.size / data.num_row
  out = out.each_slice(num_class).to_a if num_class > 1
  out
end

#save_model(fname) ⇒ Object



55
56
57
# File 'lib/xgb/booster.rb', line 55

def save_model(fname)
  check_result FFI.XGBoosterSaveModel(handle_pointer, fname)
end

#score(fmap: "", importance_type: "weight") ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/xgb/booster.rb', line 91

def score(fmap: "", importance_type: "weight")
  if importance_type == "weight"
    trees = dump(fmap: fmap, with_stats: false)
    fmap = {}
    trees.each do |tree|
      tree.split("\n").each do |line|
        arr = line.split("[")
        next if arr.size == 1

        fid = arr[1].split("]")[0].split("<")[0]
        fmap[fid] ||= 0
        fmap[fid] += 1
      end
    end
    fmap
  else
    average_over_splits = true
    if importance_type == "total_gain"
      importance_type = "gain"
      average_over_splits = false
    elsif importance_type == "total_cover"
      importance_type = "cover"
      average_over_splits = false
    end

    trees = dump(fmap: fmap, with_stats: true)

    importance_type += "="
    fmap = {}
    gmap = {}
    trees.each do |tree|
      tree.split("\n").each do |line|
        arr = line.split("[")
        next if arr.size == 1

        fid = arr[1].split("]")

        g = fid[1].split(importance_type)[1].split(",")[0].to_f

        fid = fid[0].split("<")[0]

        fmap[fid] ||= 0
        gmap[fid] ||= 0

        fmap[fid] += 1
        gmap[fid] += g
      end
    end

    if average_over_splits
      gmap.each_key do |fid|
        gmap[fid] = gmap[fid] / fmap[fid]
      end
    end

    gmap
  end
end

#set_param(params, value = nil) ⇒ Object



34
35
36
37
38
39
40
41
42
# File 'lib/xgb/booster.rb', line 34

def set_param(params, value = nil)
  if params.is_a?(Enumerable)
    params.each do |k, v|
      check_result FFI.XGBoosterSetParam(handle_pointer, k.to_s, v.to_s)
    end
  else
    check_result FFI.XGBoosterSetParam(handle_pointer, params.to_s, value.to_s)
  end
end

#update(dtrain, iteration) ⇒ Object



16
17
18
# File 'lib/xgb/booster.rb', line 16

def update(dtrain, iteration)
  check_result FFI.XGBoosterUpdateOneIter(handle_pointer, iteration, dtrain.handle_pointer)
end