PyMC3和Theano:参数估计几何广告

时间:2018-09-05 01:20:01

标签: theano pymc3 theano.scan

我正在尝试估算adstock几何函数的参数(参数名称为alpha),但是PyMC3会以某种方式收敛到完全错误的结果。

我不确定这是否取决于我对adstock函数的执行情况或其他因素。

adstock函数由python中的以下代码定义:

    def geometric_adstock_function(xx, alpha, normalize=True):
        result = []
        for i, x in enumerate(xx):
            cumsum = 0
            wcumsum = 0
            for l in range(i + 1):
                w = alpha ** l

                cumsum += w * xx[i - l]
                wcumsum += w
            if not normalize:
                result.append(cumsum)
            else:
                result.append(cumsum / wcumsum)

        return np.array(result)

,然后使用

使用PyMC3定义用于参数估计的theano函数
def geometric_adstock_theano(xx, alpha):
    """
    This very complex function implement a normalized, geometric adstock using scan in theano

    """

    def fn(x, prior_result, prior_norm, carry, prior_numerator, alpha):

        carry = carry * alpha
        new_norm = prior_norm + carry
        new_result = (x + alpha * prior_numerator) / prior_norm

        new_numerator = (x + alpha * prior_numerator)

        return new_result, new_norm, carry, new_numerator

    channel_adstock, updates = theano.scan(fn=fn,
                                           sequences=[xx],
                                           outputs_info=[tt.zeros_like(alpha), tt.ones_like(alpha),
                                                         tt.ones_like(alpha), tt.zeros_like(alpha)],
                                           non_sequences=alpha)

    return channel_adstock, updates

使用theano运行这两个函数时,它们返回相同的结果:

import theano
from theano import tensor as tt


alpha = tt.scalar("alpha",dtype='float64')
xx = tt.vector("X",dtype='float64')

channel_adstock,updates = geometric_adstock_theano(xx,alpha)

test_adstock = theano.function(inputs=[xx,alpha], outputs=channel_adstock, updates=updates)

#the two functions return the same result for the same value of alpha here 0.8
print(test_adstock([1.,0,0.,0, 0 , 0],.8)[0])
print(geometric_adstock_function([1.,0.,0.,0, 0, 0],.8))

但是,当使用PyMC3估算已知信号的alpha值时,我得到的估算值很差。

在theano中实现几何广告素材或在PyMC3代码中存在任何错误吗?

# defines groud truth for the original signal and the transformed one
true_alpha = 0.8
original = np.sin(np.linspace(0,np.pi*2*4,50))
transformed = geometric_adstock_function(original, alpha=true_alpha)

# tries to estimate alpha using pymc3
with pm.Model() as model:
    alpha = pm.Beta('alpha', .5, .5)
    channel_adstock, _ = geometric_adstock_theano(original, alpha)

    likelyhood =pm.Normal('y',mu=channel_adstock,observed=transformed,sd=.001)


#map estimate for alpha also very off
map_estimate = pm.find_MAP(model=model, method='L-BFGS-B',start=dict(alpha=.8))
print(map_estimate)

#using the sampling strategy
with model:
    trace = pm.sample(500, cores=2, tune=500)# use_mmap=True, nuts_kwargs=dict(target_accept=.99))  # draw 3000 posterior samples using NUTS sampling

result = pm.summary(trace)
print(result)
estimated_alpha = result.loc['alpha']['mean']
ppc = pm.sample_ppc(trace, samples=500, model=model)
mean_prediction = ppc['y'].mean(axis=0)[0]

# plotting some results 
plt.figure(figsize = (12,20))
plt.subplot(1,2,1)
plt.plot(geometric_adstock_function([1,0,0,0,0,0],estimated_alpha),'-')
plt.plot(geometric_adstock_function([1,0,0,0,0,0],true_alpha),'-')
plt.legend(['kernel estimated','kernel original'])
plt.subplot(1,2,2)
plt.plot(geometric_adstock_function(original,estimated_alpha),'-')
plt.plot(geometric_adstock_function(original,true_alpha),'-')
plt.plot(mean_prediction)
plt.plot(theano_channel_adstock,'-')

plt.legend(['signal estimated','signal original','mean_prediction','theano result with true alpha'])

0 个答案:

没有答案