{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"\n\n### Q1) What is Prostate Cancer?\nProstate cancer is cancer that occurs in the prostate ,a small walnut-shaped gland in men that produces the seminal fluid that nourishes and transports sperm.\n\nProstate cancer is one of the most common types of cancer in men. Usually prostate cancer grows slowly and is initially confined to the prostate gland, where it may not cause serious harm. However, while some types of prostate cancer grow slowly and may need minimal or even no treatment, other types are aggressive and can spread quickly.\n\n<img src=\"https://www.mayoclinic.org/-/media/kcms/gbs/patient-consumer/images/2013/11/15/17/38/ds00043_-my01633_im01561_prostca1thu_jpg.jpg\" height=\"100px\">\n\n### Q2) How it is tested and detected?\nProstate screening tests might include:\n\n* Digital rectal exam (DRE): During a DRE, your doctor inserts a gloved, lubricated finger into your rectum to examine your prostate, which is adjacent to the rectum. If your doctor finds any abnormalities in the texture, shape or size of the gland, you may need further tests.\n* Prostate-specific antigen (PSA) test: A blood sample is drawn from a vein in your arm and analyzed for PSA, a substance that's naturally produced by your prostate gland. It's normal for a small amount of PSA to be in your bloodstream. However, if a higher than normal level is found, it may indicate prostate infection, inflammation, enlargement or cancer.\n\nIf a DRE or PSA test detects an abnormality, your doctor may recommend further tests to determine whether you have prostate cancer, such as:\n\n* Ultrasound : If other tests raise concerns, your doctor may use transrectal ultrasound to further evaluate your prostate. A small probe, about the size and shape of a cigar, is inserted into your rectum. The probe uses sound waves to create a picture of your prostate gland.\n* Collecting a sample of prostate tissue : If initial test results suggest prostate cancer, your doctor may recommend a procedure to collect a sample of cells from your prostate (prostate biopsy). Prostate biopsy is often done using a thin needle that's inserted into the prostate to collect tissue. The tissue sample is analyzed in a lab to determine whether cancer cells are present.\n\n### Q3) Where does GLEASON score fit-in all of this?\nWhen a biopsy confirms the presence of cancer, the next step is to determine the level of aggressiveness (grade) of the cancer cells. A laboratory pathologist examines a sample of your cancer to determine how much cancer cells differ from the healthy cells. A higher grade indicates a more aggressive cancer that is more likely to spread quickly.\n\nThe most common scale used to evaluate the grade of prostate cancer cells is called a Gleason score. Gleason scoring combines two numbers and can range from 2 (nonaggressive cancer) to 10 (very aggressive cancer), though the lower part of the range isn't used as often.\n","metadata":{}},{"cell_type":"markdown","source":"\nAccording to current guidelines by the International Society of Urological Pathology (ISUP), the Gleason scores are summarized into an ISUP grade on a scale from 1 to 5 according to the following rule:\n\n* Gleason score 6 = ISUP grade 1\u2028\n* Gleason score 7 (3 + 4) = ISUP grade 2\u2028\n* Gleason score 7 (4 + 3) = ISUP grade 3\u2028\n* Gleason score 8 = ISUP grade 4\u2028\n* Gleason score 9-10 = ISUP grade 5\u2028\n\nIf there is no cancer in the sample, we use the label ISUP grade 0 in this competition. \n\n<img src=\"https://storage.googleapis.com/kaggle-media/competitions/PANDA/Screen%20Shot%202020-04-08%20at%202.03.53%20PM.png\" height=\"100px\">\n\n### Q6) How has the Gleason scores been generated in the dataset?\nEach WSI in this challenge contains one, or in some cases two, thin tissue sections cut from a single biopsy sample. Prior to scanning, the tissue is stained with haematoxylin & eosin (H&E). This is a standard way of staining the originally transparent tissue to produce some contrast. The samples are made up of glandular tissue and connective tissue. The glands are hollow structures, which can be seen as white “holes” or branched cavities in the WSI. The appearance of the glands forms the basis of the Gleason grading system. The glandular structure characteristic of healthy prostate tissue is progressively lost with increasing grade. The grading system recognizes three categories: 3, 4, and 5. \n\n* [A]Benign prostate glands with folded epithelium :The cytoplasm is pale and the nuclei small and regular. The glands are grouped together.\n* [B]Prostatic adenocarcinoma : Gleason Pattern 3 has no loss of glandular differentiation. Small glands infiltrate between benign glands. The cytoplasm is often dark and the nuclei enlarged with dark chromatin and some prominent nucleoli. Each epithelial unit is separate and has a lumen.\n* [C]Prostatic adenocarcinoma : Gleason Pattern 4 has partial loss of glandular differentiation. There is an attempt to form lumina but the tumor fails to form complete, well-developed glands. This microphotograph shows irregular cribriform cancer, i.e. epithelial sheets with multiple lumina. There are also some poorly formed small glands and some fused glands. All of these are included in Gleason Pattern 4.\n* [D]Prostatic adenocarcinoma : Gleason Pattern 5 has an almost complete loss of glandular differentiation. Dispersed single cancer cells are seen in the stroma. Gleason Pattern 5 may also contain solid sheets or strands of cancer cells. All microphotographs show hematoxylin and eosin stains at 20x lens magnification.\n\n<img src=\"https://storage.googleapis.com/kaggle-media/competitions/PANDA/GleasonPattern_4squares%20copy500.png\" height=\"100px\">","metadata":{}},{"cell_type":"markdown","source":"# Preliminaries\nNow Let's Begin by Importing the data","metadata":{}},{"cell_type":"code","source":"#BASIC\nimport numpy as np \nimport pandas as pd \nimport os\n\n# DATA visualization\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport PIL\nfrom IPython.display import Image, display\nfrom plotly import graph_objs as go\nimport plotly.express as px\nimport plotly.figure_factory as ff\n\nimport openslide\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-25T18:18:35.621363Z","iopub.execute_input":"2022-09-25T18:18:35.621635Z","iopub.status.idle":"2022-09-25T18:18:38.907727Z","shell.execute_reply.started":"2022-09-25T18:18:35.621603Z","shell.execute_reply":"2022-09-25T18:18:38.906451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BASE_FOLDER = \"/kaggle/input/prostate-cancer-grade-assessment/\"\n!ls {BASE_FOLDER}","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2022-09-25T18:18:38.909635Z","iopub.execute_input":"2022-09-25T18:18:38.909957Z","iopub.status.idle":"2022-09-25T18:18:39.942238Z","shell.execute_reply.started":"2022-09-25T18:18:38.909919Z","shell.execute_reply":"2022-09-25T18:18:39.941232Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mask_dir = f'{BASE_FOLDER}/train_label_masks'","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:39.9438Z","iopub.execute_input":"2022-09-25T18:18:39.944186Z","iopub.status.idle":"2022-09-25T18:18:39.949168Z","shell.execute_reply.started":"2022-09-25T18:18:39.944139Z","shell.execute_reply":"2022-09-25T18:18:39.948133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.read_csv(BASE_FOLDER+\"train.csv\")\ntest = pd.read_csv(BASE_FOLDER+\"test.csv\")\nsub = pd.read_csv(BASE_FOLDER+\"sample_submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:39.952827Z","iopub.execute_input":"2022-09-25T18:18:39.953175Z","iopub.status.idle":"2022-09-25T18:18:40.0311Z","shell.execute_reply.started":"2022-09-25T18:18:39.953131Z","shell.execute_reply":"2022-09-25T18:18:40.030161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-26T13:27:02.749022Z","iopub.execute_input":"2022-09-26T13:27:02.749728Z","iopub.status.idle":"2022-09-26T13:27:02.859359Z","shell.execute_reply.started":"2022-09-26T13:27:02.749607Z","shell.execute_reply":"2022-09-26T13:27:02.857437Z"},"_kg_hide-output":false,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.drop([7273],inplace=True) #Mislabelled ","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:40.164648Z","iopub.execute_input":"2022-09-25T18:18:40.16502Z","iopub.status.idle":"2022-09-25T18:18:40.174584Z","shell.execute_reply.started":"2022-09-25T18:18:40.164977Z","shell.execute_reply":"2022-09-25T18:18:40.173742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Negative and 0+0 are same labels only from different data-providers and are interchangeable**\n<br>Let's go ahead and change negative to '0+0'","metadata":{}},{"cell_type":"code","source":"train['gleason_score'] = train['gleason_score'].apply(lambda x: \"0+0\" if x==\"negative\" else x)","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:40.176439Z","iopub.execute_input":"2022-09-25T18:18:40.176827Z","iopub.status.idle":"2022-09-25T18:18:40.187452Z","shell.execute_reply.started":"2022-09-25T18:18:40.176781Z","shell.execute_reply":"2022-09-25T18:18:40.186367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Exploratory Data Analysis\n","metadata":{}},{"cell_type":"code","source":"temp = train.groupby('isup_grade').count()['image_id'].reset_index().sort_values(by='image_id',ascending=False)\ntemp.style.background_gradient(cmap='Purples')","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:40.202477Z","iopub.execute_input":"2022-09-25T18:18:40.20274Z","iopub.status.idle":"2022-09-25T18:18:40.327066Z","shell.execute_reply.started":"2022-09-25T18:18:40.202705Z","shell.execute_reply":"2022-09-25T18:18:40.326073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = go.Figure(go.Funnelarea(\n    text =temp.isup_grade,\n    values = temp.image_id,\n    title = {\"position\": \"top center\", \"text\": \"Funnel-Chart of ISUP_grade Distribution\"}\n    ))\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:40.328566Z","iopub.execute_input":"2022-09-25T18:18:40.328935Z","iopub.status.idle":"2022-09-25T18:18:41.973621Z","shell.execute_reply.started":"2022-09-25T18:18:40.328893Z","shell.execute_reply":"2022-09-25T18:18:41.972597Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.bar(temp, x='isup_grade', y='image_id',\n             hover_data=['image_id', 'isup_grade'], color='image_id',\n             labels={'pop':'population of Canada'}, height=400)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:41.975297Z","iopub.execute_input":"2022-09-25T18:18:41.975647Z","iopub.status.idle":"2022-09-25T18:18:42.344179Z","shell.execute_reply.started":"2022-09-25T18:18:41.975605Z","shell.execute_reply":"2022-09-25T18:18:42.343386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"We see that the isup_grade 0 and 1 i.e no cancer, has the most number of values and that's what expected in case of most medical datasets , the target class will always be underrepresented and that's also the most important challenge when performing machine learning tasks on Medical DATA\n\nNow let's Look at how much data is provided by which data-provider","metadata":{}},{"cell_type":"code","source":"fig = plt.figure(figsize=(10,6))\nax = sns.countplot(x=\"isup_grade\", hue=\"data_provider\", data=train)\nfor p in ax.patches:\n    height = p.get_height()\n    ax.text(p.get_x()+p.get_width()/2,\n                height +3,\n                '{:1.2f}%'.format(100*height/10616),\n                ha=\"center\")","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:42.345703Z","iopub.execute_input":"2022-09-25T18:18:42.345969Z","iopub.status.idle":"2022-09-25T18:18:42.618233Z","shell.execute_reply.started":"2022-09-25T18:18:42.34594Z","shell.execute_reply":"2022-09-25T18:18:42.617116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now Let's Look at the gleason score distribution as well","metadata":{}},{"cell_type":"code","source":"temp = train.groupby('gleason_score').count()['image_id'].reset_index().sort_values(by='image_id',ascending=False)\ntemp.style.background_gradient(cmap='Reds')","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:42.619949Z","iopub.execute_input":"2022-09-25T18:18:42.620223Z","iopub.status.idle":"2022-09-25T18:18:42.64972Z","shell.execute_reply.started":"2022-09-25T18:18:42.620192Z","shell.execute_reply":"2022-09-25T18:18:42.64883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = go.Figure(go.Funnelarea(\n    text =temp.gleason_score,\n    values = temp.image_id,\n    title = {\"position\": \"top center\", \"text\": \"Funnel-Chart of ISUP_grade Distribution\"}\n    ))\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:42.651622Z","iopub.execute_input":"2022-09-25T18:18:42.651992Z","iopub.status.idle":"2022-09-25T18:18:42.933813Z","shell.execute_reply.started":"2022-09-25T18:18:42.651949Z","shell.execute_reply":"2022-09-25T18:18:42.932782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.bar(temp, x='gleason_score', y='image_id',\n             hover_data=['image_id', 'gleason_score'], color='image_id',\n             labels={'pop':'population of Canada'}, height=400)\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:42.935172Z","iopub.execute_input":"2022-09-25T18:18:42.935423Z","iopub.status.idle":"2022-09-25T18:18:43.311108Z","shell.execute_reply.started":"2022-09-25T18:18:42.935395Z","shell.execute_reply":"2022-09-25T18:18:43.310388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From this graph it is also clear that the data will be baised towards non-cancer examples","metadata":{}},{"cell_type":"code","source":"'''\nVisualizing the GLEASON_SCORE distribution wrt Data_providers\n'''\n\nfig = plt.figure(figsize=(10,6))\nax = sns.countplot(x=\"gleason_score\", hue=\"data_provider\", data=train)\nfor p in ax.patches:\n    height = p.get_height()\n    ax.text(p.get_x()+p.get_width()/2.,\n                height + 3,\n                '{:1.2f}%'.format(100*height/10616),\n                ha=\"center\")","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:43.312191Z","iopub.execute_input":"2022-09-25T18:18:43.312546Z","iopub.status.idle":"2022-09-25T18:18:43.657557Z","shell.execute_reply.started":"2022-09-25T18:18:43.312517Z","shell.execute_reply":"2022-09-25T18:18:43.656702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Image EDA\n\n## Q1) What is .tff format and Why it is used?\n\nTagged Image File Format (TIFF) is a variable-resolution bitmapped image format developed by Aldus (now part of Adobe) in 1986. TIFF is very common for transporting color or gray-scale images into page layout applications, but is less suited to delivering web content.\n\nReasons for Usage:\n* IFF files are large and of very high quality. Baseline TIFF images are highly portable; most graphics, desktop publishing, and word processing applications understand them.\n* The TIFF specification is readily extensible, though this comes at the price of some of its portability. Many applications incorporate their own extensions, but a number of application-independent extensions are recognized by most programs.\n* Four types of baseline TIFF images are available: bilevel (black and white), gray scale, palette (i.e., indexed), and RGB (i.e., true color). RGB images may store up to 16.7 million colors. Palette and gray-scale images are limited to 256 colors or shades. A common extension of TIFF also allows for CMYK images.\n* TIFF files may or may not be compressed. A number of methods may be used to compress TIFF files, including the Huffman and LZW algorithms. Even compressed, TIFF files are usually much larger than similar GIF or JPEG files.\n* Because the files are so large and because there are so many possible variations of each TIFF file type, few web browsers can display them without plug-ins.\n\n## Q2) What are image levels?\nIn some image formats the image data has a fixed amount of possible intensities. For instance an image may be defined as uint8 (unsigned integer 8-bit) which means that each pixel can have a value (intensity) between 0-255, and each intensity is a whole number (integer) in that range. So that gives 256 possible intensity levels. Another way to interpret this would be layers. An RGB (red green blue) type image uses three layers to define colour (a single layer would define a large-scale image, some image types contain more than 3 layers). For each pixel there are 3 intensity levels, 1 for each colour, are defined and together (using a kind of mixing of the colours) they define the colour of that pixels. Similarly for a grayscale there can be two levels i.e black and white\n\n## Q3) What is Down-sampling and Up-sampling in Image processing?\nDownsampling and upsampling are two fundamental and widely used image operations, with\napplications in image display, compression, and progressive transmission. Downsampling is\nthe reduction in spatial resolution while keeping the same two-dimensional (2D) representation. It is typically used to reduce the storage and/or transmission requirements of images.\nUpsampling is the increasing of the spatial resolution while keeping the 2D representation\nof an image. It is typically used for zooming in on a small region of an image, and for\neliminating the pixelation effect that arises when a low-resolution image is displayed on a\nrelatively large frame\n\n","metadata":{}},{"cell_type":"code","source":"\n\n\n# Open the image (does not yet read the image into memory)\nexample = openslide.OpenSlide(os.path.join(BASE_FOLDER+\"train_images\", '005e66f06bce9c2e49142536caf2f6ee.tiff'))\n\n# Read a specific region of the image starting at upper left coordinate (x=17800, y=19500) on level 0 and extracting a 256*256 pixel patch.\n# At this point image data is read from the file and loaded into memory.\npatch = example.read_region((17800,19500), 0, (256, 256))\n\n# Display the image\ndisplay(patch)\n\n# Close the opened slide after use\nexample.close()","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:43.658749Z","iopub.execute_input":"2022-09-25T18:18:43.659206Z","iopub.status.idle":"2022-09-25T18:18:43.94147Z","shell.execute_reply.started":"2022-09-25T18:18:43.659165Z","shell.execute_reply":"2022-09-25T18:18:43.940386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now Let's see what all information can we get out of an image after creating an Openslide object","metadata":{}},{"cell_type":"code","source":"train = train.set_index('image_id')\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:43.942887Z","iopub.execute_input":"2022-09-25T18:18:43.943311Z","iopub.status.idle":"2022-09-25T18:18:43.959504Z","shell.execute_reply.started":"2022-09-25T18:18:43.943248Z","shell.execute_reply":"2022-09-25T18:18:43.95829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_values(image,max_size=(600,400)):\n    slide = openslide.OpenSlide(os.path.join(BASE_FOLDER+\"train_images\", f'{image}.tiff'))\n    \n    # Here we compute the \"pixel spacing\": the physical size of a pixel in the image.\n    # OpenSlide gives the resolution in centimeters so we convert this to microns.\n    f,ax =  plt.subplots(2 ,figsize=(6,16))\n    spacing = 1 / (float(slide.properties['tiff.XResolution']) / 10000)\n    patch = slide.read_region((1780,1950), 0, (256, 256)) #ZOOMED FUGURE\n    ax[0].imshow(patch) \n    ax[0].set_title('Zoomed Image')\n    \n    \n    ax[1].imshow(slide.get_thumbnail(size=max_size)) #UNZOOMED FIGURE\n    ax[1].set_title('Full Image')\n    \n    \n    print(f\"File id: {slide}\")\n    print(f\"Dimensions: {slide.dimensions}\")\n    print(f\"Microns per pixel / pixel spacing: {spacing:.3f}\")\n    print(f\"Number of levels in the image: {slide.level_count}\")\n    print(f\"Downsample factor per level: {slide.level_downsamples}\")\n    print(f\"Dimensions of levels: {slide.level_dimensions}\\n\\n\")\n    \n    print(f\"ISUP grade: {train.loc[image, 'isup_grade']}\")\n    print(f\"Gleason score: {train.loc[image, 'gleason_score']}\")","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:43.960904Z","iopub.execute_input":"2022-09-25T18:18:43.961291Z","iopub.status.idle":"2022-09-25T18:18:43.970474Z","shell.execute_reply.started":"2022-09-25T18:18:43.961257Z","shell.execute_reply":"2022-09-25T18:18:43.969563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* This Function prints Zoomed and Non-Zoomed images side by side and also all the information that can be derived from it\n* You can read about what every function does in the documentation of Open slide\n* You can play around with the read_region to zoom in different parts of an image and by little modifications you can build a function that takes in multiple images and displays their zoomed and non-Zoomed Images side by side","metadata":{}},{"cell_type":"code","source":"get_values('07a7ef0ba3bb0d6564a73f4f3e1c2293')","metadata":{"execution":{"iopub.status.busy":"2022-09-25T18:18:43.971692Z","iopub.execute_input":"2022-09-25T18:18:43.972119Z","iopub.status.idle":"2022-09-25T18:18:44.860085Z","shell.execute_reply.started":"2022-09-25T18:18:43.972088Z","shell.execute_reply":"2022-09-25T18:18:44.859312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def display_images(images):\n    '''\n    This function takes in input a list of images. It then iterates through the image making openslide objects , on which different functions\n    for getting out information can be called later\n    '''\n    f, ax = plt.subplots(5,3, figsize=(18,22))\n    for i, image in enumerate(images):\n        slide = openslide.OpenSlide(os.path.join(BASE_FOLDER+\"train_images\", f'{image}.tiff')) # Making Openslide Object\n        #Here we compute the \"pixel spacing\": the physical size of a pixel in the image,\n        #OpenSlide gives the resolution in centimeters so we convert this to microns\n        spacing = 1/(float(slide.properties['tiff.XResolution']) / 10000)\n        patch = slide.read_region((1780,1950), 0, (256, 256)) #Reading the image as before betweeen x=1780 to y=1950 and of pixel size =256*256\n        ax[i//3, i%3].imshow(patch) #Displaying Image\n        slide.close()       \n        ax[i//3, i%3].axis('off')\n        \n        image_id = image\n        data_provider = train.loc[image, 'data_provider']\n        isup_grade = train.loc[image, 'isup_grade']\n        gleason_score = train.loc[image, 'gleason_score']\n        ax[i//3, i%3].set_title(f\"ID: {image_id}\\nSource: {data_provider} ISUP: {isup_grade} Gleason: {gleason_score}\")\n\n    plt.show() ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images = [\n'07a7ef0ba3bb0d6564a73f4f3e1c2293',\n    '037504061b9fba71ef6e24c48c6df44d',\n    '035b1edd3d1aeeffc77ce5d248a01a53',\n    '059cbf902c5e42972587c8d17d49efed',\n    '06a0cbd8fd6320ef1aa6f19342af2e68',\n    '06eda4a6faca84e84a781fee2d5f47e1',\n    '0a4b7a7499ed55c71033cefb0765e93d',\n    '0838c82917cd9af681df249264d2769c',\n    '046b35ae95374bfb48cdca8d7c83233f',\n    '074c3e01525681a275a42282cd21cbde',\n    '05abe25c883d508ecc15b6e857e59f32',\n    '05f4e9415af9fdabc19109c980daf5ad',\n    '060121a06476ef401d8a21d6567dee6d',\n    '068b0e3be4c35ea983f77accf8351cc8',\n    '08f055372c7b8a7e1df97c6586542ac8'\n]\n\ndisplay_images(images)","metadata":{},"execution_count":null,"outputs":[]}]}