计算表达式解析为True的预期概率

时间:2014-01-12 20:20:33

标签: ruby probability

假设我有一个模拟掷硬币的简单程序,其中给定的概率由表达式指定。它可能看起来像这样:

# This is the probability that you will get heads.
$expr = "rand < 0.5"

def get_result(expr)
   eval(expr)
end

def toss_coin
  if get_result($expr)
     return "Head"
  else
     return "Tail"
  end
end

现在,我还想告诉用户获取Head的概率是多少。

对于给定的表达式

"rand < 0.5"

我们可以对它进行调整并说概率是50%,因为rand返回0到1之间的数字,因此表达式平均评估为50%的真实时间。

然而,如果我决定提供一个装配硬币投掷,其中用于确定结果的表达式

"rand < 0.3"

现在,我有30%的机会获得Head

是否有可能编写一个采用任意表达式的方法(计算结果为布尔值!)并将其解析为true的概率返回?

def get_expected_probability(expr)
  # Returns the probability the `expr` returns true
  #    `rand < 0.5` would return 0.5
  #    `rand < 0.3` would return 0.3
  #    `true` would return 1
  #    `false` would return 0
end

3 个答案:

答案 0 :(得分:1)

我的猜测将是理论上可以编写这样的方法,假设您将自己局限于rand和确定性数学函数并且完全了解系统浮点实现等等。

然而,通过大量执行表达式并跟踪成功的百分比来近似概率将会更加直截了当。

答案 1 :(得分:1)

对于统一随机数的简单比较,是的,但一般来说,没有。它取决于您用来确定布尔值的表达式的分布,并且您可以使用奇怪的分布编写任意复杂的表达式。但是,根据经验估计概率非常简单。

基于表达式创建伯努利(0/1)结果,当表达式为真时产生1,当为假时产生0。生成大量(n)个。伯努利结果的长期平均值将收敛于获得真实的概率。如果你调用那个p-hat并且真值是p,那么p-hat应该在95%的时间内落在p +/- (1.96 * sqrt(p*(1-p)/n))范围内。从中可以看出,样本量n越大,估计值就越精确。

答案 2 :(得分:1)

一种非常缓慢的近似方法是对表达式进行非常多次的估计并估计它收敛的概率。 Law of Large Numbers保证当n接近无穷大时,就是那个概率。

$expr = "rand < 0.5"

def get_result(expr)
  eval(expr)
end

n = 1000000
a = Array.new(n)

n.times do |i|
  a[i] = eval($expr)
end

puts a.count(true)/n.to_f

为我退回0.499899