Kaggle competition: Google Analytics Customer Revenue Prediction
X_train, y_train, X_test = feature_creator(train_imputed.copy() , test_imputed.copy())
 y_train = y_train.astype(int )<choose_model_class>
warnings.simplefilter('error', SettingWithCopyWarning)
 gc.enable()
%matplotlib inline
class FeatureEngineering(BaseEstimator, TransformerMixin):
def __init__(self, bin_fare=False, bin_age=True, family_size=True, bin_family_size=True,
drop_Name_length=False, drop_Ticket_frequency=False, drop_all=True, drop_Family_Survival=True,
drop_Ticket_extracted=False, scaling='StandardScaler', target_encode_title=True, test=False):
self.bin_fare = bin_fare
self.bin_age = bin_age
self.family_size = family_size
self.bin_family_size = bin_family_size
self.drop_Name_length = drop_Name_length
self.drop_Ticket_frequency = drop_Ticket_frequency
self.drop_all = drop_all
self.drop_Ticket_extracted = drop_Ticket_extracted
self.scaling = scaling
self.drop_Family_Survival = drop_Family_Survival
self.target_encode_title = target_encode_title
self.transformer = None
self.drop_list = []
self.test = test
def fit(self, X, y=None):
return self
def transform(self, X, y=None):
X['Pclass'] = X['Pclass'].astype(str)
 dummies = pd.get_dummies(X.loc[:, ['Pclass', 'Sex']], drop_first=True)
 X = pd.concat([X, dummies], axis=1)
 X.drop(['Pclass', 'Sex'], axis=1, inplace=True)
 X.drop(['Name', 'Ticket'], axis=1, inplace=True)
 if self.bin_fare:
self.drop_list.append('Fare')
 else:
self.drop_list.append('Fare_cat')
 if self.bin_age:
self.drop_list.append('Age')
 else:
self.drop_list.append('Age_cat')
 if self.family_size:
self.drop_list.extend(['SibSp', 'Parch'])
 if self.bin_family_size:
self.drop_list.append('Family_size')
 else:
self.drop_list.append('Family_size_cat')
 else:
self.drop_list.extend(['Family_size', 'Family_size_cat'])
 if self.drop_Name_length:
X.drop('Name_length', axis=1, inplace=True)
 if self.drop_Ticket_frequency:
X.drop('Ticket_frequency', axis=1, inplace=True)
 if self.drop_Family_Survival:
X.drop('Family_Survival', axis=1, inplace=True)
 if self.drop_all:
X.drop(self.drop_list, axis=1, inplace=True)
 self.cols = ['Title', 'Ticket_extracted'] if self.target_encode_title else ['Ticket_extracted']
if not self.test and len(X)> 400:
self.target_encoder = TargetEncoder(cols=self.cols, smoothing=5)
 X.loc[:, self.cols] = self.target_encoder.fit_transform(X.loc[:, self.cols], y_train.loc[X.index])
 else:
X.loc[:, self.cols] = self.target_encoder.transform(X.loc[:, self.cols])
 if self.drop_Ticket_extracted:
X.drop('Ticket_extracted', axis=1, inplace=True)
 X = pd.get_dummies(X, drop_first=True)
 features_to_scale = [feature for feature in X.columns if X[feature].nunique() != 2]
if not self.test and len(X)> 400:
if self.scaling == 'StandardScaler':
self.transformer = StandardScaler()
X.loc[:, features_to_scale] = self.transformer.fit_transform(X.loc[:, features_to_scale])
 elif self.scaling == 'RobustScaler':
self.transformer = RobustScaler()
X.loc[:, features_to_scale] = self.transformer.fit_transform(X.loc[:, features_to_scale])
 elif self.scaling == 'MinMaxScaler':
self.transformer = MinMaxScaler()
X.loc[:, features_to_scale] = self.transformer.fit_transform(X.loc[:, features_to_scale])
 else:
X.loc[:, features_to_scale] = self.transformer.transform(X.loc[:, features_to_scale])
 return X<define_search_space>
train = pd.read_csv('.. /input/create-extracted-json-fields-dataset/extracted_fields_train.gz',
dtype={'date': str, 'fullVisitorId': str, 'sessionId':str}, nrows=None)
 test = pd.read_csv('.. /input/create-extracted-json-fields-dataset/extracted_fields_test.gz',
dtype={'date': str, 'fullVisitorId': str, 'sessionId':str}, nrows=None)
 train.shape, test.shape
