Kaggle competition: Mechanisms of Action (MoA) Prediction
train_proc = train.copy()
train_proc = train_proc.merge(
 train_sentiment_gr, how='left', on='PetID')
 train_proc = train_proc.merge(
 train_metadata_gr, how='left', on='PetID')
 train_proc = train_proc.merge(
 train_metadata_desc, how='left', on='PetID')
 train_proc = train_proc.merge(
 train_sentiment_desc, how='left', on='PetID')
 test_proc = test.copy()
test_proc = test_proc.merge(
 test_sentiment_gr, how='left', on='PetID')
 test_proc = test_proc.merge(
 test_metadata_gr, how='left', on='PetID')
 test_proc = test_proc.merge(
 test_metadata_desc, how='left', on='PetID')
 test_proc = test_proc.merge(
 test_sentiment_desc, how='left', on='PetID')
 print(train_proc.shape, test_proc.shape)
 assert train_proc.shape[0] == train.shape[0]
assert test_proc.shape[0] == test.shape[0]<merge>
import pickle
import numpy as np
import pandas as pd
import tensorflow as tf
train_breed_main = train_proc[['Breed1']].merge(
 labels_breed, how='left',
left_on='Breed1', right_on='BreedID',
suffixes=('', '_main_breed'))
train_breed_main = train_breed_main.iloc[:, 2:]
train_breed_main = train_breed_main.add_prefix('main_breed_')
 train_breed_second = train_proc[['Breed2']].merge(
 labels_breed, how='left',
left_on='Breed2', right_on='BreedID',
suffixes=('', '_second_breed'))
train_breed_second = train_breed_second.iloc[:, 2:]
train_breed_second = train_breed_second.add_prefix('second_breed_')
 train_proc = pd.concat(
 [train_proc, train_breed_main, train_breed_second], axis=1)
 test_breed_main = test_proc[['Breed1']].merge(
 labels_breed, how='left',
left_on='Breed1', right_on='BreedID',
suffixes=('', '_main_breed'))
test_breed_main = test_breed_main.iloc[:, 2:]
test_breed_main = test_breed_main.add_prefix('main_breed_')
 test_breed_second = test_proc[['Breed2']].merge(
 labels_breed, how='left',
left_on='Breed2', right_on='BreedID',
suffixes=('', '_second_breed'))
test_breed_second = test_breed_second.iloc[:, 2:]
test_breed_second = test_breed_second.add_prefix('second_breed_')
 test_proc = pd.concat(
 [test_proc, test_breed_main, test_breed_second], axis=1)
 print(train_proc.shape, test_proc.shape )<concatenate>
MIXED_PRECISION = False
XLA_ACCELERATE = True
X = pd.concat([train_proc, test_proc], ignore_index=True, sort=False )<define_variables>
if MIXED_PRECISION:
policy = tf.keras.mixed_precision.experimental.Policy("mixed_float16")
 tf.keras.mixed_precision.experimental.set_policy(policy)
 tf.config.optimizer.set_jit(XLA_ACCELERATE )
X_temp = X.copy()
text_columns = ['Description', 'metadata_annots_top_desc', 'sentiment_entities']
categorical_columns = ['main_breed_BreedName', 'second_breed_BreedName']
to_drop_columns = ['PetID', 'Name', 'RescuerID']<merge>
def build_callbacks(
 checkpoint_path,
factor=0.1,
mode="auto",
monitor="val_loss",
patience_for_es=0,
patience_for_rlop=10,
save_best_only=False,
verbose=0, 
):
callbacks = []
if checkpoint_path is not None:
model_checkpoint = tf.keras.callbacks.ModelCheckpoint(
 checkpoint_path,
mode=mode,
monitor=monitor,
save_best_only=save_best_only,
verbose=verbose, 
)
 callbacks.append(model_checkpoint)
 if patience_for_es is not None:
early_stopping = tf.keras.callbacks.EarlyStopping(
 mode=mode, monitor=monitor, patience=patience_for_es, verbose=verbose 
)
 callbacks.append(early_stopping)
 if patience_for_rlop is not None:
