Kaggle competition: Santa's Workshop Tour 2019
<SOS> metric: SantaWorkshopSchedule2019 Kaggle data source: santas-workshop-tour-2019<feature_engineering>
import numpy as np
import pandas as pd
import scipy.special
import matplotlib.pyplot as plt
import os
datasets = [X_train, X_test]
titles = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Rare": 5}
for dataset in datasets:
dataset['Title'] = dataset['Name'].str.extract('([A-Za-z]+)\.', expand=False)
 dataset['Title'] = dataset['Title'].replace(['Don', 'Rev', 'Dr', 'Major', 'Sir', 'Col', 'Capt', 'Jonkheer', 'Countess', 'Lady', 'Dona'], 'Rare')
 dataset['Title'] = dataset['Title'].replace(['Ms', 'Mlle'], 'Miss')
 dataset['Title'] = dataset['Title'].replace('Mme', 'Miss')
 dataset['Title'] = dataset['Title'].map(titles)
 dataset['Title'] = dataset['Title'].astype(int)
 dataset.drop('Name', axis=1, inplace=True )<categorify>
path_in = '.. /input/santa-workshop-tour-2019/'
path_start_solution = '.. /input/santa-workshop-tour-start-solution/'
print('input_data:', os.listdir(path_in))
print('start solution:', os.listdir(path_start_solution))
dep = {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7, 'U': 8}
for dataset in datasets:
dataset['Cabin'] = dataset['Cabin'].fillna("U0")
 dataset['Deck'] = dataset['Cabin'].map(lambda x: re.compile('([a-zA-Z])+' ).search(x ).group())
 dataset['Deck'] = dataset['Deck'].map(dep)
 dataset['Deck'].fillna(0, inplace=True)
 dataset['Deck'] = dataset['Deck'].astype(int)
 dataset.drop('Cabin', axis=1, inplace=True )<data_type_conversions>
data = pd.read_csv(path_in+'family_data.csv')
 data.index = data['family_id']
samp_subm = pd.read_csv(path_in+'sample_submission.csv')
 start_solution = pd.read_csv(path_start_solution+'santa_workshop_tour_start_solution_01.csv', index_col=0 )
for dataset in datasets:
dataset['relatives'] = dataset['SibSp'] + dataset['Parch']
dataset.loc[dataset['relatives'] > 0, 'is_alone'] = 0
dataset.loc[dataset['relatives'] == 0, 'is_alone'] = 1
dataset['is_alone'] = dataset['is_alone'].astype(int )<feature_engineering>
num_days = 100
lower = 125
upper = 300
days = list(range(num_days, 0, -1))
for dataset in datasets:
dataset.loc[(dataset.Sex == "male"), 'Sex'] = 0
dataset.loc[(dataset.Sex == "female"), 'Sex'] = 1<feature_engineering>
def calc_family_costs(family):
assigned_day = family['assigned_day']
number_member = family['n_people']
if assigned_day == family['choice_0']:
penalty = 0
elif assigned_day == family['choice_1']:
penalty = 50
elif assigned_day == family['choice_2']:
penalty = 50 + 9 * number_member
elif assigned_day == family['choice_3']:
penalty = 100 + 9 * number_member
elif assigned_day == family['choice_4']:
penalty = 200 + 9 * number_member
elif assigned_day == family['choice_5']:
penalty = 200 + 18 * number_member
elif assigned_day == family['choice_6']:
penalty = 300 + 18 * number_member
elif assigned_day == family['choice_7']:
penalty = 300 + 36 * number_member
elif assigned_day == family['choice_8']:
penalty = 400 + 36 * number_member
elif assigned_day == family['choice_9']:
penalty = 500 + 36 * number_member + 199 * number_member
else:
penalty = 500 + 36 * number_member + 398 * number_member
return penalty
for dataset in datasets:
dataset["Embarked"].fillna("S", inplace=True)
 dataset.loc[(dataset.Embarked == "S"), "Embarked"] = 0
