{"cells":[{"metadata":{},"cell_type":"markdown","source":"You can try on your best submit the post-processing technique of our team (inspired by the ideas of @4ui_iurz1)\n\n\n\nIdea: sort by Position3 and apply fixed 1x3 filters for each channel.\n\nFor this, for each image, its neighbor was calculated on the left and on the right.\nThen these filters were applied several times, seriously smoothing the result.\n\nDataset with precalculated neigbours provided here\n\nThis technology improved the leaderboard competition metric by a value in the range of 0.002 - 0.01\n\nThe following is an example of applying this filter to the test data from the first and second stages."},{"metadata":{},"cell_type":"markdown","source":"## Some Helper Functions"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"from sklearn.metrics import log_loss\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm_notebook as tqdm\npd.set_option(\"display.max_rows\", 50)\n\ndef calc_logloss(targets, outputs, eps=1e-5):\n    logloss_classes = [log_loss(np.floor(targets[:,i]), np.clip(outputs[:,i], eps, 1-eps)) for i in range(6)]\n    return {\n        'logloss_classes': logloss_classes,\n        'logloss': np.average(logloss_classes, weights=[2,1,1,1,1,1]),\n    }\n\ndef build_2d_labels(labels_1d):\n    labels = np.zeros((labels_1d.shape[0] // 6, 6))\n    for class_id in range(6):\n        labels[:, class_id] = labels_1d[class_id::6]\n    return labels\n\ndef eval_submit(sub, answers_path='../input/hemorrhagehelpers/stage_1_answers.npy'):\n    labels_1d = sub.sort_values('ID').Label.values\n    labels_2d = build_2d_labels(labels_1d)\n    targets = np.load(answers_path)\n    return calc_logloss(targets, labels_2d)\n\ndef eval_df(df, answers_path='../input/hemorrhagehelpers/stage_1_answers.npy'):\n    df.sort_index(inplace=True)\n    targets = np.load(answers_path)\n    metrics = {}\n    for col in tqdm(df.columns):\n        labels_1d = df[col].values\n        labels_2d = build_2d_labels(labels_1d)\n        current_loss = calc_logloss(targets, labels_2d)['logloss']\n        current_repr = float('{:.6}'.format(current_loss))\n        metrics[col] = current_repr\n    \n    info = pd.DataFrame.from_dict([metrics]).T\n    info.columns = ['leaderboard']\n    return info.sort_values('leaderboard')\n\ndef add_table(df, fname, colname):\n    sub = pd.read_csv(fname)\n    sub = sub.sort_values('ID').reset_index(drop=True)\n    sub['image_id'] = sub.ID.apply(lambda x: '_'.join(x.split('_')[:-1]))\n    df[colname] = sub.set_index('ID').Label","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Loading first stage submissions\n\nFor comparison, I’ll upload the first stage submissions."},{"metadata":{"trusted":true},"cell_type":"code","source":"stage1_names = {    \n    'takato_original_seresnext': '../input/hemoorhagesubsfirststage/se_resnext50_32x4d_102105_hflip.csv',\n    'takato_original_effb1': '../input/hemoorhagesubsfirststage/efficientnet-b1_102407_hflip.csv',\n    'takato_original_effb2': '../input/hemoorhagesubsfirststage/efficientnet-b2_102000_hflip.csv',\n    'takato_original_effb3': '../input/hemoorhagesubsfirststage/efficientnet-b3_102112_hflip.csv',\n    'takato_original_effb4': '../input/hemoorhagesubsfirststage/efficientnet-b4_102100_hflip.csv',\n    \n    'agro_b7': '../input/hemoorhagesubsfirststage/agroeffnet_stage1_test_tta8.csv',\n    'sneddy_b7': '../input/hemoorhagesubsfirststage/effnet-b7-e1.csv',\n    'resnet152': '../input/hemoorhagesubsfirststage/resnet152_stage1.csv',\n    'effnet_b5': '../input/hemoorhagesubsfirststage/effnetb5_stage1_test_tta8.csv',\n    'balanced_effb4': '../input/hemoorhagesubsfirststage/balansed_effb4_stage1.csv',\n    'inceptionv4': '../input/hemoorhagesubsfirststage/inceptionv4_stage1.csv',\n    'effnet_b0': '../input/hemoorhagesubsfirststage/effb0_stage1.csv',\n    'densenet121': '../input/hemoorhagesubsfirststage/densenet121_stage1.csv',\n}\n\nstage1 = pd.read_csv('../input/hemorrhagehelpers/stage_1_sample_submission.csv').sort_values('ID')\nstage1['image_id'] = stage1.ID.apply(lambda x: '_'.join(x.split('_')[:-1]))\nstage1['group_id'] = stage1.ID.apply(lambda x: x.split('_')[-1])\nstage1.drop('Label', 1, inplace=True)\nhelpers_cols = ['image_id', 'group_id']\nstage1.set_index('ID', inplace=True)\nfor name, fpath in tqdm(stage1_names.items()):\n    add_table(stage1, fpath, name)\n\nstage1.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"current_leaderboard = eval_df(stage1.drop(helpers_cols, 1))\ncurrent_leaderboard","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Loading first stage metadata\n\n- Position3 (Axial)\n- Information about \"neigbours\" images: previous and next images by position in one StudyInstanceUID"},{"metadata":{"trusted":true},"cell_type":"code","source":"stage1_meta_df = pd.read_csv('../input/hemoorrhagemetadata/stage_1_test_meta.csv')\n\nstage1_meta_df['Axial'] = stage1_meta_df['ImagePositionPatient'].apply(lambda s: float(s.split('\\'')[-2]))\nstage1_meta_df = stage1_meta_df.sort_values(['StudyInstanceUID', 'Axial']).reset_index(drop=True)\nstage1_meta_df = stage1_meta_df[['SOPInstanceUID', 'StudyInstanceUID', 'Axial']]\n\nstage1_meta_df['InstancePosition'] = stage1_meta_df.groupby(['StudyInstanceUID']).Axial.cumcount()\n\nstage1_meta_df['PrevPositionUID'] = stage1_meta_df.SOPInstanceUID.shift(1)\nstage1_meta_df.loc[stage1_meta_df.InstancePosition==0, 'PrevPositionUID'] = None\n\nstage1_meta_df['NextPosition'] = stage1_meta_df.InstancePosition.shift(-1)\nstage1_meta_df['NextPositionUID'] = stage1_meta_df.SOPInstanceUID.shift(-1)\nstage1_meta_df.loc[stage1_meta_df.NextPosition==0, 'NextPositionUID'] = None\n\nstage1_meta_df.drop('NextPosition', 1, inplace=True)\n\nstage1_meta_df.columns = ['image_id'] + list(stage1_meta_df.columns[1:])\nstage1_meta_df.iloc[28:37]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Postprocessing for first stage"},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_channel_postproc(test_df, group_name, w_next, w_prev, levels=1):\n    sample = test_df[test_df.group_id==group_name].copy()\n    w_center = 1 - w_next - w_prev\n    for lvl in range(levels):\n        label_mapper = sample.set_index('ID').Label\n        next_labels = (sample.NextPositionUID + '_' + sample.group_id).map(\n            label_mapper).fillna(0)\n        prev_labels = (sample.PrevPositionUID + '_' + sample.group_id).map(\n            label_mapper).fillna(0)\n        sample.Label = sample.Label * w_center + \\\n            next_labels * w_next + \\\n            prev_labels * w_prev\n    return sample[['image_id', 'Label']].set_index('image_id')\n\ndef apply_triplets(df, class_triplets):\n    channel_df = pd.DataFrame(index=df.image_id.unique())\n    for current_class, current_triplet in class_triplets.items():\n        channel_df[current_class] = get_channel_postproc(df, current_class, *current_triplet)\n    channel_df.reset_index(inplace=True)\n    channel_df = channel_df.melt(id_vars=['index'])\n    channel_df['ID'] = channel_df['index'] + '_' + channel_df.variable\n    channel_df['Label'] = channel_df['value']\n    channel_df['image_id'] = channel_df['index']\n    channel_df = channel_df[['ID', 'Label', 'image_id']]\n    return channel_df.sort_values('ID').reset_index(drop=True)\n\ndef add_custom_postproc(df, col, test_meta_df, used_triplets, postfix='postproc'):\n    sub = df[['image_id', 'group_id', col]].reset_index()\n    sub.columns = ['ID', 'image_id', 'group_id', 'Label']\n    merged = pd.merge(sub, test_meta_df, on='image_id', how='left')\n    postprocessed = apply_triplets(merged, used_triplets)\n    \n    postproc_name = '{}_{}'.format(col, postfix)\n    df[postproc_name] = postprocessed.set_index('ID').Label\n\noptimal_triplets = {\n    'any': (0.1, 0.1, 3), \n    'epidural': (0.2, 0.2, 3),\n    'intraparenchymal': (0.05, 0.05, 4), \n    'intraventricular': (0.05, 0.05, 3),\n    'subarachnoid': (0.2, 0.2, 2), \n    'subdural': (0.2, 0.2, 3)\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"current_leaderboard = eval_df(stage1.drop(helpers_cols, 1))\ncurrent_leaderboard","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"postproc_cols = [col for col in stage1.columns if col not in helpers_cols]\nfor col in postproc_cols:\n    print('Make postprocessing for {}'.format(col))\n#     used_triplets = add_autopostproc(stage1, col, stage1_meta_df, triplet_search_space)\n    add_custom_postproc(stage1, col, stage1_meta_df, optimal_triplets)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"updated_leaderboard = eval_df(stage1.drop(helpers_cols, 1))\nupdated_leaderboard","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Loading second stage data"},{"metadata":{"trusted":true},"cell_type":"code","source":"stage2_names = {\n    'takato_original_seresnext': '../input/hemorrhagesubssecondstage/se_resnext50_32x4d_102105_hflip.csv',\n    'takato_original_effb1': '../input/hemorrhagesubssecondstage/efficientnet-b1_102407_hflip.csv',\n    'takato_original_effb2': '../input/hemorrhagesubssecondstage/efficientnet-b2_102000_hflip.csv',\n    'takato_original_effb3': '../input/hemorrhagesubssecondstage/efficientnet-b3_102112_hflip.csv',\n    'takato_original_effb4': '../input/hemorrhagesubssecondstage/efficientnet-b4_102100_hflip.csv',\n    \n    'agro_b7': '../input/hemorrhagesubssecondstage/agroeffnet_stage2_test_tta10.csv',\n    'sneddy_b7': '../input/hemorrhagesubssecondstage/effnet-b7-new_stage2_test_tta10.csv',\n    'resnet152': '../input/hemorrhagesubssecondstage/resnet152_stage2.csv',\n    'effnet_b5': '../input/hemorrhagesubssecondstage/effnetb5_stage2_test_tta8.csv',\n    'balanced_effb4': '../input/hemorrhagesubssecondstage/balansed_effb4_stage2.csv',\n    'inceptionv4': '../input/hemorrhagesubssecondstage/inceptionv4_stage2.csv',\n    'effnet_b0': '../input/hemorrhagesubssecondstage/effb0_stage2.csv',\n    'densenet121': '../input/hemorrhagesubssecondstage/densenet121_stage2.csv',\n}\n\nstage2 = pd.read_csv('../input/hemorrhagehelpers/stage_2_sample_submission.csv').sort_values('ID')\nstage2['image_id'] = stage2.ID.apply(lambda x: '_'.join(x.split('_')[:-1]))\nstage2['group_id'] = stage2.ID.apply(lambda x: x.split('_')[-1])\n\nstage2.drop('Label', 1, inplace=True)\nhelpers_cols = ['image_id', 'group_id']\nstage2.set_index('ID', inplace=True)\nfor name, fpath in tqdm(stage2_names.items()):\n    add_table(stage2, fpath, name)\n\nstage2.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Loading metadata for second stage"},{"metadata":{"trusted":true},"cell_type":"code","source":"stage2_meta_df = pd.read_csv('../input/hemoorrhagemetadata/stage_2_test_meta.csv')\n\nstage2_meta_df['Axial'] = stage2_meta_df['ImagePositionPatient'].apply(lambda s: float(s.split('\\'')[-2]))\nstage2_meta_df = stage2_meta_df.sort_values(['StudyInstanceUID', 'Axial']).reset_index(drop=True)\nstage2_meta_df = stage2_meta_df[['SOPInstanceUID', 'StudyInstanceUID', 'Axial']]\n\nstage2_meta_df['InstancePosition'] = stage2_meta_df.groupby(['StudyInstanceUID']).Axial.cumcount()\n\nstage2_meta_df['PrevPositionUID'] = stage2_meta_df.SOPInstanceUID.shift(1)\nstage2_meta_df.loc[stage2_meta_df.InstancePosition==0, 'PrevPositionUID'] = None\n\nstage2_meta_df['NextPosition'] = stage2_meta_df.InstancePosition.shift(-1)\nstage2_meta_df['NextPositionUID'] = stage2_meta_df.SOPInstanceUID.shift(-1)\nstage2_meta_df.loc[stage2_meta_df.NextPosition==0, 'NextPositionUID'] = None\n\nstage2_meta_df.drop('NextPosition', 1, inplace=True)\n\nstage2_meta_df.columns = ['image_id'] + list(stage2_meta_df.columns[1:])\nstage2_meta_df.iloc[27:37]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Apply postproc procedure to second stage data"},{"metadata":{"trusted":true},"cell_type":"code","source":"postproc_cols = [col for col in stage2.columns if col not in helpers_cols]\nfor col in postproc_cols:\n    print('Make postprocessing for {}'.format(col))\n#     used_triplets = add_autopostproc(stage1, col, stage1_meta_df, triplet_search_space)\n    add_custom_postproc(stage2, col, stage2_meta_df, optimal_triplets)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"stage2.to_csv('updated_stage_2.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":1}