Kaggle competition: University of Liverpool - Ion Switching
<SOS> metric: MacroFScore Kaggle data source: university-of-liverpool-ion-switching<compute_test_metric>
py.init_notebook_mode(connected=True)
 pd.set_option('max_columns', 50)
def discriminator_loss(real_output, fake_output):
real_loss = cross_entropy(tf.ones_like(real_output), real_output)
 fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
 total_loss = real_loss + fake_loss
return total_loss<compute_test_metric>
def macro_f1_score(y_true, y_pred, n_labels):
total_f1 = 0.
 for i in range(n_labels):
yt = y_true == i
yp = y_pred == i
tp = np.sum(yt & yp)
 tpfp = np.sum(yp)
 tpfn = np.sum(yt)
 if tpfp == 0:
print('[WARNING] F-score is ill-defined and being set to 0.0 in labels with no predicted samples.')
 precision = 0.
 else:
precision = tp / tpfp
if tpfn == 0:
print(f'[ERROR] label not found in y_true...')
 recall = 0.
 else:
recall = tp / tpfn
if precision == 0.or recall == 0.:
f1 = 0.
 else:
f1 = 2 * precision * recall /(precision + recall)
 total_f1 += f1
return total_f1 / n_labels
macro_f1_score_nb = nb.jit(nb.float64(nb.int32[:], nb.int32[:], nb.int64), nopython=True, nogil=True )(macro_f1_score )
def generator_loss(fake_output):
return cross_entropy(tf.ones_like(fake_output), fake_output )<choose_model_class>
%%time
datadir = Path('/kaggle/input/liverpool-ion-switching-feather')
 train = pd.read_feather(datadir/'train.feather')
 test = pd.read_feather(datadir/'test.feather')
 submission = pd.read_feather(datadir/'sample_submission.feather' )
generator_optimizer = tf.keras.optimizers.Adam(1e-4)
 discriminator_optimizer = tf.keras.optimizers.Adam(1e-4 )<train_model>
signal_array = train['signal'].values
open_channels = train['open_channels'].values
test_signal_array = test['signal'].values
checkpoint_dir = './training_checkpoints'
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt")
 checkpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer,
discriminator_optimizer=discriminator_optimizer,
generator=generator,
discriminator=discriminator )<define_variables>
debug = False
arch = 'lgb'
outdir = Path('.' )
EPOCHS = 75
noise_dim = 100
num_examples_to_generate = 6000
seed = tf.random.normal([num_examples_to_generate, noise_dim] )<statistical_test>

 def clean_train(train):
def f(x, low, high, mid):
return -(( -low + high)/ 625)*(x - mid)** 2 + high - low
a = 500000
b = 600000
train.loc[train.index[a:b], 'signal'] = train.signal[a:b].values - 3 *(train.time.values[a:b] - 50)/ 10.
 batch = 7
a = 500000 *(batch - 1)
 b = 500000 * batch
train.loc[train.index[a:b], 'signal'] = train.signal.values[a:b] - f(train.time[a:b].values, -1.817, 3.186, 325)
 batch = 8
a = 500000 *(batch - 1)
 b = 500000 * batch
train.loc[train.index[a:b], 'signal'] = train.signal.values[a:b] - f(train.time[a:b].values, -0.094, 4.936, 375)
 batch = 9
a = 500000 *(batch - 1)
 b = 500000 * batch
train.loc[train.index[a:b], 'signal'] = train.signal.values[a:b] - f(train.time[a:b].values, 1.715, 6.689, 425)
 batch = 10
a = 500000 *(batch - 1)
 b = 500000 * batch
train.loc[train.index[a:b], 'signal'] = train.signal.values[a:b] - f(train.time[a:b].values, 3.361, 8.45, 475)
 return train
def clean_test(test):
start = 500
a = 0
b = 100000
test.loc[test.index[a:b], 'signal'] = test.signal.values[a:b] - 3 *(test.time.values[a:b] - start)/ 10.
 start = 510
