Go Gonum 分布的 Prob 与 CDF 有什么区别
在 Go 的 Gonum stat/distuv 包里,Prob(x) 和 CDF(x) 都接收一个 x,但回答的不是同一个问题:Prob(x) 看的是分布在 x 处的概率密度(离散分布可理解为该点的概率质量),CDF(x) 看的是从分布左端累计到 x 的比例。前者像“曲线在这个位置有多高”,后者像“到这个位置为止已经覆盖了多少概率”。
官方文档:https://pkg.go.dev/gonum.org/v1/gonum/stat/distuv
如果业务要判断“随机变量是否不超过 x”,使用CDF(x);如果要观察分布曲线在一个点上的密度,使用Prob(x)。连续分布中,Prob(x)不是“随机变量恰好等于 x 的概率”,也不能直接当成区间概率。
先把两个返回值放回概率问题里
设随机变量是 X,给定一个查询点 x,Gonum 的两个方法可以这样读:
dist.Prob(x):返回概率密度函数在x处的值,写成连续分布的记号就是f(x)。dist.CDF(x):返回累计分布函数在x处的值,即P(X≤x),写成F(x)。
因此,正态分布里 Prob(80) 可能是一个小于 1 的密度高度;它不能直接解释成“成绩恰好等于 80 的概率”。要表达“成绩不超过 80 的比例”,应该使用 CDF(80)。要表达“超过 80 的比例”,则可以使用 Survival(80),它是 CDF 的补值方向。

