This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ## 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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']) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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]) | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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', |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |