dslighting 1.7.1__py3-none-any.whl → 1.7.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dslighting/__init__.py +1 -1
- dslighting/core/agent.py +78 -62
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/METADATA +3 -1
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/RECORD +352 -7
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/top_level.txt +1 -0
- mlebench/README.md +39 -0
- mlebench/__init__.py +0 -0
- mlebench/cli.py +221 -0
- mlebench/competitions/3d-object-detection-for-autonomous-vehicles/grade.py +161 -0
- mlebench/competitions/3d-object-detection-for-autonomous-vehicles/mAP_evaluation.py +425 -0
- mlebench/competitions/3d-object-detection-for-autonomous-vehicles/prepare.py +483 -0
- mlebench/competitions/3d-object-detection-for-autonomous-vehicles/prepare_val.py +719 -0
- mlebench/competitions/AI4Code/grade.py +70 -0
- mlebench/competitions/AI4Code/prepare.py +84 -0
- mlebench/competitions/AI4Code/prepare_val.py +159 -0
- mlebench/competitions/__init__.py +0 -0
- mlebench/competitions/aerial-cactus-identification/grade.py +11 -0
- mlebench/competitions/aerial-cactus-identification/prepare.py +71 -0
- mlebench/competitions/aerial-cactus-identification/prepare_val.py +133 -0
- mlebench/competitions/alaska2-image-steganalysis/grade.py +136 -0
- mlebench/competitions/alaska2-image-steganalysis/prepare.py +88 -0
- mlebench/competitions/alaska2-image-steganalysis/prepare_val.py +148 -0
- mlebench/competitions/aptos2019-blindness-detection/grade.py +35 -0
- mlebench/competitions/aptos2019-blindness-detection/prepare.py +75 -0
- mlebench/competitions/aptos2019-blindness-detection/prepare_val.py +123 -0
- mlebench/competitions/bike-sharing-demand/__init__.py +0 -0
- mlebench/competitions/bike-sharing-demand/grade.py +55 -0
- mlebench/competitions/bike-sharing-demand/prepare.py +37 -0
- mlebench/competitions/billion-word-imputation/grade.py +37 -0
- mlebench/competitions/billion-word-imputation/prepare.py +107 -0
- mlebench/competitions/billion-word-imputation/prepare_val.py +179 -0
- mlebench/competitions/bms-molecular-translation/grade.py +40 -0
- mlebench/competitions/bms-molecular-translation/prepare.py +68 -0
- mlebench/competitions/bms-molecular-translation/prepare_val.py +131 -0
- mlebench/competitions/cassava-leaf-disease-classification/grade.py +12 -0
- mlebench/competitions/cassava-leaf-disease-classification/prepare.py +113 -0
- mlebench/competitions/cassava-leaf-disease-classification/prepare_val.py +186 -0
- mlebench/competitions/cdiscount-image-classification-challenge/grade.py +11 -0
- mlebench/competitions/cdiscount-image-classification-challenge/prepare.py +144 -0
- mlebench/competitions/cdiscount-image-classification-challenge/prepare_val.py +205 -0
- mlebench/competitions/chaii-hindi-and-tamil-question-answering/grade.py +67 -0
- mlebench/competitions/chaii-hindi-and-tamil-question-answering/prepare.py +31 -0
- mlebench/competitions/chaii-hindi-and-tamil-question-answering/prepare_val.py +94 -0
- mlebench/competitions/champs-scalar-coupling/grade.py +60 -0
- mlebench/competitions/champs-scalar-coupling/prepare.py +116 -0
- mlebench/competitions/champs-scalar-coupling/prepare_val.py +155 -0
- mlebench/competitions/conways-reverse-game-of-life-2020/__init__.py +0 -0
- mlebench/competitions/conways-reverse-game-of-life-2020/grade.py +40 -0
- mlebench/competitions/conways-reverse-game-of-life-2020/prepare.py +41 -0
- mlebench/competitions/demand-forecasting-kernels-only/__init__.py +0 -0
- mlebench/competitions/demand-forecasting-kernels-only/grade.py +66 -0
- mlebench/competitions/demand-forecasting-kernels-only/prepare.py +27 -0
- mlebench/competitions/demand_forecasting_kernels_only/__init__.py +0 -0
- mlebench/competitions/demand_forecasting_kernels_only/grade.py +66 -0
- mlebench/competitions/demand_forecasting_kernels_only/prepare.py +27 -0
- mlebench/competitions/denoising-dirty-documents/grade.py +44 -0
- mlebench/competitions/denoising-dirty-documents/prepare.py +134 -0
- mlebench/competitions/denoising-dirty-documents/prepare_val.py +178 -0
- mlebench/competitions/detecting-insults-in-social-commentary/grade.py +11 -0
- mlebench/competitions/detecting-insults-in-social-commentary/prepare.py +72 -0
- mlebench/competitions/detecting-insults-in-social-commentary/prepare_val.py +128 -0
- mlebench/competitions/dog-breed-identification/dogs.py +124 -0
- mlebench/competitions/dog-breed-identification/grade.py +42 -0
- mlebench/competitions/dog-breed-identification/prepare.py +55 -0
- mlebench/competitions/dog-breed-identification/prepare_val.py +104 -0
- mlebench/competitions/dogs-vs-cats-redux-kernels-edition/grade.py +43 -0
- mlebench/competitions/dogs-vs-cats-redux-kernels-edition/prepare.py +70 -0
- mlebench/competitions/dogs-vs-cats-redux-kernels-edition/prepare_val.py +143 -0
- mlebench/competitions/ethanol-concentration/grade.py +23 -0
- mlebench/competitions/ethanol-concentration/prepare.py +90 -0
- mlebench/competitions/facebook-recruiting-iii-keyword-extraction/grade.py +60 -0
- mlebench/competitions/facebook-recruiting-iii-keyword-extraction/prepare.py +41 -0
- mlebench/competitions/facebook-recruiting-iii-keyword-extraction/prepare_val.py +92 -0
- mlebench/competitions/feedback-prize-english-language-learning/__init__.py +0 -0
- mlebench/competitions/feedback-prize-english-language-learning/grade.py +60 -0
- mlebench/competitions/feedback-prize-english-language-learning/prepare.py +39 -0
- mlebench/competitions/freesound-audio-tagging-2019/grade.py +64 -0
- mlebench/competitions/freesound-audio-tagging-2019/prepare.py +94 -0
- mlebench/competitions/freesound-audio-tagging-2019/prepare_val.py +175 -0
- mlebench/competitions/freesound-audio-tagging-2019/vocabulary.py +83 -0
- mlebench/competitions/google-quest-challenge/classes.py +32 -0
- mlebench/competitions/google-quest-challenge/grade.py +45 -0
- mlebench/competitions/google-quest-challenge/prepare.py +58 -0
- mlebench/competitions/google-quest-challenge/prepare_val.py +120 -0
- mlebench/competitions/google-research-identify-contrails-reduce-global-warming/grade.py +77 -0
- mlebench/competitions/google-research-identify-contrails-reduce-global-warming/prepare.py +155 -0
- mlebench/competitions/google-research-identify-contrails-reduce-global-warming/prepare_val.py +211 -0
- mlebench/competitions/h-and-m-personalized-fashion-recommendations/grade.py +42 -0
- mlebench/competitions/h-and-m-personalized-fashion-recommendations/prepare.py +102 -0
- mlebench/competitions/h-and-m-personalized-fashion-recommendations/prepare_val.py +132 -0
- mlebench/competitions/handwriting/grade.py +23 -0
- mlebench/competitions/handwriting/prepare.py +179 -0
- mlebench/competitions/herbarium-2020-fgvc7/grade.py +34 -0
- mlebench/competitions/herbarium-2020-fgvc7/prepare.py +251 -0
- mlebench/competitions/herbarium-2020-fgvc7/prepare_val.py +242 -0
- mlebench/competitions/herbarium-2021-fgvc8/grade.py +34 -0
- mlebench/competitions/herbarium-2021-fgvc8/prepare.py +251 -0
- mlebench/competitions/herbarium-2021-fgvc8/prepare_val.py +222 -0
- mlebench/competitions/herbarium-2022-fgvc9/grade.py +31 -0
- mlebench/competitions/herbarium-2022-fgvc9/prepare.py +233 -0
- mlebench/competitions/herbarium-2022-fgvc9/prepare_val.py +213 -0
- mlebench/competitions/histopathologic-cancer-detection/grade.py +12 -0
- mlebench/competitions/histopathologic-cancer-detection/prepare.py +59 -0
- mlebench/competitions/histopathologic-cancer-detection/prepare_val.py +131 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/constants.py +9 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/grade.py +43 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/kaggle_metric_utilities.py +96 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/kullback_leibler_divergence.py +118 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/prepare.py +121 -0
- mlebench/competitions/hms-harmful-brain-activity-classification/prepare_val.py +190 -0
- mlebench/competitions/hotel-id-2021-fgvc8/grade.py +41 -0
- mlebench/competitions/hotel-id-2021-fgvc8/prepare.py +63 -0
- mlebench/competitions/hotel-id-2021-fgvc8/prepare_val.py +132 -0
- mlebench/competitions/hubmap-kidney-segmentation/grade.py +62 -0
- mlebench/competitions/hubmap-kidney-segmentation/prepare.py +108 -0
- mlebench/competitions/hubmap-kidney-segmentation/prepare_val.py +153 -0
- mlebench/competitions/icecube-neutrinos-in-deep-ice/grade.py +111 -0
- mlebench/competitions/icecube-neutrinos-in-deep-ice/prepare.py +127 -0
- mlebench/competitions/icecube-neutrinos-in-deep-ice/prepare_val.py +183 -0
- mlebench/competitions/ili/grade.py +60 -0
- mlebench/competitions/ili/prepare.py +99 -0
- mlebench/competitions/imet-2020-fgvc7/grade.py +54 -0
- mlebench/competitions/imet-2020-fgvc7/prepare.py +77 -0
- mlebench/competitions/imet-2020-fgvc7/prepare_val.py +157 -0
- mlebench/competitions/inaturalist-2019-fgvc6/grade.py +35 -0
- mlebench/competitions/inaturalist-2019-fgvc6/prepare.py +259 -0
- mlebench/competitions/inaturalist-2019-fgvc6/prepare_val.py +304 -0
- mlebench/competitions/instant-gratification/__init__.py +0 -0
- mlebench/competitions/instant-gratification/grade.py +55 -0
- mlebench/competitions/instant-gratification/prepare.py +25 -0
- mlebench/competitions/instant_gratification/__init__.py +0 -0
- mlebench/competitions/instant_gratification/grade.py +55 -0
- mlebench/competitions/instant_gratification/prepare.py +25 -0
- mlebench/competitions/invasive-species-monitoring/grade.py +11 -0
- mlebench/competitions/invasive-species-monitoring/prepare.py +97 -0
- mlebench/competitions/invasive-species-monitoring/prepare_val.py +164 -0
- mlebench/competitions/iwildcam-2019-fgvc6/grade.py +44 -0
- mlebench/competitions/iwildcam-2019-fgvc6/prepare.py +118 -0
- mlebench/competitions/iwildcam-2019-fgvc6/prepare_val.py +194 -0
- mlebench/competitions/iwildcam-2020-fgvc7/grade.py +11 -0
- mlebench/competitions/iwildcam-2020-fgvc7/prepare.py +164 -0
- mlebench/competitions/iwildcam-2020-fgvc7/prepare_val.py +245 -0
- mlebench/competitions/jigsaw-toxic-comment-classification-challenge/classes.py +1 -0
- mlebench/competitions/jigsaw-toxic-comment-classification-challenge/grade.py +54 -0
- mlebench/competitions/jigsaw-toxic-comment-classification-challenge/prepare.py +42 -0
- mlebench/competitions/jigsaw-toxic-comment-classification-challenge/prepare_val.py +88 -0
- mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/grade.py +153 -0
- mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/prepare.py +36 -0
- mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/prepare_val.py +117 -0
- mlebench/competitions/kuzushiji-recognition/grade.py +58 -0
- mlebench/competitions/kuzushiji-recognition/kuzushiji_metric.py +118 -0
- mlebench/competitions/kuzushiji-recognition/prepare.py +92 -0
- mlebench/competitions/kuzushiji-recognition/prepare_val.py +149 -0
- mlebench/competitions/leaf-classification/classes.py +101 -0
- mlebench/competitions/leaf-classification/grade.py +44 -0
- mlebench/competitions/leaf-classification/prepare.py +60 -0
- mlebench/competitions/leaf-classification/prepare_val.py +116 -0
- mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/grade.py +44 -0
- mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/prepare.py +51 -0
- mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/prepare_val.py +96 -0
- mlebench/competitions/liverpool-ion-switching/__init__.py +0 -0
- mlebench/competitions/liverpool-ion-switching/grade.py +52 -0
- mlebench/competitions/liverpool-ion-switching/prepare.py +27 -0
- mlebench/competitions/liverpool_ion_switching/__init__.py +0 -0
- mlebench/competitions/liverpool_ion_switching/grade.py +52 -0
- mlebench/competitions/liverpool_ion_switching/prepare.py +27 -0
- mlebench/competitions/lmsys-chatbot-arena/grade.py +63 -0
- mlebench/competitions/lmsys-chatbot-arena/prepare.py +52 -0
- mlebench/competitions/lmsys-chatbot-arena/prepare_val.py +115 -0
- mlebench/competitions/mcm_2024_c_test/grade.py +107 -0
- mlebench/competitions/mcm_2024_c_test/prepare.py +2 -0
- mlebench/competitions/ml2021spring-hw2/grade.py +11 -0
- mlebench/competitions/ml2021spring-hw2/prepare.py +58 -0
- mlebench/competitions/ml2021spring-hw2/prepare_val.py +135 -0
- mlebench/competitions/mlsp-2013-birds/grade.py +11 -0
- mlebench/competitions/mlsp-2013-birds/prepare.py +182 -0
- mlebench/competitions/mlsp-2013-birds/prepare_val.py +241 -0
- mlebench/competitions/movie-review-sentiment-analysis-kernels-only/grade.py +11 -0
- mlebench/competitions/movie-review-sentiment-analysis-kernels-only/prepare.py +58 -0
- mlebench/competitions/movie-review-sentiment-analysis-kernels-only/prepare_val.py +120 -0
- mlebench/competitions/multi-modal-gesture-recognition/grade.py +58 -0
- mlebench/competitions/multi-modal-gesture-recognition/prepare.py +85 -0
- mlebench/competitions/multi-modal-gesture-recognition/prepare_val.py +139 -0
- mlebench/competitions/my-custom-task-01/prepare.py +2 -0
- mlebench/competitions/new-my-task-01/prepare.py +2 -0
- mlebench/competitions/new-my-task-03/grade.py +107 -0
- mlebench/competitions/new-my-task-03/prepare.py +2 -0
- mlebench/competitions/new-york-city-taxi-fare-prediction/grade.py +28 -0
- mlebench/competitions/new-york-city-taxi-fare-prediction/prepare.py +44 -0
- mlebench/competitions/new-york-city-taxi-fare-prediction/prepare_val.py +89 -0
- mlebench/competitions/nfl-player-contact-detection/grade.py +36 -0
- mlebench/competitions/nfl-player-contact-detection/prepare.py +101 -0
- mlebench/competitions/nfl-player-contact-detection/prepare_val.py +186 -0
- mlebench/competitions/nomad2018-predict-transparent-conductors/grade.py +47 -0
- mlebench/competitions/nomad2018-predict-transparent-conductors/prepare.py +77 -0
- mlebench/competitions/nomad2018-predict-transparent-conductors/prepare_val.py +144 -0
- mlebench/competitions/osic-pulmonary-fibrosis-progression/grade.py +74 -0
- mlebench/competitions/osic-pulmonary-fibrosis-progression/prepare.py +95 -0
- mlebench/competitions/osic-pulmonary-fibrosis-progression/prepare_val.py +167 -0
- mlebench/competitions/paddy-disease-classification/grade.py +35 -0
- mlebench/competitions/paddy-disease-classification/prepare.py +69 -0
- mlebench/competitions/paddy-disease-classification/prepare_val.py +122 -0
- mlebench/competitions/petfinder-pawpularity-score/grade.py +41 -0
- mlebench/competitions/petfinder-pawpularity-score/prepare.py +76 -0
- mlebench/competitions/petfinder-pawpularity-score/prepare_val.py +154 -0
- mlebench/competitions/plant-pathology-2020-fgvc7/grade.py +41 -0
- mlebench/competitions/plant-pathology-2020-fgvc7/prepare.py +74 -0
- mlebench/competitions/plant-pathology-2020-fgvc7/prepare_val.py +160 -0
- mlebench/competitions/plant-pathology-2021-fgvc8/grade.py +54 -0
- mlebench/competitions/plant-pathology-2021-fgvc8/prepare.py +65 -0
- mlebench/competitions/plant-pathology-2021-fgvc8/prepare_val.py +130 -0
- mlebench/competitions/plant-seedlings-classification/grade.py +39 -0
- mlebench/competitions/plant-seedlings-classification/prepare.py +91 -0
- mlebench/competitions/plant-seedlings-classification/prepare_val.py +158 -0
- mlebench/competitions/playground-series-s3e1/__init__.py +0 -0
- mlebench/competitions/playground-series-s3e1/grade.py +52 -0
- mlebench/competitions/playground-series-s3e1/prepare.py +25 -0
- mlebench/competitions/playground-series-s3e11/__init__.py +0 -0
- mlebench/competitions/playground-series-s3e11/grade.py +55 -0
- mlebench/competitions/playground-series-s3e11/prepare.py +25 -0
- mlebench/competitions/playground-series-s3e18/grade.py +39 -0
- mlebench/competitions/playground-series-s3e18/prepare.py +36 -0
- mlebench/competitions/playground-series-s3e18/prepare_val.py +89 -0
- mlebench/competitions/playground_series_s3e1/__init__.py +0 -0
- mlebench/competitions/playground_series_s3e1/grade.py +52 -0
- mlebench/competitions/playground_series_s3e1/prepare.py +25 -0
- mlebench/competitions/playground_series_s3e11/__init__.py +0 -0
- mlebench/competitions/playground_series_s3e11/grade.py +55 -0
- mlebench/competitions/playground_series_s3e11/prepare.py +25 -0
- mlebench/competitions/predict-volcanic-eruptions-ingv-oe/grade.py +44 -0
- mlebench/competitions/predict-volcanic-eruptions-ingv-oe/prepare.py +68 -0
- mlebench/competitions/predict-volcanic-eruptions-ingv-oe/prepare_val.py +146 -0
- mlebench/competitions/random-acts-of-pizza/grade.py +14 -0
- mlebench/competitions/random-acts-of-pizza/prepare.py +80 -0
- mlebench/competitions/random-acts-of-pizza/prepare_val.py +144 -0
- mlebench/competitions/ranzcr-clip-catheter-line-classification/classes.py +11 -0
- mlebench/competitions/ranzcr-clip-catheter-line-classification/grade.py +31 -0
- mlebench/competitions/ranzcr-clip-catheter-line-classification/prepare.py +53 -0
- mlebench/competitions/ranzcr-clip-catheter-line-classification/prepare_val.py +113 -0
- mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/grade.py +124 -0
- mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/prepare.py +219 -0
- mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/prepare_val.py +257 -0
- mlebench/competitions/rsna-breast-cancer-detection/grade.py +65 -0
- mlebench/competitions/rsna-breast-cancer-detection/prepare.py +141 -0
- mlebench/competitions/rsna-breast-cancer-detection/prepare_val.py +201 -0
- mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/grade.py +13 -0
- mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/prepare.py +47 -0
- mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/prepare_val.py +97 -0
- mlebench/competitions/santander-customer-satisfaction/grade.py +10 -0
- mlebench/competitions/santander-customer-satisfaction/prepare.py +41 -0
- mlebench/competitions/sciencebench-001-clintox-nn/__init__.py +0 -0
- mlebench/competitions/sciencebench-001-clintox-nn/grade.py +56 -0
- mlebench/competitions/sciencebench-001-clintox-nn/prepare.py +75 -0
- mlebench/competitions/sciencebench-015-aai/grade.py +37 -0
- mlebench/competitions/sciencebench-015-aai/prepare.py +102 -0
- mlebench/competitions/sciencebench-051-brain-blood-qsar/grade.py +58 -0
- mlebench/competitions/sciencebench-051-brain-blood-qsar/prepare.py +69 -0
- mlebench/competitions/sciencebench-101-experimental-band-gap-prediction/grade.py +55 -0
- mlebench/competitions/sciencebench-101-experimental-band-gap-prediction/prepare.py +88 -0
- mlebench/competitions/see-click-predict-fix/__init__.py +0 -0
- mlebench/competitions/see-click-predict-fix/grade.py +66 -0
- mlebench/competitions/see-click-predict-fix/prepare.py +25 -0
- mlebench/competitions/see_click_predict_fix/__init__.py +0 -0
- mlebench/competitions/see_click_predict_fix/grade.py +66 -0
- mlebench/competitions/see_click_predict_fix/prepare.py +25 -0
- mlebench/competitions/seti-breakthrough-listen/grade.py +11 -0
- mlebench/competitions/seti-breakthrough-listen/prepare.py +71 -0
- mlebench/competitions/seti-breakthrough-listen/prepare_val.py +159 -0
- mlebench/competitions/siim-covid19-detection/grade.py +194 -0
- mlebench/competitions/siim-covid19-detection/prepare.py +123 -0
- mlebench/competitions/siim-covid19-detection/prepare_val.py +164 -0
- mlebench/competitions/siim-isic-melanoma-classification/grade.py +11 -0
- mlebench/competitions/siim-isic-melanoma-classification/prepare.py +127 -0
- mlebench/competitions/siim-isic-melanoma-classification/prepare_val.py +158 -0
- mlebench/competitions/smartphone-decimeter-2022/grade.py +55 -0
- mlebench/competitions/smartphone-decimeter-2022/notebook.py +86 -0
- mlebench/competitions/smartphone-decimeter-2022/prepare.py +143 -0
- mlebench/competitions/smartphone-decimeter-2022/prepare_val.py +199 -0
- mlebench/competitions/spaceship-titanic/grade.py +11 -0
- mlebench/competitions/spaceship-titanic/prepare.py +23 -0
- mlebench/competitions/spaceship-titanic/prepare_val.py +61 -0
- mlebench/competitions/spooky-author-identification/classes.py +1 -0
- mlebench/competitions/spooky-author-identification/grade.py +38 -0
- mlebench/competitions/spooky-author-identification/prepare.py +40 -0
- mlebench/competitions/spooky-author-identification/prepare_val.py +78 -0
- mlebench/competitions/stanford-covid-vaccine/grade.py +65 -0
- mlebench/competitions/stanford-covid-vaccine/prepare.py +129 -0
- mlebench/competitions/stanford-covid-vaccine/prepare_val.py +199 -0
- mlebench/competitions/statoil-iceberg-classifier-challenge/grade.py +41 -0
- mlebench/competitions/statoil-iceberg-classifier-challenge/prepare.py +105 -0
- mlebench/competitions/statoil-iceberg-classifier-challenge/prepare_val.py +157 -0
- mlebench/competitions/tabular-playground-series-dec-2021/grade.py +11 -0
- mlebench/competitions/tabular-playground-series-dec-2021/prepare.py +39 -0
- mlebench/competitions/tabular-playground-series-dec-2021/prepare_val.py +99 -0
- mlebench/competitions/tabular-playground-series-may-2022/grade.py +9 -0
- mlebench/competitions/tabular-playground-series-may-2022/prepare.py +56 -0
- mlebench/competitions/tabular-playground-series-may-2022/prepare_val.py +116 -0
- mlebench/competitions/tensorflow-speech-recognition-challenge/grade.py +11 -0
- mlebench/competitions/tensorflow-speech-recognition-challenge/prepare.py +90 -0
- mlebench/competitions/tensorflow-speech-recognition-challenge/prepare_val.py +148 -0
- mlebench/competitions/tensorflow2-question-answering/grade.py +122 -0
- mlebench/competitions/tensorflow2-question-answering/prepare.py +122 -0
- mlebench/competitions/tensorflow2-question-answering/prepare_val.py +187 -0
- mlebench/competitions/text-normalization-challenge-english-language/grade.py +49 -0
- mlebench/competitions/text-normalization-challenge-english-language/prepare.py +115 -0
- mlebench/competitions/text-normalization-challenge-english-language/prepare_val.py +213 -0
- mlebench/competitions/text-normalization-challenge-russian-language/grade.py +49 -0
- mlebench/competitions/text-normalization-challenge-russian-language/prepare.py +113 -0
- mlebench/competitions/text-normalization-challenge-russian-language/prepare_val.py +165 -0
- mlebench/competitions/tgs-salt-identification-challenge/grade.py +144 -0
- mlebench/competitions/tgs-salt-identification-challenge/prepare.py +158 -0
- mlebench/competitions/tgs-salt-identification-challenge/prepare_val.py +166 -0
- mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/grade.py +11 -0
- mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/prepare.py +95 -0
- mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/prepare_val.py +141 -0
- mlebench/competitions/tmdb-box-office-prediction/__init__.py +0 -0
- mlebench/competitions/tmdb-box-office-prediction/grade.py +55 -0
- mlebench/competitions/tmdb-box-office-prediction/prepare.py +35 -0
- mlebench/competitions/tweet-sentiment-extraction/grade.py +67 -0
- mlebench/competitions/tweet-sentiment-extraction/prepare.py +36 -0
- mlebench/competitions/tweet-sentiment-extraction/prepare_val.py +106 -0
- mlebench/competitions/us-patent-phrase-to-phrase-matching/grade.py +31 -0
- mlebench/competitions/us-patent-phrase-to-phrase-matching/prepare.py +33 -0
- mlebench/competitions/us-patent-phrase-to-phrase-matching/prepare_val.py +71 -0
- mlebench/competitions/utils.py +266 -0
- mlebench/competitions/uw-madison-gi-tract-image-segmentation/grade.py +158 -0
- mlebench/competitions/uw-madison-gi-tract-image-segmentation/prepare.py +139 -0
- mlebench/competitions/uw-madison-gi-tract-image-segmentation/prepare_val.py +193 -0
- mlebench/competitions/ventilator-pressure-prediction/__init__.py +0 -0
- mlebench/competitions/ventilator-pressure-prediction/grade.py +52 -0
- mlebench/competitions/ventilator-pressure-prediction/prepare.py +27 -0
- mlebench/competitions/ventilator-pressure-prediction/prepare_val.py +142 -0
- mlebench/competitions/ventilator_pressure_prediction/__init__.py +0 -0
- mlebench/competitions/ventilator_pressure_prediction/grade.py +52 -0
- mlebench/competitions/ventilator_pressure_prediction/prepare.py +27 -0
- mlebench/competitions/vesuvius-challenge-ink-detection/grade.py +97 -0
- mlebench/competitions/vesuvius-challenge-ink-detection/prepare.py +122 -0
- mlebench/competitions/vesuvius-challenge-ink-detection/prepare_val.py +170 -0
- mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/grade.py +220 -0
- mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/prepare.py +129 -0
- mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/prepare_val.py +204 -0
- mlebench/competitions/whale-categorization-playground/grade.py +41 -0
- mlebench/competitions/whale-categorization-playground/prepare.py +103 -0
- mlebench/competitions/whale-categorization-playground/prepare_val.py +196 -0
- mlebench/data.py +420 -0
- mlebench/grade.py +209 -0
- mlebench/grade_helpers.py +235 -0
- mlebench/metrics.py +75 -0
- mlebench/registry.py +332 -0
- mlebench/utils.py +346 -0
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/WHEEL +0 -0
- {dslighting-1.7.1.dist-info → dslighting-1.7.8.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from sklearn.model_selection import train_test_split
|
|
6
|
+
from tqdm import tqdm
|
|
7
|
+
|
|
8
|
+
from mlebench.utils import read_csv
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def prepare(raw: Path, public: Path, private: Path):
|
|
12
|
+
"""
|
|
13
|
+
Splits the data in raw into public and private datasets with appropriate test/train splits.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
dev = False
|
|
17
|
+
|
|
18
|
+
# Create train, test from train split
|
|
19
|
+
old_train = read_csv(raw / "train.csv")
|
|
20
|
+
unique_image_ids = old_train["image_id"].unique()
|
|
21
|
+
# Original train has 15k images, original test has 3k images
|
|
22
|
+
# Our new train will have 13.5k images, our new test will have 1.5k images
|
|
23
|
+
expected_train_size = 13500
|
|
24
|
+
expected_test_size = 1500
|
|
25
|
+
train_image_ids, test_image_ids = train_test_split(
|
|
26
|
+
unique_image_ids, test_size=0.1, random_state=0
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
new_train = old_train[old_train["image_id"].isin(train_image_ids)]
|
|
30
|
+
answers = old_train[old_train["image_id"].isin(test_image_ids)]
|
|
31
|
+
|
|
32
|
+
# Create sample submission
|
|
33
|
+
sample_submission = pd.DataFrame(
|
|
34
|
+
{
|
|
35
|
+
"image_id": test_image_ids,
|
|
36
|
+
"PredictionString": "14 1 0 0 1 1",
|
|
37
|
+
} # As per the original sample submission
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Checks
|
|
41
|
+
assert (
|
|
42
|
+
len(set(new_train["image_id"])) == expected_train_size
|
|
43
|
+
), f"Expected {expected_train_size} train image_ids, got {len(set(new_train['image_id']))}"
|
|
44
|
+
assert (
|
|
45
|
+
len(set(answers["image_id"])) == expected_test_size
|
|
46
|
+
), f"Expected {expected_test_size} test image_ids, got {len(set(answers['image_id']))}"
|
|
47
|
+
assert set(new_train["image_id"]).isdisjoint(
|
|
48
|
+
set(answers["image_id"])
|
|
49
|
+
), f"image_id is not disjoint between train and test sets"
|
|
50
|
+
assert (
|
|
51
|
+
new_train.columns.tolist() == old_train.columns.tolist()
|
|
52
|
+
), f"Columns of new train and old train are not the same: {new_train.columns.tolist()} vs {old_train.columns.tolist()}"
|
|
53
|
+
assert len(new_train) + len(answers) == len(
|
|
54
|
+
old_train
|
|
55
|
+
), f"Length of new train and answers should add up to the length of old train, got {len(new_train) + len(answers)} vs {len(old_train)}"
|
|
56
|
+
assert len(sample_submission) == len(
|
|
57
|
+
set(answers["image_id"])
|
|
58
|
+
), f"Length of sample submission should be equal to the number of unique image_ids in answers, got {len(sample_submission)} vs {len(set(answers['image_id']))}"
|
|
59
|
+
|
|
60
|
+
# Reformat answers
|
|
61
|
+
def _get_consensus_annotation(answers, inspect_duplicates=False):
|
|
62
|
+
"""
|
|
63
|
+
In the original train, there can be multiple annotations of the same image_id, class_id pair. (Different radiologists draw the bounding boxes differently for the same finding)
|
|
64
|
+
|
|
65
|
+
In the original test, there is only one annotation per image_id, class_id pair. The original test set is labeled by consensus of 5 radiologists. (Source: https://www.kaggle.com/competitions/vinbigdata-chest-xray-abnormalities-detection/discussion/207969#1134645)
|
|
66
|
+
|
|
67
|
+
We simulate consensus by taking the first annotation for each image_id, class_id pair.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
if inspect_duplicates:
|
|
71
|
+
duplicates = answers[answers.duplicated(subset=["image_id", "class_id"], keep=False)]
|
|
72
|
+
duplicates = duplicates.sort_values(by=["image_id", "class_id"])
|
|
73
|
+
duplicates.to_csv("duplicates.csv", index=False)
|
|
74
|
+
|
|
75
|
+
answers = answers.groupby(by=["image_id", "class_id"]).first().reset_index()
|
|
76
|
+
return answers
|
|
77
|
+
|
|
78
|
+
answers = _get_consensus_annotation(answers)
|
|
79
|
+
# Filling in missing values for when there is no finding (class_id = 14)
|
|
80
|
+
answers = answers.fillna(0)
|
|
81
|
+
answers.loc[answers["class_id"] == 14, ["x_max", "y_max"]] = 1.0
|
|
82
|
+
|
|
83
|
+
# Create gold submission
|
|
84
|
+
gold = answers[["image_id", "class_id", "x_min", "y_min", "x_max", "y_max"]].copy()
|
|
85
|
+
# Create individual prediction strings
|
|
86
|
+
gold.loc[:, "PredictionString"] = gold.apply(
|
|
87
|
+
lambda row: f"{row['class_id']} 1.0 {row['x_min']} {row['y_min']} {row['x_max']} {row['y_max']}",
|
|
88
|
+
axis=1, # 1.0 is the confidence score
|
|
89
|
+
)
|
|
90
|
+
# Group by image_id and concatenate prediction strings
|
|
91
|
+
gold = gold.groupby("image_id")["PredictionString"].agg(" ".join).reset_index()
|
|
92
|
+
gold = gold.reset_index(drop=True)
|
|
93
|
+
assert len(gold) == len(
|
|
94
|
+
set(answers["image_id"])
|
|
95
|
+
), f"Length of gold should be equal to the number of unique image_ids in answers, got {len(gold)} vs {len(set(answers['image_id']))}"
|
|
96
|
+
|
|
97
|
+
# Write CSVs
|
|
98
|
+
new_train.to_csv(public / "train.csv", index=False)
|
|
99
|
+
sample_submission.to_csv(public / "sample_submission.csv", index=False)
|
|
100
|
+
answers.to_csv(private / "answers.csv", index=False)
|
|
101
|
+
gold.to_csv(private / "gold_submission.csv", index=False)
|
|
102
|
+
|
|
103
|
+
# Copy over files
|
|
104
|
+
(public / "test").mkdir(exist_ok=True)
|
|
105
|
+
(public / "train").mkdir(exist_ok=True)
|
|
106
|
+
|
|
107
|
+
if dev == True:
|
|
108
|
+
train_image_ids = train_image_ids[:10]
|
|
109
|
+
test_image_ids = test_image_ids[:10]
|
|
110
|
+
|
|
111
|
+
for file_id in tqdm(train_image_ids, desc="Copying train files"):
|
|
112
|
+
shutil.copyfile(
|
|
113
|
+
src=raw / "train" / f"{file_id}.dicom",
|
|
114
|
+
dst=public / "train" / f"{file_id}.dicom",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
for file_id in tqdm(test_image_ids, desc="Copying test files"):
|
|
118
|
+
shutil.copyfile(
|
|
119
|
+
src=raw / "train" / f"{file_id}.dicom",
|
|
120
|
+
dst=public / "test" / f"{file_id}.dicom",
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Check files
|
|
124
|
+
assert len(list(public.glob("train/*.dicom"))) == len(
|
|
125
|
+
train_image_ids
|
|
126
|
+
), f"Expected {len(train_image_ids)} train files, got {len(list(public.glob('train/*.dicom')))}"
|
|
127
|
+
assert len(list(public.glob("test/*.dicom"))) == len(
|
|
128
|
+
test_image_ids
|
|
129
|
+
), f"Expected {len(test_image_ids)} test files, got {len(list(public.glob('test/*.dicom')))}"
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import pandas as pd
|
|
5
|
+
from sklearn.model_selection import train_test_split
|
|
6
|
+
from tqdm import tqdm
|
|
7
|
+
|
|
8
|
+
from mlebench.utils import read_csv
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _get_consensus_annotation(answers, inspect_duplicates=False):
|
|
12
|
+
"""
|
|
13
|
+
In the original train, there can be multiple annotations of the same image_id, class_id pair. (Different radiologists draw the bounding boxes differently for the same finding)
|
|
14
|
+
|
|
15
|
+
In the original test, there is only one annotation per image_id, class_id pair. The original test set is labeled by consensus of 5 radiologists. (Source: https://www.kaggle.com/competitions/vinbigdata-chest-xray-abnormalities-detection/discussion/207969#1134645)
|
|
16
|
+
|
|
17
|
+
We simulate consensus by taking the first annotation for each image_id, class_id pair.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
if inspect_duplicates:
|
|
21
|
+
duplicates = answers[answers.duplicated(subset=["image_id", "class_id"], keep=False)]
|
|
22
|
+
duplicates = duplicates.sort_values(by=["image_id", "class_id"])
|
|
23
|
+
duplicates.to_csv("duplicates.csv", index=False)
|
|
24
|
+
|
|
25
|
+
answers = answers.groupby(by=["image_id", "class_id"]).first().reset_index()
|
|
26
|
+
return answers
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _create_split_files(
|
|
30
|
+
train_df: pd.DataFrame,
|
|
31
|
+
answers_df: pd.DataFrame,
|
|
32
|
+
train_image_ids: list,
|
|
33
|
+
test_image_ids: list,
|
|
34
|
+
public_path: Path,
|
|
35
|
+
private_path: Path,
|
|
36
|
+
raw_images_path: Path,
|
|
37
|
+
dev: bool = False,
|
|
38
|
+
):
|
|
39
|
+
"""
|
|
40
|
+
Helper function to process and save a single train/test split to the specified paths.
|
|
41
|
+
This encapsulates the logic for creating submissions, writing CSVs, and copying image files.
|
|
42
|
+
"""
|
|
43
|
+
public_path.mkdir(parents=True, exist_ok=True)
|
|
44
|
+
private_path.mkdir(parents=True, exist_ok=True)
|
|
45
|
+
|
|
46
|
+
# Create sample submission for the test set
|
|
47
|
+
sample_submission = pd.DataFrame(
|
|
48
|
+
{
|
|
49
|
+
"image_id": test_image_ids,
|
|
50
|
+
"PredictionString": "14 1 0 0 1 1", # As per the original sample submission
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# Reformat answers
|
|
55
|
+
answers = _get_consensus_annotation(answers_df)
|
|
56
|
+
# Filling in missing values for when there is no finding (class_id = 14)
|
|
57
|
+
answers = answers.fillna(0)
|
|
58
|
+
answers.loc[answers["class_id"] == 14, ["x_max", "y_max"]] = 1.0
|
|
59
|
+
|
|
60
|
+
# Create gold submission
|
|
61
|
+
gold = answers[["image_id", "class_id", "x_min", "y_min", "x_max", "y_max"]].copy()
|
|
62
|
+
# Create individual prediction strings
|
|
63
|
+
gold.loc[:, "PredictionString"] = gold.apply(
|
|
64
|
+
lambda row: f"{row['class_id']} 1.0 {row['x_min']} {row['y_min']} {row['x_max']} {row['y_max']}",
|
|
65
|
+
axis=1, # 1.0 is the confidence score
|
|
66
|
+
)
|
|
67
|
+
# Group by image_id and concatenate prediction strings
|
|
68
|
+
gold = gold.groupby("image_id")["PredictionString"].agg(" ".join).reset_index()
|
|
69
|
+
gold = gold.reset_index(drop=True)
|
|
70
|
+
|
|
71
|
+
# Checks for this split
|
|
72
|
+
assert len(set(train_df["image_id"])) == len(
|
|
73
|
+
train_image_ids
|
|
74
|
+
), f"Number of unique image_ids in train_df does not match the provided list for {public_path.name}"
|
|
75
|
+
assert len(set(answers["image_id"])) == len(
|
|
76
|
+
test_image_ids
|
|
77
|
+
), f"Number of unique image_ids in answers does not match the provided list for {public_path.name}"
|
|
78
|
+
assert set(train_df["image_id"]).isdisjoint(
|
|
79
|
+
set(answers["image_id"])
|
|
80
|
+
), f"image_id is not disjoint between train and test sets for {public_path.name}"
|
|
81
|
+
assert len(sample_submission) == len(
|
|
82
|
+
set(answers["image_id"])
|
|
83
|
+
), f"Length of sample submission is incorrect for {public_path.name}"
|
|
84
|
+
assert len(gold) == len(
|
|
85
|
+
set(answers["image_id"])
|
|
86
|
+
), f"Length of gold submission is incorrect for {public_path.name}"
|
|
87
|
+
|
|
88
|
+
# Write CSVs
|
|
89
|
+
train_df.to_csv(public_path / "train.csv", index=False)
|
|
90
|
+
sample_submission.to_csv(public_path / "sample_submission.csv", index=False)
|
|
91
|
+
answers.to_csv(private_path / "answers.csv", index=False)
|
|
92
|
+
gold.to_csv(private_path / "gold_submission.csv", index=False)
|
|
93
|
+
|
|
94
|
+
# Copy over files
|
|
95
|
+
(public_path / "test").mkdir(exist_ok=True)
|
|
96
|
+
(public_path / "train").mkdir(exist_ok=True)
|
|
97
|
+
|
|
98
|
+
if dev:
|
|
99
|
+
train_image_ids = train_image_ids[:10]
|
|
100
|
+
test_image_ids = test_image_ids[:10]
|
|
101
|
+
|
|
102
|
+
for file_id in tqdm(train_image_ids, desc=f"Copying {public_path.name} train files"):
|
|
103
|
+
shutil.copyfile(
|
|
104
|
+
src=raw_images_path / "train" / f"{file_id}.dicom",
|
|
105
|
+
dst=public_path / "train" / f"{file_id}.dicom",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
for file_id in tqdm(test_image_ids, desc=f"Copying {public_path.name} test files"):
|
|
109
|
+
shutil.copyfile(
|
|
110
|
+
src=raw_images_path / "train" / f"{file_id}.dicom",
|
|
111
|
+
dst=public_path / "test" / f"{file_id}.dicom",
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Check files
|
|
115
|
+
assert len(list(public_path.glob("train/*.dicom"))) == len(
|
|
116
|
+
train_image_ids
|
|
117
|
+
), f"Incorrect number of train files copied for {public_path.name}"
|
|
118
|
+
assert len(list(public_path.glob("test/*.dicom"))) == len(
|
|
119
|
+
test_image_ids
|
|
120
|
+
), f"Incorrect number of test files copied for {public_path.name}"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def prepare(raw: Path, public: Path, private: Path):
|
|
124
|
+
"""
|
|
125
|
+
Splits the data in raw into public and private datasets with appropriate test/train splits.
|
|
126
|
+
Also creates a parallel validation split (public_val, private_val).
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
dev = False
|
|
130
|
+
|
|
131
|
+
# Create train, test from train split
|
|
132
|
+
old_train = read_csv(raw / "train.csv")
|
|
133
|
+
unique_image_ids = old_train["image_id"].unique()
|
|
134
|
+
|
|
135
|
+
# --- 1. Original Train/Test Split ---
|
|
136
|
+
# Original train has 15k images, original test has 3k images
|
|
137
|
+
# Our new train will have 13.5k images, our new test will have 1.5k images
|
|
138
|
+
expected_train_size = 13500
|
|
139
|
+
expected_test_size = 1500
|
|
140
|
+
train_image_ids, test_image_ids = train_test_split(
|
|
141
|
+
unique_image_ids, test_size=0.1, random_state=0
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
new_train = old_train[old_train["image_id"].isin(train_image_ids)]
|
|
145
|
+
answers = old_train[old_train["image_id"].isin(test_image_ids)]
|
|
146
|
+
|
|
147
|
+
# Checks
|
|
148
|
+
assert (
|
|
149
|
+
len(set(new_train["image_id"])) == expected_train_size
|
|
150
|
+
), f"Expected {expected_train_size} train image_ids, got {len(set(new_train['image_id']))}"
|
|
151
|
+
assert (
|
|
152
|
+
len(set(answers["image_id"])) == expected_test_size
|
|
153
|
+
), f"Expected {expected_test_size} test image_ids, got {len(set(answers['image_id']))}"
|
|
154
|
+
assert set(new_train["image_id"]).isdisjoint(
|
|
155
|
+
set(answers["image_id"])
|
|
156
|
+
), f"image_id is not disjoint between train and test sets"
|
|
157
|
+
assert len(new_train) + len(answers) == len(
|
|
158
|
+
old_train
|
|
159
|
+
), f"Length of new train and answers should add up to the length of old train, got {len(new_train) + len(answers)} vs {len(old_train)}"
|
|
160
|
+
|
|
161
|
+
# Create all files for the original public/private split
|
|
162
|
+
_create_split_files(
|
|
163
|
+
train_df=new_train,
|
|
164
|
+
answers_df=answers,
|
|
165
|
+
train_image_ids=train_image_ids,
|
|
166
|
+
test_image_ids=test_image_ids,
|
|
167
|
+
public_path=public,
|
|
168
|
+
private_path=private,
|
|
169
|
+
raw_images_path=raw,
|
|
170
|
+
dev=dev,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# --- 2. New Validation Split (from the `new_train` set) ---
|
|
174
|
+
print("\nCreating validation split...")
|
|
175
|
+
|
|
176
|
+
# Define paths for the new validation set
|
|
177
|
+
public_val = public.parent / "public_val"
|
|
178
|
+
private_val = private.parent / "private_val"
|
|
179
|
+
|
|
180
|
+
# The new validation set should have the same size as the original test set
|
|
181
|
+
train_for_val_split_ids = new_train["image_id"].unique()
|
|
182
|
+
val_test_size = expected_test_size / len(train_for_val_split_ids)
|
|
183
|
+
|
|
184
|
+
# Split `new_train` again to create a smaller train set and a validation set
|
|
185
|
+
# We use the same random_state for consistency in splitting methodology
|
|
186
|
+
train_val_image_ids, test_val_image_ids = train_test_split(
|
|
187
|
+
train_for_val_split_ids, test_size=val_test_size, random_state=0
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
train_val = new_train[new_train["image_id"].isin(train_val_image_ids)]
|
|
191
|
+
answers_val = new_train[new_train["image_id"].isin(test_val_image_ids)]
|
|
192
|
+
|
|
193
|
+
# Create all files for the new validation split
|
|
194
|
+
_create_split_files(
|
|
195
|
+
train_df=train_val,
|
|
196
|
+
answers_df=answers_val,
|
|
197
|
+
train_image_ids=train_val_image_ids,
|
|
198
|
+
test_image_ids=test_val_image_ids,
|
|
199
|
+
public_path=public_val,
|
|
200
|
+
private_path=private_val,
|
|
201
|
+
raw_images_path=raw,
|
|
202
|
+
dev=dev,
|
|
203
|
+
)
|
|
204
|
+
print("Validation split created successfully.")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
from mlebench.grade_helpers import InvalidSubmissionError
|
|
4
|
+
from mlebench.metrics import mean_average_precision_at_k
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def prepare_for_metric(submission: pd.DataFrame, answers: pd.DataFrame) -> dict:
|
|
8
|
+
# Answers checks
|
|
9
|
+
assert set(answers.columns) == {
|
|
10
|
+
"Image",
|
|
11
|
+
"Id",
|
|
12
|
+
}, "Answers DataFrame must have 'Image' and 'Id' columns."
|
|
13
|
+
|
|
14
|
+
# Submission checks
|
|
15
|
+
if set(submission.columns) != {"Image", "Id"}:
|
|
16
|
+
raise InvalidSubmissionError("Submission DataFrame must have 'Image' and 'Id' columns.")
|
|
17
|
+
if len(submission) != len(answers):
|
|
18
|
+
raise InvalidSubmissionError(
|
|
19
|
+
"Submission and answers DataFrames must have the same number of rows."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Ensure the IDs match
|
|
23
|
+
if not set(submission["Image"]) == set(answers["Image"]):
|
|
24
|
+
raise InvalidSubmissionError("Submission and answers have different Image IDs")
|
|
25
|
+
|
|
26
|
+
# Sort to ensure we're grading the right rows
|
|
27
|
+
submission = submission.sort_values("Image").reset_index(drop=True)
|
|
28
|
+
answers = answers.sort_values("Image").reset_index(drop=True)
|
|
29
|
+
|
|
30
|
+
y_true = answers["Id"].astype(str).str.split(" ").apply(set).tolist()
|
|
31
|
+
y_pred = submission["Id"].astype(str).str.split(" ").tolist()
|
|
32
|
+
|
|
33
|
+
return {"actual": y_true, "predicted": y_pred}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def grade(submission: pd.DataFrame, answers: pd.DataFrame) -> float:
|
|
37
|
+
# Prepare the data for metric calculation
|
|
38
|
+
prepped = prepare_for_metric(submission, answers)
|
|
39
|
+
return mean_average_precision_at_k(
|
|
40
|
+
actual=prepped["actual"], predicted=prepped["predicted"], k=5
|
|
41
|
+
)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
from sklearn.model_selection import train_test_split
|
|
6
|
+
from tqdm import tqdm
|
|
7
|
+
|
|
8
|
+
from mlebench.utils import read_csv
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def prepare(raw: Path, public: Path, private: Path):
|
|
12
|
+
"""
|
|
13
|
+
Splits the data in raw into public and private datasets with appropriate test/train splits.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# Create train, test from train split
|
|
17
|
+
old_train = read_csv(raw / "train.csv")
|
|
18
|
+
|
|
19
|
+
old_train["split"] = "undecided"
|
|
20
|
+
target_test_size = 0.1
|
|
21
|
+
|
|
22
|
+
# seeded random generator for numpy
|
|
23
|
+
np_rng = np.random.default_rng(0)
|
|
24
|
+
|
|
25
|
+
# ensure each id occurs in train and test set at least once
|
|
26
|
+
# when there's only one image for an id, goes randomly to train or test
|
|
27
|
+
whale_ids = old_train["Id"].unique()
|
|
28
|
+
for whale_id in whale_ids:
|
|
29
|
+
whale_images = old_train[old_train["Id"] == whale_id]
|
|
30
|
+
if len(whale_images) >= 2:
|
|
31
|
+
# randomly assign one of these to train and one to test
|
|
32
|
+
selected = whale_images.sample(2, random_state=0)
|
|
33
|
+
old_train.loc[selected.index[0], "split"] = "train"
|
|
34
|
+
old_train.loc[selected.index[1], "split"] = "test"
|
|
35
|
+
else:
|
|
36
|
+
# randomly assign this one image to train or test
|
|
37
|
+
old_train.loc[whale_images.index[0], "split"] = np_rng.choice(
|
|
38
|
+
["train", "test"], replace=False, p=[1 - target_test_size, target_test_size]
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# split the remaining data
|
|
42
|
+
remaining_data = old_train[old_train["split"] == "undecided"]
|
|
43
|
+
train, test = train_test_split(remaining_data, test_size=target_test_size, random_state=0)
|
|
44
|
+
old_train.loc[train.index, "split"] = "train"
|
|
45
|
+
old_train.loc[test.index, "split"] = "test"
|
|
46
|
+
|
|
47
|
+
# finally, can split out into separate dataframes
|
|
48
|
+
new_train = old_train[old_train["split"] == "train"].drop(columns=["split"]).copy()
|
|
49
|
+
answers = old_train[old_train["split"] == "test"].drop(columns=["split"]).copy()
|
|
50
|
+
|
|
51
|
+
# If a whale Id is only in the test set, it should be labeled as new_whale instead
|
|
52
|
+
ids_in_test_but_not_train = set(answers["Id"]) - set(new_train["Id"])
|
|
53
|
+
answers.loc[answers["Id"].isin(ids_in_test_but_not_train), "Id"] = "new_whale"
|
|
54
|
+
|
|
55
|
+
# Create sample submission
|
|
56
|
+
sample_submission = answers.copy()
|
|
57
|
+
sample_submission["Id"] = "new_whale w_1287fbc w_98baff9 w_7554f44 w_1eafe46"
|
|
58
|
+
|
|
59
|
+
# Checks
|
|
60
|
+
assert len(answers) == len(
|
|
61
|
+
sample_submission
|
|
62
|
+
), "Answers and sample submission should have the same length"
|
|
63
|
+
assert new_train.shape[1] == 2, "Train should have exactly 2 columns"
|
|
64
|
+
assert sample_submission.shape[1] == 2, "Sample submission should have exactly 2 columns"
|
|
65
|
+
assert answers.shape[1] == 2, "Answers should have exactly 2 columns"
|
|
66
|
+
assert (
|
|
67
|
+
"new_whale" in answers["Id"].values
|
|
68
|
+
), "Answers should contain at least some values with 'new_whale' in the 'Id' column"
|
|
69
|
+
assert len(new_train) + len(answers) == len(
|
|
70
|
+
old_train
|
|
71
|
+
), "The combined length of new_train and answers should equal the length of old_train"
|
|
72
|
+
|
|
73
|
+
# Write CSVs
|
|
74
|
+
answers.to_csv(private / "test.csv", index=False)
|
|
75
|
+
new_train.to_csv(public / "train.csv", index=False)
|
|
76
|
+
sample_submission.to_csv(public / "sample_submission.csv", index=False)
|
|
77
|
+
|
|
78
|
+
# Copy over files
|
|
79
|
+
(public / "test").mkdir(exist_ok=True)
|
|
80
|
+
(public / "train").mkdir(exist_ok=True)
|
|
81
|
+
|
|
82
|
+
for file_id in tqdm(new_train["Image"], desc="Copying train images"):
|
|
83
|
+
shutil.copyfile(
|
|
84
|
+
src=raw / "train" / f"{file_id}",
|
|
85
|
+
dst=public / "train" / f"{file_id}",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
for file_id in tqdm(answers["Image"], desc="Copying test images"):
|
|
89
|
+
shutil.copyfile(
|
|
90
|
+
src=raw / "train" / f"{file_id}",
|
|
91
|
+
dst=public / "test" / f"{file_id}",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# File checks
|
|
95
|
+
train_files = list(public.glob("train/*.jpg"))
|
|
96
|
+
test_files = list(public.glob("test/*.jpg"))
|
|
97
|
+
assert len(train_files) == len(
|
|
98
|
+
new_train
|
|
99
|
+
), "Train dir should have the same number of images as the length of train set"
|
|
100
|
+
assert len(test_files) == len(
|
|
101
|
+
answers
|
|
102
|
+
), "Test dir should have the same number of images as the length of test set"
|
|
103
|
+
assert not set(train_files) & set(test_files), "Train and test files should be distinct"
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from sklearn.model_selection import train_test_split
|
|
7
|
+
from tqdm import tqdm
|
|
8
|
+
|
|
9
|
+
from mlebench.utils import read_csv
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _perform_split(
|
|
13
|
+
df: pd.DataFrame, target_test_size: float, random_seed: int
|
|
14
|
+
) -> tuple[pd.DataFrame, pd.DataFrame]:
|
|
15
|
+
"""
|
|
16
|
+
Performs the custom splitting logic on a given dataframe.
|
|
17
|
+
|
|
18
|
+
This logic ensures that for IDs with 2 or more images, one is guaranteed
|
|
19
|
+
to be in the train set and one in the test set. The remaining data is
|
|
20
|
+
split randomly.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
df: The input dataframe with "Image" and "Id" columns.
|
|
24
|
+
target_test_size: The approximate fraction of data to allocate to the test set.
|
|
25
|
+
random_seed: The random seed for reproducibility.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
A tuple containing the train dataframe and the test dataframe.
|
|
29
|
+
"""
|
|
30
|
+
# Make a copy to avoid modifying the original dataframe
|
|
31
|
+
data_to_split = df.copy()
|
|
32
|
+
data_to_split["split"] = "undecided"
|
|
33
|
+
|
|
34
|
+
# seeded random generator for numpy
|
|
35
|
+
np_rng = np.random.default_rng(random_seed)
|
|
36
|
+
|
|
37
|
+
# ensure each id occurs in train and test set at least once
|
|
38
|
+
# when there's only one image for an id, goes randomly to train or test
|
|
39
|
+
whale_ids = data_to_split["Id"].unique()
|
|
40
|
+
for whale_id in whale_ids:
|
|
41
|
+
whale_images = data_to_split[data_to_split["Id"] == whale_id]
|
|
42
|
+
if len(whale_images) >= 2:
|
|
43
|
+
# randomly assign one of these to train and one to test
|
|
44
|
+
selected = whale_images.sample(2, random_state=random_seed)
|
|
45
|
+
data_to_split.loc[selected.index[0], "split"] = "train"
|
|
46
|
+
data_to_split.loc[selected.index[1], "split"] = "test"
|
|
47
|
+
else:
|
|
48
|
+
# randomly assign this one image to train or test
|
|
49
|
+
data_to_split.loc[whale_images.index[0], "split"] = np_rng.choice(
|
|
50
|
+
["train", "test"],
|
|
51
|
+
replace=False,
|
|
52
|
+
p=[1 - target_test_size, target_test_size],
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# split the remaining data
|
|
56
|
+
remaining_data = data_to_split[data_to_split["split"] == "undecided"]
|
|
57
|
+
if not remaining_data.empty:
|
|
58
|
+
train, test = train_test_split(
|
|
59
|
+
remaining_data, test_size=target_test_size, random_state=random_seed
|
|
60
|
+
)
|
|
61
|
+
data_to_split.loc[train.index, "split"] = "train"
|
|
62
|
+
data_to_split.loc[test.index, "split"] = "test"
|
|
63
|
+
|
|
64
|
+
# finally, can split out into separate dataframes
|
|
65
|
+
train_df = data_to_split[data_to_split["split"] == "train"].drop(
|
|
66
|
+
columns=["split"]
|
|
67
|
+
)
|
|
68
|
+
test_df = data_to_split[data_to_split["split"] == "test"].drop(columns=["split"])
|
|
69
|
+
|
|
70
|
+
return train_df.copy(), test_df.copy()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _write_output_files(
|
|
74
|
+
train_df: pd.DataFrame,
|
|
75
|
+
test_df: pd.DataFrame,
|
|
76
|
+
public_dir: Path,
|
|
77
|
+
private_dir: Path,
|
|
78
|
+
raw_dir: Path,
|
|
79
|
+
):
|
|
80
|
+
"""
|
|
81
|
+
Writes all required output files for a given train/test split.
|
|
82
|
+
This includes CSVs, images, and a sample submission file.
|
|
83
|
+
"""
|
|
84
|
+
public_dir.mkdir(exist_ok=True)
|
|
85
|
+
private_dir.mkdir(exist_ok=True)
|
|
86
|
+
|
|
87
|
+
# Make a copy of the test dataframe to create the final answers
|
|
88
|
+
answers = test_df.copy()
|
|
89
|
+
|
|
90
|
+
# If a whale Id is only in the test set, it should be labeled as new_whale instead
|
|
91
|
+
ids_in_test_but_not_train = set(answers["Id"]) - set(train_df["Id"])
|
|
92
|
+
answers.loc[answers["Id"].isin(ids_in_test_but_not_train), "Id"] = "new_whale"
|
|
93
|
+
|
|
94
|
+
# Create sample submission
|
|
95
|
+
sample_submission = answers.copy()
|
|
96
|
+
sample_submission["Id"] = "new_whale w_1287fbc w_98baff9 w_7554f44 w_1eafe46"
|
|
97
|
+
|
|
98
|
+
# Checks
|
|
99
|
+
assert len(answers) == len(
|
|
100
|
+
sample_submission
|
|
101
|
+
), "Answers and sample submission should have the same length"
|
|
102
|
+
assert train_df.shape[1] == 2, "Train should have exactly 2 columns"
|
|
103
|
+
assert sample_submission.shape[1] == 2, "Sample submission should have exactly 2 columns"
|
|
104
|
+
assert answers.shape[1] == 2, "Answers should have exactly 2 columns"
|
|
105
|
+
assert (
|
|
106
|
+
"new_whale" in answers["Id"].values
|
|
107
|
+
), "Answers should contain at least some values with 'new_whale' in the 'Id' column"
|
|
108
|
+
assert len(train_df) + len(answers) == len(train_df) + len(
|
|
109
|
+
test_df
|
|
110
|
+
), "The combined length of train_df and answers should equal their original combined length"
|
|
111
|
+
|
|
112
|
+
# Write CSVs
|
|
113
|
+
answers.to_csv(private_dir / "test.csv", index=False)
|
|
114
|
+
train_df.to_csv(public_dir / "train.csv", index=False)
|
|
115
|
+
sample_submission.to_csv(public_dir / "sample_submission.csv", index=False)
|
|
116
|
+
|
|
117
|
+
# Copy over files
|
|
118
|
+
(public_dir / "test").mkdir(exist_ok=True)
|
|
119
|
+
(public_dir / "train").mkdir(exist_ok=True)
|
|
120
|
+
|
|
121
|
+
for file_id in tqdm(train_df["Image"], desc=f"Copying train images to {public_dir}"):
|
|
122
|
+
shutil.copyfile(
|
|
123
|
+
src=raw_dir / "train" / f"{file_id}",
|
|
124
|
+
dst=public_dir / "train" / f"{file_id}",
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
for file_id in tqdm(answers["Image"], desc=f"Copying test images to {public_dir}"):
|
|
128
|
+
shutil.copyfile(
|
|
129
|
+
src=raw_dir / "train" / f"{file_id}",
|
|
130
|
+
dst=public_dir / "test" / f"{file_id}",
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# File checks
|
|
134
|
+
train_files = list(public_dir.glob("train/*.jpg"))
|
|
135
|
+
test_files = list(public_dir.glob("test/*.jpg"))
|
|
136
|
+
assert len(train_files) == len(
|
|
137
|
+
train_df
|
|
138
|
+
), f"Train dir {public_dir / 'train'} should have the same number of images as the length of its train set"
|
|
139
|
+
assert len(test_files) == len(
|
|
140
|
+
answers
|
|
141
|
+
), f"Test dir {public_dir / 'test'} should have the same number of images as the length of its test set"
|
|
142
|
+
assert not set(train_files) & set(test_files), "Train and test files should be distinct"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def prepare(raw: Path, public: Path, private: Path):
|
|
146
|
+
"""
|
|
147
|
+
Splits the data in raw into public and private datasets with appropriate test/train splits.
|
|
148
|
+
Additionally, it creates a second parallel split (train_val, test_val) for validation purposes.
|
|
149
|
+
"""
|
|
150
|
+
old_train = read_csv(raw / "train.csv")
|
|
151
|
+
target_test_size = 0.1
|
|
152
|
+
random_seed = 0
|
|
153
|
+
|
|
154
|
+
# --- Step 1: Create the original train/test split ---
|
|
155
|
+
# This split generates the main competition data.
|
|
156
|
+
new_train, answers = _perform_split(
|
|
157
|
+
df=old_train, target_test_size=target_test_size, random_seed=random_seed
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Write the original output files. This part is unchanged in its output.
|
|
161
|
+
_write_output_files(
|
|
162
|
+
train_df=new_train,
|
|
163
|
+
test_df=answers,
|
|
164
|
+
public_dir=public,
|
|
165
|
+
private_dir=private,
|
|
166
|
+
raw_dir=raw,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# --- Step 2: Create the new validation split ---
|
|
170
|
+
# This takes the `new_train` set from the first split and splits it again
|
|
171
|
+
# to create a validation set (`test_val`) of a similar size to the original `answers`.
|
|
172
|
+
# The new, smaller training set is `train_val`.
|
|
173
|
+
|
|
174
|
+
# Define paths for the new validation directories
|
|
175
|
+
public_val = public.parent / "public_val"
|
|
176
|
+
private_val = private.parent / "private_val"
|
|
177
|
+
|
|
178
|
+
# To get a validation test set of size ~0.1*N from a training set of size ~0.9*N,
|
|
179
|
+
# the new test_size must be 0.1/0.9.
|
|
180
|
+
val_target_test_size = target_test_size / (1 - target_test_size)
|
|
181
|
+
|
|
182
|
+
# Perform the second split on the `new_train` data using the same logic and seed.
|
|
183
|
+
train_val, test_val = _perform_split(
|
|
184
|
+
df=new_train,
|
|
185
|
+
target_test_size=val_target_test_size,
|
|
186
|
+
random_seed=random_seed,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# Write the validation output files to the new directories.
|
|
190
|
+
_write_output_files(
|
|
191
|
+
train_df=train_val,
|
|
192
|
+
test_df=test_val,
|
|
193
|
+
public_dir=public_val,
|
|
194
|
+
private_dir=private_val,
|
|
195
|
+
raw_dir=raw,
|
|
196
|
+
)
|