reduce_lr_on_plateau = tf.keras.callbacks.ReduceLROnPlateau(
 factor=factor,
monitor=monitor,
mode=mode,
patience=patience_for_rlop,
verbose=verbose, 
)
 callbacks.append(reduce_lr_on_plateau)
 return callbacks
rescuer_count = X.groupby(['RescuerID'])['PetID'].count().reset_index()
rescuer_count.columns = ['RescuerID', 'RescuerID_COUNT']
X_temp = X_temp.merge(rescuer_count, how='left', on='RescuerID' )<feature_engineering>
def build_model(
 input_dim,
output_dim,
activation="relu",
kernel_initializer="glorot_uniform",
label_smoothing=0.0,
momentum=0.99,
n_layers=3,
n_units="auto",
optimizer_params=None,
rate=0.0, 
):
if n_units == "auto":
n_units = 0.5 *(input_dim + output_dim)
 inputs = tf.keras.layers.Input(shape=input_dim)
 x = inputs
for i in range(n_layers - 2):
x = tf.keras.layers.Dense(n_units, kernel_initializer=kernel_initializer )(x)
 x = tf.keras.layers.BatchNormalization(momentum=momentum )(x)
 x = tf.keras.layers.Activation(activation )(x)
 x = tf.keras.layers.Dropout(rate )(x)
 x = tf.keras.layers.Dense(output_dim )(x)
 outputs = tf.keras.layers.Activation("sigmoid" )(x)
 model = ModelWithMixup(inputs=inputs, outputs=outputs)
 if optimizer_params is None:
optimizer_params = {}
loss = tf.keras.losses.BinaryCrossentropy(label_smoothing=label_smoothing)
 optimizer = tf.keras.optimizers.Adam(**optimizer_params)
 model.compile(loss=loss, optimizer=optimizer)
 return model
for i in categorical_columns:
X_temp.loc[:, i] = pd.factorize(X_temp.loc[:, i])[0]<feature_engineering>
def score(Y, Y_pred, eps=1e-15, label_smoothing=0.0):
Y = np.asarray(Y)
 Y = np.ravel(Y)
 if label_smoothing > 0.0:
Y = Y *(1.0 - label_smoothing)+ 0.5 * label_smoothing
Y_pred = np.asarray(Y_pred)
 Y_pred = np.ravel(Y_pred)
 Y_pred = np.clip(Y_pred, eps, 1.0 - eps)
 return -np.mean(Y * np.log(Y_pred)+(1.0 - Y)* np.log(1.0 - Y_pred))
X_text = X_temp[text_columns]
for i in X_text.columns:
X_text.loc[:, i] = X_text.loc[:, i].fillna('none' )<categorify>
def set_seed(seed=0):
os.environ["PYTHONHASHSEED"] = str(seed)
 rn.seed(seed)
 np.random.seed(seed)
 tf.random.set_seed(seed)
 graph = tf.compat.v1.get_default_graph()
session_conf = tf.compat.v1.ConfigProto(
 inter_op_parallelism_threads=1, intra_op_parallelism_threads=1 
)
 sess = tf.compat.v1.Session(graph=graph, config=session_conf)
 tf.compat.v1.keras.backend.set_session(sess )
X_temp['Length_Description'] = X_text['Description'].map(len)
 X_temp['Length_metadata_annots_top_desc'] = X_text['metadata_annots_top_desc'].map(len)
 X_temp['Lengths_sentiment_entities'] = X_text['sentiment_entities'].map(len )<feature_engineering>
def mixup(x, y=None, alpha=0.2, p=1.0, random_state=None):
n, _ = x.shape
if n is not None and rn.random() < p:
random_state = check_random_state(random_state)
 l = random_state.beta(alpha, alpha)
 shuffle = random_state.choice(n, n, replace=False)
 x = l * x +(1.0 - l)* x[shuffle]
if y is not None:
y = l * y +(1.0 - l)* y[shuffle]
return x, y
class ModelWithMixup(tf.keras.models.Model):
def __init__(self, *args, alpha=1.0, p=1.0, **kwargs):
super().__init__(*args, **kwargs)
 self.alpha = alpha
self.p = p
def train_step(self, data):
data = mixup(*data, alpha=self.alpha, p=self.p)
 return super().train_step(data )