a = 100000
b = 200000
test.loc[test.index[a:b], 'signal'] = test.signal.values[a:b] - 3 *(test.time.values[a:b] - start)/ 10.
 start = 540
a = 400000
b = 500000
test.loc[test.index[a:b], 'signal'] = test.signal.values[a:b] - 3 *(test.time.values[a:b] - start)/ 10.
 start = 560
a = 600000
b = 700000
test.loc[test.index[a:b], 'signal'] = test.signal.values[a:b] - 3 *(test.time.values[a:b] - start)/ 10.
 start = 570
a = 700000
b = 800000
test.loc[test.index[a:b], 'signal'] = test.signal.values[a:b] - 3 *(test.time.values[a:b] - start)/ 10.
 start = 580
a = 800000
b = 900000
test.loc[test.index[a:b], 'signal'] = test.signal.values[a:b] - 3 *(test.time.values[a:b] - start)/ 10.
 def f(x):
return -(0.00788)*(x - 625)** 2 + 2.345 + 2.58
a = 1000000
b = 1500000
test.loc[test.index[a:b], 'signal'] = test.signal.values[a:b] - f(test.time[a:b].values)
 return test
def plot_all_train_signal(train, title):
plt.figure(figsize=(20,5)) ; res = 1000
plt.plot(range(0,train.shape[0],res),train.signal[0::res])
 for i in range(11): plt.plot([i*500000,i*500000],[-5,12.5],'r')
 for j in range(10): plt.text(j*500000+200000,10,str(j+1),size=20)
 plt.xlabel('Row',size=16); plt.ylabel('Signal',size=16);
plt.title(title,size=20)
 plt.show()
def plot_all_test_signal(test, title):
let = ['A','B','C','D','E','F','G','H','I','J']
plt.figure(figsize=(20,5))
res = 1000
plt.plot(range(0,test.shape[0],res),test.signal[0::res])
 for i in range(5): plt.plot([i*500000,i*500000],[-5,12.5],'r')
 for i in range(21): plt.plot([i*100000,i*100000],[-5,12.5],'r:')
 for k in range(4): plt.text(k*500000+250000,10,str(k+1),size=20)
 for k in range(10): plt.text(k*100000+40000,7.5,let[k],size=16)
 plt.title(title,size=20)
 plt.show()
@tf.function
def train_step(images):
noise = tf.random.normal([BATCH_SIZE, noise_dim])
 with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
generated_images = generator(noise, training=True)
 real_output = discriminator(images, training=True)
 fake_output = discriminator(generated_images, training=True)
 gen_loss = generator_loss(fake_output)
 disc_loss = discriminator_loss(real_output, fake_output)
 gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
 gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)
 generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))<train_model>
if debug:
s = 500000*4
train = train.iloc[s:s+50000]
test = test.iloc[:1000]
submission = submission.iloc[:1000]
def train(dataset, epochs):
for epoch in range(epochs):
start = time.time()
for image_batch in dataset:
train_step(image_batch)
 display.clear_output(wait=True)
 generate_and_save_images(generator,
epoch + 1,
seed)
 if(epoch + 1)% 15 == 0:
checkpoint.save(file_prefix = checkpoint_prefix)
 print('Time for epoch {} is {} sec'.format(epoch + 1, time.time() -start))
display.clear_output(wait=True)
 new_images=generate_and_save_images(generator,
epochs,
seed)
 return new_images<define_variables>
def filter_wave(x, cutoff=(-1, -1), N=4, filtering='lfilter'):

 assert x.ndim == 1
output = 'sos' if filtering == 'sos' else 'ba'
if cutoff[0] <= 0 and cutoff[1] <= 0:
return x
elif cutoff[0] <= 0 and cutoff[1] > 0:
output = signal.butter(N, Wn=cutoff[1]/len(x), btype='lowpass', output=output)
 elif cutoff[0] > 0 and cutoff[1] <= 0:
output = signal.butter(N, Wn=cutoff[0]/len(x), btype='highpass', output=output)
 else:
