python - 如何在Python中计算非常小的数字的二项式概率?

标签 python scipy

我正在尝试计算在 Python 中成功猜测密码的可能性。例如,如果我们采用 10 个字符的小写密码(26**10 个可能的密码),并且每秒可以猜测 10 亿次,我们可以计算一小时内成功猜出密码的概率:

from scipy.stats import binom
(1 - binom.pmf(k=0, n=1000000000*3600, p=1 / 26**10))

这给我们的结果是0.02525515384826793(即2.5%)。但是,当我们增加密码长度时(或更严格地说,当 p 接近于零时),这不起作用。例如,如果我们将密码长度增加到 12 个字符:

from scipy.stats import binom
(1 - binom.pmf(k=0, n=1000000000*3600, p=1 / 26**12))

那么返回的值只是 0.0,这是不正确的 - 可能是由于 float 在某个时刻向下舍入为零。我如何计算以获得更准确的答案?


编辑:这是使用 SciPy 1.10.1 的。对最新版本(撰写本文时为 1.11.2)的测试给出了正确的值 - 因此看起来这是旧版本的问题。

最佳答案

我认为这是关于浮点运算的局限性,我也经常遇到这种局限性(即浮点溢出)。

您可以使用 mpmath 库,它提供任意精度算术:

from mpmath import mp
mp.dps = 50  # Set the desired precision (adjust as needed)
total_passwords = 26**12
guesses_per_second = 1000000000
seconds_in_an_hour = 3600

p = mp.mpf(1) / mp.mpf(total_passwords)
n = mp.mpf(guesses_per_second) * mp.mpf(seconds_in_an_hour)

probability = 1 - mp.power(1 - p, n)
print(float(probability))

额外注意:即使您只是使用 0.2 或 76.5 这样看似无害的数字, float 也会失去精度。对相同数据进行大量浮点运算时应格外小心,因为错误可能会很快累积。

我希望这能有所帮助。

关于python - 如何在Python中计算非常小的数字的二项式概率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77043946/

相关文章:

python - Manim 展示 latex table

python - 如果我安装了两个不同的版本,如何指定要导入的 pytorch?

python - 如何强制signal.sawtooth从0开始?

python - 具有多维(或非标量)输出的 Scipy 过滤器

python - 与 SciPy kmeans 相比,使用 sklearn KMeans 是否有优势?

python - 如何将python包安装到GDB/clion2017.1中的嵌入式python

python - 如何在 Selenium 的 XPath 选择器中选择所有子文本但排除标签?

python - 根据具有特定值的行创建新的 Dataframe 并从原始 Dataframe 中删除行

python - 在 scipy 中使用直方图数据生成随机样本

python - 一次性对分段函数进行多次 curve_fit 迭代