Hi pymc team,
I am trying to replicate the work of Hello Fresh by referring to this video. But when I try to include the geodecay duration in the training, I got the error saying ‘FreeRV’ object cannot be interpreted as an integer. Please see the code and error below. I understand this error but wonder if there is any workaround for it?
from datetime import datetime
import arviz as az
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pymc3 as pm
import theano.tensor as tt
import seaborn as sns
from scipy import stats
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error
from copy import deepcopy
def reach(x, mu=0.1):
"""
:param x_t: marketing spend vector (float)
:parma mu: half-saturation point (float)
:return: transformed spend vector
"""
return (1 - np.exp(-mu * x)) / (1 + np.exp(-mu * x))
def geo_decay(x, alpha=0, L=12, normalize=True):
"""
:param alpha: rate of decay (float)
:param L: Length of time carryover effects can have an impact (int)
:normalize: Boolean
:return: transformed spend vector
"""
w = tt.as_tensor_variable([tt.power(alpha, i) for i in range(L)])
xx = tt.stack([tt.concatenate([tt.zeros(i), x[:x.shape[0] -i]]) for i in range(L)])
if not normalize:
y = tt.dot(w, xx)
else:
y = tt.dot(w / tt.sum(w), xx)
return y
decay_channel = [
...
]
with pm.Model() as model:
response_mean = []
# Intercept
a = pm.Normal("intercept", mu=25000, sigma=1000)
response_mean.append(a)
# Trend
b_trend = pm.Normal("b_trend", mu=0, sigma=100)
x = pm.Data("trend", X_scale["trend"].values)
term = b_trend * x
response_mean.append(term)
for c in decay_channel:
x = pm.Data(c, X_scale[c].values)
b_channel = pm.HalfNormal(f"b_{c}", sigma=2000)
alpha_channel = pm.Beta(f"alpha_{c}", alpha=3, beta=3)
mu_channel = pm.Gamma(f"mu_{c}", alpha=3, beta=1)
L_channel = pm.Poisson(f"L_{c}", mu=4)
term = reach(geo_decay(x, alpha=alpha_channel, L=L_channel), mu=mu_channel) * b_channel
response_mean.append(term)
likelihood = pm.Poisson("y", mu=sum(response_mean), observed=y.values)
And the error message:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [7], in <cell line: 15>()
34 mu_channel = pm.Gamma(f"mu_{c}", alpha=3, beta=1)
35 L_channel = pm.Poisson(f"L_{c}", mu=4)
---> 37 term = reach(geo_decay(x, alpha=alpha_channel, L=L_channel), mu=mu_channel) * b_channel
38 response_mean.append(term)
40 likelihood = pm.Poisson("y", mu=sum(response_mean), observed=y.values)
Input In [5], in geo_decay(x, alpha, L, normalize)
9 def geo_decay(x, alpha=0, L=12, normalize=True):
10 """
11 :param alpha: rate of decay (float)
12 :param L: Length of time carryover effects can have an impact (int)
13 :normalize: Boolean
14 :return: transformed spend vector
15 """
---> 16 w = tt.as_tensor_variable([tt.power(alpha, i) for i in range(L)])
17 xx = tt.stack([tt.concatenate([tt.zeros(i), x[:x.shape[0] -i]]) for i in range(L)])
19 if not normalize:
TypeError: 'FreeRV' object cannot be interpreted as an integer