output = signal.butter(N, Wn=(cutoff[0]/len(x), cutoff[1]/len(x)) , btype='bandpass', output=output)
 if filtering == 'lfilter':
b, a = output
return signal.lfilter(b, a, x)
 elif filtering == 'filtfilt':
b, a = output
return signal.filtfilt(b, a, x)
 elif filtering == 'sos':
sos = output
return signal.sosfilt(sos, x)
 else:
raise ValueError("[ERROR] Unexpected value filtering={}".format(filtering))
%%time
train_dataset = tf.data.Dataset.from_tensor_slices(X_label0 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images0=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label1 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images1=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label2 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images2=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label3 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images3=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label4 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images4=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label5 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images5=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label6 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images6=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label7 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images7=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label8 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images8=train(train_dataset, EPOCHS)
 train_dataset = tf.data.Dataset.from_tensor_slices(X_label9 ).shuffle(BUFFER_SIZE ).batch(BATCH_SIZE)
 gen_images9=train(train_dataset, EPOCHS)
<concatenate>
train_separate_indices = [
0, 500_000, 600_000, 1_000000, 1_500000, 2_000000, 2_500000,
3_000000, 3_500000, 4_000000, 4_500000, 5_000000]
test_separate_indices = [
0, 100_000, 200_000, 300_000, 400_000, 500_000, 600_000, 700_000,
800_000, 900_000, 1_000000, 1_500000, 2_000000]
def _create_total_batch_indices(separate_indices):
s = separate_indices
total_batch = np.zeros(( s[-1],), dtype=np.int64)
 for i in range(len(s)- 1):
total_batch[s[i]:s[i+1]] = i
return total_batch
def create_total_batch_indices(train: bool = True):
separate_indices = train_separate_indices if train else test_separate_indices
return _create_total_batch_indices(separate_indices)
 class Preprocessor(object):

 def __init__(self, feature_cols=None, debug=False, use_sep=True):
self.feature_cols = feature_cols
self.debug = debug
self.use_sep = use_sep
self.window_list = [5000, 10000, 50000]
def preprocess(self, tt, train=True):
feature_cols = self.feature_cols
window_list = self.window_list
window_str = '-'.join(list(map(str, window_list)))
 cache_path = f'pp_tt_train{int(train)}_debug{int(self.debug)}_usesep{int(self.use_sep)}_w{window_str}.feather'
msignal_cols = []
for window in window_list:
msignal_cols.extend([
f'signal_batch_{window}_min', f'signal_batch_{window}_max',
f'signal_batch_{window}_std', f'signal_batch_{window}_mean',
f'mean_abs_chg_batch_{window}',
f'abs_max_batch_{window}', f'abs_min_batch_{window}',
f'range_batch_{window}', f'maxtomin_batch_{window}', f'abs_avg_batch_{window}'
])
 msignal_cols.extend([
'signal_shift+1', 'signal_shift-1',
'signal_shift+2', 'signal_shift-2'])
 default_feature_cols = ['signal', 'baseline']
default_feature_cols.extend(msignal_cols)
 default_feature_cols.extend([f'{c}_msignal' for c in msignal_cols])
 default_feature_cols.extend([f'{c}_mbase' for c in msignal_cols])
 if not os.path.exists(cache_path):
tt = tt.sort_values(by=['time'] ).reset_index(drop=True)
 tt.index =(( tt.time * 10_000)- 1 ).values
if self.use_sep:
separate_indices = train_separate_indices if train else test_separate_indices
separate_indices = separate_indices[:len(tt)]
tt['total_batch'] = create_total_batch_indices(train=train)[:len(tt)]
else:
raise NotImplementedError()
separate_indices = None
tt['total_batch'] = tt.index // 500_000
tt['batch'] = tt.index // 50_000
tt['batch_index'] = tt.index -(tt.batch * 50_000)
 tt['batch_slices'] = tt['batch_index'] // 5_000
tt['batch_slices2'] = tt.apply(lambda r: '_'.join(
 [str(r['batch'] ).zfill(3), str(r['batch_slices'] ).zfill(3)]), axis=1)
 cutoff_high = 100
signal = tt['signal'].values
total_batch = tt['total_batch'].values
smooth_fn = lambda x: filter_wave(x, cutoff=(0, cutoff_high), filtering='filtfilt')
 baseline = np.concatenate([smooth_fn(signal[separate_indices[k]:separate_indices[k+1]])
 for k in range(total_batch[-1] + 1)])
 tt['baseline'] = baseline
for window in window_list:
rolling_df = tt.groupby('total_batch')['signal'].rolling(
 window=window, min_periods=1, center=True)
 tt[f'signal_batch_{window}_min'] = rolling_df.min().values
tt[f'signal_batch_{window}_max'] = rolling_df.max().values
tt[f'signal_batch_{window}_std'] = rolling_df.std().values
tt[f'signal_batch_{window}_mean'] = rolling_df.mean().values
tt[f'mean_abs_chg_batch_{window}'] = rolling_df.apply(
 lambda x: np.mean(np.abs(np.diff(x))), raw=True ).values
tt[f'abs_max_batch_{window}'] = rolling_df.apply(
 lambda x: np.max(np.abs(x)) , raw=True ).values
tt[f'abs_min_batch_{window}'] = rolling_df.apply(
 lambda x: np.min(np.abs(x)) , raw=True ).values
tt[f'range_batch_{window}'] = \
tt[f'signal_batch_{window}_max'] - tt[f'signal_batch_{window}_min']
tt[f'maxtomin_batch_{window}'] = \
tt[f'signal_batch_{window}_max'] / tt[f'signal_batch_{window}_min']
tt[f'abs_avg_batch_{window}'] = \ 
(tt[f'abs_min_batch_{window}'] + tt[f'abs_max_batch_{window}'])/ 2
tt['signal_shift+1'] = tt.groupby(['batch'] ).shift(1, fill_value=0.) ['signal']
tt['signal_shift-1'] = tt.groupby(['batch'] ).shift(-1, fill_value=0.) ['signal']
tt['signal_shift+2'] = tt.groupby(['batch'] ).shift(2, fill_value=0.) ['signal']
tt['signal_shift-2'] = tt.groupby(['batch'] ).shift(-2, fill_value=0.) ['signal']
for c in msignal_cols:
tt[f'{c}_msignal'] = tt[c] - tt['signal']
for c in msignal_cols:
tt[f'{c}_mbase'] = tt[c] - tt['baseline']
tt = tt.replace([np.inf, -np.inf], np.nan)
 print('Number of nan', tt.isna().sum().sum())
 tt.fillna(-1, inplace=True)
 print(f'saving to {cache_path}')
 else:
print(f'loading from {cache_path}')
 tt = pd.read_feather(cache_path)
 if feature_cols is None:
feature_cols = default_feature_cols
X_train = tt[feature_cols]
if train:
y_train = tt['open_channels'].values
else:
y_train = None
return X_train, y_train
gen_images=np.vstack(( gen_images0,gen_images1,gen_images2,gen_images3,gen_images4,gen_images5,gen_images6,gen_images7,gen_images8,gen_images9))
print(gen_images.shape)
 Y_labels=np.vstack(( Y_label0,Y_label1,Y_label2,Y_label3,Y_label4,Y_label5,Y_label6,Y_label7,Y_label8,Y_label9,))
Y_labels=Y_labels.reshape(60000)
<concatenate>
pp = Preprocessor(debug=debug)
 with timer('preprocess train'):
X_train, y_train = pp.preprocess(train )
train_CNN_X=np.vstack(( train_CNN_X.reshape(-1,28,28,1),gen_images.reshape(-1,28,28,1)))
 print(train_CNN_X.shape)
 train_CNN_Y=np.vstack(( train_CNN_Y,Y_labels))
train_CNN_Y=train_CNN_Y.reshape(120000)
 print(train_CNN_Y.shape )<choose_model_class>
class F1MacroScorerWrapper(object):

 def fit(self, X, y):
print('F1MacroScorerWrapper fit called!')
 def predict(self, X):
raise NotImplementedError()
def score(self, X, y):
y_pred = self.predict(X)
 y_pred_valid_int = np.round(np.clip(y_pred, 0, 10))
macro_f1 = macro_f1_score_nb(y.astype(np.int32), y_pred_valid_int.astype(np.int32), 10)
 return macro_f1
class LGBWrapper(F1MacroScorerWrapper):
def __init__(self, lgb_model):
self.lgb_model = lgb_model
def predict(self, X):
return self.lgb_model.predict(X, num_iteration=self.lgb_model.best_iteration)
 def feature_importance(self, **kwargs):
return self.lgb_model.feature_importance(**kwargs)
 def calc_permutation_importance(model, valid_data, feature_names=None):

 perm = PermutationImportance(
 model, random_state=1, cv='prefit' ).fit(*valid_data)
 perm_importance_df = pd.DataFrame({
'importance': perm.feature_importances_
}, index=feature_names ).sort_values('importance', ascending=True)
 return perm, perm_importance_df
model = keras.Sequential([
keras.layers.Conv2D(filters=32, kernel_size=(5, 5),padding='Same',activation='relu',input_shape=(28,28,1)) ,
keras.layers.Conv2D(filters=32,kernel_size=(5,5),padding='Same',activation='relu',),
keras.layers.BatchNormalization(momentum=.15),
keras.layers.MaxPool2D(pool_size=(2,2)) ,
keras.layers.Dropout(0.25),
keras.layers.Conv2D(filters = 64, kernel_size =(3,3),padding = 'Same', activation ='relu'),
keras.layers.Conv2D(filters = 64, kernel_size =(3,3),padding = 'Same', activation ='relu'),
keras.layers.BatchNormalization(momentum=0.15),
keras.layers.MaxPool2D(pool_size=(2,2), strides=(2,2)) ,
keras.layers.Dropout(0.25),
keras.layers.Conv2D(filters = 32, kernel_size =(5,5),padding = 'Same', activation ='relu', input_shape =(28,28,1)) ,
keras.layers.Conv2D(filters = 32, kernel_size =(5,5),padding = 'Same', activation ='relu'),
keras.layers.BatchNormalization(momentum=.15),
keras.layers.MaxPool2D(pool_size=(2,2)) ,
keras.layers.Dropout(0.25),
keras.layers.Flatten() ,
keras.layers.Dense(256, activation='relu'),
keras.layers.Dropout(0.4),
keras.layers.Dense(10, activation='softmax')
 ])
 model.summary()<choose_model_class>
def fit_lgb(train, val, devices=(-1,), seed=None, cat_features=None,
num_rounds=1500, lr=0.1):

 X_train, y_train = train
X_valid, y_valid = val
metric = 'l1'
params = {'num_leaves': 128,
'min_data_in_leaf': 64,
'objective': 'huber',
'max_depth': -1,
'learning_rate': lr,
"boosting": "gbdt",
"bagging_freq": 5,
"bagging_fraction": 0.8,
"bagging_seed": 11,
"metric": metric,
"verbosity": -1,
'reg_alpha': 0.1,
'reg_lambda': 0.3
}
device = devices[0]
if device == -1:
pass
else:
print(f'using gpu device_id {device}...')
 params.update({'device': 'gpu', 'gpu_device_id': device})
 params['seed'] = seed
early_stop = 20
verbose_eval = 20
d_train = lgb.Dataset(X_train, label=y_train, categorical_feature=cat_features)
 d_valid = lgb.Dataset(X_valid, label=y_valid, categorical_feature=cat_features)
 watchlist = [d_train, d_valid]
print('training LGB:')
 model = lgb.train(params,
train_set=d_train,
num_boost_round=num_rounds,
valid_sets=watchlist,
verbose_eval=verbose_eval,
early_stopping_rounds=early_stop)
 y_pred_valid = model.predict(X_valid, num_iteration=model.best_iteration)
 print('best_score', model.best_score)
 log = {'train/mae': model.best_score['training'][metric],
'valid/mae': model.best_score['valid_1'][metric]}
return model, y_pred_valid, log
optimizer=keras.optimizers.Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999, amsgrad=False)
 model.compile(optimizer=optimizer,
loss='sparse_categorical_crossentropy',
metrics=['accuracy'] )<train_model>
calc_perm = True
y_valid_pred_total = np.zeros(X_train.shape[0])
 models = []