n_components = 16
text_features = []
for i in X_text.columns:
print(f'generating features from: {i}')
 tfv = TfidfVectorizer(min_df=2, max_features=None,
strip_accents='unicode', analyzer='word', token_pattern=r'(?u)\b\w+\b',
ngram_range=(1, 3), use_idf=1, smooth_idf=1, sublinear_tf=1)
 svd_ = TruncatedSVD(
 n_components=n_components, random_state=1337)
 tfidf_col = tfv.fit_transform(X_text.loc[:, i].values)
 svd_col = svd_.fit_transform(tfidf_col)
 svd_col = pd.DataFrame(svd_col)
 svd_col = svd_col.add_prefix('TFIDF_{}_'.format(i))
text_features.append(svd_col)
 text_features = pd.concat(text_features, axis=1)
 X_temp = pd.concat([X_temp, text_features], axis=1)
 for i in X_text.columns:
X_temp = X_temp.drop(i, axis=1 )<merge>
class MultilabelStratifiedGroupKFold(_BaseKFold):
def __init__(self, n_splits=5, random_state=None, shuffle=False):
super().__init__(n_splits=n_splits, random_state=random_state, shuffle=shuffle)
 def _iter_test_indices(self, X=None, y=None, groups=None):
cv = MultilabelStratifiedKFold(
 n_splits=self.n_splits,
random_state=self.random_state,
shuffle=self.shuffle, 
)
 value_counts = groups.value_counts()
regluar_indices = value_counts.loc[value_counts <= 18].index.sort_values()
irregluar_indices = value_counts.loc[value_counts > 18].index.sort_values()
group_to_fold = {}
tmp = y.groupby(groups ).mean().loc[regluar_indices]
for fold,(_, test)in enumerate(cv.split(tmp, tmp)) :
group_to_fold.update({group: fold for group in tmp.index[test]})
 sample_to_fold = {}
tmp = y.loc[groups.isin(irregluar_indices)]
for fold,(_, test)in enumerate(cv.split(tmp, tmp)) :
sample_to_fold.update({sample: fold for sample in tmp.index[test]})
 folds = groups.map(group_to_fold)
 is_na = folds.isna()
folds[is_na] = folds[is_na].index.map(sample_to_fold ).values
for i in range(self.n_splits):
yield np.where(folds == i)[0]
X_temp = X_temp.merge(img_features, how='left', on='PetID' )<define_variables>
dtype = {"cp_type": "category", "cp_dose": "category"}
index_col = "sig_id"
train_features = pd.read_csv(
 ".. /input/lish-moa/train_features.csv", dtype=dtype, index_col=index_col 
)
 test_features = pd.read_csv(
 ".. /input/lish-moa/test_features.csv", dtype=dtype, index_col=index_col 
)
 X = train_features.select_dtypes("number")
 X_test = test_features.select_dtypes("number")
 Y = pd.read_csv(".. /input/lish-moa/train_targets_scored.csv", index_col=index_col)
 groups = pd.read_csv(
 ".. /input/lish-moa/train_drug.csv", index_col=index_col, squeeze=True 
)
 train_size, n_features = X.shape
test_size, _ = X_test.shape
_, n_classes = Y.shape
train_df_ids = train[['PetID']]
test_df_ids = test[['PetID']]
train_df_imgs = pd.DataFrame(train_image_files)
 train_df_imgs.columns = ['image_filename']
train_imgs_pets = train_df_imgs['image_filename'].apply(lambda x: x.split(split_char)[-1].split('-')[0])
 test_df_imgs = pd.DataFrame(test_image_files)
 test_df_imgs.columns = ['image_filename']
test_imgs_pets = test_df_imgs['image_filename'].apply(lambda x: x.split(split_char)[-1].split('-')[0])
 train_df_imgs = train_df_imgs.assign(PetID=train_imgs_pets)
 test_df_imgs = test_df_imgs.assign(PetID=test_imgs_pets)
 def getSize(filename):
st = os.stat(filename)
 return st.st_size
