Training of neural networks for automated diagnosis of pigmented skin lesions is hampered by the small size and lack of diversity of available dataset of dermatoscopic images. We collected dermatoscopic images from different populations, acquired and stored by different modalities. The final dataset consists of 10015 dermatoscopic images which can serve as a training set for academic machine learning purposes. Cases include a representative collection of all important diagnostic categories in the realm of pigmented lesions: Actinic keratoses and intraepithelial carcinoma / Bowen's disease (akiec), basal cell carcinoma (bcc), benign keratosis-like lesions (solar lentigines / seborrheic keratoses and lichen-planus like keratoses, bkl), dermatofibroma (df), melanoma (mel), melanocytic nevi (nv) and vascular lesions (angiomas, angiokeratomas, pyogenic granulomas and hemorrhage, vasc).
Training of neural networks for automated diagnosis of pigmented skin lesions is hampered by the small size and lack of diversity of available dataset of dermatoscopic images. We collected dermatoscopic images from different populations, acquired and stored by different modalities. The final dataset consists of 10015 dermatoscopic images which can serve as a training set for academic machine learning purposes. Cases include a representative collection of all important diagnostic categories in the realm of pigmented lesions: Actinic keratoses and intraepithelial carcinoma / Bowen's disease (akiec), basal cell carcinoma (bcc), benign keratosis-like lesions (solar lentigines / seborrheic keratoses and lichen-planus like keratoses, bkl), dermatofibroma (df), melanoma (mel), melanocytic nevi (nv) and vascular lesions (angiomas, angiokeratomas, pyogenic granulomas and hemorrhage, vasc).
# Prerequisites for Use
# Prerequisites for Use
1. Download the training data [Here](https://isic-challenge-data.s3.amazonaws.com/2018/ISIC2018_Task3_Training_Input.zip)
2. Download the training ground truth [Here](https://isic-challenge-data.s3.amazonaws.com/2018/ISIC2018_Task3_Training_GroundTruth.zip)
All of the data will need to be placed in directory:
3. Download the test data images [Here](https://isic-challenge-data.s3.amazonaws.com/2018/ISIC2018_Task3_Validation_Input.zip)
4. Download the test data ground truth [Here](https://isic-challenge-data.s3.amazonaws.com/2018/ISIC2018_Task3_Validation_GroundTruth.zip)
`hvm-image-clf/data`
5. Unzip the files into the data folder in this repository.
6. Download required packages from requirements.txt, "pip install -r requirements.txt"
First we will need to download 3 data files used by the package. The first two can be downloaded by clicking the links below.
\ No newline at end of file
[Training Data](https://isic-challenge-data.s3.amazonaws.com/2018/ISIC2018_Task3_Training_Input.zip) - Unzip and place the folder named "ISIC2018_TASK3_Training_Input" and place in the data directory. This contains all of the training images.
[Ground Truth](https://isic-challenge-data.s3.amazonaws.com/2018/ISIC2018_Task3_Training_GroundTruth.zip) - Unzip and place the file named "ISIC2018_Task3_Training_GroundTruth.csv". This contains all of our ground truth labels of the training images.
The third dataset can be downloaded by following this link
[Metadata](https://dataverse.harvard.edu/file.xhtml?fileId=4338392&version=3.0). This will bring you to a website called Harvard Dataverse. On the page you will be able to see dropdown box called "Access File". Select the option called "Comma Separated Values (Original File Format) to download the dataset.
Project dependencies can be installed using
`pip install -r requirements.txt`
# Running the notebook.
If all of the pre-requisites are setup correctly, the notebook file can be run using an IPython or Anaconda distributed notebook ide.
"The project we are presenting is a multi-label image classification task based on the 2018 Human vs Machine skin lesion analysis toward melanoma detection hosted by the International Skin Imaging Collaboration (ISIC).\n",
"\n",
"This notebook will contain the following sections:\n",
" 1. Problem Definition & Data Description\n",
" 2. Data Preparation\n",
" 3. Exploratory Analysis\n",
" 4. Data Processing for Model Ingestion\n",
" 5. Model Creation\n",
" 6. Model Scoring & Evaluation\n",
" 7. Interpretation of Results"
]
},
{
"cell_type": "markdown",
"id": "830dee53",
"metadata": {},
"source": [
"# 1. Problem Definition & Data description\n",
"\n",
"#### Problem Definition:\n",
"Training of neural networks for automated diagnosis of pigmented skin lesions is hampered by the small size and lack of diversity of available dataset of dermatoscopic images. With a sufficiently large and diverse collection of skin lesions we will develop a method to automate the prediction of disease classification within dermoscopic images. The project is meant to human computer computer collaboration and not intended to replace traditional forms of diagnosis. \n",
"\n",
"Possible disease categories (and abbreviation) for classification are:\n",
" - dx_type: Method of how the diagnosis was confirmed. \n",
" - age: Numeric year age of the patient.\n",
" - sex: String binary value 'male' or 'female'.\n",
" - localization: Categorical location on the body the image was taken. \n",
" - dataset: Image source.\n",
"\n",
"*Further details of the data will be provided in the data preparation section."
]
},
{
"cell_type": "markdown",
"id": "96ff082e",
"metadata": {},
"source": [
"# 2. Data Preparation\n",
"\n",
"#### Step 1. Load and Sort\n",
"First we will load the data using the function `load_sort_data()`.\n",
"\n",
"The `load_sort_data()` function sorts the images into folders based on the diagnosis label. This will help reduce the overall size of the dataset and make preprocessing the images much faster. The function will return the metadata as a pandas DataFrame and the path of the sorted image folders. "
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b8c4f292",
"metadata": {},
"outputs": [],
"source": [
"# function takes 3 parameters: metadata filename, the folder of the raw images, and the desired name of the destination directory. \n",
"# We will need to change the Dtypes of the columns into the expected types\n",
"metadata.info()\n"
]
},
{
"cell_type": "markdown",
"id": "3f4a3578",
"metadata": {},
"source": [
"As we can see below, we have a total of 57 NA values in age. When looking at the distribution of NA values, only our largest quantity of labels have NA's. The age variable is only useful in providing context to our problem and will not be used as a feature in our model. Therefore it is not necessary to do anything further to the NA values. During exploratory analysis we can deal with the NA values as needed."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "e6d378d5",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Total number of unique labels\n",
" nv 6705\n",
"mel 1113\n",
"bkl 1099\n",
"bcc 514\n",
"akiec 327\n",
"vasc 142\n",
"df 115\n",
"Name: dx, dtype: int64 \n",
"Number of NaN values within each label\n",
" dx image_id age sex localization\n",
"0 akiec 0 0 0 0\n",
"1 bcc 0 0 0 0\n",
"2 bkl 0 10 0 0\n",
"3 df 0 0 0 0\n",
"4 mel 0 2 0 0\n",
"5 nv 0 45 0 0\n",
"6 vasc 0 0 0 0\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\Bennett Nolan\\AppData\\Local\\Temp\\ipykernel_10700\\2944415004.py:5: FutureWarning: In a future version of pandas all arguments of DataFrame.drop except for the argument 'labels' will be keyword-only.\n",
" metadata.drop('dx',1).isna().groupby(\n"
]
}
],
"source": [
"# Sum the na values contained within each label\n",
"print(\"Total number of unique labels\\n\",\n",
" metadata['dx'].value_counts(), \n",
" \"\\nNumber of NaN values within each label\\n\",\n",
" metadata.drop('dx',1).isna().groupby(\n",
" metadata.dx, \n",
" dropna=False, \n",
" observed = True\n",
" ).sum().reset_index()\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "91aa284b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 10015 entries, 0 to 10014\n",
"Data columns (total 5 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 image_id 10015 non-null string \n",
" 1 dx 10015 non-null category\n",
" 2 age 9958 non-null float64 \n",
" 3 sex 10015 non-null category\n",
" 4 localization 10015 non-null category\n",
"dtypes: category(3), float64(1), string(1)\n",
"memory usage: 187.1 KB\n"
]
}
],
"source": [
"#Changing datatypes\n",
"dtypes = {'image_id':'string', \n",
" 'dx':'category', \n",
" 'sex':'category',\n",
" 'localization': 'category'\n",
" }\n",
"metadata = metadata.astype(dtypes)\n",
"metadata.info()"
]
},
{
"cell_type": "markdown",
"id": "41f467b5",
"metadata": {},
"source": [
"#### Step 3. Image Processing\n",
"\n",
"In this step we will construct an NxM matrix where N is an image and M is the number of pixels in the image. "
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "05398a91",
"metadata": {},
"outputs": [],
"source": [
"#Assign vectorized images to variables\n",
"akiec_images = transform(dest_dir + 'akiec')\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "e8642d8d",
"metadata": {},
"outputs": [],
"source": [
"bcc_images = transform(dest_dir + 'bcc')"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "5312b5de",
"metadata": {},
"outputs": [],
"source": [
"bkl_images = transform(dest_dir + 'bkl')"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "49338970",
"metadata": {},
"outputs": [],
"source": [
"df_images = transform(dest_dir + 'df')"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "784d69cd",
"metadata": {},
"outputs": [],
"source": [
"mel_images = transform(dest_dir + 'mel')"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "6cd167a7",
"metadata": {},
"outputs": [],
"source": [
"#This takes a really long time to run even when cutting down the images size.\n",
The project we are presenting is a multi-label image classification task based on the 2018 Human vs Machine skin lesion analysis toward melanoma detection hosted by the International Skin Imaging Collaboration (ISIC).
This notebook will contain the following sections:
1. Problem Definition & Data Description
2. Data Preparation
3. Exploratory Analysis
4. Data Processing for Model Ingestion
5. Model Creation
6. Model Scoring & Evaluation
7. Interpretation of Results
%% Cell type:markdown id:830dee53 tags:
# 1. Problem Definition & Data description
#### Problem Definition:
Training of neural networks for automated diagnosis of pigmented skin lesions is hampered by the small size and lack of diversity of available dataset of dermatoscopic images. With a sufficiently large and diverse collection of skin lesions we will develop a method to automate the prediction of disease classification within dermoscopic images. The project is meant to human computer computer collaboration and not intended to replace traditional forms of diagnosis.
Possible disease categories (and abbreviation) for classification are:
1. Melanoma (mel)
2. Melanocytic Nevus (nv)
3. Basal Cell Carcinoma (bcc)
4. Actinic Keratosis / Bowen's Disease (akiec)
5. Benign Keratosis (bkl)
6. Dermatofibroma (df)
7. Vascular Lesion (vasc)
#### Data Description
- Data images are in JPEG format using the naming scheme `ISIC_.jpg` where _ is a 7 digit unique identifier of the image.
- There are a total of 10,015 600x450 pixel color images contained in the training data folder.
- There are a total of 193 600x450 pixel color images contained in the validation data folder.
- The training metadata is a 10,015x8 .csv file containing the following variables*:
- lesion_id: Unique identifier of a legion with multiple images.
- image_id: Unique identifier of the associated image file.
- dx: Prediction label containing the 7 abbreviated disease categories.
- dx_type: Method of how the diagnosis was confirmed.
- age: Numeric year age of the patient.
- sex: String binary value 'male' or 'female'.
- localization: Categorical location on the body the image was taken.
- dataset: Image source.
*Further details of the data will be provided in the data preparation section.
%% Cell type:markdown id:96ff082e tags:
# 2. Data Preparation
#### Step 1. Load and Sort
First we will load the data using the function `load_sort_data()`.
The `load_sort_data()` function sorts the images into folders based on the diagnosis label. This will help reduce the overall size of the dataset and make preprocessing the images much faster. The function will return the metadata as a pandas DataFrame and the path of the sorted image folders.
%% Cell type:code id:b8c4f292 tags:
``` python
# function takes 3 parameters: metadata filename, the folder of the raw images, and the desired name of the destination directory.
# We will need to change the Dtypes of the columns into the expected types
metadata.info()
```
%% Output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10015 entries, 0 to 10014
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 image_id 10015 non-null object
1 dx 10015 non-null object
2 age 9958 non-null float64
3 sex 10015 non-null object
4 localization 10015 non-null object
dtypes: float64(1), object(4)
memory usage: 391.3+ KB
%% Cell type:markdown id:3f4a3578 tags:
As we can see below, we have a total of 57 NA values in age. When looking at the distribution of NA values, only our largest quantity of labels have NA's. The age variable is only useful in providing context to our problem and will not be used as a feature in our model. Therefore it is not necessary to do anything further to the NA values. During exploratory analysis we can deal with the NA values as needed.
%% Cell type:code id:e6d378d5 tags:
``` python
# Sum the na values contained within each label
print("Total number of unique labels\n",
metadata['dx'].value_counts(),
"\nNumber of NaN values within each label\n",
metadata.drop('dx',1).isna().groupby(
metadata.dx,
dropna=False,
observed=True
).sum().reset_index()
)
```
%% Output
Total number of unique labels
nv 6705
mel 1113
bkl 1099
bcc 514
akiec 327
vasc 142
df 115
Name: dx, dtype: int64
Number of NaN values within each label
dx image_id age sex localization
0 akiec 0 0 0 0
1 bcc 0 0 0 0
2 bkl 0 10 0 0
3 df 0 0 0 0
4 mel 0 2 0 0
5 nv 0 45 0 0
6 vasc 0 0 0 0
C:\Users\Bennett Nolan\AppData\Local\Temp\ipykernel_10700\2944415004.py:5: FutureWarning: In a future version of pandas all arguments of DataFrame.drop except for the argument 'labels' will be keyword-only.
metadata.drop('dx',1).isna().groupby(
%% Cell type:code id:91aa284b tags:
``` python
#Changing datatypes
dtypes={'image_id':'string',
'dx':'category',
'sex':'category',
'localization':'category'
}
metadata=metadata.astype(dtypes)
metadata.info()
```
%% Output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10015 entries, 0 to 10014
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 image_id 10015 non-null string
1 dx 10015 non-null category
2 age 9958 non-null float64
3 sex 10015 non-null category
4 localization 10015 non-null category
dtypes: category(3), float64(1), string(1)
memory usage: 187.1 KB
%% Cell type:markdown id:41f467b5 tags:
#### Step 3. Image Processing
In this step we will construct an NxM matrix where N is an image and M is the number of pixels in the image.
%% Cell type:code id:05398a91 tags:
``` python
#Assign vectorized images to variables
akiec_images=transform(dest_dir+'akiec')
```
%% Cell type:code id:e8642d8d tags:
``` python
bcc_images=transform(dest_dir+'bcc')
```
%% Cell type:code id:5312b5de tags:
``` python
bkl_images=transform(dest_dir+'bkl')
```
%% Cell type:code id:49338970 tags:
``` python
df_images=transform(dest_dir+'df')
```
%% Cell type:code id:784d69cd tags:
``` python
mel_images=transform(dest_dir+'mel')
```
%% Cell type:code id:6cd167a7 tags:
``` python
#This takes a really long time to run even when cutting down the images size.
nv_images=transform(dest_dir+'nv',size=(200,150))
```
%% Cell type:code id:4de5cec3 tags:
``` python
vasc_images=transform(dest_dir+'vasc')
```
%% Cell type:code id:d92158fa tags:
``` python
mel_images.shape
```
%% Output
(1113, 67500)
%% Cell type:markdown id:3fb5f03e tags:
# 3. Exploritory Data Analysis
Exploritory analysis will be conducted on in two major steps. First we will complete analysis on the metadata then the image dataset.
%% Cell type:markdown id:6ca3d6bf tags:
#### Step 1: Metadata EDA
We will perform the following analysis on the metadata:
- Summary Statistics
- Class label distributions
- Correlation
%% Cell type:markdown id:686965dd tags:
Summary Statistics
%% Cell type:code id:5d475aed tags:
``` python
metadata.head()
```
%% Output
image_id dx age sex localization
0 ISIC_0027419 bkl 80.0 male scalp
1 ISIC_0025030 bkl 80.0 male scalp
2 ISIC_0026769 bkl 80.0 male scalp
3 ISIC_0025661 bkl 80.0 male scalp
4 ISIC_0031633 bkl 75.0 male ear
%% Cell type:code id:6e579e93 tags:
``` python
metadata.agg({
"age":["min","max","median","mean","skew"]
})
```
%% Output
age
min 0.000000
max 85.000000
median 50.000000
mean 51.863828
skew -0.166802
%% Cell type:code id:ea361300 tags:
``` python
metadata.groupby("sex")["sex"].count()
```
%% Output
sex
female 4552
male 5406
unknown 57
Name: sex, dtype: int64
%% Cell type:markdown id:e031ebf0 tags:
Class Label Distributions
%% Cell type:markdown id:bf51add8 tags:
Distributions for metadata including Age, Localization, Sex, and Diagnosis