dataset.loc[(dataset.Embarked == "Q"), "Embarked"] = 1
dataset.loc[(dataset.Embarked == "C"), "Embarked"] = 2<data_type_conversions>
def calc_accounting_cost(data):
accounting_cost = 0
daily_occupancy = {k:0 for k in days}
family_size_dict = data[['n_people']].to_dict() ['n_people']
for f, d in enumerate(data['assigned_day']):
n = family_size_dict[f]
daily_occupancy[d] += n
accounting_cost =(daily_occupancy[days[0]]-125.0)/ 400.0 * daily_occupancy[days[0]]**(0.5)
 accounting_cost = max(0, accounting_cost)
 yesterday_count = daily_occupancy[days[0]]
for day in days[1:]:
today_count = daily_occupancy[day]
diff = abs(today_count - yesterday_count)
 accounting_cost += max(0,(daily_occupancy[day]-125.0)/ 400.0 * daily_occupancy[day]**(0.5 + diff / 50.0))
yesterday_count = today_count
return accounting_cost
for dataset in datasets:
Age_avg = dataset['Age'].mean()
Age_std = dataset['Age'].std()
Age_null_count = dataset['Age'].isnull().sum()
Age_null_random_list = np.random.randint(Age_avg - Age_std, Age_avg + Age_std, size=Age_null_count)
 dataset['Age'][np.isnan(dataset['Age'])] = Age_null_random_list
dataset['Age'] = dataset['Age'].astype(int)
 dataset.loc[(dataset.Age <= 18), 'Age'] = 0
dataset.loc[(dataset.Age > 18)&(dataset.Age <= 23), 'Age'] = 1
dataset.loc[(dataset.Age > 23)&(dataset.Age <= 29), 'Age'] = 2
dataset.loc[(dataset.Age > 29)&(dataset.Age <= 35), 'Age'] = 3
dataset.loc[(dataset.Age > 35)&(dataset.Age <= 42), 'Age'] = 4
dataset.loc[(dataset.Age > 42), 'Age'] = 5<feature_engineering>
def check_day(data, day):
group_data = data.groupby('assigned_day' ).sum() ['n_people'].to_frame()
if(125 <= group_data.loc[day, 'n_people'])&(group_data.loc[day, 'n_people'] <= 300):
return True
else:
return False
X_test['Fare'].fillna(X_test['Fare'].mean() , inplace=True)
 for dataset in datasets:
dataset.loc[(dataset.Fare <= 7.775), 'Fare'] = 0
dataset.loc[(dataset.Fare > 7.775)&(dataset.Fare <= 8.662), 'Fare'] = 1
dataset.loc[(dataset.Fare > 8.662)&(dataset.Fare <= 14.454), 'Fare'] = 2
dataset.loc[(dataset.Fare > 14.454)&(dataset.Fare <= 26), 'Fare'] = 3
dataset.loc[(dataset.Fare > 26)&(dataset.Fare <= 52.369), 'Fare'] = 4
dataset.loc[(dataset.Fare > 52.369), 'Fare'] = 5
dataset['Fare'] = dataset['Fare'].astype(int)
 dataset.drop(['Ticket', 'PassengerId'], axis=1, inplace=True )<count_missing_values>
for i in range(num_days):
data.loc[i*50:(i+1)*50-1, 'assigned_day'] = i+1
data['assigned_day'] = data['assigned_day'].astype(int )
print("----- After cleaning -----")
 print(missing_data(X_train))
print(missing_data(X_test))<train_on_grid>
data['assigned_day'] = start_solution['assigned_day']
SVC_model = SVC(gamma='scale')
 SVC_model.fit(X_train, y_train)
 SVC_score = round(accuracy_score(SVC_model.predict(X_train), y_train)* 100, 2)
 KNN_model = KNeighborsClassifier()
KNN_model.fit(X_train, y_train)
 KNN_score = round(accuracy_score(KNN_model.predict(X_train), y_train)* 100, 2)
 DC_model = DecisionTreeClassifier()
DC_model.fit(X_train, y_train)
 DC_score = round(accuracy_score(DC_model.predict(X_train), y_train)* 100, 2)
 XGB_model = XGBClassifier()
XGB_model.fit(X_train, y_train)
 XGB_score = round(accuracy_score(XGB_model.predict(X_train), y_train)* 100, 2)
 RF_model = RandomForestClassifier(n_estimators=100)
 RF_model.fit(X_train, y_train)
 RF_score = round(accuracy_score(RF_model.predict(X_train), y_train)* 100, 2)
 GNB_model = GaussianNB()