log_list = []
macro_f1_list = []
gain_importance_list = []
split_importance_list = []
perm_importance_list = []
for fold_idx,(train_idx, valid_idx)in enumerate(cv_iter):
train_data = X_train.iloc[train_idx, :], y_train[train_idx]
valid_data = X_train.iloc[valid_idx, :], y_train[valid_idx]
print('fold_idx', fold_idx, 'train', len(train_idx), 'valid', len(valid_idx))
model, y_pred_valid, log = fit_lgb(train_data, valid_data,
num_rounds=5000, lr=0.3)
 model = LGBWrapper(model)
 print('log', log)
 y_valid_pred_total[valid_idx] = y_pred_valid
models.append(model)
 y_true_valid = valid_data[1]
y_pred_valid_int = np.round(np.clip(y_pred_valid, 0, 10))
macro_f1 = macro_f1_score(y_true_valid, y_pred_valid_int, 10)
 print('macro_f1', macro_f1)
 log['fold_idx'] = fold_idx
log['macro_f1'] = macro_f1
log_list.append(log)
 macro_f1_list.append(macro_f1)
 feature_names = train_data[0].columns.tolist()
gain_importance_df = calc_model_importance(
 model, feature_names=feature_names, importance_type='gain')
 gain_importance_list.append(gain_importance_df)
 split_importance_df = calc_model_importance(
 model, feature_names=feature_names, importance_type='split')
 split_importance_list.append(split_importance_df)
 if calc_perm:
