登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  Golang >  Go教程

Go Gonum distuv 怎样计算正态分布尾部概率

来源:17golang原创

时间:2026-10-30 20:58:52 230浏览 收藏

在 Go 里用 Gonum 处理正态分布时,尾部概率不要自己先写误差函数。gonum.org/v1/gonum/stat/distuv 的 Normal 已经提供了 CDF(x) 和 Survival(x):前者表示随机变量小于等于 x 的累计概率,后者表示大于 x 的右尾概率。需要右尾时直接调用 Survival,可读性也比手写 1-CDF(x) 更好。

官方地址:https://pkg.go.dev/gonum.org/v1/gonum/stat/distuv

把观测值先放回它所属的分布,再决定看左尾还是右尾:左侧用 CDF,右侧用 Survival,双侧则分别计算两端再相加。
  • Mu 是正态分布的均值,Sigma 是标准差。
  • CDF(x) 适合“低于阈值”的累计概率。
  • Survival(x) 适合“超过阈值”的右尾概率。

先判断要查哪一侧的概率

我在把统计规则写成程序时,最容易混淆的是“超过阈值”和“低于阈值”。如果随机变量记为 X,CDF(x) 对应的是 P(X≤x);Survival(x) 对应的是 P(X>x)。例如检测分数超过 80 的比例属于右尾,应该让 x=80 传给 Survival。

Go Gonum distuv 中 CDF 与 Survival 的尾部接口关系说明图
图1:接口选择说明图,区分 CDF 的左侧累计概率与 Survival 的右侧尾部概率;这是静态结构图,不是运行截图。

用 Mu 和 Sigma 构造 Normal

Normal 的 Mu 和 Sigma 描述的是原始观测值的分布。若业务数据的均值是 70、标准差是 8,那么阈值 86 就直接作为 x 传入;不需要先手动把 86 改成 z 分数。只有在你已经拿到标准化后的 z 分数,并且分布本身是标准正态分布时,才使用 Mu: 0、Sigma: 1。

package main

import (
    "fmt"

    "gonum.org/v1/gonum/stat/distuv"
)

func main() {
    // 用业务数据的均值和标准差描述原始正态分布。
    dist := distuv.Normal{Mu: 70, Sigma: 8}
    threshold := 86.0

    // Survival 返回超过阈值的右尾概率。
    rightTail := dist.Survival(threshold)
    // CDF 返回不超过阈值的累计概率,和右尾互为补集。
    leftTail := dist.CDF(threshold)

    fmt.Printf("P(X>%.0f)=%.6f\n", threshold, rightTail)
    fmt.Printf("P(X

这段写法的重点不是把输出保留到多少位,而是让变量名和概率方向一致。实际项目中可以根据报表要求再做百分比格式化,但不要把小数直接当成百分数展示。

Mu、Sigma、阈值与正态分布两侧尾部的关系说明图
图2:参数关系说明图,展示 Mu、Sigma、阈值与左右尾部的静态关系;这是原创说明图,不代表实际运行结果。

单侧、左侧和双侧尾部怎么写

右尾是 dist.Survival(x),左尾是 dist.CDF(x)。双侧检验不能只看一边:先计算阈值距离均值的标准化距离,再把对称的两端概率相加。对于均值为 70、标准差为 8 的分布,观测值 86 距离均值两个标准差;如果要表达“离均值至少这么远”的双侧概率,可以计算下侧 70-16 和上侧 70+16 两个阈值的概率。

// 双侧尾部只对称适用;阈值必须按同一个 Mu 和 Sigma 换算回原始尺度。
lower := dist.Mu - 2*dist.Sigma
upper := dist.Mu + 2*dist.Sigma

// 两端概率分别取左尾和右尾,再合并为双侧概率。
twoTail := dist.CDF(lower) + dist.Survival(upper)
fmt.Printf("P(|X-Mu|>=2*Sigma)=%.6f\n", twoTail)

如果你的业务阈值不是围绕 Mu 对称,不能套用上面的双侧公式;那时应明确两个实际阈值,分别计算两端事件。更极端的 x 也不意味着一定报错,应该把概率解释为接近 0 或 1 的数值,并在业务层决定展示精度。

容易出错的边界

第一,Sigma 是标准差,必须为正;把方差直接填入会改变分布形状。第二,Prob(x) 是概率密度,不是“小于 x 的概率”,累计概率应使用 CDF。第三,Survival(x) 的语义是互补 CDF,写告警规则时要把“超过阈值”的自然语言和代码保持一致。第四,不要把静态说明图当成真实输出,数值结果仍应由你的输入数据、精度和业务定义决定。

常见问题

正态分布右尾概率应该调用哪个方法?

调用 distuv.Normal 的 Survival(x),它直接表达 P(X>x)。只有需要左侧累计概率时才调用 CDF(x)。

已经有 z 分数还要重新设置均值吗?

如果 z 分数对应标准正态分布,可以使用 Mu: 0、Sigma: 1。如果手里的值还是原始业务量,就应使用原始分布的均值和标准差。

为什么不统一写成 1 减 CDF?

数学上右尾是互补概率,但库提供的 Survival 更直接,也能避免把概率方向写反;文章和代码都更容易复查。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>