Class: EMAlgorithm::Mixture
- Inherits:
-
Model
- Object
- Model
- EMAlgorithm::Mixture
show all
- Defined in:
- lib/em_algorithm/models/mixture.rb
Constant Summary
Constants inherited
from Model
EMAlgorithm::Model::DIGIT
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods inherited from Model
#pdf, #value_distribution, #value_distribution_to_gnuplot
Constructor Details
#initialize(options) ⇒ Mixture
Returns a new instance of Mixture.
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# File 'lib/em_algorithm/models/mixture.rb', line 5
def initialize(options)
opts = {
:models =>
[
Gaussian.new(0.0, 9.0), Gaussian.new(10.0, 9.0)
],
:weights =>
[
0.5, 0.5
]
}.merge(options)
@models = opts[:models]
@weights = opts[:weights]
if !proper_weights?
argument_error
end
@temp_weights = Array.new(@models.size)
@temp_weight_per_datum = Array.new(@models.size).map { Array.new }
end
|
Instance Attribute Details
#models ⇒ Object
Returns the value of attribute models.
3
4
5
|
# File 'lib/em_algorithm/models/mixture.rb', line 3
def models
@models
end
|
#weights ⇒ Object
Returns the value of attribute weights.
3
4
5
|
# File 'lib/em_algorithm/models/mixture.rb', line 3
def weights
@weights
end
|
Instance Method Details
#add(model = Gaussian.new(0.0, 9.0), weight = 0.0) ⇒ Object
29
30
31
32
33
34
35
|
# File 'lib/em_algorithm/models/mixture.rb', line 29
def add(model = Gaussian.new(0.0, 9.0), weight = 0.0)
@models << model
@weights << weight
if !proper_weights?
argument_error
end
end
|
#argument_error ⇒ Object
25
26
27
|
# File 'lib/em_algorithm/models/mixture.rb', line 25
def argument_error
raise ArgumentError, "The summation of @weights must be equal to 1.0."
end
|
#calculate_posterior_data_array(data_array) ⇒ Object
53
54
55
56
57
58
59
60
61
|
# File 'lib/em_algorithm/models/mixture.rb', line 53
def calculate_posterior_data_array(data_array)
posterior_data_array = Array.new(data_array.size, 0.0)
@models.each_with_index do |model, mi|
data_array.each_with_index do |x, di|
posterior_data_array[di] += @weights[mi] * model.pdf(x)
end
end
posterior_data_array
end
|
#clear_temp_weight_per_datum! ⇒ Object
49
50
51
|
# File 'lib/em_algorithm/models/mixture.rb', line 49
def clear_temp_weight_per_datum!
@temp_weight_per_datum.each {|w| w.clear}
end
|
#debug_output ⇒ Object
113
114
115
116
117
118
119
120
|
# File 'lib/em_algorithm/models/mixture.rb', line 113
def debug_output
<<-DEBUG_OUT
@weights=#{@weights.inspect}
@temp_weights=#{@temp_weights.inspect}
@models
#{@models.inspect}
DEBUG_OUT
end
|
#probability_density_function(x) ⇒ Object
41
42
43
44
45
46
47
|
# File 'lib/em_algorithm/models/mixture.rb', line 41
def probability_density_function(x)
pdf = 0.0
@models.each_with_index do |model, mi|
pdf += model.pdf(x) * @weights[mi]
end
pdf
end
|
#proper_weights? ⇒ Boolean
37
38
39
|
# File 'lib/em_algorithm/models/mixture.rb', line 37
def proper_weights?
@weights.inject(0) {|sum, v| sum + v} == 1.0
end
|
#to_gnuplot(type = :full) ⇒ Object
output types :full (default) :separate_only :mixture_only
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/em_algorithm/models/mixture.rb', line 91
def to_gnuplot(type = :full)
output = []
@models.each_with_index do |model, mi|
output << "#{@weights[mi].round(DIGIT)} * #{model.to_gnuplot_with_title(@weights[mi])}"
end
separate = output.join(", ")
output = []
@models.each_with_index do |model, mi|
output << "#{@weights[mi].round(DIGIT)} * #{model.to_gnuplot}"
end
mixture = output.join(" + ")
case type
when :separate_only
return separate
when :mixture_only
return mixture
end
"#{separate}, #{mixture}"
end
|
#update_parameters!(data_array) ⇒ Object
80
81
82
83
84
85
|
# File 'lib/em_algorithm/models/mixture.rb', line 80
def update_parameters!(data_array)
@models.each_with_index do |model, mi|
model.update_parameters!(data_array, @temp_weights[mi], @temp_weight_per_datum[mi])
end
update_weights!(data_array)
end
|
#update_temp_weights!(data_array, posterior_data_array) ⇒ Object
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/em_algorithm/models/mixture.rb', line 63
def update_temp_weights!(data_array, posterior_data_array)
@models.each_with_index do |model, mi|
data_array.each_with_index do |x, di|
temp_weight_per_datum = @weights[mi] * model.pdf(x) / posterior_data_array[di]
temp_weight_per_datum = 0.0 if temp_weight_per_datum.nan?
@temp_weight_per_datum[mi] << temp_weight_per_datum
end
@temp_weights[mi] = @temp_weight_per_datum[mi].inject(0.0) {|sum, w| sum + w}
end
end
|
#update_weights!(data_array) ⇒ Object
74
75
76
77
78
|
# File 'lib/em_algorithm/models/mixture.rb', line 74
def update_weights!(data_array)
(0..(@models.size-1)).each do |mi|
@weights[mi] = @temp_weights[mi] / data_array.size
end
end
|