class MachineLearner::BayesLearner

ナイブベイズ学習器

Public Class Methods

new() click to toggle source

コンストラクタ

# File lib/machine_learner/bayes.rb, line 12
def initialize
end

Public Instance Methods

classify(xs) click to toggle source

識別を行う @param x 特徴空間 @return [Fixnum] 識別結果

# File lib/machine_learner/bayes.rb, line 33
def classify(xs)
  # 最も尤度の高い候補 y を探す
  classify_raw(xs).max{ |x, y| x[1] <=> y[1] }[0]
end
classify_raw(xs) click to toggle source
# File lib/machine_learner/bayes.rb, line 38
def classify_raw(xs)
  candidate_y.map{|y| [y, p_y_x(y, xs)]}.to_h
end
learn(datas, ds = nil) click to toggle source

データを元に学習を行う @param datas [Array<DataSet>] トレーニングデータの配列 @return [Array<Boolean>] 識別結果の配列

# File lib/machine_learner/bayes.rb, line 18
def learn(datas, ds = nil)
  # 学習データ
  @training = datas

  # 学習データがHashか
  @hash_mode = @training[0].x.kind_of?(Hash)

  # 学習データの結果のリスト
  @ys = @training.map{|data| data.y }
  @candidate_x = @hash_mode ? {} : []
end

Private Instance Methods

candidate_x(field) click to toggle source

xの候補を列挙

# File lib/machine_learner/bayes.rb, line 74
def candidate_x(field)
  @candidate_x[field] ||= @training.map{|data| data.x[field]}.uniq.compact
end
candidate_y() click to toggle source

yの候補を列挙

# File lib/machine_learner/bayes.rb, line 79
def candidate_y
  @candidate_y ||= @ys.uniq.compact
end
p_xi_y(x, i, y) click to toggle source

P(Xi | Y) を計算

# File lib/machine_learner/bayes.rb, line 57
def p_xi_y(x, i, y)
  total = count = 0
  @ys.each_with_index do |ysj, j|
    next if ysj != y
    total += 1
    count += 1 if @training[j].x[i] == x
  end
  return (count + 1).to_f / (total + candidate_x(i).size + 1).to_f
end
p_y(y) click to toggle source

P(Y) を計算

# File lib/machine_learner/bayes.rb, line 68
def p_y(y)
  count = @ys.count(y)
  return (count + 1).to_f / (@ys.size + candidate_y.size + 1).to_f
end
p_y_x(y, xs) click to toggle source

P(Y | X) を計算

# File lib/machine_learner/bayes.rb, line 45
def p_y_x(y, xs)
  # P(Y | X) =  P(Y) * product(P(Xi | Y))
  p = Math.log(p_y(y))
  xs.each_with_index do |xi, i|
    i, xi = xi if @hash_mode
    next if xi.nil?
    p += Math.log(p_xi_y(xi, i, y))
  end
  return Math.exp(p)
end