Kaggle competition: Titanic - Machine Learning from Disaster
<SOS> metric: categorizationaccuracy Kaggle data source: titanic-machine-learning-from-disaster<compute_test_metric>
from typing import Tuple, Dict, Any
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import tensorflow_addons as tfa
from tensorflow.keras.metrics import Mean
import tensorflow.keras.backend as K
import tensorflow.keras.layers
print("Model: Hybrid Collaborative Filtering")
 print("Similarity: Hybrid(0.2 * Jaccard + 0.8 * Cosine)")
 collab_hybrid = weighted_hybrid([ 
(collab_jac10, 0.5), 
(collab_cos10, 0.5)
 ])
 print("MAP = {0:.3f}".format(mapk_score(s_hidden, get_recs(collab_hybrid), k=k_top)))
 print("UHR = {0:.3f}".format(uhr_score(s_hidden, get_recs(collab_hybrid), k=k_top)) )<compute_train_metric>
def extract_titanic_features(
 source: pd.DataFrame, 
):

 features = {
name: np.array(value, np.float32)
 for name, value in source[["Age", "Fare", "SibSp", "Parch", "Pclass"]].items()
}
for age in [4, 8, 12, 16, 22, 26, 30, 35, 40, 45, 50, 60]:
features['at_least_' + str(age)] = np.array(source['Age'] >= age, np.float32)
 features['name_len'] = np.array(source["Name"].str.len() , np.float32)
 for title in ['Miss.', 'Master', 'Mr.', 'Mrs.']:
features['is_' + title] = np.array(source['Name'].str.contains(title), np.float32)
 features["Sex"] = np.array(source["Sex"], np.str)
 features["Embarked"] = np.array(source["Embarked"], np.str)
 return features
train_labels = titanic_train_df["Survived"]
train_features = extract_titanic_features(titanic_train_df)
 test_features = extract_titanic_features(titanic_test_df)
 inputs = {
k: tf.keras.Input(shape=(1,), name=k, dtype=v.dtype)
 for k, v in train_features.items()
}
preprocessed_inputs = []
numeric_inputs = {k: v for k, v in inputs.items() if v.dtype == tf.float32}
def nan_mask(
 layer: tf.keras.layers.Layer, 
)-> Tuple[tf.keras.layers.Layer, tf.keras.layers.Layer]:

 is_nan = tf.math.is_nan(layer)
 finite_input = tf.where(is_nan, tf.zeros_like(layer), layer)
 norm_input = tf.keras.layers.BatchNormalization()(finite_input)
 mask = tf.cast(tf.math.logical_not(is_nan), tf.float32)
 return mask, norm_input
finite_numeric_inputs = {}
numeric_masks = {}
for k, v in numeric_inputs.items() :
mask_v, finite_v = nan_mask(v)
 preprocessed_inputs.append(mask_v)
 preprocessed_inputs.append(finite_v)
 finite_numeric_inputs[k] = finite_v
numeric_masks[k] = mask_v
accomp_count = tf.math.add(
 finite_numeric_inputs["Parch"], finite_numeric_inputs["SibSp"] 
)
 preprocessed_inputs.append(accomp_count)
 gender_vocab = np.unique(train_features["Sex"])
 gender_lookup = tf.keras.layers.experimental.preprocessing.StringLookup(
 vocabulary=gender_vocab 
)
 gender_onehot = tf.keras.layers.experimental.preprocessing.CategoryEncoding(
 max_tokens=gender_lookup.vocab_size() 
)
 gender_input = gender_onehot(gender_lookup(inputs["Sex"]))
preprocessed_inputs.append(gender_input)
 embarked_vocab = np.array(( "C", "Q", "S"))
embarked_lookup = tf.keras.layers.experimental.preprocessing.StringLookup(
 vocabulary=embarked_vocab 
)
 embarked_onehot = tf.keras.layers.experimental.preprocessing.CategoryEncoding(
 max_tokens=embarked_lookup.vocab_size() 
)
 embarked_input = embarked_onehot(embarked_lookup(inputs["Embarked"]))
preprocessed_inputs.append(embarked_input)
 x = tf.keras.layers.Concatenate()(preprocessed_inputs)
 preprocess_model = tf.keras.Model(inputs, x)
 tf.keras.utils.plot_model(
 preprocess_model,
to_file="preprocess_model.png",
rankdir="LR",
show_shapes=True,
show_layer_names=True,
)
print("Model: Collaborative Filtering with Cosine Similarity(j=10)")
 collab_cos10 = collaborative_filter(s_train, s_input, sim_fn=cosine_sim, j=10, k=k_top)
 print("MAP = {0:.3f}".format(mapk_score(s_hidden, get_recs(collab_cos10), k=k_top)))
 print("UHR = {0:.3f}".format(uhr_score(s_hidden, get_recs(collab_cos10), k=k_top)) )<define_variables>
head = preprocess_model(inputs)
 columns = []
activation="relu"
for i in range(4):
c = head
c = tf.keras.layers.Dense(64, activation=activation )(c)
 c = tf.keras.layers.Dropout(0.5 )(c)
 c = tf.keras.layers.Dense(64, activation=activation )(c)
 c = tf.keras.layers.BatchNormalization()(c)
 c = tf.keras.layers.Dropout(0.2 )(c)
 c = tf.keras.layers.Dense(32, activation=activation )(c)
 columns.append(c)
 if len(columns)== 1:
tail = columns[0]
else:
tail = tf.keras.layers.Add()(columns)
 tail = tf.keras.layers.Dense(16, activation="relu" )(tail)
 tail = tf.keras.layers.Dense(1, activation="sigmoid" )(tail)
 model = tf.keras.Model(inputs, tail)
 model.compile(
 loss=tf.losses.BinaryCrossentropy() ,
optimizer=tfa.optimizers.Lookahead(tf.keras.optimizers.Nadam()),
metrics=["accuracy"], 
)
 if False:
model.summary()
tf.keras.utils.plot_model(
 model,
to_file="final_model.png",
rankdir="LR",
show_shapes=True, 
)
 callbacks = [
tf.keras.callbacks.ProgbarLogger() ,
tf.keras.callbacks.EarlyStopping(
 monitor='val_loss',
patience=10, 
),
]
fit_params = dict(
 batch_size=128,
validation_freq=1,
validation_split=0.1,
epochs=300,
verbose=0,
callbacks=[callbacks], 
)
 submit = True
if submit:
fit_params.update(dict(
 validation_freq=0,
validation_split=0,
epochs=125,
verbose=0, 
))
history = model.fit(
 train_features,
train_labels.to_numpy() ,
**fit_params, 
)
 print("accuracy:", history.history['accuracy'][-1])
 if not submit:
print("val_accuracy:", history.history['val_accuracy'][-1])
 plt.plot(history.history['accuracy'][10:])
 plt.plot(history.history['loss'][10:])
 if not submit:
plt.plot(history.history['val_accuracy'][10:])
 plt.plot(history.history['val_loss'][10:])
 plt.xlabel('epoch')
 plt.show()
results = [ 
(collab_jac10, "Jaccard(j=10)"), 
(collab_cos10, "Cosine(j=10)")
 ]<compute_test_metric>
test_predictions = model(test_features)
 test_ids = titanic_test_df["PassengerId"].to_numpy()
test_hard_predictions =(
 np.floor(np.array(test_predictions)+ 0.5 ).astype("int" ).reshape(-1)
)
 pred_df = pd.Series(data=test_hard_predictions, name="Survived", index=test_ids)
 pred_df.to_csv(
 "submission.csv",
index_label="PassengerId",
header=["Survived"],
)