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,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
+ )