class Probably::Distribution
The Discrete Distribution
representation class
Public Class Methods
Creates a new Discrete Distribution
with said constructor type (init_type) and initial data upon construction the data are automatically normalized if init_type is:
-
:MAP then the given map use used directly and should not
be used anymore by someone else but the current distribution class
-
:MAPCOPY then the given map is copied for further use
-
:LISTS then the second parameter is the list of keys and the
third parameter the corresponding list of probabilities
# File lib/prob.rb, line 68 def initialize(init_type, *data) case init_type when :MAP @map = data[0] when :MAPCOPY init_map(data[0]) when :LISTS init_lsts(data[0], data[1]) else raise "unable to create probability distribution" end self.normalize_probabilities end
Public Instance Methods
# File lib/prob.rb, line 202 def * (other) self.mult other end
# File lib/prob.rb, line 241 def adjust_min(new_min = 0.01) tmp = Hash.new(0) self.each do |prob, value| tmp[value] = if prob > new_min then prob else new_min end end self.class.new :MAP, tmp end
# File lib/prob.rb, line 167 def dep self.class.new :MAP, block1(Hash.new(0)) {|m| @map.each do |key, p1| tmp = yield key if tmp != nil tmp.each do |p2, value| m[value] += p1 * p2 end else m[nil] += p1 end end } end
# File lib/prob.rb, line 234 def distance(other) (self.keys | other.keys).reduce(0) {|sum, value| tmp = self.probability(value) - other.probability(value) sum + tmp * tmp } end
# File lib/prob.rb, line 125 def each @map.each { |value, prob| yield prob, value } end
# File lib/prob.rb, line 182 def event_dep(pred) self.dep {|value| if !pred.call value nil else yield value end } end
computes expectation given that keys in distribution are numeric
# File lib/prob.rb, line 208 def expectation @map.reduce(0) {|sum, (value, p)| sum + value.to_f * p } end
# File lib/prob.rb, line 137 def filter self.class.new :MAP, @map.reject { |value,prob| !(yield value) } end
# File lib/prob.rb, line 156 def join tmp = Hash.new(0) @map.each do |dist, p1| dist.each do |p2, value| tmp[value] += p1 * p2 end end self.class.new(:MAP, tmp) end
set of keys in distribution
# File lib/prob.rb, line 83 def keys @map.keys end
# File lib/prob.rb, line 129 def map tmp = Hash.new(0) @map.each do |value, prob| tmp[yield(value)] += prob end self.class.new(:MAP, tmp) end
use most_probable
to retrieve most probable event and its probability from given distribution
# File lib/prob.rb, line 107 def most_probable @map.reduce { |best, value| if best[1] < value[1] then value else best end } end
# File lib/prob.rb, line 192 def mult(dist2) self.dep do |k| if block_given? dist2.map { |k2| yield(k, k2) } else dist2.map { |k2| [k, k2] } end end end
returns normalized distribution removing all nil values. In combination with condition, normalize must be used to compute normalization of bayes theorem
# File lib/prob.rb, line 91 def normalize if @map[nil] > 0.0 self.filter { |value| value != nil } else self end end
randomly pick a key-value with respect to its probability in given distribution
# File lib/prob.rb, line 115 def pick tst = rand sum = 0 @map.each do |value, prob| sum += prob return value,prob if tst < sum end return nil end
returns probability of event val from distribution
# File lib/prob.rb, line 101 def probability(val) @map[val] end
# File lib/prob.rb, line 149 def query? @map.reduce(0) {|probability, (dat,dp)| if yield dat then probability + dp else probability end } end
# File lib/prob.rb, line 143 def reject self.class.new :MAP, @map.reject { |value, prob| yield value } end
computes standard deviation given that keys in distribution are numeric
# File lib/prob.rb, line 224 def std_dev Math.sqrt( self.variance ) end
# File lib/prob.rb, line 228 def to_s @map.reduce("") { |str,(value, prob)| str + "#{value} : #{prob * 100} %\n" } end
computes variance given that keys in distribution are numeric
# File lib/prob.rb, line 214 def variance expected = self.expectation @map.reduce(0) {|sum, (value,p)| tmp = (value.to_f - expectation) sum + tmp * tmp * p } end
Protected Instance Methods
# File lib/prob.rb, line 37 def init_lsts(data, shape) @map = Hash.new(0) count = data.length data.each_with_index { |value, index| @map[value] += shape.call( Float(index + 1) / count ) } end
# File lib/prob.rb, line 45 def init_map(map) @map = Hash.new(0) map.each { |value, prob| @map[value] = prob } self.normalize_probabilities end
# File lib/prob.rb, line 51 def normalize_probabilities sum = Float( @map.values.inject(:+) ) @map.keys.each { |value| @map[value] /= sum } if sum != 1.0 end