param_grid_pipeline = {'feature_engineering__bin_fare':[True, False],
'feature_engineering__bin_age':[True, False],
'feature_engineering__family_size':[True, False],
'feature_engineering__bin_family_size':[True, False],
'feature_engineering__drop_Name_length':[False],
'feature_engineering__drop_Ticket_frequency':[False],
'feature_engineering__drop_all':[True],
'feature_engineering__drop_Ticket_extracted':[True, False],
'feature_engineering__target_encode_title':[True, False],
'feature_engineering__scaling':['StandardScaler']}
pipeline_ = Pipeline([('feature_engineering', FeatureEngineering()), 
('model', LogisticRegression())])
 cv = StratifiedShuffleSplit(n_splits=20, test_size=0.15, random_state=101)
 grid = GridSearchCV(pipeline_, param_grid_pipeline,
cv=cv.split(X_train, X_train.Deck),
scoring='accuracy', verbose=2, n_jobs=-1)
 grid.fit(X_train.copy() , y_train )<count_missing_values>
y_reg = train['totals.transactionRevenue'].fillna(0)
 del train['totals.transactionRevenue']
if 'totals.transactionRevenue' in test.columns:
del test['totals.transactionRevenue']
pd.DataFrame(grid.cv_results_)['mean_test_score'].isna().sum()<categorify>
for df in [train, test]:
df['date'] = pd.to_datetime(df['visitStartTime'], unit='s')
 df['sess_date_dow'] = df['date'].dt.dayofweek
df['sess_date_hours'] = df['date'].dt.hour
df['sess_date_dom'] = df['date'].dt.day
X_train_fe = fe.fit_transform(X_train.copy())
 X_train_fe<feature_engineering>
def browser_mapping(x):
browsers = ['chrome','safari','firefox','internet explorer','edge','opera','coc coc','maxthon','iron']
if x in browsers:
return x.lower()
elif('android' in x)or('samsung' in x)or('mini' in x)or('iphone' in x)or('in-app' in x)or('playstation' in x):
return 'mobile browser'
elif('mozilla' in x)or('chrome' in x)or('blackberry' in x)or('nokia' in x)or('browser' in x)or('amazon' in x):
return 'mobile browser'
elif('lunascape' in x)or('netscape' in x)or('blackberry' in x)or('konqueror' in x)or('puffin' in x)or('amazon' in x):
return 'mobile browser'
elif '(not set)' in x:
return x
else:
return 'others'
def adcontents_mapping(x):
if('google' in x):
return 'google'
elif('placement' in x)|('placememnt' in x):
return 'placement'
elif '(not set)' in x or 'nan' in x:
return x
elif 'ad' in x:
return 'ad'
else:
return 'others'
def source_mapping(x):
if('google' in x):
return 'google'
elif('youtube' in x):
return 'youtube'
elif '(not set)' in x or 'nan' in x:
return x
elif 'yahoo' in x:
return 'yahoo'
elif 'facebook' in x:
return 'facebook'
elif 'reddit' in x:
return 'reddit'
elif 'bing' in x:
return 'bing'
elif 'quora' in x:
return 'quora'
elif 'outlook' in x:
return 'outlook'
elif 'linkedin' in x:
return 'linkedin'
elif 'pinterest' in x:
return 'pinterest'
elif 'ask' in x:
return 'ask'
elif 'siliconvalley' in x:
return 'siliconvalley'
elif 'lunametrics' in x:
return 'lunametrics'
elif 'amazon' in x:
return 'amazon'
elif 'mysearch' in x:
return 'mysearch'
elif 'qiita' in x:
return 'qiita'
elif 'messenger' in x:
return 'messenger'
elif 'twitter' in x:
return 'twitter'
elif 't.co' in x:
return 't.co'
elif 'vk.com' in x:
return 'vk.com'
elif 'search' in x:
return 'search'
elif 'edu' in x:
return 'edu'
elif 'mail' in x:
return 'mail'
elif 'ad' in x:
return 'ad'
elif 'golang' in x:
return 'golang'
elif 'direct' in x:
return 'direct'
elif 'dealspotr' in x:
return 'dealspotr'
elif 'sashihara' in x:
return 'sashihara'
elif 'phandroid' in x:
return 'phandroid'
elif 'baidu' in x:
return 'baidu'
elif 'mdn' in x:
return 'mdn'
elif 'duckduckgo' in x:
return 'duckduckgo'
elif 'seroundtable' in x:
return 'seroundtable'
elif 'metrics' in x:
return 'metrics'
elif 'sogou' in x:
return 'sogou'
elif 'businessinsider' in x:
return 'businessinsider'
elif 'github' in x:
return 'github'
elif 'gophergala' in x:
return 'gophergala'
elif 'yandex' in x:
return 'yandex'
elif 'msn' in x:
return 'msn'
elif 'dfa' in x:
return 'dfa'
elif '(not set)' in x:
return '(not set)'
elif 'feedly' in x:
return 'feedly'
elif 'arstechnica' in x:
return 'arstechnica'
elif 'squishable' in x:
return 'squishable'
elif 'flipboard' in x:
return 'flipboard'
elif 't-online.de' in x:
return 't-online.de'
elif 'sm.cn' in x:
return 'sm.cn'
elif 'wow' in x:
return 'wow'
elif 'baidu' in x:
return 'baidu'
elif 'partners' in x:
return 'partners'
else:
return 'others'
train['device.browser'] = train['device.browser'].map(lambda x:browser_mapping(str(x ).lower())).astype('str')
 train['trafficSource.adContent'] = train['trafficSource.adContent'].map(lambda x:adcontents_mapping(str(x ).lower())).astype('str')
 train['trafficSource.source'] = train['trafficSource.source'].map(lambda x:source_mapping(str(x ).lower())).astype('str')
 test['device.browser'] = test['device.browser'].map(lambda x:browser_mapping(str(x ).lower())).astype('str')
 test['trafficSource.adContent'] = test['trafficSource.adContent'].map(lambda x:adcontents_mapping(str(x ).lower())).astype('str')
 test['trafficSource.source'] = test['trafficSource.source'].map(lambda x:source_mapping(str(x ).lower())).astype('str')
 def process_device(data_df):