准备一个能反复查询的小项目
为了避免只背 API 名字,可以做一个很小的命令行程序:固定一个正态分布,输入若干查询点,同时打印密度、左侧累计值和右侧尾部值。先创建模块并添加 Gonum:
# 创建一个独立模块,示例中的依赖版本由 go mod 管理 mkdir gonum-prob-cdf cd gonum-prob-cdf go mod init example.com/gonum-prob-cdf # 安装 Gonum 的统计分布包 go get gonum.org/v1/gonum/stat/distuv
下面的代码只保留一个分布对象,所有查询都基于同一组 Mu 和 Sigma,这样比较结果时不会混入参数差异。
package main
import (
"fmt"
"gonum.org/v1/gonum/stat/distuv"
)
// queryDistribution 统一打印同一个查询点对应的四类统计量。
func queryDistribution(dist distuv.Normal, x float64) {
// Prob 是曲线在 x 处的密度值,不把它当作连续变量的点概率。
density := dist.Prob(x)
// CDF 表示 X 小于等于 x 的累计概率。
leftTail := dist.CDF(x)
// Survival 表示 X 大于 x 的右尾概率。
rightTail := dist.Survival(x)
fmt.Printf("x=%.2f Prob=%.6f CDF=%.6f Survival=%.6f\\n",
x, density, leftTail, rightTail)
}
func main() {
// 平均值为 70、标准差为 10 的正态分布。
dist := distuv.Normal{Mu: 70, Sigma: 10}
// 选择低于、接近和高于平均值的点,便于观察三种结果如何变化。
for _, x := range []float64{60, 70, 80} {
queryDistribution(dist, x)
}
}
运行后会得到三组查询结果。这里最应该观察的不是某个小数位,而是语义:CDF 和 Survival 在同一个点上通常互补,而 Prob 的量纲和它们不同,不能拿来和累计概率直接比较大小后下业务结论。
同一个 x,Prob 和 CDF 到底差在哪里
以 Mu=70、Sigma=10 的正态分布为例,查询 x=80 时,Prob(80) 代表钟形曲线在 80 这个位置的高度;CDF(80) 代表曲线从左侧一直累加到 80 的面积。由于连续分布的概率来自区间面积,而不是单个点的高度,二者自然不会是同一类数值。
如果要回答“一个人的分数不超过 80 的比例是多少”,调用方式应是:
// scoreRate 返回分数不超过 limit 的累计比例。
func scoreRate(limit float64) float64 {
// CDF 的结果可直接解释为 P(X
实际项目中常见的误用是把 densityAt(80) 当成命中率,或者把几个点的 Prob 相加来估算一个区间概率。对于连续分布,区间概率应使用两个 CDF 的差,例如 P(a
离散分布时,Prob 的含义会更直观
连续分布和离散分布都暴露了 Prob 与 CDF,但读者对 Prob 的解释要随分布类型变化。以二项分布为例,Prob(k) 可以理解为“成功次数恰好等于 k 的概率”,而 CDF(k) 表示“成功次数不超过 k 的累计概率”。
package main
import (
"fmt"
"gonum.org/v1/gonum/stat/distuv"
)
func main() {
// N 是试验次数,P 是每次试验成功的概率。
dist := distuv.Binomial{N: 10, P: 0.4}
k := 4.0
// 离散分布的 Prob(k) 对应恰好出现 k 次的概率质量。
exact := dist.Prob(k)
// CDF(k) 把 0 到 k 的所有可能结果累计起来。
atMost := dist.CDF(k)
fmt.Printf("恰好 %.0f 次: %.6f\\n", k, exact)
fmt.Printf("不超过 %.0f 次: %.6f\\n", k, atMost)
}
这也是为什么不能只记一句“Prob 就是概率”。在正态分布中它是密度函数值,在二项分布中它对应某个离散结果的概率质量;而 CDF 的累计方向相对稳定,都是从分布的左侧累加到查询点。
右尾判断用 Survival,反向查询用 Quantile
当问题从“低于某个阈值的比例”变成“超过某个阈值的比例”时,不要手写 1-CDF(x) 作为默认表达。distuv 提供了语义更清楚的 Survival(x),它表示互补 CDF,也就是右尾概率。
// probabilityAbove 返回随机变量超过 threshold 的右尾概率。
func probabilityAbove(threshold float64) float64 {
// Survival 直接表达 P(X>threshold),调用方不需要自行做补值。
dist := distuv.Normal{Mu: 70, Sigma: 10}
return dist.Survival(threshold)
}
// thresholdForRate 根据累计比例反查一个分位点。
func thresholdForRate(rate float64) float64 {
// Quantile 的输入是累计概率,返回满足该累计位置的 x。
dist := distuv.Normal{Mu: 70, Sigma: 10}
return dist.Quantile(rate)
}
可以把四个方法按问题方向记忆:
| 你要回答的问题 | 方法 | 返回值应该怎样解释 |
|---|---|---|
| 曲线在 x 处有多高 | Prob(x) | 密度值;离散分布中是点概率质量 |
| 不超过 x 的比例是多少 | CDF(x) | P(X≤x) |
| 超过 x 的比例是多少 | Survival(x) | 右尾概率,通常对应 P(X>x) |
| 给定比例要找阈值 | Quantile(p) | 累计概率为 p 时的分位点 |

把 API 选择固定成业务判断
落到业务代码时,建议先写清楚自然语言,再选择函数,而不是看到 x 就随手调用 Prob。例如:
- “低于及格线的人占比”对应
CDF(passLine)。 - “超过告警阈值的请求占比”对应
Survival(alarmLine)。 - “某个观测点附近的密度”对应
Prob(observation),但不能把它写成单点命中率。 - “找出覆盖 95% 样本的阈值”对应
Quantile(0.95)。 - “区间
[a,b]内的概率”通常对应CDF(b)-CDF(a),要根据分布的端点约定处理开闭区间。
如果代码接收的是一个抽象分布接口,还要注意方法是否存在于接口中;具体类型如 Normal、Binomial、Beta 等都提供相应的查询方法,但每种分布的支持范围和参数约束仍应回到官方文档确认。
相关问题
Prob(x) 能不能直接当成概率?
不能一概而论。连续分布中它是密度函数值,不能解释为“恰好等于 x 的概率”;离散分布中它通常对应恰好取到该点的概率质量。文章中的业务判断应优先使用 CDF、Survival 或区间差值。
为什么 CDF 的结果通常在 0 和 1 之间?
CDF 表示累计概率,因此在正常参数和有限查询点下,它表达的是从左侧累计到该点的比例。极端尾部可能受到浮点数精度影响,但语义仍是累计分布函数,而不是密度高度。
如何计算某个区间的概率?
对于连续分布,常用 CDF(上界)-CDF(下界)。如果要计算右尾,优先使用 Survival;如果是离散分布,则要结合端点是否包含以及分布的整数取值范围确认写法。
Quantile 和 CDF 是什么关系?
CDF 是给定 x 求累计概率,Quantile 是给定累计概率反查 x。可以把它们看成正向查询和反向查询,但分位点在离散分布中还涉及最小满足条件的取值规则。
总结一下:Gonum 的 Prob 解决“分布在一个点附近的函数值是什么”,CDF 解决“截至这个点累计了多少概率”。先说清业务问题是密度、左尾、右尾还是分位点,再选对应 API,就不会把一个曲线高度误写成累计概率。
Go Gonum distuv 怎样计算正态分布尾部概率
- 上一篇
- Go Gonum distuv 怎样计算正态分布尾部概率
- 下一篇
- Go Gonum quad 怎样计算有限区间上的定点数值积分
-
- Golang · Go问答 | 29分钟前 |
- Go go-pretty 的分页大小与实际数据行数有什么区别
- 434浏览 收藏
-
- Golang · Go问答 | 35分钟前 |
- Go uniseg 分段函数的 state 为什么需要传回下一次调用
- 414浏览 收藏
-
- Golang · Go问答 | 40分钟前 |
- Go go-i18n 多个语言偏好参数怎样决定匹配结果
- 266浏览 收藏
-
- Golang · Go问答 | 44分钟前 |
- Go jsonschema 的 format 为什么不总是强制断言
- 188浏览 收藏
-
- Golang · Go问答 | 56分钟前 |
- Go Kong 的 passthrough 参数为什么保留后续原始输入
- 284浏览 收藏
-
- Golang · Go问答 | 58分钟前 | go · 排错 · Go Dijkstra 负权重边 Gonum BellmanFord
- Go Gonum Dijkstra 为什么不能处理负权重边
- 222浏览 收藏
-
- Golang · Go问答 | 1小时前 | 数据校验 · Go教程 · Go 插值 Gonum interp 横坐标 严格递增 PiecewiseLinear NaturalCubic
- Go Gonum 插值的横坐标为什么必须严格递增
- 173浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go Gonum Hermite 求积为什么包含权函数约定
- 353浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 797次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 789次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 877次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 847次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 678次使用
-
- 用Nginx反向代理部署go写的网站。
- 2023-01-17 502浏览
-
- GoLand调式动态执行代码
- 2023-01-13 502浏览
-
- Go generate 未执行指令的注释与目录检查
- 2026-10-28 501浏览
-
- Go RWMutex 写锁等待过久的竞争分析
- 2026-10-28 501浏览
-
- Go os.File.ReadAt 为什么到文件末尾仍返回部分数据
- 2026-10-26 501浏览

