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