dslighting 1.7.1__py3-none-any.whl → 1.7.6__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.
Files changed (352) hide show
  1. dslighting/__init__.py +1 -1
  2. dslighting/core/agent.py +78 -62
  3. {dslighting-1.7.1.dist-info → dslighting-1.7.6.dist-info}/METADATA +1 -1
  4. {dslighting-1.7.1.dist-info → dslighting-1.7.6.dist-info}/RECORD +352 -7
  5. {dslighting-1.7.1.dist-info → dslighting-1.7.6.dist-info}/top_level.txt +1 -0
  6. mlebench/README.md +39 -0
  7. mlebench/__init__.py +0 -0
  8. mlebench/cli.py +221 -0
  9. mlebench/competitions/3d-object-detection-for-autonomous-vehicles/grade.py +161 -0
  10. mlebench/competitions/3d-object-detection-for-autonomous-vehicles/mAP_evaluation.py +425 -0
  11. mlebench/competitions/3d-object-detection-for-autonomous-vehicles/prepare.py +483 -0
  12. mlebench/competitions/3d-object-detection-for-autonomous-vehicles/prepare_val.py +719 -0
  13. mlebench/competitions/AI4Code/grade.py +70 -0
  14. mlebench/competitions/AI4Code/prepare.py +84 -0
  15. mlebench/competitions/AI4Code/prepare_val.py +159 -0
  16. mlebench/competitions/__init__.py +0 -0
  17. mlebench/competitions/aerial-cactus-identification/grade.py +11 -0
  18. mlebench/competitions/aerial-cactus-identification/prepare.py +71 -0
  19. mlebench/competitions/aerial-cactus-identification/prepare_val.py +133 -0
  20. mlebench/competitions/alaska2-image-steganalysis/grade.py +136 -0
  21. mlebench/competitions/alaska2-image-steganalysis/prepare.py +88 -0
  22. mlebench/competitions/alaska2-image-steganalysis/prepare_val.py +148 -0
  23. mlebench/competitions/aptos2019-blindness-detection/grade.py +35 -0
  24. mlebench/competitions/aptos2019-blindness-detection/prepare.py +75 -0
  25. mlebench/competitions/aptos2019-blindness-detection/prepare_val.py +123 -0
  26. mlebench/competitions/bike-sharing-demand/__init__.py +0 -0
  27. mlebench/competitions/bike-sharing-demand/grade.py +55 -0
  28. mlebench/competitions/bike-sharing-demand/prepare.py +37 -0
  29. mlebench/competitions/billion-word-imputation/grade.py +37 -0
  30. mlebench/competitions/billion-word-imputation/prepare.py +107 -0
  31. mlebench/competitions/billion-word-imputation/prepare_val.py +179 -0
  32. mlebench/competitions/bms-molecular-translation/grade.py +40 -0
  33. mlebench/competitions/bms-molecular-translation/prepare.py +68 -0
  34. mlebench/competitions/bms-molecular-translation/prepare_val.py +131 -0
  35. mlebench/competitions/cassava-leaf-disease-classification/grade.py +12 -0
  36. mlebench/competitions/cassava-leaf-disease-classification/prepare.py +113 -0
  37. mlebench/competitions/cassava-leaf-disease-classification/prepare_val.py +186 -0
  38. mlebench/competitions/cdiscount-image-classification-challenge/grade.py +11 -0
  39. mlebench/competitions/cdiscount-image-classification-challenge/prepare.py +144 -0
  40. mlebench/competitions/cdiscount-image-classification-challenge/prepare_val.py +205 -0
  41. mlebench/competitions/chaii-hindi-and-tamil-question-answering/grade.py +67 -0
  42. mlebench/competitions/chaii-hindi-and-tamil-question-answering/prepare.py +31 -0
  43. mlebench/competitions/chaii-hindi-and-tamil-question-answering/prepare_val.py +94 -0
  44. mlebench/competitions/champs-scalar-coupling/grade.py +60 -0
  45. mlebench/competitions/champs-scalar-coupling/prepare.py +116 -0
  46. mlebench/competitions/champs-scalar-coupling/prepare_val.py +155 -0
  47. mlebench/competitions/conways-reverse-game-of-life-2020/__init__.py +0 -0
  48. mlebench/competitions/conways-reverse-game-of-life-2020/grade.py +40 -0
  49. mlebench/competitions/conways-reverse-game-of-life-2020/prepare.py +41 -0
  50. mlebench/competitions/demand-forecasting-kernels-only/__init__.py +0 -0
  51. mlebench/competitions/demand-forecasting-kernels-only/grade.py +66 -0
  52. mlebench/competitions/demand-forecasting-kernels-only/prepare.py +27 -0
  53. mlebench/competitions/demand_forecasting_kernels_only/__init__.py +0 -0
  54. mlebench/competitions/demand_forecasting_kernels_only/grade.py +66 -0
  55. mlebench/competitions/demand_forecasting_kernels_only/prepare.py +27 -0
  56. mlebench/competitions/denoising-dirty-documents/grade.py +44 -0
  57. mlebench/competitions/denoising-dirty-documents/prepare.py +134 -0
  58. mlebench/competitions/denoising-dirty-documents/prepare_val.py +178 -0
  59. mlebench/competitions/detecting-insults-in-social-commentary/grade.py +11 -0
  60. mlebench/competitions/detecting-insults-in-social-commentary/prepare.py +72 -0
  61. mlebench/competitions/detecting-insults-in-social-commentary/prepare_val.py +128 -0
  62. mlebench/competitions/dog-breed-identification/dogs.py +124 -0
  63. mlebench/competitions/dog-breed-identification/grade.py +42 -0
  64. mlebench/competitions/dog-breed-identification/prepare.py +55 -0
  65. mlebench/competitions/dog-breed-identification/prepare_val.py +104 -0
  66. mlebench/competitions/dogs-vs-cats-redux-kernels-edition/grade.py +43 -0
  67. mlebench/competitions/dogs-vs-cats-redux-kernels-edition/prepare.py +70 -0
  68. mlebench/competitions/dogs-vs-cats-redux-kernels-edition/prepare_val.py +143 -0
  69. mlebench/competitions/ethanol-concentration/grade.py +23 -0
  70. mlebench/competitions/ethanol-concentration/prepare.py +90 -0
  71. mlebench/competitions/facebook-recruiting-iii-keyword-extraction/grade.py +60 -0
  72. mlebench/competitions/facebook-recruiting-iii-keyword-extraction/prepare.py +41 -0
  73. mlebench/competitions/facebook-recruiting-iii-keyword-extraction/prepare_val.py +92 -0
  74. mlebench/competitions/feedback-prize-english-language-learning/__init__.py +0 -0
  75. mlebench/competitions/feedback-prize-english-language-learning/grade.py +60 -0
  76. mlebench/competitions/feedback-prize-english-language-learning/prepare.py +39 -0
  77. mlebench/competitions/freesound-audio-tagging-2019/grade.py +64 -0
  78. mlebench/competitions/freesound-audio-tagging-2019/prepare.py +94 -0
  79. mlebench/competitions/freesound-audio-tagging-2019/prepare_val.py +175 -0
  80. mlebench/competitions/freesound-audio-tagging-2019/vocabulary.py +83 -0
  81. mlebench/competitions/google-quest-challenge/classes.py +32 -0
  82. mlebench/competitions/google-quest-challenge/grade.py +45 -0
  83. mlebench/competitions/google-quest-challenge/prepare.py +58 -0
  84. mlebench/competitions/google-quest-challenge/prepare_val.py +120 -0
  85. mlebench/competitions/google-research-identify-contrails-reduce-global-warming/grade.py +77 -0
  86. mlebench/competitions/google-research-identify-contrails-reduce-global-warming/prepare.py +155 -0
  87. mlebench/competitions/google-research-identify-contrails-reduce-global-warming/prepare_val.py +211 -0
  88. mlebench/competitions/h-and-m-personalized-fashion-recommendations/grade.py +42 -0
  89. mlebench/competitions/h-and-m-personalized-fashion-recommendations/prepare.py +102 -0
  90. mlebench/competitions/h-and-m-personalized-fashion-recommendations/prepare_val.py +132 -0
  91. mlebench/competitions/handwriting/grade.py +23 -0
  92. mlebench/competitions/handwriting/prepare.py +179 -0
  93. mlebench/competitions/herbarium-2020-fgvc7/grade.py +34 -0
  94. mlebench/competitions/herbarium-2020-fgvc7/prepare.py +251 -0
  95. mlebench/competitions/herbarium-2020-fgvc7/prepare_val.py +242 -0
  96. mlebench/competitions/herbarium-2021-fgvc8/grade.py +34 -0
  97. mlebench/competitions/herbarium-2021-fgvc8/prepare.py +251 -0
  98. mlebench/competitions/herbarium-2021-fgvc8/prepare_val.py +222 -0
  99. mlebench/competitions/herbarium-2022-fgvc9/grade.py +31 -0
  100. mlebench/competitions/herbarium-2022-fgvc9/prepare.py +233 -0
  101. mlebench/competitions/herbarium-2022-fgvc9/prepare_val.py +213 -0
  102. mlebench/competitions/histopathologic-cancer-detection/grade.py +12 -0
  103. mlebench/competitions/histopathologic-cancer-detection/prepare.py +59 -0
  104. mlebench/competitions/histopathologic-cancer-detection/prepare_val.py +131 -0
  105. mlebench/competitions/hms-harmful-brain-activity-classification/constants.py +9 -0
  106. mlebench/competitions/hms-harmful-brain-activity-classification/grade.py +43 -0
  107. mlebench/competitions/hms-harmful-brain-activity-classification/kaggle_metric_utilities.py +96 -0
  108. mlebench/competitions/hms-harmful-brain-activity-classification/kullback_leibler_divergence.py +118 -0
  109. mlebench/competitions/hms-harmful-brain-activity-classification/prepare.py +121 -0
  110. mlebench/competitions/hms-harmful-brain-activity-classification/prepare_val.py +190 -0
  111. mlebench/competitions/hotel-id-2021-fgvc8/grade.py +41 -0
  112. mlebench/competitions/hotel-id-2021-fgvc8/prepare.py +63 -0
  113. mlebench/competitions/hotel-id-2021-fgvc8/prepare_val.py +132 -0
  114. mlebench/competitions/hubmap-kidney-segmentation/grade.py +62 -0
  115. mlebench/competitions/hubmap-kidney-segmentation/prepare.py +108 -0
  116. mlebench/competitions/hubmap-kidney-segmentation/prepare_val.py +153 -0
  117. mlebench/competitions/icecube-neutrinos-in-deep-ice/grade.py +111 -0
  118. mlebench/competitions/icecube-neutrinos-in-deep-ice/prepare.py +127 -0
  119. mlebench/competitions/icecube-neutrinos-in-deep-ice/prepare_val.py +183 -0
  120. mlebench/competitions/ili/grade.py +60 -0
  121. mlebench/competitions/ili/prepare.py +99 -0
  122. mlebench/competitions/imet-2020-fgvc7/grade.py +54 -0
  123. mlebench/competitions/imet-2020-fgvc7/prepare.py +77 -0
  124. mlebench/competitions/imet-2020-fgvc7/prepare_val.py +157 -0
  125. mlebench/competitions/inaturalist-2019-fgvc6/grade.py +35 -0
  126. mlebench/competitions/inaturalist-2019-fgvc6/prepare.py +259 -0
  127. mlebench/competitions/inaturalist-2019-fgvc6/prepare_val.py +304 -0
  128. mlebench/competitions/instant-gratification/__init__.py +0 -0
  129. mlebench/competitions/instant-gratification/grade.py +55 -0
  130. mlebench/competitions/instant-gratification/prepare.py +25 -0
  131. mlebench/competitions/instant_gratification/__init__.py +0 -0
  132. mlebench/competitions/instant_gratification/grade.py +55 -0
  133. mlebench/competitions/instant_gratification/prepare.py +25 -0
  134. mlebench/competitions/invasive-species-monitoring/grade.py +11 -0
  135. mlebench/competitions/invasive-species-monitoring/prepare.py +97 -0
  136. mlebench/competitions/invasive-species-monitoring/prepare_val.py +164 -0
  137. mlebench/competitions/iwildcam-2019-fgvc6/grade.py +44 -0
  138. mlebench/competitions/iwildcam-2019-fgvc6/prepare.py +118 -0
  139. mlebench/competitions/iwildcam-2019-fgvc6/prepare_val.py +194 -0
  140. mlebench/competitions/iwildcam-2020-fgvc7/grade.py +11 -0
  141. mlebench/competitions/iwildcam-2020-fgvc7/prepare.py +164 -0
  142. mlebench/competitions/iwildcam-2020-fgvc7/prepare_val.py +245 -0
  143. mlebench/competitions/jigsaw-toxic-comment-classification-challenge/classes.py +1 -0
  144. mlebench/competitions/jigsaw-toxic-comment-classification-challenge/grade.py +54 -0
  145. mlebench/competitions/jigsaw-toxic-comment-classification-challenge/prepare.py +42 -0
  146. mlebench/competitions/jigsaw-toxic-comment-classification-challenge/prepare_val.py +88 -0
  147. mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/grade.py +153 -0
  148. mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/prepare.py +36 -0
  149. mlebench/competitions/jigsaw-unintended-bias-in-toxicity-classification/prepare_val.py +117 -0
  150. mlebench/competitions/kuzushiji-recognition/grade.py +58 -0
  151. mlebench/competitions/kuzushiji-recognition/kuzushiji_metric.py +118 -0
  152. mlebench/competitions/kuzushiji-recognition/prepare.py +92 -0
  153. mlebench/competitions/kuzushiji-recognition/prepare_val.py +149 -0
  154. mlebench/competitions/leaf-classification/classes.py +101 -0
  155. mlebench/competitions/leaf-classification/grade.py +44 -0
  156. mlebench/competitions/leaf-classification/prepare.py +60 -0
  157. mlebench/competitions/leaf-classification/prepare_val.py +116 -0
  158. mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/grade.py +44 -0
  159. mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/prepare.py +51 -0
  160. mlebench/competitions/learning-agency-lab-automated-essay-scoring-2/prepare_val.py +96 -0
  161. mlebench/competitions/liverpool-ion-switching/__init__.py +0 -0
  162. mlebench/competitions/liverpool-ion-switching/grade.py +52 -0
  163. mlebench/competitions/liverpool-ion-switching/prepare.py +27 -0
  164. mlebench/competitions/liverpool_ion_switching/__init__.py +0 -0
  165. mlebench/competitions/liverpool_ion_switching/grade.py +52 -0
  166. mlebench/competitions/liverpool_ion_switching/prepare.py +27 -0
  167. mlebench/competitions/lmsys-chatbot-arena/grade.py +63 -0
  168. mlebench/competitions/lmsys-chatbot-arena/prepare.py +52 -0
  169. mlebench/competitions/lmsys-chatbot-arena/prepare_val.py +115 -0
  170. mlebench/competitions/mcm_2024_c_test/grade.py +107 -0
  171. mlebench/competitions/mcm_2024_c_test/prepare.py +2 -0
  172. mlebench/competitions/ml2021spring-hw2/grade.py +11 -0
  173. mlebench/competitions/ml2021spring-hw2/prepare.py +58 -0
  174. mlebench/competitions/ml2021spring-hw2/prepare_val.py +135 -0
  175. mlebench/competitions/mlsp-2013-birds/grade.py +11 -0
  176. mlebench/competitions/mlsp-2013-birds/prepare.py +182 -0
  177. mlebench/competitions/mlsp-2013-birds/prepare_val.py +241 -0
  178. mlebench/competitions/movie-review-sentiment-analysis-kernels-only/grade.py +11 -0
  179. mlebench/competitions/movie-review-sentiment-analysis-kernels-only/prepare.py +58 -0
  180. mlebench/competitions/movie-review-sentiment-analysis-kernels-only/prepare_val.py +120 -0
  181. mlebench/competitions/multi-modal-gesture-recognition/grade.py +58 -0
  182. mlebench/competitions/multi-modal-gesture-recognition/prepare.py +85 -0
  183. mlebench/competitions/multi-modal-gesture-recognition/prepare_val.py +139 -0
  184. mlebench/competitions/my-custom-task-01/prepare.py +2 -0
  185. mlebench/competitions/new-my-task-01/prepare.py +2 -0
  186. mlebench/competitions/new-my-task-03/grade.py +107 -0
  187. mlebench/competitions/new-my-task-03/prepare.py +2 -0
  188. mlebench/competitions/new-york-city-taxi-fare-prediction/grade.py +28 -0
  189. mlebench/competitions/new-york-city-taxi-fare-prediction/prepare.py +44 -0
  190. mlebench/competitions/new-york-city-taxi-fare-prediction/prepare_val.py +89 -0
  191. mlebench/competitions/nfl-player-contact-detection/grade.py +36 -0
  192. mlebench/competitions/nfl-player-contact-detection/prepare.py +101 -0
  193. mlebench/competitions/nfl-player-contact-detection/prepare_val.py +186 -0
  194. mlebench/competitions/nomad2018-predict-transparent-conductors/grade.py +47 -0
  195. mlebench/competitions/nomad2018-predict-transparent-conductors/prepare.py +77 -0
  196. mlebench/competitions/nomad2018-predict-transparent-conductors/prepare_val.py +144 -0
  197. mlebench/competitions/osic-pulmonary-fibrosis-progression/grade.py +74 -0
  198. mlebench/competitions/osic-pulmonary-fibrosis-progression/prepare.py +95 -0
  199. mlebench/competitions/osic-pulmonary-fibrosis-progression/prepare_val.py +167 -0
  200. mlebench/competitions/paddy-disease-classification/grade.py +35 -0
  201. mlebench/competitions/paddy-disease-classification/prepare.py +69 -0
  202. mlebench/competitions/paddy-disease-classification/prepare_val.py +122 -0
  203. mlebench/competitions/petfinder-pawpularity-score/grade.py +41 -0
  204. mlebench/competitions/petfinder-pawpularity-score/prepare.py +76 -0
  205. mlebench/competitions/petfinder-pawpularity-score/prepare_val.py +154 -0
  206. mlebench/competitions/plant-pathology-2020-fgvc7/grade.py +41 -0
  207. mlebench/competitions/plant-pathology-2020-fgvc7/prepare.py +74 -0
  208. mlebench/competitions/plant-pathology-2020-fgvc7/prepare_val.py +160 -0
  209. mlebench/competitions/plant-pathology-2021-fgvc8/grade.py +54 -0
  210. mlebench/competitions/plant-pathology-2021-fgvc8/prepare.py +65 -0
  211. mlebench/competitions/plant-pathology-2021-fgvc8/prepare_val.py +130 -0
  212. mlebench/competitions/plant-seedlings-classification/grade.py +39 -0
  213. mlebench/competitions/plant-seedlings-classification/prepare.py +91 -0
  214. mlebench/competitions/plant-seedlings-classification/prepare_val.py +158 -0
  215. mlebench/competitions/playground-series-s3e1/__init__.py +0 -0
  216. mlebench/competitions/playground-series-s3e1/grade.py +52 -0
  217. mlebench/competitions/playground-series-s3e1/prepare.py +25 -0
  218. mlebench/competitions/playground-series-s3e11/__init__.py +0 -0
  219. mlebench/competitions/playground-series-s3e11/grade.py +55 -0
  220. mlebench/competitions/playground-series-s3e11/prepare.py +25 -0
  221. mlebench/competitions/playground-series-s3e18/grade.py +39 -0
  222. mlebench/competitions/playground-series-s3e18/prepare.py +36 -0
  223. mlebench/competitions/playground-series-s3e18/prepare_val.py +89 -0
  224. mlebench/competitions/playground_series_s3e1/__init__.py +0 -0
  225. mlebench/competitions/playground_series_s3e1/grade.py +52 -0
  226. mlebench/competitions/playground_series_s3e1/prepare.py +25 -0
  227. mlebench/competitions/playground_series_s3e11/__init__.py +0 -0
  228. mlebench/competitions/playground_series_s3e11/grade.py +55 -0
  229. mlebench/competitions/playground_series_s3e11/prepare.py +25 -0
  230. mlebench/competitions/predict-volcanic-eruptions-ingv-oe/grade.py +44 -0
  231. mlebench/competitions/predict-volcanic-eruptions-ingv-oe/prepare.py +68 -0
  232. mlebench/competitions/predict-volcanic-eruptions-ingv-oe/prepare_val.py +146 -0
  233. mlebench/competitions/random-acts-of-pizza/grade.py +14 -0
  234. mlebench/competitions/random-acts-of-pizza/prepare.py +80 -0
  235. mlebench/competitions/random-acts-of-pizza/prepare_val.py +144 -0
  236. mlebench/competitions/ranzcr-clip-catheter-line-classification/classes.py +11 -0
  237. mlebench/competitions/ranzcr-clip-catheter-line-classification/grade.py +31 -0
  238. mlebench/competitions/ranzcr-clip-catheter-line-classification/prepare.py +53 -0
  239. mlebench/competitions/ranzcr-clip-catheter-line-classification/prepare_val.py +113 -0
  240. mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/grade.py +124 -0
  241. mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/prepare.py +219 -0
  242. mlebench/competitions/rsna-2022-cervical-spine-fracture-detection/prepare_val.py +257 -0
  243. mlebench/competitions/rsna-breast-cancer-detection/grade.py +65 -0
  244. mlebench/competitions/rsna-breast-cancer-detection/prepare.py +141 -0
  245. mlebench/competitions/rsna-breast-cancer-detection/prepare_val.py +201 -0
  246. mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/grade.py +13 -0
  247. mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/prepare.py +47 -0
  248. mlebench/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/prepare_val.py +97 -0
  249. mlebench/competitions/santander-customer-satisfaction/grade.py +10 -0
  250. mlebench/competitions/santander-customer-satisfaction/prepare.py +41 -0
  251. mlebench/competitions/sciencebench-001-clintox-nn/__init__.py +0 -0
  252. mlebench/competitions/sciencebench-001-clintox-nn/grade.py +56 -0
  253. mlebench/competitions/sciencebench-001-clintox-nn/prepare.py +75 -0
  254. mlebench/competitions/sciencebench-015-aai/grade.py +37 -0
  255. mlebench/competitions/sciencebench-015-aai/prepare.py +102 -0
  256. mlebench/competitions/sciencebench-051-brain-blood-qsar/grade.py +58 -0
  257. mlebench/competitions/sciencebench-051-brain-blood-qsar/prepare.py +69 -0
  258. mlebench/competitions/sciencebench-101-experimental-band-gap-prediction/grade.py +55 -0
  259. mlebench/competitions/sciencebench-101-experimental-band-gap-prediction/prepare.py +88 -0
  260. mlebench/competitions/see-click-predict-fix/__init__.py +0 -0
  261. mlebench/competitions/see-click-predict-fix/grade.py +66 -0
  262. mlebench/competitions/see-click-predict-fix/prepare.py +25 -0
  263. mlebench/competitions/see_click_predict_fix/__init__.py +0 -0
  264. mlebench/competitions/see_click_predict_fix/grade.py +66 -0
  265. mlebench/competitions/see_click_predict_fix/prepare.py +25 -0
  266. mlebench/competitions/seti-breakthrough-listen/grade.py +11 -0
  267. mlebench/competitions/seti-breakthrough-listen/prepare.py +71 -0
  268. mlebench/competitions/seti-breakthrough-listen/prepare_val.py +159 -0
  269. mlebench/competitions/siim-covid19-detection/grade.py +194 -0
  270. mlebench/competitions/siim-covid19-detection/prepare.py +123 -0
  271. mlebench/competitions/siim-covid19-detection/prepare_val.py +164 -0
  272. mlebench/competitions/siim-isic-melanoma-classification/grade.py +11 -0
  273. mlebench/competitions/siim-isic-melanoma-classification/prepare.py +127 -0
  274. mlebench/competitions/siim-isic-melanoma-classification/prepare_val.py +158 -0
  275. mlebench/competitions/smartphone-decimeter-2022/grade.py +55 -0
  276. mlebench/competitions/smartphone-decimeter-2022/notebook.py +86 -0
  277. mlebench/competitions/smartphone-decimeter-2022/prepare.py +143 -0
  278. mlebench/competitions/smartphone-decimeter-2022/prepare_val.py +199 -0
  279. mlebench/competitions/spaceship-titanic/grade.py +11 -0
  280. mlebench/competitions/spaceship-titanic/prepare.py +23 -0
  281. mlebench/competitions/spaceship-titanic/prepare_val.py +61 -0
  282. mlebench/competitions/spooky-author-identification/classes.py +1 -0
  283. mlebench/competitions/spooky-author-identification/grade.py +38 -0
  284. mlebench/competitions/spooky-author-identification/prepare.py +40 -0
  285. mlebench/competitions/spooky-author-identification/prepare_val.py +78 -0
  286. mlebench/competitions/stanford-covid-vaccine/grade.py +65 -0
  287. mlebench/competitions/stanford-covid-vaccine/prepare.py +129 -0
  288. mlebench/competitions/stanford-covid-vaccine/prepare_val.py +199 -0
  289. mlebench/competitions/statoil-iceberg-classifier-challenge/grade.py +41 -0
  290. mlebench/competitions/statoil-iceberg-classifier-challenge/prepare.py +105 -0
  291. mlebench/competitions/statoil-iceberg-classifier-challenge/prepare_val.py +157 -0
  292. mlebench/competitions/tabular-playground-series-dec-2021/grade.py +11 -0
  293. mlebench/competitions/tabular-playground-series-dec-2021/prepare.py +39 -0
  294. mlebench/competitions/tabular-playground-series-dec-2021/prepare_val.py +99 -0
  295. mlebench/competitions/tabular-playground-series-may-2022/grade.py +9 -0
  296. mlebench/competitions/tabular-playground-series-may-2022/prepare.py +56 -0
  297. mlebench/competitions/tabular-playground-series-may-2022/prepare_val.py +116 -0
  298. mlebench/competitions/tensorflow-speech-recognition-challenge/grade.py +11 -0
  299. mlebench/competitions/tensorflow-speech-recognition-challenge/prepare.py +90 -0
  300. mlebench/competitions/tensorflow-speech-recognition-challenge/prepare_val.py +148 -0
  301. mlebench/competitions/tensorflow2-question-answering/grade.py +122 -0
  302. mlebench/competitions/tensorflow2-question-answering/prepare.py +122 -0
  303. mlebench/competitions/tensorflow2-question-answering/prepare_val.py +187 -0
  304. mlebench/competitions/text-normalization-challenge-english-language/grade.py +49 -0
  305. mlebench/competitions/text-normalization-challenge-english-language/prepare.py +115 -0
  306. mlebench/competitions/text-normalization-challenge-english-language/prepare_val.py +213 -0
  307. mlebench/competitions/text-normalization-challenge-russian-language/grade.py +49 -0
  308. mlebench/competitions/text-normalization-challenge-russian-language/prepare.py +113 -0
  309. mlebench/competitions/text-normalization-challenge-russian-language/prepare_val.py +165 -0
  310. mlebench/competitions/tgs-salt-identification-challenge/grade.py +144 -0
  311. mlebench/competitions/tgs-salt-identification-challenge/prepare.py +158 -0
  312. mlebench/competitions/tgs-salt-identification-challenge/prepare_val.py +166 -0
  313. mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/grade.py +11 -0
  314. mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/prepare.py +95 -0
  315. mlebench/competitions/the-icml-2013-whale-challenge-right-whale-redux/prepare_val.py +141 -0
  316. mlebench/competitions/tmdb-box-office-prediction/__init__.py +0 -0
  317. mlebench/competitions/tmdb-box-office-prediction/grade.py +55 -0
  318. mlebench/competitions/tmdb-box-office-prediction/prepare.py +35 -0
  319. mlebench/competitions/tweet-sentiment-extraction/grade.py +67 -0
  320. mlebench/competitions/tweet-sentiment-extraction/prepare.py +36 -0
  321. mlebench/competitions/tweet-sentiment-extraction/prepare_val.py +106 -0
  322. mlebench/competitions/us-patent-phrase-to-phrase-matching/grade.py +31 -0
  323. mlebench/competitions/us-patent-phrase-to-phrase-matching/prepare.py +33 -0
  324. mlebench/competitions/us-patent-phrase-to-phrase-matching/prepare_val.py +71 -0
  325. mlebench/competitions/utils.py +266 -0
  326. mlebench/competitions/uw-madison-gi-tract-image-segmentation/grade.py +158 -0
  327. mlebench/competitions/uw-madison-gi-tract-image-segmentation/prepare.py +139 -0
  328. mlebench/competitions/uw-madison-gi-tract-image-segmentation/prepare_val.py +193 -0
  329. mlebench/competitions/ventilator-pressure-prediction/__init__.py +0 -0
  330. mlebench/competitions/ventilator-pressure-prediction/grade.py +52 -0
  331. mlebench/competitions/ventilator-pressure-prediction/prepare.py +27 -0
  332. mlebench/competitions/ventilator-pressure-prediction/prepare_val.py +142 -0
  333. mlebench/competitions/ventilator_pressure_prediction/__init__.py +0 -0
  334. mlebench/competitions/ventilator_pressure_prediction/grade.py +52 -0
  335. mlebench/competitions/ventilator_pressure_prediction/prepare.py +27 -0
  336. mlebench/competitions/vesuvius-challenge-ink-detection/grade.py +97 -0
  337. mlebench/competitions/vesuvius-challenge-ink-detection/prepare.py +122 -0
  338. mlebench/competitions/vesuvius-challenge-ink-detection/prepare_val.py +170 -0
  339. mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/grade.py +220 -0
  340. mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/prepare.py +129 -0
  341. mlebench/competitions/vinbigdata-chest-xray-abnormalities-detection/prepare_val.py +204 -0
  342. mlebench/competitions/whale-categorization-playground/grade.py +41 -0
  343. mlebench/competitions/whale-categorization-playground/prepare.py +103 -0
  344. mlebench/competitions/whale-categorization-playground/prepare_val.py +196 -0
  345. mlebench/data.py +420 -0
  346. mlebench/grade.py +209 -0
  347. mlebench/grade_helpers.py +235 -0
  348. mlebench/metrics.py +75 -0
  349. mlebench/registry.py +332 -0
  350. mlebench/utils.py +346 -0
  351. {dslighting-1.7.1.dist-info → dslighting-1.7.6.dist-info}/WHEEL +0 -0
  352. {dslighting-1.7.1.dist-info → dslighting-1.7.6.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,159 @@
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 _create_and_populate_split(
12
+ input_df: pd.DataFrame,
13
+ test_size: float,
14
+ random_state: int,
15
+ raw_data_path: Path,
16
+ public_dest_path: Path,
17
+ private_dest_path: Path,
18
+ ) -> (pd.DataFrame, pd.DataFrame):
19
+ """
20
+ Splits a dataframe and populates the corresponding public and private directories.
21
+
22
+ This function performs a train-test split, copies the necessary .npy files,
23
+ creates the ground truth file for the test set, and a sample submission file.
24
+ It's designed to be called multiple times for creating different data splits
25
+ (e.g., train/test and train/validation).
26
+
27
+ Args:
28
+ input_df: The dataframe to be split.
29
+ test_size: The proportion of the dataset to allocate to the test split.
30
+ random_state: The seed used by the random number generator.
31
+ raw_data_path: The path to the raw data directory.
32
+ public_dest_path: The destination path for public-facing files.
33
+ private_dest_path: The destination path for private/solution files.
34
+
35
+ Returns:
36
+ A tuple containing the training and testing dataframes from the split.
37
+ """
38
+ # Ensure destination directories exist
39
+ public_dest_path.mkdir(parents=True, exist_ok=True)
40
+ private_dest_path.mkdir(parents=True, exist_ok=True)
41
+
42
+ # 1. Create train, test from the input dataframe
43
+ split_train, split_test = train_test_split(
44
+ input_df, test_size=test_size, random_state=random_state
45
+ )
46
+
47
+ # 2. Copy over files
48
+ split_train.to_csv(public_dest_path / "train_labels.csv", index=False)
49
+ split_test.to_csv(private_dest_path / "test.csv", index=False)
50
+
51
+ # Copy shared, non-data-specific files if they exist
52
+ if (raw_data_path / "old_leaky_data").exists():
53
+ shutil.copytree(
54
+ raw_data_path / "old_leaky_data",
55
+ public_dest_path / "old_leaky_data",
56
+ dirs_exist_ok=True,
57
+ )
58
+
59
+ for file_id in tqdm(split_train["id"], desc=f"Copying train files to {public_dest_path.name}"):
60
+ subdir = file_id[0]
61
+ src = raw_data_path / "train" / subdir / f"{file_id}.npy"
62
+ dst = public_dest_path / "train" / subdir / f"{file_id}.npy"
63
+ dst.parent.mkdir(parents=True, exist_ok=True)
64
+ shutil.copy(src, dst)
65
+
66
+ for file_id in tqdm(split_test["id"], desc=f"Copying test files to {public_dest_path.name}"):
67
+ subdir = file_id[0]
68
+ src = raw_data_path / "train" / subdir / f"{file_id}.npy"
69
+ dst = public_dest_path / "test" / subdir / f"{file_id}.npy"
70
+ dst.parent.mkdir(parents=True, exist_ok=True)
71
+ shutil.copy(src, dst)
72
+
73
+ # 3. Create sample submission
74
+ sample_submission = split_test.copy()
75
+ sample_submission["target"] = 0.5 # Overwrite with dummy values
76
+ sample_submission.to_csv(public_dest_path / "sample_submission.csv", index=False)
77
+
78
+ # 4. Perform checks for this specific split
79
+ assert len(sample_submission) == len(
80
+ split_test
81
+ ), f"Sample submission length mismatch in {public_dest_path.name}."
82
+ assert not set(split_train["id"]).intersection(
83
+ set(split_test["id"])
84
+ ), f"Overlapping IDs in train/test sets for {public_dest_path.name}."
85
+
86
+ train_files = {
87
+ file_path.name
88
+ for file_path in (public_dest_path / "train").rglob("*.npy")
89
+ if file_path.is_file()
90
+ }
91
+ test_files = {
92
+ file_path.name
93
+ for file_path in (public_dest_path / "test").rglob("*.npy")
94
+ if file_path.is_file()
95
+ }
96
+
97
+ assert len(train_files) == len(
98
+ split_train
99
+ ), f"Train file count mismatch in {public_dest_path.name}."
100
+ assert len(test_files) == len(
101
+ split_test
102
+ ), f"Test file count mismatch in {public_dest_path.name}."
103
+ assert train_files.isdisjoint(
104
+ test_files
105
+ ), f"Overlapping files in train/test directories for {public_dest_path.name}."
106
+
107
+ return split_train, split_test
108
+
109
+
110
+ def prepare(raw: Path, public: Path, private: Path):
111
+ """
112
+ Prepares the data by creating two parallel splits:
113
+ 1. A standard train/test split (outputs to `public` and `private`).
114
+ 2. A subsequent train/validation split (outputs to `public_val` and `private_val`).
115
+ """
116
+ # Read the full raw training data manifest
117
+ full_train_df = read_csv(raw / "train_labels.csv")
118
+
119
+ # --- Stage 1: Create the original train/test split ---
120
+ # This split generates the main competition files in `public` and `private`.
121
+ # The logic and outputs here remain identical to the original script.
122
+ print("--- Creating main train/test split ---")
123
+ new_train, new_test = _create_and_populate_split(
124
+ input_df=full_train_df,
125
+ test_size=0.1,
126
+ random_state=0,
127
+ raw_data_path=raw,
128
+ public_dest_path=public,
129
+ private_dest_path=private,
130
+ )
131
+ print("--- Main train/test split created successfully ---\n")
132
+
133
+ # --- Stage 2: Create the new train/validation split ---
134
+ # This split takes the `new_train` set from Stage 1 and splits it again.
135
+ # The outputs go into new, parallel directories (`public_val`, `private_val`).
136
+ # The number of samples in the validation set (`test_val`) is designed to be
137
+ # the same as the number of samples in the original test set (`new_test`).
138
+ print("--- Creating train/validation split ---")
139
+ public_val = public.parent / "public_val"
140
+ private_val = private.parent / "private_val"
141
+
142
+ # To make the new validation set size equal to the original test set size,
143
+ # we calculate the required proportion.
144
+ # test_size = len(new_test) / len(new_train)
145
+ # Since len(new_test) is 0.1 * total and len(new_train) is 0.9 * total,
146
+ # the ratio is 0.1 / 0.9 = 1/9.
147
+ validation_test_size = 1 / 9
148
+
149
+ # We reuse the same function, ensuring the logic is identical.
150
+ # The returned dataframes are not needed, as this is the final split.
151
+ _create_and_populate_split(
152
+ input_df=new_train, # Use the training set from the first split as input
153
+ test_size=validation_test_size,
154
+ random_state=0, # Use the same random state for consistency
155
+ raw_data_path=raw,
156
+ public_dest_path=public_val,
157
+ private_dest_path=private_val,
158
+ )
159
+ print("--- Train/validation split created successfully ---")
@@ -0,0 +1,194 @@
1
+ from typing import List, Tuple
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ from sklearn.metrics import average_precision_score
6
+
7
+ from mlebench.grade_helpers import InvalidSubmissionError
8
+
9
+
10
+ def calculate_iou(
11
+ box1: Tuple[float, float, float, float], box2: Tuple[float, float, float, float]
12
+ ) -> float:
13
+ """
14
+ Calculate the Intersection over Union (IoU) of two bounding boxes.
15
+ (this image helps: https://machinelearningspace.com/wp-content/uploads/2023/01/IOU2.jpg)
16
+ """
17
+ xmin1, ymin1, xmax1, ymax1 = box1
18
+ xmin2, ymin2, xmax2, ymax2 = box2
19
+
20
+ inter_xmin = max(xmin1, xmin2)
21
+ inter_ymin = max(ymin1, ymin2)
22
+ inter_xmax = min(xmax1, xmax2)
23
+ inter_ymax = min(ymax1, ymax2)
24
+
25
+ inter_width = max(0, inter_xmax - inter_xmin)
26
+ inter_height = max(0, inter_ymax - inter_ymin)
27
+ inter_area = inter_width * inter_height
28
+
29
+ box1_area = (xmax1 - xmin1) * (ymax1 - ymin1)
30
+ box2_area = (xmax2 - xmin2) * (ymax2 - ymin2)
31
+
32
+ union_area = box1_area + box2_area - inter_area
33
+
34
+ iou = inter_area / union_area if union_area > 0 else 0.0
35
+ return iou
36
+
37
+
38
+ def calculate_map(submission_preds: List[List[Tuple]], answers_preds: List[List[Tuple]]) -> float:
39
+ """
40
+ Calculate mean Average Precision (mAP) for object detection.
41
+
42
+ > The challenge uses the standard PASCAL VOC 2010 mean Average Precision (mAP) at IoU > 0.5.
43
+ Note that the linked document describes VOC 2012, which differs in some minor ways
44
+ (e.g. there is no concept of "difficult" classes in VOC 2010).
45
+ The P/R curve and AP calculations remain the same.
46
+ (www.kaggle.com/competitions/siim-covid19-detection/overview/evaluation)
47
+
48
+ Some choices made here that were not explicitly specified in the challenge description:
49
+
50
+ 1. Treating "none" or "negative" as prediction classes of their own, instead of as the non-positive class
51
+ - Justification: Treating them as their own classes is implied by the data format:
52
+ - Study level - train_study_level.csv has 4 binary classes including the "negative" class instead of 3
53
+ - Image level - We're asked to predict "none" with full bounding boxes instead of withholding a prediction
54
+ Also, 3rd place winner says "It probably treats the six classes equally", where the six classes are
55
+ "negative", "typical", "indeterminate", "atypical", "none" and "opacity".
56
+ (https://www.kaggle.com/competitions/siim-covid19-detection/discussion/240363)
57
+
58
+ 2. Rules for populating y_pairs (see comments below), in particular the (0, 0) case
59
+ - Justification: The general rules follow the descriptions of the PASCAL VOC 2010 mAP documented online.
60
+ The only custom addition is handling the edge case of (0, 0) false negatives, which was necessary because
61
+ if we don't include (0, 0) pairs, both the sample submission and gold submission end up with all values of
62
+ y_true being 1, so the AP is undefined.
63
+ Behavior of our implementation is consistent with this comment from the organizers:
64
+ https://www.kaggle.com/competitions/siim-covid19-detection/discussion/248467#1362916
65
+
66
+ """
67
+ aps = []
68
+
69
+ # Group predictions by class - the general idea is to calculate AP for each class separately
70
+ # and then average them to get mAP
71
+ classes = sorted(list(set(pred[0] for preds in answers_preds for pred in preds)))
72
+
73
+ for cls in classes:
74
+ # We will populate y_true and y_scores with (y_true, y_score) of:
75
+ # (1, confidence) for every predicted box that matches a ground truth box
76
+ # (0, confidence) for every predicted box that does not match a ground truth box
77
+ # (1, 0) for every ground truth box that is not matched to a predicted box
78
+ # (0, 0) when there are neither predicted nor ground truth boxes
79
+ y_pairs = [] # List of (y_true, y_score) pairs
80
+
81
+ # Gather all predictions and ground truth boxes related to this class from all samples
82
+ for img_preds, img_gts in zip(submission_preds, answers_preds):
83
+ y_pairs_ = []
84
+
85
+ # Get ground truth boxes for this class
86
+ gt_boxes = [gt[2:] for gt in img_gts if gt[0] == cls]
87
+
88
+ # Sort img_preds by confidence
89
+ img_preds.sort(key=lambda x: x[1], reverse=True)
90
+
91
+ # For each prediction of this class
92
+ matched_gt = [False] * len(gt_boxes) # Initialize all ground truths as unmatched
93
+ for pred in img_preds:
94
+ if pred[0] == cls:
95
+ # Find the best matching ground truth box
96
+ best_iou = 0
97
+ best_gt_idx = -1
98
+ for i, gt in enumerate(gt_boxes):
99
+ if matched_gt[i]: # Don't reuse matched ground truths
100
+ continue
101
+ iou = calculate_iou(pred[2:], gt)
102
+ if iou > best_iou and iou > 0.5:
103
+ best_iou = iou
104
+ best_gt_idx = i
105
+
106
+ pred_confidence = pred[1]
107
+ if best_gt_idx != -1:
108
+ y_pairs_.append((1, pred_confidence)) # True positive
109
+ matched_gt[best_gt_idx] = True
110
+ else:
111
+ y_pairs_.append((0, pred_confidence)) # False positive
112
+
113
+ # Add false negatives for unmatched ground truths
114
+ y_pairs_.extend([(1, 0)] * matched_gt.count(False))
115
+
116
+ if len(y_pairs_) == 0:
117
+ # A true negative
118
+ y_pairs_.append((0, 0))
119
+
120
+ y_pairs.extend(y_pairs_)
121
+
122
+ y_true = [pair[0] for pair in y_pairs]
123
+ y_scores = [pair[1] for pair in y_pairs]
124
+ if len(y_true) > 0:
125
+ assert not all(
126
+ y == 1 for y in y_true
127
+ ), "y_true is all 1s; this shouldn't happen and will result in undefined AP"
128
+ ap = average_precision_score(y_true, y_scores)
129
+ aps.append(ap)
130
+ else:
131
+ raise ValueError(f"Unexpected error: y_true is empty for class {cls}")
132
+
133
+ # Calculate mAP
134
+ return np.mean(aps) if aps else 0.0
135
+
136
+
137
+ def parse_prediction_string(
138
+ prediction_string: str,
139
+ ) -> List[Tuple[str, float, float, float, float, float]]:
140
+ """
141
+ `prediction_string` should have the form "{label} {confidence} {xmin} {ymin} {xmax} {ymax}" for each bounding box
142
+ (so there may be 6 x N space-separated values in total, where N is the number of bounding boxes).
143
+
144
+ Returns a list of tuples, each with the form (label, confidence, xmin, ymin, xmax, ymax).
145
+ """
146
+ toks = prediction_string.strip().split()
147
+ try:
148
+ return [
149
+ (
150
+ toks[i],
151
+ float(toks[i + 1]),
152
+ float(toks[i + 2]),
153
+ float(toks[i + 3]),
154
+ float(toks[i + 4]),
155
+ float(toks[i + 5]),
156
+ )
157
+ for i in range(0, len(toks), 6)
158
+ ]
159
+ except ValueError as e:
160
+ raise InvalidSubmissionError(f"Could not parse PredictionString: {e}")
161
+
162
+
163
+ def grade(submission: pd.DataFrame, answers: pd.DataFrame) -> float:
164
+ """
165
+ Grade the submission against the answers.
166
+
167
+ `submission` and `answers` are DataFrames with the following columns:
168
+ - `id` (str): The study ID
169
+ - `PredictionString` (str): Has the form "{label} {confidence} {xmin} {ymin} {xmax} {ymax}" for each bounding box
170
+ (so there may be 6 x N space-separated values in total, where N is the number of bounding boxes).
171
+ """
172
+ if len(submission) != len(answers):
173
+ raise InvalidSubmissionError("Submission and answers must have the same length")
174
+
175
+ if "id" not in submission.columns:
176
+ raise InvalidSubmissionError("Submission must have an 'Id' column")
177
+
178
+ if "PredictionString" not in submission.columns:
179
+ raise InvalidSubmissionError("Submission must have a 'PredictionString' column")
180
+
181
+ assert "id" in answers.columns, "Answers must have an 'id' column"
182
+ assert "PredictionString" in answers.columns, "Answers must have a 'PredictionString' column"
183
+
184
+ submission = submission.sort_values("id")
185
+ answers = answers.sort_values("id")
186
+ if (submission["id"].values != answers["id"].values).any():
187
+ raise InvalidSubmissionError("Submission and answers must have the same ids")
188
+
189
+ # Attempt to parse the PredictionString
190
+ submission_preds = submission["PredictionString"].apply(parse_prediction_string)
191
+ answers_preds = answers["PredictionString"].apply(parse_prediction_string)
192
+
193
+ # Calculate the mAP
194
+ return calculate_map(submission_preds, answers_preds) if len(submission_preds) > 0 else 0.0
@@ -0,0 +1,123 @@
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
+ There are two tasks:
14
+ - Image level: Object detection problem - detect the presence of pneumonia in the image using bounding boxes
15
+ - Study level: Classification problem - classify the study into one of the four classes
16
+
17
+ Images in train/ and test/ are stored in paths with the form {study}/{series}/{image}.
18
+
19
+ Original train has 6,334 samples, and test "is of roughly the same scale as the training dataset".
20
+ We'll split the original train into a new train/test split with 90/10 ratio.
21
+
22
+ The split happens at the study level, with image level following accordingly.
23
+ """
24
+ DEV_MODE = False
25
+
26
+ # Create new train_study_level.csv
27
+ train_study = read_csv(raw / "train_study_level.csv")
28
+ if DEV_MODE:
29
+ # randomly sample 200 rows for development
30
+ train_study = train_study.sample(n=200, random_state=0)
31
+ new_train_study, new_test_study = train_test_split(train_study, test_size=0.1, random_state=0)
32
+ new_train_study = new_train_study.sort_values(by="id")
33
+ new_test_study = new_test_study.sort_values(by="id")
34
+ new_train_study.to_csv(public / "train_study_level.csv", index=False)
35
+
36
+ # Create new train_image_level.csv
37
+ train_image = read_csv(raw / "train_image_level.csv")
38
+ new_train_image = train_image[
39
+ (train_image["StudyInstanceUID"] + "_study").isin(new_train_study["id"])
40
+ ]
41
+ new_test_image = train_image[
42
+ (train_image["StudyInstanceUID"] + "_study").isin(new_test_study["id"])
43
+ ]
44
+ new_train_image = new_train_image.sort_values(by="id")
45
+ new_test_image = new_test_image.sort_values(by="id")
46
+ if not DEV_MODE:
47
+ assert len(new_train_image) + len(new_test_image) == len(
48
+ train_image
49
+ ), f"Expected {len(train_image)} images"
50
+ new_train_image.to_csv(public / "train_image_level.csv", index=False)
51
+
52
+ # Copy data with shutil
53
+ for study_id in tqdm(new_train_study["id"], desc="Copying train data"):
54
+ study_id = study_id.replace("_study", "")
55
+ shutil.copytree(raw / "train" / study_id, public / "train" / study_id)
56
+ for study_id in tqdm(new_test_study["id"], desc="Copying test data"):
57
+ study_id = study_id.replace("_study", "")
58
+ shutil.copytree(raw / "train" / study_id, public / "test" / study_id)
59
+ assert len(list(public.glob("train/*"))) == len(
60
+ new_train_study
61
+ ), f"Expected {len(new_train_study)} studies"
62
+ assert len(list(public.glob("test/*"))) == len(
63
+ new_test_study
64
+ ), f"Expected {len(new_test_study)} studies"
65
+
66
+ # Create gold answer submission
67
+ rows = []
68
+
69
+ """
70
+ # new_test_study currently looks like:
71
+ id,Negative for Pneumonia,Typical Appearance,Indeterminate Appearance,Atypical Appearance
72
+ 00086460a852_study,0,1,0,0
73
+ 000c9c05fd14_study,0,0,0,1
74
+ # but for the submission we need to convert it to the following, where label is one of "negative", "typical", "indeterminate", "atypical"
75
+ id,PredictionString
76
+ 00188a671292_study,{label} 1 0 0 1 1
77
+ 004bd59708be_study,{label} 1 0 0 1 1
78
+ """
79
+ for idx, row in new_test_study.iterrows():
80
+ label = ["negative", "typical", "indeterminate", "atypical"][row[1:].argmax()]
81
+ # Study-level task is just a classification task, so set bounding boxes all the same (1 0 0 1 1)
82
+ # then the metric will only care about the label
83
+ # https://www.kaggle.com/competitions/siim-covid19-detection/data
84
+ rows.append({"id": row["id"], "PredictionString": f"{label} 1 0 0 1 1"})
85
+
86
+ # new_test_image currently looks like this, and we only want the "label" column as the PredictionString
87
+ """
88
+ id,boxes,label,StudyInstanceUID
89
+ 000a312787f2_image,"[{'x': 789.28836, 'y': 582.43035, 'width': 1026.65662, 'height': 1917.30292}, {'x': 2245.91208, 'y': 591.20528, 'width': 1094.66162, 'height': 1761.54944}]",opacity 1 789.28836 582.43035 1815.94498 2499.73327 opacity 1 2245.91208 591.20528 3340.5737 2352.75472,5776db0cec75
90
+ 000c3a3f293f_image,,none 1 0 0 1 1,ff0879eb20ed
91
+ 0012ff7358bc_image,"[{'x': 677.42216, 'y': 197.97662, 'width': 867.79767, 'height': 999.78214}, {'x': 1792.69064, 'y': 402.5525, 'width': 617.02734, 'height': 1204.358}]",opacity 1 677.42216 197.97662 1545.21983 1197.75876 opacity 1 1792.69064 402.5525 2409.71798 1606.9105,9d514ce429a7
92
+ """
93
+ for idx, row in new_test_image.iterrows():
94
+ rows.append({"id": row["id"], "PredictionString": row["label"]})
95
+
96
+ answers = pd.DataFrame(rows)
97
+ assert len(answers) == len(new_test_study) + len(
98
+ new_test_image
99
+ ), f"Expected {len(new_test_study) + len(new_test_image)} answers"
100
+ answers.to_csv(private / "test.csv", index=False)
101
+
102
+ # Create sample submission
103
+ """ Sample submission should look like:
104
+ id,PredictionString
105
+ 00188a671292_study,negative 1 0 0 1 1
106
+ 004bd59708be_study,negative 1 0 0 1 1
107
+ 00508faccd39_study,negative 1 0 0 1 1
108
+ ...
109
+ f77d7d1aebab_image,none 1 0 0 1 1
110
+ ccc5b63ca96d_image,none 1 0 0 1 1
111
+ 5e8ac1fe2b82_image,none 1 0 0 1 1
112
+ """
113
+ rows = []
114
+ for idx, row in new_test_study.iterrows():
115
+ rows.append({"id": row["id"], "PredictionString": "negative 1 0 0 1 1"})
116
+ for idx, row in new_test_image.iterrows():
117
+ rows.append({"id": row["id"], "PredictionString": "none 1 0 0 1 1"})
118
+
119
+ sample_submission = pd.DataFrame(rows)
120
+ assert len(sample_submission) == len(new_test_study) + len(
121
+ new_test_image
122
+ ), f"Expected {len(new_test_study) + len(new_test_image)} answers"
123
+ sample_submission.to_csv(public / "sample_submission.csv", index=False)
@@ -0,0 +1,164 @@
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 _process_split(
12
+ train_study_df: pd.DataFrame,
13
+ test_study_df: pd.DataFrame,
14
+ full_image_df: pd.DataFrame,
15
+ raw_data_root: Path,
16
+ output_public_path: Path,
17
+ output_private_path: Path,
18
+ dev_mode: bool,
19
+ ):
20
+ """
21
+ Helper function to process a single data split and generate all required output files.
22
+
23
+ Args:
24
+ train_study_df: DataFrame of studies for the training set.
25
+ test_study_df: DataFrame of studies for the test set.
26
+ full_image_df: DataFrame of all images, to be filtered for this split.
27
+ raw_data_root: Path to the original raw data.
28
+ output_public_path: Path to the public output directory.
29
+ output_private_path: Path to the private output directory.
30
+ dev_mode: Boolean flag for development mode.
31
+ """
32
+ # Create output directories if they don't exist
33
+ output_public_path.mkdir(parents=True, exist_ok=True)
34
+ (output_public_path / "train").mkdir(exist_ok=True)
35
+ (output_public_path / "test").mkdir(exist_ok=True)
36
+ output_private_path.mkdir(parents=True, exist_ok=True)
37
+
38
+ # Save the study-level train CSV
39
+ train_study_df.to_csv(output_public_path / "train_study_level.csv", index=False)
40
+
41
+ # Filter and save the image-level CSVs based on the study split
42
+ split_train_image = full_image_df[
43
+ (full_image_df["StudyInstanceUID"] + "_study").isin(train_study_df["id"])
44
+ ]
45
+ split_test_image = full_image_df[
46
+ (full_image_df["StudyInstanceUID"] + "_study").isin(test_study_df["id"])
47
+ ]
48
+ split_train_image = split_train_image.sort_values(by="id")
49
+ split_test_image = split_test_image.sort_values(by="id")
50
+ if not dev_mode:
51
+ assert len(split_train_image) + len(split_test_image) == len(
52
+ full_image_df[
53
+ (full_image_df["StudyInstanceUID"] + "_study").isin(
54
+ pd.concat([train_study_df["id"], test_study_df["id"]])
55
+ )
56
+ ]
57
+ ), f"Image split mismatch"
58
+ split_train_image.to_csv(output_public_path / "train_image_level.csv", index=False)
59
+
60
+ # Copy image data for the split
61
+ for study_id in tqdm(train_study_df["id"], desc=f"Copying train data to {output_public_path.name}"):
62
+ study_id = study_id.replace("_study", "")
63
+ shutil.copytree(raw_data_root / "train" / study_id, output_public_path / "train" / study_id, dirs_exist_ok=True)
64
+ for study_id in tqdm(test_study_df["id"], desc=f"Copying test data to {output_public_path.name}"):
65
+ study_id = study_id.replace("_study", "")
66
+ shutil.copytree(raw_data_root / "train" / study_id, output_public_path / "test" / study_id, dirs_exist_ok=True)
67
+
68
+ assert len(list(output_public_path.glob("train/*"))) == len(
69
+ train_study_df
70
+ ), f"Expected {len(train_study_df)} studies in {output_public_path.name}/train"
71
+ assert len(list(output_public_path.glob("test/*"))) == len(
72
+ test_study_df
73
+ ), f"Expected {len(test_study_df)} studies in {output_public_path.name}/test"
74
+
75
+
76
+ # Create gold answer submission for the test set
77
+ rows = []
78
+ for idx, row in test_study_df.iterrows():
79
+ label = ["negative", "typical", "indeterminate", "atypical"][row[1:].argmax()]
80
+ rows.append({"id": row["id"], "PredictionString": f"{label} 1 0 0 1 1"})
81
+ for idx, row in split_test_image.iterrows():
82
+ rows.append({"id": row["id"], "PredictionString": row["label"]})
83
+
84
+ answers = pd.DataFrame(rows)
85
+ assert len(answers) == len(test_study_df) + len(
86
+ split_test_image
87
+ ), f"Expected {len(test_study_df) + len(split_test_image)} answers"
88
+ answers.to_csv(output_private_path / "test.csv", index=False)
89
+
90
+ # Create sample submission for the test set
91
+ rows = []
92
+ for idx, row in test_study_df.iterrows():
93
+ rows.append({"id": row["id"], "PredictionString": "negative 1 0 0 1 1"})
94
+ for idx, row in split_test_image.iterrows():
95
+ rows.append({"id": row["id"], "PredictionString": "none 1 0 0 1 1"})
96
+
97
+ sample_submission = pd.DataFrame(rows)
98
+ assert len(sample_submission) == len(test_study_df) + len(
99
+ split_test_image
100
+ ), f"Expected {len(test_study_df) + len(split_test_image)} sample answers"
101
+ sample_submission.to_csv(output_public_path / "sample_submission.csv", index=False)
102
+
103
+
104
+ def prepare(raw: Path, public: Path, private: Path):
105
+ """
106
+ There are two tasks:
107
+ - Image level: Object detection problem - detect the presence of pneumonia in the image using bounding boxes
108
+ - Study level: Classification problem - classify the study into one of the four classes
109
+
110
+ Images in train/ and test/ are stored in paths with the form {study}/{series}/{image}.
111
+
112
+ Original train has 6,334 samples, and test "is of roughly the same scale as the training dataset".
113
+ We'll split the original train into a new train/test split with 90/10 ratio.
114
+
115
+ The split happens at the study level, with image level following accordingly.
116
+ """
117
+ DEV_MODE = False
118
+
119
+ # Read the original full datasets
120
+ train_study = read_csv(raw / "train_study_level.csv")
121
+ train_image = read_csv(raw / "train_image_level.csv")
122
+
123
+ if DEV_MODE:
124
+ # randomly sample 200 rows for development
125
+ train_study = train_study.sample(n=200, random_state=0)
126
+
127
+ # --- First Split: Create the main train/test sets ---
128
+ # This split creates the primary competition data, saved to `public` and `private`.
129
+ new_train_study, new_test_study = train_test_split(train_study, test_size=0.1, random_state=0)
130
+ new_train_study = new_train_study.sort_values(by="id").reset_index(drop=True)
131
+ new_test_study = new_test_study.sort_values(by="id").reset_index(drop=True)
132
+
133
+ _process_split(
134
+ train_study_df=new_train_study,
135
+ test_study_df=new_test_study,
136
+ full_image_df=train_image,
137
+ raw_data_root=raw,
138
+ output_public_path=public,
139
+ output_private_path=private,
140
+ dev_mode=DEV_MODE,
141
+ )
142
+
143
+ # --- Second Split: Create the validation train/test sets ---
144
+ # This split takes the *training set* from the first split (`new_train_study`)
145
+ # and splits it again to create a validation set. The outputs are saved to
146
+ # parallel `public_val` and `private_val` directories.
147
+ public_val = public.parent / "public_val"
148
+ private_val = private.parent / "private_val"
149
+
150
+ # We use the exact same splitting parameters to maintain consistency.
151
+ # The new test set (`test_val_study`) will be 10% of the `new_train_study`.
152
+ train_val_study, test_val_study = train_test_split(new_train_study, test_size=0.1, random_state=0)
153
+ train_val_study = train_val_study.sort_values(by="id").reset_index(drop=True)
154
+ test_val_study = test_val_study.sort_values(by="id").reset_index(drop=True)
155
+
156
+ _process_split(
157
+ train_study_df=train_val_study,
158
+ test_study_df=test_val_study,
159
+ full_image_df=train_image, # The full image set is used for filtering
160
+ raw_data_root=raw,
161
+ output_public_path=public_val,
162
+ output_private_path=private_val,
163
+ dev_mode=DEV_MODE,
164
+ )
@@ -0,0 +1,11 @@
1
+ import pandas as pd
2
+ from sklearn.metrics import roc_auc_score
3
+
4
+ from mlebench.competitions.utils import prepare_for_auroc_metric
5
+
6
+
7
+ def grade(submission: pd.DataFrame, answers: pd.DataFrame) -> float:
8
+ roc_auc_inputs = prepare_for_auroc_metric(
9
+ submission, answers, id_col="image_name", target_col="target"
10
+ )
11
+ return roc_auc_score(y_true=roc_auc_inputs["y_true"], y_score=roc_auc_inputs["y_score"])