def getDimensions(filename):
img_size = Image.open(filename ).size
return img_size
train_df_imgs['image_size'] = train_df_imgs['image_filename'].apply(getSize)
 train_df_imgs['temp_size'] = train_df_imgs['image_filename'].apply(getDimensions)
 train_df_imgs['width'] = train_df_imgs['temp_size'].apply(lambda x : x[0])
 train_df_imgs['height'] = train_df_imgs['temp_size'].apply(lambda x : x[1])
 train_df_imgs = train_df_imgs.drop(['temp_size'], axis=1)
 test_df_imgs['image_size'] = test_df_imgs['image_filename'].apply(getSize)
 test_df_imgs['temp_size'] = test_df_imgs['image_filename'].apply(getDimensions)
 test_df_imgs['width'] = test_df_imgs['temp_size'].apply(lambda x : x[0])
 test_df_imgs['height'] = test_df_imgs['temp_size'].apply(lambda x : x[1])
 test_df_imgs = test_df_imgs.drop(['temp_size'], axis=1)
 aggs = {
'image_size': ['sum', 'mean', 'var'],
'width': ['sum', 'mean', 'var'],
'height': ['sum', 'mean', 'var'],
}
agg_train_imgs = train_df_imgs.groupby('PetID' ).agg(aggs)
 new_columns = [
k + '_' + agg for k in aggs.keys() for agg in aggs[k]
]
agg_train_imgs.columns = new_columns
agg_train_imgs = agg_train_imgs.reset_index()
agg_test_imgs = test_df_imgs.groupby('PetID' ).agg(aggs)
 new_columns = [
k + '_' + agg for k in aggs.keys() for agg in aggs[k]
]
agg_test_imgs.columns = new_columns
agg_test_imgs = agg_test_imgs.reset_index()
agg_imgs = pd.concat([agg_train_imgs, agg_test_imgs], axis=0 ).reset_index(drop=True )<merge>
n_seeds = 5
n_splits = 5
shuffle = True
params = {"n_layers": 4, "rate": 0.25}
callbacks_params = {"patience_for_es": 20, "save_best_only": True}
fit_params = {"epochs": 1_000}
X_temp = X_temp.merge(agg_imgs, how='left', on='PetID' )<save_to_csv>
%%time
Y_pred = np.zeros(( train_size, n_classes))
Y_pred = pd.DataFrame(Y_pred, columns=Y.columns, index=Y.index)
 for i in range(n_seeds):
set_seed(seed=i)
 cv = MultilabelStratifiedGroupKFold(
 n_splits=n_splits, random_state=i, shuffle=shuffle 
)
 for j,(train, valid)in enumerate(cv.split(X, Y, groups)) :
model_path = f"model_seed_{i}_fold_{j}.h5"
model = build_model(n_features, n_classes, **params)
 callbacks = build_callbacks(model_path, **callbacks_params)
 model.fit(
 X.iloc[train],
Y.iloc[train],
callbacks=callbacks,
validation_data=(X.iloc[valid], Y.iloc[valid]),
**fit_params, 
)
 model.load_weights(model_path)
 Y_pred.iloc[valid] += model.predict(X.iloc[valid])/ n_seeds
Y_pred[train_features["cp_type"] == "ctl_vehicle"] = 0.0
X_train.to_csv('train_precomputed.csv', index=False)
 X_test.to_csv('test_precomputed.csv', index=False )<define_variables>
score(Y, Y_pred )
X_train_non_null = X_train.fillna(-1)
 X_test_non_null = X_test.fillna(-1 )<count_missing_values>
%%time
Y_pred = np.zeros(( test_size, n_classes))
Y_pred = pd.DataFrame(Y_pred, columns=Y.columns, index=X_test.index)
 for i in range(n_seeds):
for j in range(n_splits):
model = tf.keras.models.load_model(
 f"model_seed_{i}_fold_{j}.h5",
compile=False,
custom_objects={"ModelWithMixup": ModelWithMixup}, 
)
 Y_pred += model.predict(X_test)/ n_seeds / n_splits
Y_pred[test_features["cp_type"] == "ctl_vehicle"] = 0.0
X_train_non_null.isnull().any().any() , X_test_non_null.isnull().any().any()<import_modules>
Y_pred.to_csv("submission.csv" )