Rubythinking: Chapter 2, Excercise M2


Like in the previous notebook for 2M1, we have the following globe tossing results:

We want to estimate the probability of Water $p$ as parameter of the model. The parameter is at least 0 and at most 1.

The key point for this exercise is that we employ a different prior: $$ \text{prior}(p) = \begin{cases} 0, & \text{if}\ p < 0.5 \\ 1, & \text{otherwise} \end{cases} $$

    
      
        grid_size = 100
        step_size = 1.0 / grid_size.to_f
        grid = 0.step(by: step_size, to: 1).to_a

        prior = grid.map do |x|
          y =
            if x < 0.5
              0
            else
              1
            end

          [x, y]
        end.to_h

        chart = LazyHighCharts::HighChart.new('graph') do |f|
          f.title(text: "Priors")
          f.plotOptions(series: {marker: {enabled: false}})
          f.yAxis(min: 0, max: 0.10)
          f.series(name: "Prior probability of parameter value", yAxis: 0, data: prior.values)
          f.chart({defaultSeriesType: "area"})
        end

        = high_chart("2m2-1", chart)
      
    
  
    
      
        factorial = ->(n) do
          return 1 if n < 1
          n.to_i.downto(1).inject(:*)
        end

        likelihood = ->(w, l, p) do
          (factorial[w+l].to_f / (factorial[w] * factorial[l])).to_f * (p**w) * ((1-p)**l)
        end
      
    
  

Now, let's compute the grid aprroximation of the posterior for each of the cases. The difference is only the data input we give in terms of "count of Water" versus "count of Land" of our tossing result given in the exercise.

    
      
        # For case (1)
        w = 3
        l = 0

        posterior = ->(w, l) do
          unstandardized_posterior = grid.each_with_object({}) do |x, hash|
            hash[x] = prior[x] * likelihood[w, l, x]
          end

          unstandardized_posterior.map do |x, y|
            standardized = (y.to_f / unstandardized_posterior.values.sum.to_f).round(6)
            [x, standardized]
          end.to_h
        end

        chart = LazyHighCharts::HighChart.new('graph') do |f|
          f.title(text: "Posterior Distribution")
          f.plotOptions(series: {marker: {enabled: false}})
          f.yAxis(min: 0, max: 0.10)
          f.series(name: "Posterior probability of parameter value", yAxis: 0, data: posterior[w, l].values)
          f.chart({defaultSeriesType: "area"})
        end

        = high_chart("2m2-2", chart)

      
    
  
    
      
        # For case (2)
        w = 3
        l = 1
      
    
  
    
      
        # For case (3)
        w = 5
        l = 2