print('calculating permutation importance...')
 if(debug and fold_idx == 0)or not debug:
with timer('calc_permutation_importance'):
perm, perm_importance_df = calc_permutation_importance(
 model, valid_data, feature_names=feature_names)
 perm_importance_list.append(perm_importance_df)
 gc.collect()
model.fit(train_CNN_X, train_CNN_Y, epochs=75)
 Test accuracy:', test_acc )<save_to_csv>
log_df = pd.DataFrame(log_list)
 log_df.to_csv(outdir/'log.csv', index=False)
 logmean_df = log_df.mean(axis=0)
 logmean_df.to_csv(outdir/'log_mean.csv' )
test1=test.reshape(-1,28,28,1)
 prediction1=model.predict(test1)
 prediction1=np.argmax(prediction1,axis=1)
 submission_sample['label']=prediction1
submission_sample.to_csv('submission.csv',index=False)
<load_from_csv>
def calc_mean_importance(importance_df_list):
mean_importance = np.mean(
 np.array([df['importance'].values for df in importance_df_list]), axis=0)
 mean_df = importance_df_list[0].copy()
mean_df['importance'] = mean_importance
return mean_df
train_data = pd.read_csv("/kaggle/input/Kannada-MNIST/train.csv")
 test_data = pd.read_csv("/kaggle/input/Kannada-MNIST/test.csv" )<prepare_x_and_y>