GNB_model.fit(X_train, y_train)
 GNB_score = round(accuracy_score(GNB_model.predict(X_train), y_train)* 100, 2 )<create_dataframe>
data['penalty_cost'] = data.apply(calc_family_costs, axis=1 )
ranking = pd.DataFrame({'Model': ['Support Vector Classification', 'KNN', 'Decision Classifier', 'Random Forest', 'Naive Bayes', 'XGBClassifer'], 'Score': [SVC_score, KNN_score, DC_score, RF_score, GNB_score, XGB_score]})
 ranking = ranking.sort_values(by='Score', ascending=False ).set_index('Score')
 ranking<compute_train_metric>
acc_costs = calc_accounting_cost(data)
 acc_costs
rf = RandomForestClassifier(n_estimators=100, oob_score=True, random_state=1, n_jobs=-1)
 rf.fit(X_train, y_train)
 print("Cross val score:", round(cross_val_score(rf, X_train, y_train, cv=8, scoring='accuracy' ).mean() , 3), '(+/-', round(cross_val_score(rf, X_train, y_train, cv=8, scoring='accuracy' ).std() , 2), '%)')
 print("Oob score:", round(rf.oob_score_, 4)*100, "%" )<train_model>
print('Total costs:', data['penalty_cost'].sum() + acc_costs )
rf = RandomForestClassifier(criterion="gini", min_samples_leaf=1, min_samples_split=35, n_estimators=1000, oob_score=True, random_state=1, n_jobs=-1)
 rf.fit(X_train, y_train)
 print("oob score:", round(rf.oob_score_, 4)*100, '%' )<predict_on_test>
def check_swap_day(data, family, choice):
data_copy = data.copy()
data_copy.loc[family, 'assigned_day'] = data_copy.loc[family, 'choice_'+str(choice)]
data_copy.loc[family, 'penalty_cost'] = calc_family_costs(data_copy.iloc[family])
 penalty_before = data.loc[family, 'penalty_cost']
accounting_before = calc_accounting_cost(data)
 penalty_after = data_copy.loc[family, 'penalty_cost']
accounting_after = calc_accounting_cost(data_copy)
 day_before = check_day(data_copy, data.loc[family, 'assigned_day'])
 day_after = check_day(data_copy, data_copy.loc[family, 'assigned_day'])
 if(day_before==True and day_after==True):
improvement =(penalty_before-penalty_after)+(accounting_before-accounting_after)
 else:
improvement = -1
return improvement
predictions = cross_val_predict(rf, X_train, y_train, cv=5)
 print("Precision:", precision_score(y_train, predictions))
print("Recall:", recall_score(y_train, predictions))
print("F1:", f1_score(y_train, predictions))
y_scores = rf.predict_proba(X_train)
 y_scores = y_scores[:, 1]<save_to_csv>
family_id = 386
check_swap_day(data, family_id, 0 )
r_a_score = roc_auc_score(y_train, y_scores)
 print("ROC-AUC-Score:", r_a_score)
 preds = rf.predict(X_test)
 submission = pd.DataFrame({'PassengerId': test_data['PassengerId'], 'Survived': preds})
 submission.to_csv('Titanic Predictions Final Submission.csv', index=False )<load_from_csv>
def check_swap_family(data, family, choice):
family1 = family
day_family1 = data.loc[family1, 'assigned_day']
penalty1 = data.loc[family1, 'penalty_cost']
member_family1 = data.loc[family1, 'n_people']
day_member_list = data.groupby('assigned_day')['family_id'].apply(list ).to_frame()
improvements = {}
for member in day_member_list.loc[data.loc[family1, 'choice_'+str(choice)], 'family_id']:
family2 = member
day_family2 = data.loc[family2, 'assigned_day']
member_family2 = data.loc[family2, 'n_people']
penalty2 = data.loc[family2, 'penalty_cost']
data_copy = data.copy()
data_copy.loc[family2, 'assigned_day'] = data_copy.loc[family1, 'assigned_day']
data_copy.loc[family1, 'assigned_day'] = data_copy.loc[family1, 'choice_'+str(choice)]
new_penalty1 = calc_family_costs(data_copy.iloc[family1])
 new_penalty2 = calc_family_costs(data_copy.iloc[family2])
 day_before = check_day(data_copy, data.loc[family1, 'assigned_day'])
 day_after = check_day(data_copy, data_copy.loc[family1, 'choice_'+str(choice)])
 accounting_before = calc_accounting_cost(data)
 accounting_after = calc_accounting_cost(data_copy)
 if(day_before==True and day_after==True):