print("process device...")
 data_df['source.country'] = data_df['trafficSource.source'] + '_' + data_df['geoNetwork.country']
data_df['campaign.medium'] = data_df['trafficSource.campaign'] + '_' + data_df['trafficSource.medium']
data_df['browser.category'] = data_df['device.browser'] + '_' + data_df['device.deviceCategory']
data_df['browser.os'] = data_df['device.browser'] + '_' + data_df['device.operatingSystem']
return data_df
train = process_device(train)
 test = process_device(test)
 def custom(data):
print('custom.. ')
 data['device_deviceCategory_channelGrouping'] = data['device.deviceCategory'] + "_" + data['channelGrouping']
data['channelGrouping_browser'] = data['device.browser'] + "_" + data['channelGrouping']
data['channelGrouping_OS'] = data['device.operatingSystem'] + "_" + data['channelGrouping']
for i in ['geoNetwork.city', 'geoNetwork.continent', 'geoNetwork.country','geoNetwork.metro', 'geoNetwork.networkDomain', 'geoNetwork.region','geoNetwork.subContinent']:
for j in ['device.browser','device.deviceCategory', 'device.operatingSystem', 'trafficSource.source']:
data[i + "_" + j] = data[i] + "_" + data[j]
data['content.source'] = data['trafficSource.adContent'] + "_" + data['source.country']
data['medium.source'] = data['trafficSource.medium'] + "_" + data['source.country']
return data
train = custom(train)
 test = custom(test )
fe.test = True<categorify>
excluded_features = [
'date', 'fullVisitorId', 'sessionId', 'totals.transactionRevenue',
'visitId', 'visitStartTime'
]
categorical_features = [
_f for _f in train.columns
if(_f not in excluded_features)&(train[_f].dtype == 'object')
 ]
X_test_fe = fe.transform(X_test.copy())
 X_test_fe<split>
for f in categorical_features:
train[f], indexer = pd.factorize(train[f])
 test[f] = indexer.get_indexer(test[f] )
def learning_curve_plotter(Model, X, y, params_1, params_2, step=50):
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)
 plt.figure(figsize=(16, 7))
for i,(name, params)in enumerate([params_1, params_2]):
train_score = []
val_score = []
plt.subplot(1, 2, i+1)
 for j in range(100, len(X_train), step):
model = Model(**params ).fit(X_train[:j], y_train[:j])
 train_score.append(model.score(X_train[:j], y_train[:j]))
val_score.append(model.score(X_test, y_test))
plt.plot(train_score, 'r-', label='Training accuracy')
 plt.plot(val_score, 'b-', label='Validation accuracy')
 plt.title(f'{name}')
 plt.xlabel('Training set size')
 plt.ylabel('Accuracy')
 plt.legend()
