概率代码问题

6
当我将isWinDefault替换为isWinConfidence时,结果差异很大。我觉得它们应该是相同的。我的代码有bug还是我误解了统计学的某些属性?
这个测试旨在模拟抛一次硬币与多次抛硬币的情况。
问题是:
如果P(x)为70%,那么p(x)*100是否应该在70%的时间内大于或等于70?
谢谢。
    private void TestWin()
    {
        double headsUp = 0;
        double testRuns = 100;
        for (double i = 0; i < testRuns; i++)
        {
            if (IsWinConfidence())
            {
                headsUp++;
            }

        }
        label1.Text = "Probability of Heads is " + headsUp /testRuns;

    }

    private bool IsWinDefault()
    {
        if (r.NextDouble() <= .7)
        {
            return true;
        }
        return false;
    }

    private bool IsWinConfidence()
    {
        int headsCount = 0;
        for (double x = 0; x < 100; x++)
        {
            if (IsWinDefault())
                headsCount++;

        }

        double pHeadsCount = headsCount / 100d;
        if (pHeadsCount >= .7 )
        {
            return true;
        }
        else
        {
            return false;
        }


    }

你在问题中没有定义 r(例如 r.NextDouble())是什么。 - devuxer
@DanM 这只是 C# 中的随机数。Random r = new Random(); - Curtis White
+1 对于这个问题,它实际上比看起来更有趣(对我来说是的:-)),就我所知,你的代码没有错误。 - Steve
6个回答

2
这里是简单的答案:
70%的概率意味着,平均来说,100次抛硬币会有70次正面朝上。但有时可能会高于70次或低于70次。
换句话说,每批100次抛硬币,正面朝上的次数将接近70次。有时少于70次,有时多于70次,有时恰好70次。
因此,如果数字在70附近波动,那么如果你问“它会有多少次超过70次或等于70次”,你会得到一个答案,即“大约50%的时间”。
所以你的代码中并没有提出正确的问题。
实际上,将IsWinConfidence中的循环次数增加到更高的数字会给出接近50的数字。
让我们分析一下你的论点。
你说如果你有:
一个有偏差的硬币,70%的时间正面朝上,30%的时间反面朝上
然后你说:
如果我抛100次硬币,我应该得到70个以上的正面朝上
这两个论点之间存在缺陷。概率不是关于保证的,而是关于平均数的。
如果概率是绝对的,你的第二个论点应该是:
如果我抛100次硬币,我应该得到70个正面朝上
注意这里没有“以上”的含义。
相反,第一个论点的意思是:
如果我抛100次硬币,然后再抛100次,再抛100次,以此类推,那么每100次抛硬币平均会有70次正面朝上。
现在,我不了解概率计算的足够多,无法分析你的循环和计数,但我知道只是按照逻辑来看,你的论点是错误的。
让我们尝试另一种方法。
如果硬币是均匀的,虽然有偏差,这意味着在100次抛硬币中,有时会得到超过70次或低于70次。
在我天真的想法中,这意味着... 平均而言,你只会在半数时间内得到超过70次的硬币朝上。
通过增加你的循环次数到10万次,我得到的置信函数接近50。这似乎支持了我的理论。
但正如我所说,我对概率的了解程度少于零。

这个解释写得非常好,点赞!可能考虑在最后加上一个结论来完成答案。比如说,将 (pHeadsCount >= .7) 改为 (pHeadsCount >= .5),并将 N 增加到 10000 就可以解决你的问题。 - bastijn
这很不错。提到各种分布也会增加一些内容,例如二项式、正态分布等等。还有关于随着更多的运行次数赔率减少的一些说明,例如从100到1000次,它变得更接近50%。我可能会在统计溢出上询问这个问题,以便更好地掌握它。 - Curtis White
好的,请再次完整地阅读我回答中的最后一句话 :) - Lasse V. Karlsen

1
如果 P(x) 是70%,那么 P(x)*100 就应该 >= 70,在70%的时间内,对吗?
不对。置信度不能以这种方式与概率相关联...
在第二个方法中所做的是抛掷一枚有偏差的硬币100次,并在获得70个或更多正面朝上的情况下返回true。由于你已经固定了硬币使其平均70%的时间给你正面朝上,因此你预计会在100次投掷中“有时”得到70个正面朝上的情况,但“有时”并不是70%的时间。

1

IsWinDefault“胜利”的概率为70%,正如预期的那样; IsWinConfidence“胜利”的概率约为53.77%,因此您应该看到接近这个数字的数字。 有关更多信息,请参见二项分布


1
是的,如果总数增加,这将往往趋向于50%。 - Loïc Février

0

更新:

第一个函数返回 true 的概率为 70%,因此 headsCount 将等于 ~70,非常有可能是这个数字(如果将 100 替换为更大的数字,则 tend to be 该数字的 70%)。

因此,

pHeadsCount >= .7

有50%的概率,该值将为~0.7。


@Loic 我正在尝试模拟多次投掷不公平的硬币与一次投掷的情况。在100次投掷中,我们应该至少获得70次胜利,对吧?我的意思是,如果我们获得了至少70次胜利或更多,我就算作是赢了。 - Curtis White
@Loic,请看,我正在运行第二个循环100次。我应该得到70%,如果我得到70%或更高的分数,我会称之为胜利,这样做有意义吗? - Curtis White
@Curtis White:确实。我读得太快了。你得到了什么不同的结果?这两个概率是什么?(也尝试使用10,000而不是100,并给出该结果) - Loïc Février
@Loic 当我使用默认值时,得分为70%,而当我使用替换值时,得分为55%。 ;( 随着我们向无限接近,p(x)应该逐渐接近p(x)。我非常困惑。 - Curtis White
您同意pHeadsCount将为~0.7吗?如果它的概率相等地更多或更少于0.7,那么它基本上是围绕着0.7的“噪音”。 - Loïc Février
显示剩余2条评论

0

如果 (r.NextDouble() <= .7)

对比

如果 (pHeadsCount >= .7 )


0

概率是一个计数问题。计算每个类别类型(0代表正面,1代表反面)的出现次数,然后除以总数。赔率是概率的函数。赔率告诉你在抛硬币时正面或反面的可能性。

from collections import Counter

flips=10000

data=[]
for i in range(flips):
    data.append(random.choice([0,1]))

dictProbability={}
for key,value in Counter(data).items():
    dictProbability[key]=value/flips

print(dictProbability)

输出:

{0: 0.5014, 1: 0.4986}
 .5 probability of heads
 .49 probability of tails

一个伯努利二项式分布

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接