improvement =(penalty1-new_penalty1)+(penalty2-new_penalty2)+(accounting_before-accounting_after)
 else:
improvement = -1
improvements.update({member:improvement})
 maximum = max(zip(improvements.values() , improvements.keys()))
family_swap = maximum[1]
return improvement, family_swap
train_df = pd.read_csv("/kaggle/input/titanic/train.csv")
 test_df = pd.read_csv("/kaggle/input/titanic/test.csv")
 train_df.shape, test_df.shape<prepare_x_and_y>
family_id = 386
check_swap_family(data, family_id, 0 )
y = train_df['Survived']
train_df.Age[train_df.Age.isnull() ] = train_df.Age.median()
train_df.Age = train_df.Age.astype(str)
 train_df.Fare[train_df.Fare.isnull() ] = train_df.Fare.median()
train_df.Fare = train_df.Fare.astype(str)
 train_df.Cabin[train_df.Cabin.isnull() ] = 'NA'
MaxPassEmbarked = train_df.groupby('Embarked' ).count() ['PassengerId']
train_df.Embarked[train_df.Embarked.isnull() ] = 'NAA'
X = train_df.drop(columns=['Survived','Name','PassengerId'])
 X.head(100 )<define_variables>
family_id = 386
choice = 0
improvement_day = check_swap_day(data, family_id, choice)
 improvement_family, family_swap = check_swap_family(data, family_id, choice)
 improvement_day, improvement_family, family_swap
SEED = 1<split>
def go_to_bazaar(data, family):
family1 = family
day_family1 = data.loc[family1, 'assigned_day']
penalty1 = data.loc[family1, 'penalty_cost']
member_family1 = data.loc[family1, 'n_people']
status = False
for choice in range(10):

 improvement_day = check_swap_day(data, family1, choice)

improvement_family, family2 = check_swap_family(data, family1, choice)
 if(improvement_day >= 0 or improvement_family >= 0):
if(improvement_day > improvement_family):
data.loc[family, 'assigned_day'] = data.loc[family, 'choice_'+str(choice)]
data.loc[family, 'penalty_cost'] = calc_family_costs(data.iloc[family])
 status = True
else:
data.loc[family2, 'assigned_day'] = data.loc[family1, 'assigned_day']
data.loc[family1, 'assigned_day'] = data.loc[family1, 'choice_'+str(choice)]
data.loc[family1, 'penalty_cost'] = calc_family_costs(data.iloc[family1])
 data.loc[family2, 'penalty_cost'] = calc_family_costs(data.iloc[family2])
 status = True
if(status==True):
break
X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.40, random_state=SEED)
 cat_features = list(range(X.shape[1]))<create_dataframe>
results = results.reindex(sorted(results.columns), axis=1 )
train_data = Pool(data=X_train,
label=y_train,
cat_features=cat_features 
)
 valid_data = Pool(data=X_valid,
label=y_valid,
cat_features=cat_features
)<train_model>
print('Total costs:', data['penalty_cost'].sum() + calc_accounting_cost(data))
%%time
params = {'loss_function':'Logloss',
'eval_metric':'AUC',
'early_stopping_rounds': 200,
'verbose': 200,
'random_seed': SEED
}
cbc_7 = CatBoostClassifier(**params)
 cbc_7.fit(train_data,
eval_set=valid_data,
use_best_model=True,
plot=True 
);<compute_test_metric>
data = data.sort_index()
output = pd.DataFrame({'family_id': samp_subm.index,
'assigned_day': data['assigned_day']})
 output.to_csv('submission.csv', index=False )
<data_type_conversions><EOS> 
santa_workshop_tour_start_solution_01 = pd.read_csv(".. /input/santa-workshop-tour-start-solution/santa_workshop_tour_start_solution_01.csv" )