lib/eps/base_regressor.rb in eps-0.1.0 vs lib/eps/base_regressor.rb in eps-0.1.1
- old
+ new
@@ -22,10 +22,26 @@
pred = matrix_arr(x * c)
singular ? pred[0] : pred
end
+ def evaluate(data, y = nil, target: nil)
+ raise ArgumentError, "missing target" if !target && !y
+
+ actual = y
+ actual ||=
+ if daru?(data)
+ data[target].to_a
+ else
+ data.map { |v| v[target] }
+ end
+
+ actual = prep_y(actual)
+ estimated = predict(data)
+ Eps.metrics(actual, estimated)
+ end
+
# ruby
def self.load(data)
BaseRegressor.new(Hash[data.map { |k, v| [k.to_sym, v] }])
end
@@ -54,11 +70,15 @@
end
# pmml
def self.load_pmml(data)
- data = Nokogiri::XML(data) if data.is_a?(String)
+ if data.is_a?(String)
+ require "nokogiri"
+ data = Nokogiri::XML(data)
+ end
+
# TODO more validation
node = data.css("RegressionTable")
coefficients = {
_intercept: node.attribute("intercept").value.to_f
}
@@ -92,11 +112,11 @@
coefficients[name] = c
end
BaseRegressor.new(coefficients: coefficients)
end
- private
+ protected
def daru?(x)
defined?(Daru) && x.is_a?(Daru::DataFrame)
end
@@ -130,10 +150,14 @@
x.each do |xi|
row = {}
xi.each do |k, v|
key = v.is_a?(String) ? [k.to_sym, v] : k.to_sym
v2 = v.is_a?(String) ? 1 : v
+
+ # TODO make more efficient
+ next if !train && !coefficients.key?(symbolize_coef(key))
+
raise "Missing data" if v2.nil?
unless cache[key]
cache[key] = i
first_key[k] ||= key if v.is_a?(String)
@@ -165,19 +189,44 @@
end
ret2 << ([1] + ret)
end
# flatten keys
- c = [:_intercept] + cache.sort_by { |_, v| v }.map { |k, _| (k.is_a?(Array) ? k.join("") : k).to_sym }
+ c = [:_intercept] + cache.sort_by { |_, v| v }.map { |k, _| symbolize_coef(k) }
if c.size != c.uniq.size
raise "Overlapping coefficients"
end
[ret2, c]
end
+ def symbolize_coef(k)
+ (k.is_a?(Array) ? k.join("") : k).to_sym
+ end
+
def matrix_arr(matrix)
matrix.to_a.map { |xi| xi[0].to_f }
+ end
+
+ # determine if target is a string or symbol
+ def prep_target(target, data)
+ if daru?(data)
+ data.has_vector?(target) ? target : flip_target(target)
+ else
+ x = data[0] || {}
+ x[target] ? target : flip_target(target)
+ end
+ end
+
+ def flip_target(target)
+ target.is_a?(String) ? target.to_sym : target.to_s
+ end
+
+ def prep_y(y)
+ y.each do |yi|
+ raise "Target missing in data" if yi.nil?
+ end
+ y.map(&:to_f)
end
end
end