{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","collapsed":true,"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":false},"cell_type":"markdown","source":"I have never worked with image data before, so my goals are limited to basic data set exploration.\n\n**Credits:**\n*  When I was wondering how to work with images and which image packges (scikit-image, Pillow, Matplotlib, OpenCV) to use: \n    -  Checked out few kernels from past image competitions and the current competition, this kernel -  https://www.kaggle.com/jschnab/exploring-the-human-protein-atlas-images came to the rescue. I decided to go with OpenCV and learn along the way."},{"metadata":{"_uuid":"d5007e67627e5c76a33f88868d170b075ba9e1e9"},"cell_type":"markdown","source":"# Imports"},{"metadata":{"trusted":true,"_uuid":"d36f08d8d44be5467818d156918e7890eb85b4eb"},"cell_type":"code","source":"%matplotlib inline\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport cv2\nimport re\nfrom itertools import product\n\n# matplotlib style\nplt.style.use('fivethirtyeight')\n\n# random state\nRSTATE=1984","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"52f619bd400e9d09b4f421d58f062df9800eebca"},"cell_type":"markdown","source":"# Definitions"},{"metadata":{"trusted":true,"_uuid":"e08a7f872a88cf7343f3066ac7cdf17363def641"},"cell_type":"code","source":"# color hunt palettes\nch_div_palette_1 = [\"#288fb4\", \"#1d556f\", \"#efddb2\", \"#fa360a\"]\nch_div_palette_2 = [\"#ff5335\", \"#dfe0d4\", \"#3e92a3\", \"#353940\"]\nch_div_palette_3 = [\"#daebee\", \"#b6d7de\", \"#fcedda\", \"#ff5126\"]\n# matplotlib \"fivethirtyeight\" style colors\nch_div_palette_4 = ['#008fd5', '#fc4f30', '#e5ae38', '#6d904f', '#8b8b8b', '#810f7c']","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"89aaa2a27217df30d9a8d98ce753c7827a88d6b7"},"cell_type":"markdown","source":"# Helper functions"},{"metadata":{"trusted":true,"_uuid":"1a391080584d8977ae9ee430f0e325170ad2964a"},"cell_type":"code","source":"# https://www.kaggle.com/c/human-protein-atlas-image-classification/data\nlabel_names = [\n    \"Nucleoplasm\",\n    \"Nuclear membrane\",\n    \"Nucleoli\",\n    \"Nucleoli fibrillar center\",\n    \"Nuclear speckles\",\n    \"Nuclear bodies\",\n    \"Endoplasmic reticulum\",\n    \"Golgi apparatus\",\n    \"Peroxisomes\",\n    \"Endosomes\",\n    \"Lysosomes\",\n    \"Intermediate filaments\",\n    \"Actin filaments\",\n    \"Focal adhesion sites\",\n    \"Microtubules\",\n    \"Microtubule ends\",\n    \"Cytokinetic bridge\",\n    \"Mitotic spindle\",\n    \"Microtubule organizing center\",\n    \"Centrosome\",\n    \"Lipid droplets\",\n    \"Plasma membrane\",\n    \"Cell junctions\",\n    \"Mitochondria\",\n    \"Aggresome\",\n    \"Cytosol\",\n    \"Cytoplasmic bodies\",\n    \"Rods & rings\",    \n]\n    \ndef get_num_labels_for_instance(label_string):\n    labels = re.split(r'\\s+', label_string)\n    return len(labels)\n\ndef get_label_presence_func(label):\n    def is_label_present(label_string):\n        labels = set(re.split(r'\\s+', label_string))\n        return int(str(label) in labels)\n    return is_label_present\n\ndef is_single_label(label_string):\n    label_ids = re.split(r'\\s+', label_string)\n    if len(label_ids) > 1:\n        return False\n    return True\n \ndef get_label_name_for_label_id_string(label_ids_str):\n    label_ids = re.split(r'\\s+', label_ids_str)\n    label_ids = [int(id) for id in label_ids]\n    label = \"+\".join([label_names[id] for id in label_ids])\n    return label\n\n# Returns different bar color for single and multi-labels\ndef get_bar_color_1(is_single_label):\n    if is_single_label:\n        return ch_div_palette_1[0]\n    return ch_div_palette_1[2]\n\n# Returns different bar color for single and multi-labels\ndef get_bar_color_2(is_single_label):\n    if is_single_label:\n        return ch_div_palette_2[0]\n    return ch_div_palette_2[2]\n\n# Returns different bar color for single and multi-labels\ndef get_bar_color_3(is_single_label):\n    if is_single_label:\n        return ch_div_palette_3[2]\n    return ch_div_palette_3[3]\n\n# Returns different bar color for single and multi-labels\ndef get_bar_color_4(is_single_label):\n    if is_single_label:\n        return ch_div_palette_4[0]\n    return ch_div_palette_4[1]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ced595642ec663e7d767c5b5e56920918f69da92"},"cell_type":"markdown","source":"# Training labels"},{"metadata":{"trusted":true,"_uuid":"69b12321d5a83bdfccb1968769905aeca8a87d85"},"cell_type":"code","source":"labels_df = pd.read_csv(\"../input/train.csv\")\nprint(\"Shape of the training labels frame (train.csv): \", labels_df.shape)\nlabels_df.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"240a29199a2f91138c3226cc2747d8ac6a153afe"},"cell_type":"markdown","source":"The target is a multi-labels separated by a space. Our task is to predict those labels using multi-label classification methods."},{"metadata":{"_uuid":"a369db3473605296f5c9a5012795a14932f69a81"},"cell_type":"markdown","source":"## Breakdown of multi-labels distribution"},{"metadata":{"trusted":true,"_uuid":"7af21d049c28833873edaf3b2f7ee2fb0bf86053"},"cell_type":"code","source":"labels_df[\"num_labels\"] = labels_df[\"Target\"].apply(get_num_labels_for_instance)\nlabels_count_dist = labels_df.groupby(\"num_labels\")[\"num_labels\"].count()\nfig, ax = plt.subplots(num=1)\nax.bar(labels_count_dist.index.values, labels_count_dist.values)\nax.set_xlabel(\"Number of labels per instance\")\nax.set_ylabel(\"Number of instances\")\nax.set_title(\"Labels count distribution\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"66ddf2a6a3231b8a3f522480f77666bb19e61cfe"},"cell_type":"markdown","source":"Most of the training images have 1 or 2 labels. The number labels per image vary from 1 to 5. "},{"metadata":{"_uuid":"15d42031a605b9610398a32617ab729e36456725"},"cell_type":"markdown","source":"## Distribution of top-50 training labels (single/multi)"},{"metadata":{"trusted":true,"_uuid":"e0c2a4a848d791cfce8e42a84a8572bbfc11ac56"},"cell_type":"code","source":"multi_labels_dist = pd.DataFrame()\ntmp = labels_df.groupby(\"Target\")[\"Target\"].count().sort_values(ascending=False)\nmulti_labels_dist[\"Target\"] = tmp.index.values\nmulti_labels_dist[\"Count\"] = tmp.values\nmulti_labels_dist[\"is_single_label\"] = multi_labels_dist[\"Target\"].apply(is_single_label)\nmulti_labels_dist[\"Target_str\"] = multi_labels_dist[\"Target\"].apply(get_label_name_for_label_id_string)\nmulti_labels_dist = multi_labels_dist[[\"Target\", \"Target_str\", \"Count\", \"is_single_label\"]]\nprint(\"Number of unique labels (single/multi): {}\".format(multi_labels_dist.shape[0]))\nmulti_labels_dist.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4684061c60ee113d8b987742852bbd4081c5538e"},"cell_type":"code","source":"topn = 50\nfig, ax = plt.subplots(num=2)\nfig.set_figwidth(15)\nfig.set_figheight(10)\nbar_colors = multi_labels_dist[\"is_single_label\"].apply(get_bar_color_4).head(topn)\nax.bar(multi_labels_dist[\"Target_str\"].head(topn), multi_labels_dist[\"Count\"].head(topn), color=bar_colors)\nax.set_xticks(range(topn))\nax.set_xticklabels(multi_labels_dist[\"Target_str\"].head(topn), rotation = 45, ha=\"right\")\nax.set_title(\"Distribution of top-{} training labels (single/multi)\".format(topn))\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c952bc7b3642c385be29b6de3901cafb1ccf3526"},"cell_type":"markdown","source":"Many top frequency labels are multi-label categories. "},{"metadata":{"_uuid":"132695b26619ee25c866c5865dd8a736d2fc2058"},"cell_type":"markdown","source":"## Distribution of single training labels"},{"metadata":{"trusted":true,"_uuid":"ab9ee173d9ab71c302f1fdbc676ce0ea36a51f5d"},"cell_type":"code","source":"label_columns_df = pd.DataFrame()\nfor i in range(len(label_names)):\n    label_chk_fn = get_label_presence_func(i)\n    label_columns_df[label_names[i]] = labels_df[\"Target\"].apply(label_chk_fn)\nlabels_dist = label_columns_df.sum().sort_values(ascending=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7925c376861ccc11d0af44bf4345c9bb8a65bd8d"},"cell_type":"code","source":"fig, ax = plt.subplots(num=2)\nfig.set_figwidth(15)\nfig.set_figheight(10)\nax.bar(labels_dist.index.values, labels_dist.values)\nax.set_xticks(range(len(labels_dist.values)))\nax.set_xticklabels(labels_dist.index.values, rotation = 45, ha=\"right\")\nax.set_title(\"Distribution of single labels\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"39b3086dc62fb7e57bb43c3718c83d3bdd9ee3ac"},"cell_type":"markdown","source":"# Look at sample training images"},{"metadata":{"_uuid":"60c3b0c9d7f16b7e0950af1e859e55380cb51381"},"cell_type":"markdown","source":"> Each file represents a different filter on the subcellular protein patterns represented by the sample. The format should be [filename]_[filter color].png for the PNG files, and [filename]_[filter color].tif for the TIFF files.\n\n> All image samples are represented by four filters (stored as individual files), the protein of interest (green) plus three cellular landmarks: nucleus (blue), microtubules (red), endoplasmic reticulum (yellow). The green filter should hence be used to predict the label, and the other filters are used as references.\n\nWe may want to look at some images to understand how they are labeled. "},{"metadata":{"trusted":true,"_uuid":"dca26b13d52f37f6064dd95df9750200dae1e90a"},"cell_type":"code","source":"fig, ax = plt.subplots(num=1, nrows=3, ncols=3)\nfig.set_figheight(15)\nfig.set_figwidth(15)\nfor idx, (x, y) in enumerate(product(range(3), range(3))):\n    img_blue = cv2.imread(\"../input/train/\" + labels_df.loc[idx, \"Id\"] + \"_blue.png\", cv2.IMREAD_GRAYSCALE)\n    img_green = cv2.imread(\"../input/train/\" + labels_df.loc[idx, \"Id\"] + \"_green.png\", cv2.IMREAD_GRAYSCALE)\n    img_red = cv2.imread(\"../input/train/\" + labels_df.loc[idx, \"Id\"] + \"_red.png\", cv2.IMREAD_GRAYSCALE)\n    img_bgr = cv2.merge((img_blue, img_green, img_red))\n    image_label = get_label_name_for_label_id_string(labels_df.loc[idx, \"Target\"])\n    ax[x,y].imshow(img_bgr)\n    ax[x,y].set_xticks([])\n    ax[x,y].set_yticks([])\n    ax[x,y].set_title(image_label, fontdict={\"fontsize\": 12})\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"37af0de4dcab181ee30879199b6ed8b28e2412fc"},"cell_type":"markdown","source":"## Sample images for top frequency labels\nWe have not yet looked at how the images within the same label category (single/multi) look like and how similar or dissimilar they are. We can try looking into few images per label for the top frequency labels. "},{"metadata":{"trusted":true,"_uuid":"fdd6cc4b7343d2f58619a68960ad8e32da6af64d"},"cell_type":"code","source":"# top-5\ntopn = 5\ntopn_labels = multi_labels_dist.head(topn)[\"Target\"]\nmulti_labels_dist.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"266fb38b935b280568724ed7c82d82a10cb20ee5"},"cell_type":"code","source":"images_per_label = 5\nfig, ax = plt.subplots(num=1, nrows=topn, ncols=images_per_label)\nfig.set_figheight(21)\nfig.set_figwidth(21)\nfor idx, t in enumerate(topn_labels):\n    sample_ids_for_label = labels_df[labels_df[\"Target\"] == t].sample(n=images_per_label, random_state=RSTATE)[\"Id\"].tolist()\n    ax[idx, 0].set_ylabel(get_label_name_for_label_id_string(t))\n    for idy in range(images_per_label):\n        img_blue = cv2.imread(\"../input/train/\" + sample_ids_for_label[idy] + \"_blue.png\", cv2.IMREAD_GRAYSCALE)\n        img_green = cv2.imread(\"../input/train/\" + sample_ids_for_label[idy] + \"_green.png\", cv2.IMREAD_GRAYSCALE)\n        img_red = cv2.imread(\"../input/train/\" + sample_ids_for_label[idy] + \"_red.png\", cv2.IMREAD_GRAYSCALE)\n        img_bgr = cv2.merge((img_blue, img_green, img_red))\n        ax[idx,idy].imshow(img_bgr)\n        ax[idx,idy].set_xticks([])\n        ax[idx,idy].set_yticks([])\n        ax[idx,idy].set_title(sample_ids_for_label[idy], fontdict={\"fontsize\":10})\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"54565d370261a827c58591531a9d79ce98d7dca8"},"cell_type":"markdown","source":"## Sample images for label: \"Nucleoplasm\" (0)\nWe previously looked at few sample images for top-n frequency labels and looked at them together. Let's look into more images for a particular category, for example: \"Nucleoplasm\". "},{"metadata":{"trusted":true,"_uuid":"4c1f49e0247f55bd6e838d1a66f33bd10789ddc4"},"cell_type":"code","source":"n_images = 25\nncols = 5\nnrows = n_images // ncols\nimage_ids = labels_df[labels_df[\"Target\"] == \"0\"].sample(n=n_images, random_state=RSTATE)[\"Id\"].tolist()\nfig, ax = plt.subplots(num=1, nrows=nrows, ncols=ncols)\nfig.set_figheight(21)\nfig.set_figwidth(21)\nfor idx, (x, y) in enumerate(product(range(nrows), range(ncols))):\n    img_blue = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_blue.png\", cv2.IMREAD_GRAYSCALE)\n    img_green = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_green.png\", cv2.IMREAD_GRAYSCALE)\n    img_red = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_red.png\", cv2.IMREAD_GRAYSCALE)\n    img_bgr = cv2.merge((img_blue, img_green, img_red))\n    ax[x,y].imshow(img_bgr)\n    ax[x,y].set_xticks([])\n    ax[x,y].set_yticks([])\n    ax[x,y].set_title(image_ids[idx], fontdict={\"fontsize\": 12})\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1c3c9ae3f3466306c08788015332a43cc76e8414"},"cell_type":"markdown","source":"## Sample images for label: \"Mitochondria\" (23)"},{"metadata":{"trusted":true,"_uuid":"ebecd985922b29e26673ecd9551113709a2d3cb4"},"cell_type":"code","source":"n_images = 25\nncols = 5\nnrows = n_images // ncols\nimage_ids = labels_df[labels_df[\"Target\"] == \"23\"].sample(n=n_images, random_state=RSTATE)[\"Id\"].tolist()\nfig, ax = plt.subplots(num=1, nrows=nrows, ncols=ncols)\nfig.set_figheight(21)\nfig.set_figwidth(21)\nfor idx, (x, y) in enumerate(product(range(nrows), range(ncols))):\n    img_blue = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_blue.png\", cv2.IMREAD_GRAYSCALE)\n    img_green = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_green.png\", cv2.IMREAD_GRAYSCALE)\n    img_red = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_red.png\", cv2.IMREAD_GRAYSCALE)\n    img_bgr = cv2.merge((img_blue, img_green, img_red))\n    ax[x,y].imshow(img_bgr)\n    ax[x,y].set_xticks([])\n    ax[x,y].set_yticks([])\n    ax[x,y].set_title(image_ids[idx], fontdict={\"fontsize\": 12})\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ff796d53a0d0e07543ae05d0f84db26bb81ff125"},"cell_type":"markdown","source":"## Sample images for label: \"Cytosol\" (25)"},{"metadata":{"trusted":true,"_uuid":"60e0043d8333d8b5a51aae9a869846fe300bea17"},"cell_type":"code","source":"n_images = 25\nncols = 5\nnrows = n_images // ncols\nimage_ids = labels_df[labels_df[\"Target\"] == \"25\"].sample(n=n_images, random_state=RSTATE)[\"Id\"].tolist()\nfig, ax = plt.subplots(num=1, nrows=nrows, ncols=ncols)\nfig.set_figheight(21)\nfig.set_figwidth(21)\nfor idx, (x, y) in enumerate(product(range(nrows), range(ncols))):\n    img_blue = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_blue.png\", cv2.IMREAD_GRAYSCALE)\n    img_green = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_green.png\", cv2.IMREAD_GRAYSCALE)\n    img_red = cv2.imread(\"../input/train/\" + image_ids[idx] + \"_red.png\", cv2.IMREAD_GRAYSCALE)\n    img_bgr = cv2.merge((img_blue, img_green, img_red))\n    ax[x,y].imshow(img_bgr)\n    ax[x,y].set_xticks([])\n    ax[x,y].set_yticks([])\n    ax[x,y].set_title(image_ids[idx], fontdict={\"fontsize\": 12})\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"45374f36de86ee1586811769ce0f113fa200be22"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}