Class: EMAlgorithm::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/em_algorithm/base.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Base

  • Model limitation

currently only Gaussian Mixture model is supported. if you want to use simple Gaussian, you must use a mixture model which has only one Gaussian model entry with weight 1.0.

  • Input data format

You can estimate the probability distribution and the target value distribution. If you want to estimate the target value distribution, you must specify the target value and its correspondence area size into the input vector x. x: target value x: correspondent area size



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/em_algorithm/base.rb', line 30

def initialize(options)
  opts = {
    :model => Mixture.new(:models => [Gaussian.new(0.0, 9.0)], :weights => [1.0]),
    :data_array => [],
    :value_distribution_estimation => false,
    :debug => true
  }.merge(options)
  @model = opts[:model]
  @original_data_array = opts[:data_array]
  @value_distribution_estimation = opts[:value_distribution_estimation]
  if @value_distribution_estimation
    @data_array = value_to_frequency(@original_data_array)
  else
    @data_array = @original_data_array
  end
  @likelihood = Likelihood.new(@data_array)
  @debug = opts[:debug]
  @const = 1.0
end

Instance Attribute Details

#constObject

Returns the value of attribute const.



17
18
19
# File 'lib/em_algorithm/base.rb', line 17

def const
  @const
end

#data_arrayObject

Returns the value of attribute data_array.



17
18
19
# File 'lib/em_algorithm/base.rb', line 17

def data_array
  @data_array
end

#likelihoodObject

Returns the value of attribute likelihood.



17
18
19
# File 'lib/em_algorithm/base.rb', line 17

def likelihood
  @likelihood
end

#modelObject

Returns the value of attribute model.



17
18
19
# File 'lib/em_algorithm/base.rb', line 17

def model
  @model
end

#num_stepObject

Returns the value of attribute num_step.



17
18
19
# File 'lib/em_algorithm/base.rb', line 17

def num_step
  @num_step
end

#original_data_arrayObject

Returns the value of attribute original_data_array.



17
18
19
# File 'lib/em_algorithm/base.rb', line 17

def original_data_array
  @original_data_array
end

Instance Method Details

#distribution_to_value_ratioObject

the integration of the distribution equal 1.0 so thus, the integration of the target value means the ratio of probability distribution and the target value distribution



107
108
109
110
111
112
113
114
# File 'lib/em_algorithm/base.rb', line 107

def distribution_to_value_ratio
  integrated_value = 0.0
  @original_data_array.each do |x|
    value = x[x.size-2]
    integrated_value += value * x[x.size-1]
  end
  integrated_value
end

#estepObject

calculate @posterior_data_array



51
52
53
54
55
# File 'lib/em_algorithm/base.rb', line 51

def estep
  @model.clear_temp_weight_per_datum!
  @posterior_data_array = @model.calculate_posterior_data_array(@data_array)
  @model.update_temp_weights!(@data_array, @posterior_data_array)
end

#mstepObject

calculate posterior model parameters



58
59
60
61
62
63
# File 'lib/em_algorithm/base.rb', line 58

def mstep
  if @debug
    $stderr.puts @model.inspect
  end
  @model.update_parameters!(@data_array)
end

#run!Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/em_algorithm/base.rb', line 65

def run!
  MAX_ITERATION.times do |i|
    if @debug
      $stderr.puts "step#{i}"
    end
    # check convergence
    @likelihood.calculate(@model)
    if @debug
      $stderr.puts @likelihood.debug_output
    end
    if @likelihood.converged?
      @num_step = i
      if @value_distribution_estimation
        @const = distribution_to_value_ratio
      end
      break
    end
    if @debug
      $stderr.puts @model.debug_output
      $stderr.puts ""
    end
    estep
    mstep
  end
  @model
end

#value_to_frequency(data_array) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
# File 'lib/em_algorithm/base.rb', line 92

def value_to_frequency(data_array)
  modified_data_array = []
  data_array.each do |x|
    x[x.size-2].round.times do
      x_without_value = x[0..(x.size-3)]
      x_without_value = x_without_value.first if x_without_value.size == 1
      modified_data_array << x_without_value
    end
  end
  modified_data_array
end