Skip to content

Instantly share code, notes, and snippets.

## Environment simulator
def plus(x):
return 0 if x < 0 else x
def minus(x):
return 0 if x > 0 else -x
def shock(x):
return np.sqrt(x)
def simulate_budget_roi(df, budget_total, attribution, verbose=False):
# convert attribution weights to budgets
budgets = np.ceil(attribution * (budget_total / np.sum(attribution)))
blacklist = set()
conversions = set()
for i in range(df.shape[0]): # simulation loop
campaign_id = get_campaign_id(df.loc[i]['campaigns'])
jid = df.loc[i]['jid']
if jid not in blacklist:
def get_campaign_id(x_journey_step):
return np.argmax(x_journey_step[0:n_campaigns])
# truncated model that outputs attention weights
attention_model = Model(inputs=model.input,
outputs=model.get_layer('attention_weigths').output)
# compute attention vectors for each journey
a = attention_model.predict(x_train)
n_steps, n_features = np.shape(x)[1:3]
hidden_units = 64
main_input = Input(shape=(n_steps, n_features))
embeddings = Dense(128, activation='linear', input_shape=(n_steps, n_features))(main_input)
activations = LSTM(hidden_units, dropout=0.2, recurrent_dropout=0.2, return_sequences=True)(embeddings)
attention = Dense(1, activation='tanh')(activations)
from keras.models import Sequential
from keras.layers import Dense, LSTM
n_steps, n_features = np.shape(x)[1:3]
model = Sequential()
model.add(LSTM(64, dropout=0.2, recurrent_dropout=0.2, input_shape=(n_steps, n_features)))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
def features_for_lstm(df, max_touchpoints):
df_proj = df[['jid', 'campaigns', 'cats', 'click',
'cost', 'time_since_last_click_norm', 'timestamp_norm', 'conversion']]
x2d = df_proj.values
# group events by JID
x3d_list = np.split( x2d[:, 1:], np.cumsum(np.unique(x2d[:, 0], return_counts=True)[1])[:-1])
from sklearn.utils.extmath import softmax
keras_logreg = model.get_layer('contributions').get_weights()[0].flatten()[0:n_campaigns]
keras_logreg = softmax([keras_logreg]).flatten()
m = np.shape(x)[1]
model = Sequential()
model.add(Dense(1, input_dim = m, activation = 'sigmoid', name = 'contributions'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=128, epochs=10, validation_data=(x_val, y_val))
score = model.evaluate(x_test, y_test)
print('Test score:', score[0])
print('Test accuracy:', score[1])
def features_for_logistic_regression(df):
def pairwise_max(series):
return np.max(series.tolist(), axis = 0).tolist()
aggregation = { # aggregation specification for each feature
'campaigns': pairwise_max,
'cats': pairwise_max,
'click': 'sum',
'cost': 'sum',
def last_touch_attribution(df):
# count the number of events for each campaign in df
def count_by_campaign(df):
counters = np.zeros(n_campaigns)
for campaign_one_hot in df['campaigns'].values:
campaign_id = np.argmax(campaign_one_hot)
counters[campaign_id] = counters[campaign_id] + 1
return counters