plt.show()<init_hyperparams>
params={'learning_rate': 0.03,
'objective':'regression',
'metric':'rmse',
'num_leaves': 31,
'verbose': 1,
"subsample": 0.99,
"colsample_bytree": 0.99,
"random_state":42,
'max_depth': 15,
'lambda_l2': 0.02085548700474218,
'lambda_l1': 0.004107624022751344,
'bagging_fraction': 0.7934712636944741,
'feature_fraction': 0.686612409641711,
'min_child_samples': 21
}
param_grid_logreg = {'penalty':['elasticnet'],
'C':0.01 * np.arange(100),
'l1_ratio':0.1 * np.arange(10),
'solver':['saga']}<choose_model_class>
', params)
 Best num_boost_round:', len(cv_results['rmse-mean']))
grid_logreg = GridSearchCV(LogisticRegression() , param_grid_logreg,
cv=RepeatedStratifiedKFold(n_splits=10, n_repeats=2, random_state=42),
scoring='accuracy', verbose=2, n_jobs=-1 )<train_model>
folds = get_folds(df=train, n_splits=5)
 train_features = [_f for _f in train.columns if _f not in excluded_features]
importances = pd.DataFrame()
oof_reg_preds = np.zeros(train.shape[0])
 sub_reg_preds = np.zeros(test.shape[0])
 for fold_,(trn_, val_)in enumerate(folds):
print("Fold:",fold_)
 trn_x, trn_y = train[train_features].iloc[trn_], y_reg.iloc[trn_]
val_x, val_y = train[train_features].iloc[val_], y_reg.iloc[val_]
reg = lgb.LGBMRegressor(**params,
n_estimators=1000 
)
 reg.fit(
 trn_x, np.log1p(trn_y),
eval_set=[(val_x, np.log1p(val_y)) ],
early_stopping_rounds=50,
verbose=100,
eval_metric='rmse' 
)
 imp_df = pd.DataFrame()
imp_df['feature'] = train_features
imp_df['gain'] = reg.booster_.feature_importance(importance_type='gain')
 imp_df['fold'] = fold_ + 1
importances = pd.concat([importances, imp_df], axis=0, sort=False)
 oof_reg_preds[val_] = reg.predict(val_x, num_iteration=reg.best_iteration_)
 oof_reg_preds[oof_reg_preds < 0] = 0
_preds = reg.predict(test[train_features], num_iteration=reg.best_iteration_)
 _preds[_preds < 0] = 0
sub_reg_preds += np.expm1(_preds)/ len(folds)
 mean_squared_error(np.log1p(y_reg), oof_reg_preds)**.5
grid_logreg.fit(X_train_fe, y_train )<define_search_space>
train['predictions'] = np.expm1(oof_reg_preds)
 test['predictions'] = sub_reg_preds
params_logreg = {'C': 0.28, 'l1_ratio': 0.9, 'penalty': 'elasticnet', 'solver': 'saga'}<define_search_space>
trn_data = train[train_features + ['fullVisitorId']].groupby('fullVisitorId' ).mean()
param_grid_knn = {'n_neighbors':np.arange(50),
'weights':['uniform'],
'algorithm':['ball_tree'],
'leaf_size':np.arange(1, 40, 2)}<choose_model_class>
%%time
trn_pred_list = train[['fullVisitorId', 'predictions']].groupby('fullVisitorId')\ 
.apply(lambda df: list(df.predictions)) \ 
.apply(lambda x: {'pred_'+str(i): pred for i, pred in enumerate(x)} )
grid_knn = GridSearchCV(KNeighborsClassifier() , param_grid_knn,
cv=RepeatedStratifiedKFold(n_splits=10, n_repeats=2, random_state=42),
scoring='accuracy', verbose=2, n_jobs=-1 )<train_model>
trn_all_predictions = pd.DataFrame(list(trn_pred_list.values), index=trn_data.index)
 trn_feats = trn_all_predictions.columns
trn_all_predictions['t_mean'] = np.log1p(trn_all_predictions[trn_feats].mean(axis=1))
trn_all_predictions['t_median'] = np.log1p(trn_all_predictions[trn_feats].median(axis=1))
trn_all_predictions['t_sum_log'] = np.log1p(trn_all_predictions[trn_feats] ).sum(axis=1)
 trn_all_predictions['t_sum_act'] = np.log1p(trn_all_predictions[trn_feats].fillna(0 ).sum(axis=1))
trn_all_predictions['t_nb_sess'] = trn_all_predictions[trn_feats].isnull().sum(axis=1)
 full_data = pd.concat([trn_data, trn_all_predictions], axis=1)
 del trn_data, trn_all_predictions