mean_gain_df = calc_mean_importance(gain_importance_list)
 plot_importance(mean_gain_df, title='Model feature importance by gain')
 mean_gain_df = mean_gain_df.reset_index().rename(columns={'index': 'feature_names'})
 mean_gain_df.to_csv(outdir / 'gain_importance_mean.csv', index=False )
num_classes = 10
img_rows = 28
img_cols = 28
def raw_to_img_array(raw_data):
y = np.array(raw_data.iloc[:, 0])
 out_y = keras.utils.to_categorical(y, num_classes)
 x = np.array(raw_data.iloc[:,1:])
 num_images = raw_data.shape[0]
out_x = x.reshape(num_images, img_rows, img_cols, 1)
 out_x = out_x / 255
return out_x, out_y 
<set_options>
mean_split_df = calc_mean_importance(split_importance_list)
 plot_importance(mean_split_df, title='Model feature importance by split')
 mean_split_df = mean_split_df.reset_index().rename(columns={'index': 'feature_names'})
 mean_split_df.to_csv(outdir / 'split_importance_mean.csv', index=False )
datagen = ImageDataGenerator(
 featurewise_center=False,
samplewise_center=False,
featurewise_std_normalization=False,
samplewise_std_normalization=False,
zca_whitening=False,
rotation_range=10,
zoom_range = 0.2,
shear_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
horizontal_flip=False,
vertical_flip=False,
)<split>
if calc_perm:
mean_perm_df = calc_mean_importance(perm_importance_list)
 plot_importance(mean_perm_df, title='Model permutation importance')
 mean_perm_df = mean_perm_df.reset_index().rename(columns={'index': 'feature_names'})
 mean_perm_df.to_csv(outdir / 'perm_importance_mean.csv', index=False )
