You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

zfit中自定义Skew normal分布时erf函数调用报错的解决方法

解决zfit中自定义不对称高斯分布(Skew Normal)的误差函数调用问题

错误原因

报错核心是math.erf和scipy.special.erf仅支持NumPy数组输入,而zfit基于TensorFlow构建计算图,所有变量都是符号化张量,无法直接传入普通NumPy函数处理。

解决步骤与修正代码

必须使用TensorFlow原生的张量兼容函数替换误差函数,同时修正原代码中分布公式的两处错误:

  1. 标准正态分布的指数项缺少0.5系数
  2. Skew Normal分布的累积分布部分,alpha*t需除以√2才符合标准定义

修正后的完整代码:

import zfit
import tensorflow as tf
import math

class AsymmetricGauss(zfit.pdf.ZPDF):
    _N_OBS = 1
    _PARAMS = ['mean', 'std', 'alpha']

    def _unnormalized_pdf(self, x):
        x = zfit.z.unstack_x(x)
        mean = self.params['mean']
        std = self.params['std']
        alpha = self.params['alpha']

        t = (x - mean) / std
        # 修正标准正态分布的非归一化形式
        normal = zfit.z.exp(-0.5 * t**2) / (std * tf.sqrt(2 * tf.constant(math.pi)))
        # 使用TensorFlow兼容的误差函数
        cumulative = 0.5 * (1 + tf.math.erf(alpha * t / tf.sqrt(2)))
        return 2 * normal * cumulative

更优实现方式

如果不想手动继承ZPDF,可以用zfit提供的FuncPDF快速构建自定义PDF,代码更简洁:

import zfit
import tensorflow as tf
import math

def skew_normal_func(x, mean, std, alpha):
    x = zfit.z.unstack_x(x)
    t = (x - mean) / std
    normal = zfit.z.exp(-0.5 * t**2) / (std * tf.sqrt(2 * tf.constant(math.pi)))
    cumulative = 0.5 * (1 + tf.math.erf(alpha * t / tf.sqrt(2)))
    return 2 * normal * cumulative

# 定义可拟合参数
mean = zfit.Parameter("mean", 0, -5, 5)
std = zfit.Parameter("std", 1, 0.1, 5)
alpha = zfit.Parameter("alpha", 1, -5, 5)

# 生成Skew Normal PDF
skew_normal_pdf = zfit.pdf.FuncPDF(func=skew_normal_func, params=[mean, std, alpha], obs='x')

关键注意事项

  • 所有计算必须使用TensorFlow/zfit封装的张量函数,禁止混用math/scipy等仅支持NumPy的函数,否则会破坏TensorFlow的计算图逻辑。
  • 严格遵循Skew Normal分布的数学定义,确保公式细节(如指数项系数、误差函数内的缩放因子)准确,否则会导致分布形态偏差。

内容的提问来源于stack exchange,提问作者Jordan C. Correa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 14:20:09