用PYMC3进行对数正态响应的线性回归

3
这是我第一次尝试对一个呈对数正态分布的响应建模线性回归。我有一个包含两个变量的数据框df:预测变量X和响应。当我绘制response与预测变量X的图时,我们得到了这张漂亮的图表:enter image description here 当我绘制对数响应的分布np.log(response)时,我得到了一个非常接近正态分布的结果:

. enter image description here

为了建立 Xresponse 之间的关系模型,我建立了以下模型,
import pymc3 as pm


with pm.Model() as model: 
    a = pm.Normal('a', 0, 10)
    b = pm.Normal('b', 0, 10)
    sigma = pm.Uniform('sigma', lower=0, upper=10)

    mu = pm.Deterministic('mu', a + b * df_train[X])

    y_hat = pm.Lognormal('y_hat', mu = mu, sd = sigma, observed = df['response'] )

    trace = pm.sample(2000, tune = 2000)

下一步是测量模型的正确程度,因此我计算数据集的平均响应,即:
mu_hat = np.exp(trace['mu'].mean(0)

然而,当我绘制这个平均值适配测试集的效果时,发现拟合度非常差:

enter image description here

可能的解决方案: 我尝试了其他可能性,如正态分布和泊松分布,但是模型无法收敛。我一直收到错误提示:

初始能量不好:inf。模型可能规定不当.

有什么想法,为什么这个适配失败得如此惨烈?

1个回答

2

看起来你的X服从对数正态分布,具有线性响应,可能还存在与X大小成比例的线性误差。没有数据很难确定,但是这里是我重现你的问题:

matplotlib inline

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

x = np.random.lognormal(5, 1, 10000)
y = x * np.random.normal(5,1,10000)

f, axes = plt.subplots(2, 1, figsize=(16,12))
sns.scatterplot(x,y, ax=axes[0])
sns.distplot(np.log(y), ax=axes[1])

x和y的散点图,log(y)的分布

接下来,我们可以对x系数和依赖y的误差进行建模:

with pm.Model() as model: 
    sigma = pm.InverseGamma('sigma', mu=(y/x).std(), sd = (y/x).std()/len(x))
    #intercept = pm.Normal('Intercept', 0, sigma=1)
    x_coeff = pm.Normal('x_coeff', (y/x).mean(), sigma=1)

    l = pm.Normal('l', mu=x_coeff, sigma=sigma, observed=y/x)

    trace = pm.sample(3000, tune=1000, cores=4)

现在我们绘制这些线条:

f, axes = plt.subplots(figsize=(16,8))
sns.scatterplot(x, y, ax=axes)
for (_,val) in pm.stats.quantiles(trace['x_coeff']).items():
    plt.plot(x, val*x, color='b')
    for (__, sd) in pm.stats.quantiles(trace['sigma']).items():
        plt.plot(x, (val+2*sd)*x, color='r')
        plt.plot(x, (val-2*sd)*x, color='r')

x系数以2倍标准差的正负值绘制


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接