train_x, train_y = raw_to_img_array(train_data)
 train_x,val_x,train_y,val_y=train_test_split(train_x, train_y, test_size=0.2)
<choose_model_class>
y_valid_pred_total_int = np.round(np.clip(y_valid_pred_total, 0, 10))
macro_f1 = macro_f1_score(y_train, y_valid_pred_total_int, 10)
 print('Total CV: macro_f1', macro_f1, 'macro_f1_list', macro_f1_list )
kannada_model = Sequential()
kannada_model.add(Conv2D(128, kernel_size=(4, 4),
activation='relu',padding="same",
input_shape=(img_rows, img_cols, 1)))
 kannada_model.add(BatchNormalization())
 kannada_model.add(MaxPool2D(pool_size=2,padding="valid"))
kannada_model.add(Dropout(0.25))
kannada_model.add(Conv2D(256,kernel_size=(4, 4),padding="same", activation='relu'))
kannada_model.add(BatchNormalization())
 kannada_model.add(MaxPool2D(pool_size=2,padding="valid"))
kannada_model.add(Dropout(0.25))
kannada_model.add(Conv2D(512,kernel_size=(4, 4),padding="same", activation='relu'))
kannada_model.add(BatchNormalization())
 kannada_model.add(MaxPool2D(pool_size=2,padding="valid"))
kannada_model.add(Dropout(0.25))
kannada_model.add(Flatten())
 kannada_model.add(Dense(1024, activation='relu'))
kannada_model.add(BatchNormalization())
 kannada_model.add(Dropout(0.4))
kannada_model.add(Dense(256, activation='relu'))
kannada_model.add(BatchNormalization())
 kannada_model.add(Dropout(0.4))
kannada_model.add(Dense(num_classes, activation='softmax'))
kannada_model.compile(loss=keras.losses.categorical_crossentropy,
optimizer="adam",
metrics=['accuracy'])
 learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', patience=5, verbose=1, factor=0.5, min_lr=0.00001)
 checkpoint = ModelCheckpoint("bestmodel.model", monitor='val_acc', verbose=1, save_best_only=True)
<train_model>
print('start model prediction...')
 with timer('preprocess test'):
X_test, _ = pp.preprocess(test, train=False)
 y_test_pred_total = np.zeros(X_test.shape[0])
 for i, model in enumerate(models):
print(f'predicting {i}-th model')
 y_pred_test = model.predict(X_test)
 y_test_pred_total += y_pred_test
y_test_pred_total /= len(models)
 y_test_pred_total_int = np.round(np.clip(y_test_pred_total, 0, 10))
<predict_on_test><EOS> 
submission['open_channels'] = y_test_pred_total_int.astype(np.int64)
 submission.to_csv(outdir / 'submission.csv', index=False, float_format='%.4f')
 np.savez_compressed(
 outdir / 'pred.npz',
valid=y_valid_pred_total, test=y_test_pred_total)