Class: Eps::BaseRegressor

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

Direct Known Subclasses

Regressor

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(coefficients:) ⇒ BaseRegressor

Returns a new instance of BaseRegressor.



5
6
7
# File 'lib/eps/base_regressor.rb', line 5

def initialize(coefficients:)
  @coefficients = Hash[coefficients.map { |k, v| [k.to_sym, v] }]
end

Instance Attribute Details

#coefficientsObject (readonly)

Returns the value of attribute coefficients.



3
4
5
# File 'lib/eps/base_regressor.rb', line 3

def coefficients
  @coefficients
end

Class Method Details

.load(data) ⇒ Object

ruby



29
30
31
# File 'lib/eps/base_regressor.rb', line 29

def self.load(data)
  BaseRegressor.new(Hash[data.map { |k, v| [k.to_sym, v] }])
end

.load_json(data) ⇒ Object

json



39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/eps/base_regressor.rb', line 39

def self.load_json(data)
  data = JSON.parse(data) if data.is_a?(String)
  coefficients = data["coefficients"]

  # for R models
  if coefficients["(Intercept)"]
    coefficients = coefficients.dup
    coefficients["_intercept"] = coefficients.delete("(Intercept)")
  end

  BaseRegressor.new(coefficients: coefficients)
end

.load_pfa(data) ⇒ Object

pfa



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/eps/base_regressor.rb', line 76

def self.load_pfa(data)
  data = JSON.parse(data) if data.is_a?(String)
  init = data["cells"].first[1]["init"]
  names =
    if data["input"]["fields"]
      data["input"]["fields"].map { |f| f["name"] }
    else
      init["coeff"].map.with_index { |_, i| "x#{i}" }
    end
  coefficients = {
    _intercept: init["const"]
  }
  init["coeff"].each_with_index do |c, i|
    name = names[i]
    # R can export coefficients with same name
    raise "Coefficients with same name" if coefficients[name]
    coefficients[name] = c
  end
  BaseRegressor.new(coefficients: coefficients)
end

.load_pmml(data) ⇒ Object

pmml



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/eps/base_regressor.rb', line 58

def self.load_pmml(data)
  data = Nokogiri::XML(data) if data.is_a?(String)
  # TODO more validation
  node = data.css("RegressionTable")
  coefficients = {
    _intercept: node.attribute("intercept").value.to_f
  }
  node.css("NumericPredictor").each do |n|
    coefficients[n.attribute("name").value] = n.attribute("coefficient").value.to_f
  end
  node.css("CategoricalPredictor").each do |n|
    coefficients["#{n.attribute("name").value}#{n.attribute("value").value}"] = n.attribute("coefficient").value.to_f
  end
  BaseRegressor.new(coefficients: coefficients)
end

Instance Method Details

#dumpObject



33
34
35
# File 'lib/eps/base_regressor.rb', line 33

def dump
  {coefficients: coefficients}
end

#predict(x) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/eps/base_regressor.rb', line 9

def predict(x)
  singular = !(x.is_a?(Array) || daru?(x))
  x = [x] if singular
  x, c = prep_x(x, train: false)
  coef = c.map do |v|
    # use 0 if coefficient does not exist
    # this can happen for categorical features
    # since only n-1 coefficients are stored
    coefficients[v] || 0
  end

  x = Matrix.rows(x)
  c = Matrix.column_vector(coef)
  pred = matrix_arr(x * c)

  singular ? pred[0] : pred
end

#to_jsonObject



52
53
54
# File 'lib/eps/base_regressor.rb', line 52

def to_json
  JSON.generate(dump)
end