如何在Vega formula transform中使用阶乘实现二项分布PMF计算
Vega JS 实现二项分布PMF直方图的解决方案
核心问题说明
Vega 表达式引擎为沙箱运行环境,仅支持官方定义的内置表达式,无法直接调用原生 JavaScript 的全局方法(如
Math.factorial),且默认未提供阶乘、组合数、二项分布相关计算函数。
实现思路
二项分布PMF公式为:$P(X=k) = C(n,k) \cdot p^k \cdot (1-p)^{n-k}$,其中 $C(n,k) = \frac{n!}{k! \cdot (n-k)!}$。
为避免大数值阶乘溢出、同时兼容Vega内置能力,提供两种可落地实现方案:
方案1:纯内置表达式实现(无需额外自定义代码)
通过对数转换规避阶乘溢出,完全使用Vega内置表达式完成计算:
- 先声明二项分布参数:试验次数
nval、单次成功概率pval - 生成所有可能的k值(取值范围0到n)
- 分步计算对数累加项,最终转换为PMF概率值
对应配置片段
{ "signals": [ {"name": "nval", "value": 20}, {"name": "pval", "value": 0.3} ], "data": [ { "name": "dataset", "transform": [ // 生成k值序列:0 到 nval(sequence的stop为*开区间*,因此取nval+1) {"type": "sequence", "start": 0, "stop": {"signal": "nval + 1"}, "step": 1, "as": "k"}, // 生成1到k的序列,用于累加对数阶乘项 {"type": "formula", "as": "log_factorial_k", "expr": "sum(range(1, datum.k + 1), i => log(i))"}, // 计算ln(n!) 和 ln((n-k)!) {"type": "formula", "as": "log_factorial_n", "expr": "sum(range(1, nval + 1), i => log(i))"}, {"type": "formula", "as": "log_factorial_nk", "expr": "sum(range(1, nval - datum.k + 1), i => log(i))"}, // 计算对数形式的PMF,再取指数得到最终概率 {"type": "formula", "as": "pmf", "expr": "exp( log_factorial_n - log_factorial_k - log_factorial_nk + datum.k * log(pval) + (nval - datum.k) * log(1 - pval) )"} ] } ] }
方案2:注册自定义表达式函数(适合复用场景)
如果需要频繁使用阶乘、二项分布计算,可通过Vega官方提供的自定义表达式注册能力,在初始化Vega实例前绑定JS方法,之后即可在表达式中直接调用:
- 初始化Vega前注册自定义函数:
// 注册阶乘函数 vega.expressionFunction('factorial', function(n) { if (n < 0) return NaN; let res = 1; for (let i = 2; i <= n; i++) res *= i; return res; }); // 注册直接计算二项分布PMF的函数 vega.expressionFunction('binomialPMF', function(k, n, p) { if (k < 0 || k > n) return 0; const comb = factorial(n) / (factorial(k) * factorial(n - k)); return comb * Math.pow(p, k) * Math.pow(1 - p, n - k); }); - 配置中即可直接调用自定义函数计算y值,替换原错误的
math.factorial逻辑:{"type": "formula", "as": "pmf", "expr": "binomialPMF(datum.k, nval, pval)"}
直方图绘制配置补充
计算完成PMF值后,直接绑定条形图标记即可完成绘制,核心映射规则:
- X轴绑定
k字段 - Y轴绑定
pmf字段 - 条形宽度根据k值间隔设置,实现直方图效果
注意:Vega的
sequence变换stop参数为开区间,生成连续整数序列时需将目标最大值加1作为stop值,避免最后一个k值缺失。
内容的提问来源于stack exchange,提问作者Jaidev V
相关产品推荐
相关产品推荐

