使用Pymc拟合Chi-squared分布报错及实现正确性问询
问题解答
报错原因
你遇到的AttributeError: 'TransformedRV' object has no attribute 'create_likelihood'报错,核心原因是pm.GLM.from_formula的family参数要求传入的是PyMC预定义的GLM分布族实例,而你直接传入了pm.ChiSquared生成的随机变量对象,该对象没有GLM族要求的create_likelihood方法,因此触发属性错误。
原实现的合理性问题
你的需求是拟合取值范围3~40的正实数数据,卡方分布本身是正实数分布,适配数据的取值范围是没问题的,但你的调用方式不符合PyMC的GLM接口规范,因此无法运行。
补充说明:卡方分布是Gamma分布的特例(自由度为ν的卡方分布等价于形状参数为ν/2、尺度参数为2的Gamma分布),你可以根据需求选择直接适配卡方分布,或者用Gamma分布做更灵活的拟合。
解决方案
方案1:使用GLM接口+Gamma族适配
如果你希望继续使用GLM的formula接口,可以用Gamma分布族替代,适配正实数数据的拟合需求,代码示例如下:
with pm.Model() as gamma_model: # 传入GLM预定义的Gamma分布族,log链接保证预测值为正 family = pm.glm.families.Gamma(link=pm.glm.families.links.log()) pm.GLM.from_formula(formula, data=X_train, family=family) # 执行采样 normal_trace = pm.sample(draws=2000, chains=2, tune=500)
方案2:手动构建模型,严格使用卡方分布
如果你需要严格使用卡方分布做似然,建议放弃GLM接口,手动构建贝叶斯模型,自由度更高,代码示例如下:
import pymc as pm import aesara.tensor as at # 替换为你的实际响应变量列名 target_col = "y" X = X_train.drop(target_col, axis=1) y = X_train[target_col] with pm.Model() as chi2_model: # 回归参数先验 intercept = pm.Normal("intercept", mu=0, sigma=10) beta = pm.Normal("beta", mu=0, sigma=10, shape=X.shape[1]) # 线性预测项,用指数链接保证输出为正,适配卡方自由度的正取值要求 nu = pm.Deterministic("nu", at.exp(intercept + at.dot(X.values, beta))) # 卡方分布似然 pm.ChiSquared("y_obs", nu=nu, observed=y) # 采样 chi2_trace = pm.sample(draws=2000, chains=2, tune=500)
内容的提问来源于stack exchange,提问作者azal
相关产品推荐
相关产品推荐

