lib/eps/naive_bayes.rb in eps-0.2.0 vs lib/eps/naive_bayes.rb in eps-0.2.1

- old
+ new

@@ -1,12 +1,12 @@ module Eps class NaiveBayes < BaseEstimator attr_reader :probabilities def initialize(probabilities: nil, target: nil) - @probabilities = probabilities if probabilities - @target = target if target + @probabilities = probabilities + @target = target end def train(*args) super @@ -20,23 +20,23 @@ x = @x.dup x.each_with_index do |xi, i| xi[@target] = @y[i] end keys.each do |k| - conditional[k] = {} + conditional[k.to_s] = {} x.group_by { |xi| xi[@target] }.each do |group, xs| v = xs.map { |xi| xi[k] } if categorical?(v[0]) # TODO apply smoothing # apply smoothing only to # 1. categorical features # 2. conditional probabilities # TODO more efficient count - conditional[k][group] = group_count(v) + conditional[k.to_s][group] = group_count(v) else - conditional[k][group] = {mean: mean(v), stdev: stdev(v)} + conditional[k.to_s][group] = {mean: mean(v), stdev: stdev(v)} end end end end @@ -46,19 +46,17 @@ } end # TODO better summary def summary(extended: false) - @summary_str ||= begin - str = String.new("") - probabilities[:prior].each do |k, v| - str += "#{k}: #{v}\n" - end - str += "\n" - str += "accuracy: %d%%\n" % [(100 * accuracy).round] - str + str = String.new("") + probabilities[:prior].each do |k, v| + str += "#{k}: #{v}\n" end + str += "\n" + str += "accuracy: %d%%\n" % [(100 * accuracy).round] + str end def accuracy self.class.metrics(predict(@x), @y)[:accuracy] end @@ -184,11 +182,11 @@ private def _predict(x) x.map do |xi| - probs = calculate_class_probabilities(xi) + probs = calculate_class_probabilities(stringify_keys(xi)) # deterministic for equal probabilities probs.sort_by { |k, v| [-v, k.to_s] }[0][0] end end @@ -233,8 +231,16 @@ def stdev(arr) m = mean(arr) sum = arr.inject(0) { |accum, i| accum + (i - m)**2 } Math.sqrt(sum / (arr.length - 1).to_f) + end + + def stringify_keys(h) + o = {} + h.each do |k, v| + o[k.to_s] = v + end + o end end end