Download src/data/preprocessing.py from thanakara/ham-clf: direct link, hf CLI and curl.
- Browser
- Download file 3.59 kB
-
https://huggingface.co/spaces/thanakara/ham-clf/resolve/main/src/data/preprocessing.py
- Command line
-
hf download hf://spaces/thanakara/ham-clf/src/data/preprocessing.py
-
curl -L -o preprocessing.py https://huggingface.co/spaces/thanakara/ham-clf/resolve/main/src/data/preprocessing.py
3.59 kB
| import logging | |
| from pathlib import Path | |
| import pandas as pd | |
| from sklearn.model_selection import train_test_split | |
| class HAMDataProcessor: | |
| def __init__(self, filepath: Path | str, log: logging.Logger): | |
| self.filepath = filepath | |
| self.log = log | |
| self.train_size_split = 0.7 | |
| self.target_samples_per_class = { | |
| "melanocytic_nevi": 2500, | |
| "melanoma": 1113, | |
| "benign_keratosis": 1100, | |
| "basal_cell_carcinoma": 900, | |
| "actinic_keratoses": 600, | |
| "vascular_lesions": 300, | |
| "dermatofibroma": 300, | |
| } | |
| def _balance_classes(df: pd.DataFrame, target_samples_per_class: dict[str, int]) -> pd.DataFrame: | |
| balanced = [] | |
| for class_name, target_count in target_samples_per_class.items(): | |
| class_df = df[df.dx == class_name] | |
| current_count = len(class_df) | |
| if current_count >= target_count: | |
| sampled = class_df.sample(target_count, random_state=42) | |
| else: | |
| sampled = class_df.sample(target_count, replace=True, random_state=42) | |
| balanced.append(sampled) | |
| return pd.concat(balanced).sample(frac=1.0, random_state=42).reset_index(drop=True) | |
| def _get_one_image_per_lesion(df: pd.DataFrame) -> pd.DataFrame: | |
| return df.groupby("lesion_id", group_keys=False).apply(lambda X: X.sample(1, random_state=42)) | |
| def _load_df(self) -> pd.DataFrame: | |
| self.log.debug("loading_dataframe") | |
| usecols = ["image_id", "dx", "lesion_id"] | |
| img_suffix = ".jpg" | |
| df = pd.read_csv(self.filepath, usecols=usecols) | |
| dx_names_short = { | |
| "akiec": "actinic_keratoses", | |
| "bcc": "basal_cell_carcinoma", | |
| "bkl": "benign_keratosis", | |
| "df": "dermatofibroma", | |
| "mel": "melanoma", | |
| "nv": "melanocytic_nevi", | |
| "vasc": "vascular_lesions", | |
| } | |
| df.dx = df.dx.map(dx_names_short).astype("category") | |
| df.image_id = df.image_id + img_suffix | |
| return df | |
| def _get_unique_lesions(self) -> tuple[pd.DataFrame]: | |
| df = self._load_df() | |
| unique_lesions = df[["lesion_id", "dx"]].drop_duplicates() | |
| test_size = 1.0 - self.train_size_split | |
| train_lesions, temp_lesions = train_test_split( | |
| unique_lesions, | |
| test_size=test_size, | |
| stratify=unique_lesions.dx, | |
| random_state=42, | |
| ) | |
| valid_lesions, test_lesions = train_test_split( | |
| temp_lesions, test_size=0.5, stratify=temp_lesions.dx, random_state=42 | |
| ) | |
| train_df = df[df.lesion_id.isin(train_lesions.lesion_id)] | |
| valid_df = df[df.lesion_id.isin(valid_lesions.lesion_id)] | |
| test_df = df[df.lesion_id.isin(test_lesions.lesion_id)] | |
| self.log.debug("dropping_duplicates_on_lesion") | |
| return train_df, valid_df, test_df | |
| def preprocess(self) -> tuple[pd.DataFrame]: | |
| train_df, valid_df, test_df = self._get_unique_lesions() | |
| self.log.debug("balance_training_dataset") | |
| train = self._balance_classes(train_df, self.target_samples_per_class) | |
| self.log.debug("get_one_image_per_lesion_on_validation_dataset") | |
| valid = self._get_one_image_per_lesion(valid_df) | |
| self.log.debug("get_one_image_per_lesion_on_testing_dataset") | |
| test = self._get_one_image_per_lesion(test_df) | |
| return train, valid, test | |