gc.collect()
full_data.shape
grid_knn.fit(X_train_fe, y_train )<choose_model_class>
%%time
sub_pred_list = test[['fullVisitorId', 'predictions']].groupby('fullVisitorId')\ 
.apply(lambda df: list(df.predictions)) \ 
.apply(lambda x: {'pred_'+str(i): pred for i, pred in enumerate(x)} )
params_knn = {'algorithm': 'ball_tree', 'leaf_size': 1, 'n_neighbors': 7, 'weights': 'uniform'}<define_search_space>
sub_data = test[train_features + ['fullVisitorId']].groupby('fullVisitorId' ).mean()
sub_all_predictions = pd.DataFrame(list(sub_pred_list.values), index=sub_data.index)
 for f in trn_feats:
if f not in sub_all_predictions.columns:
sub_all_predictions[f] = np.nan
sub_all_predictions['t_mean'] = np.log1p(sub_all_predictions[trn_feats].mean(axis=1))
sub_all_predictions['t_median'] = np.log1p(sub_all_predictions[trn_feats].median(axis=1))
sub_all_predictions['t_sum_log'] = np.log1p(sub_all_predictions[trn_feats] ).sum(axis=1)
 sub_all_predictions['t_sum_act'] = np.log1p(sub_all_predictions[trn_feats].fillna(0 ).sum(axis=1))
sub_all_predictions['t_nb_sess'] = sub_all_predictions[trn_feats].isnull().sum(axis=1)
 sub_full_data = pd.concat([sub_data, sub_all_predictions], axis=1)
 del sub_data, sub_all_predictions
gc.collect()
sub_full_data.shape
param_grid_svc = {'C':[0.001, 0.01, 0.1, 1, 5],
'kernel':['rbf'],
'gamma':0.01 * np.arange(100),
'probability':[True]}<choose_model_class>
train['target'] = y_reg
trn_user_target = train[['fullVisitorId', 'target']].groupby('fullVisitorId' ).sum()
grid_svc = GridSearchCV(SVC() , param_grid_svc, cv=RepeatedStratifiedKFold(n_splits=10, n_repeats=2, random_state=42),
scoring='accuracy', verbose=2, n_jobs=-1 )<train_model>
params={'learning_rate': 0.05,
'objective':'regression',
'metric':'rmse',
'num_leaves': 200,
'verbose': 1,
"subsample": 0.99,
"colsample_bytree": 0.99,
"random_state":33,
'max_depth': 14,
'lambda_l2': 0.02085548700474218,
'lambda_l1': 0.004107624022751344,
'bagging_fraction': 0.7934712636944741,
'feature_fraction': 0.686612409641711,
'min_child_samples': 21
}
', params)
 Best num_boost_round:', len(cv_results['rmse-mean']))
grid_svc.fit(X_train_fe, y_train )<set_options>
folds = get_folds(df=full_data[['totals.pageviews']].reset_index() , n_splits=5)
 oof_preds = np.zeros(full_data.shape[0])
 sub_preds = np.zeros(sub_full_data.shape[0])
 vis_importances = pd.DataFrame()
for fold_,(trn_, val_)in enumerate(folds):
trn_x, trn_y = full_data.iloc[trn_], trn_user_target['target'].iloc[trn_]
val_x, val_y = full_data.iloc[val_], trn_user_target['target'].iloc[val_]
reg = lgb.LGBMRegressor(**params,
n_estimators=1500, 
)
 reg.fit(
 trn_x, np.log1p(trn_y),
eval_set=[(trn_x, np.log1p(trn_y)) ,(val_x, np.log1p(val_y)) ],
eval_names=['TRAIN', 'VALID'],
early_stopping_rounds=50,
eval_metric='rmse',
verbose=100 
)
 imp_df = pd.DataFrame()
imp_df['feature'] = trn_x.columns
imp_df['gain'] = reg.booster_.feature_importance(importance_type='gain')
 imp_df['fold'] = fold_ + 1
vis_importances = pd.concat([vis_importances, imp_df], axis=0, sort=False)
 oof_preds[val_] = reg.predict(val_x, num_iteration=reg.best_iteration_)
 oof_preds[oof_preds < 0] = 0
_preds = reg.predict(sub_full_data[full_data.columns], num_iteration=reg.best_iteration_)
 _preds[_preds < 0] = 0
sub_preds += _preds / len(folds)
 mean_squared_error(np.log1p(trn_user_target['target']), oof_preds)**.5
params_svc = {'C': 1, 'gamma': 0.09, 'kernel': 'rbf', 'probability': True}<define_search_space>
sub_full_data['PredictedLogRevenue'] = sub_preds
sub_full_data[['PredictedLogRevenue']].to_csv('new_test.csv', index=True )