hessboost 0.2.1__tar.gz → 0.2.2__tar.gz

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 (475) hide show
  1. {hessboost-0.2.1 → hessboost-0.2.2}/Cargo.toml +1 -1
  2. {hessboost-0.2.1 → hessboost-0.2.2}/PKG-INFO +41 -2
  3. {hessboost-0.2.1 → hessboost-0.2.2}/README.md +5 -3
  4. {hessboost-0.2.1 → hessboost-0.2.2}/python/Cargo.lock +2 -2
  5. {hessboost-0.2.1 → hessboost-0.2.2}/python/Cargo.toml +1 -1
  6. {hessboost-0.2.1 → hessboost-0.2.2}/python/README.md +40 -1
  7. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/__init__.py +9 -1
  8. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_booster.py +245 -1
  9. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_data.py +40 -13
  10. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_hessboost.pyi +61 -0
  11. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_matrix.py +17 -6
  12. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_training.py +85 -4
  13. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/online.py +5 -2
  14. hessboost-0.2.2/python/hessboost/target_stats.py +245 -0
  15. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/booster.rs +24 -1
  16. hessboost-0.2.2/python/src/compact.rs +96 -0
  17. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/data.rs +2 -2
  18. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/lib.rs +6 -0
  19. hessboost-0.2.2/python/src/target_stats.rs +105 -0
  20. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/train.rs +39 -3
  21. hessboost-0.2.2/python/tests/test_compact.py +83 -0
  22. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_data.py +7 -4
  23. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_model_io.py +17 -0
  24. hessboost-0.2.2/python/tests/test_target_stats.py +168 -0
  25. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_training.py +29 -0
  26. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/dmatrix.rs +88 -3
  27. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/target_stats.rs +95 -6
  28. {hessboost-0.2.1 → hessboost-0.2.2}/src/lib.rs +3 -1
  29. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/cv/mod.rs +175 -30
  30. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/online/cache.rs +41 -3
  31. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/online/mod.rs +6 -3
  32. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/online/update.rs +5 -1
  33. hessboost-0.2.2/tests/data/saved/0.2.2/aft.bin +0 -0
  34. hessboost-0.2.2/tests/data/saved/0.2.2/aft.hbtd +0 -0
  35. hessboost-0.2.2/tests/data/saved/0.2.2/aft.json +694 -0
  36. hessboost-0.2.2/tests/data/saved/0.2.2/aft.margins +7 -0
  37. hessboost-0.2.2/tests/data/saved/0.2.2/categorical_splits.bin +0 -0
  38. hessboost-0.2.2/tests/data/saved/0.2.2/categorical_splits.hbtd +0 -0
  39. hessboost-0.2.2/tests/data/saved/0.2.2/categorical_splits.json +864 -0
  40. hessboost-0.2.2/tests/data/saved/0.2.2/categorical_splits.margins +5 -0
  41. hessboost-0.2.2/tests/data/saved/0.2.2/dart.bin +0 -0
  42. hessboost-0.2.2/tests/data/saved/0.2.2/dart.hbtd +0 -0
  43. hessboost-0.2.2/tests/data/saved/0.2.2/dart.json +850 -0
  44. hessboost-0.2.2/tests/data/saved/0.2.2/dart.margins +1 -0
  45. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_flow_matching.hbdm +0 -0
  46. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_flow_matching.hbdm.json +2874 -0
  47. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_flow_matching.hbdm.probe +1 -0
  48. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_score.hbdm +0 -0
  49. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_score.hbdm.json +2879 -0
  50. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_score.hbdm.probe +1 -0
  51. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_treeffuser_vp.hbdm +0 -0
  52. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_treeffuser_vp.hbdm.json +2526 -0
  53. hessboost-0.2.2/tests/data/saved/0.2.2/diffusion_treeffuser_vp.hbdm.probe +1 -0
  54. hessboost-0.2.2/tests/data/saved/0.2.2/dist_negbinomial.bin +0 -0
  55. hessboost-0.2.2/tests/data/saved/0.2.2/dist_negbinomial.hbtd +0 -0
  56. hessboost-0.2.2/tests/data/saved/0.2.2/dist_negbinomial.json +1173 -0
  57. hessboost-0.2.2/tests/data/saved/0.2.2/dist_negbinomial.margins +1 -0
  58. hessboost-0.2.2/tests/data/saved/0.2.2/dist_normal.bin +0 -0
  59. hessboost-0.2.2/tests/data/saved/0.2.2/dist_normal.hbtd +0 -0
  60. hessboost-0.2.2/tests/data/saved/0.2.2/dist_normal.json +1589 -0
  61. hessboost-0.2.2/tests/data/saved/0.2.2/dist_normal.margins +0 -0
  62. hessboost-0.2.2/tests/data/saved/0.2.2/dist_normal_vector_leaves.bin +0 -0
  63. hessboost-0.2.2/tests/data/saved/0.2.2/dist_normal_vector_leaves.json +975 -0
  64. hessboost-0.2.2/tests/data/saved/0.2.2/dist_normal_vector_leaves.margins +0 -0
  65. hessboost-0.2.2/tests/data/saved/0.2.2/early_stopping.bin +0 -0
  66. hessboost-0.2.2/tests/data/saved/0.2.2/early_stopping.hbtd +0 -0
  67. hessboost-0.2.2/tests/data/saved/0.2.2/early_stopping.json +798 -0
  68. hessboost-0.2.2/tests/data/saved/0.2.2/early_stopping.margins +1 -0
  69. hessboost-0.2.2/tests/data/saved/0.2.2/expectiles.bin +0 -0
  70. hessboost-0.2.2/tests/data/saved/0.2.2/expectiles.hbtd +0 -0
  71. hessboost-0.2.2/tests/data/saved/0.2.2/expectiles.json +1384 -0
  72. hessboost-0.2.2/tests/data/saved/0.2.2/expectiles.margins +0 -0
  73. hessboost-0.2.2/tests/data/saved/0.2.2/forest_diffusion.hbff +0 -0
  74. hessboost-0.2.2/tests/data/saved/0.2.2/forest_diffusion.hbff.json +127628 -0
  75. hessboost-0.2.2/tests/data/saved/0.2.2/forest_diffusion.hbff.probe +0 -0
  76. hessboost-0.2.2/tests/data/saved/0.2.2/forest_flow.hbff +0 -0
  77. hessboost-0.2.2/tests/data/saved/0.2.2/forest_flow.hbff.json +88629 -0
  78. hessboost-0.2.2/tests/data/saved/0.2.2/forest_flow.hbff.probe +3 -0
  79. hessboost-0.2.2/tests/data/saved/0.2.2/gblinear.bin +0 -0
  80. hessboost-0.2.2/tests/data/saved/0.2.2/gblinear.json +42 -0
  81. hessboost-0.2.2/tests/data/saved/0.2.2/gblinear.margins +0 -0
  82. hessboost-0.2.2/tests/data/saved/0.2.2/linear_leaves.bin +0 -0
  83. hessboost-0.2.2/tests/data/saved/0.2.2/linear_leaves.json +1066 -0
  84. hessboost-0.2.2/tests/data/saved/0.2.2/linear_leaves.margins +0 -0
  85. hessboost-0.2.2/tests/data/saved/0.2.2/multi_target.bin +0 -0
  86. hessboost-0.2.2/tests/data/saved/0.2.2/multi_target.hbtd +0 -0
  87. hessboost-0.2.2/tests/data/saved/0.2.2/multi_target.json +1615 -0
  88. hessboost-0.2.2/tests/data/saved/0.2.2/multi_target.margins +0 -0
  89. hessboost-0.2.2/tests/data/saved/0.2.2/multiclass_forest.bin +0 -0
  90. hessboost-0.2.2/tests/data/saved/0.2.2/multiclass_forest.hbtd +0 -0
  91. hessboost-0.2.2/tests/data/saved/0.2.2/multiclass_forest.json +6028 -0
  92. hessboost-0.2.2/tests/data/saved/0.2.2/multiclass_forest.margins +0 -0
  93. hessboost-0.2.2/tests/data/saved/0.2.2/quantiles.bin +0 -0
  94. hessboost-0.2.2/tests/data/saved/0.2.2/quantiles.hbtd +0 -0
  95. hessboost-0.2.2/tests/data/saved/0.2.2/quantiles.json +2358 -0
  96. hessboost-0.2.2/tests/data/saved/0.2.2/quantiles.margins +0 -0
  97. hessboost-0.2.2/tests/data/saved/0.2.2/vector_leaves.bin +0 -0
  98. hessboost-0.2.2/tests/data/saved/0.2.2/vector_leaves.json +1036 -0
  99. hessboost-0.2.2/tests/data/saved/0.2.2/vector_leaves.margins +0 -0
  100. {hessboost-0.2.1 → hessboost-0.2.2}/tests/online.rs +98 -0
  101. {hessboost-0.2.1 → hessboost-0.2.2}/LICENSE +0 -0
  102. {hessboost-0.2.1 → hessboost-0.2.2}/benches/training.rs +0 -0
  103. {hessboost-0.2.1 → hessboost-0.2.2}/examples/balanced_bagging.rs +0 -0
  104. {hessboost-0.2.1 → hessboost-0.2.2}/examples/bench_compare.rs +0 -0
  105. {hessboost-0.2.1 → hessboost-0.2.2}/examples/binary_classification.rs +0 -0
  106. {hessboost-0.2.1 → hessboost-0.2.2}/examples/boulevard_inference.rs +0 -0
  107. {hessboost-0.2.1 → hessboost-0.2.2}/examples/budget.rs +0 -0
  108. {hessboost-0.2.1 → hessboost-0.2.2}/examples/common/mod.rs +0 -0
  109. {hessboost-0.2.1 → hessboost-0.2.2}/examples/compact_model.rs +0 -0
  110. {hessboost-0.2.1 → hessboost-0.2.2}/examples/conformal.rs +0 -0
  111. {hessboost-0.2.1 → hessboost-0.2.2}/examples/constraints.rs +0 -0
  112. {hessboost-0.2.1 → hessboost-0.2.2}/examples/custom_objective.rs +0 -0
  113. {hessboost-0.2.1 → hessboost-0.2.2}/examples/distributional.rs +0 -0
  114. {hessboost-0.2.1 → hessboost-0.2.2}/examples/ebm.rs +0 -0
  115. {hessboost-0.2.1 → hessboost-0.2.2}/examples/forest_flow.rs +0 -0
  116. {hessboost-0.2.1 → hessboost-0.2.2}/examples/metal.rs +0 -0
  117. {hessboost-0.2.1 → hessboost-0.2.2}/examples/model_io.rs +0 -0
  118. {hessboost-0.2.1 → hessboost-0.2.2}/examples/multiclass.rs +0 -0
  119. {hessboost-0.2.1 → hessboost-0.2.2}/examples/online_update.rs +0 -0
  120. {hessboost-0.2.1 → hessboost-0.2.2}/examples/ordered_target_stats.rs +0 -0
  121. {hessboost-0.2.1 → hessboost-0.2.2}/examples/pfn_boost.rs +0 -0
  122. {hessboost-0.2.1 → hessboost-0.2.2}/examples/rank_xendcg.rs +0 -0
  123. {hessboost-0.2.1 → hessboost-0.2.2}/examples/ranking.rs +0 -0
  124. {hessboost-0.2.1 → hessboost-0.2.2}/examples/shap.rs +0 -0
  125. {hessboost-0.2.1 → hessboost-0.2.2}/examples/train_regression.rs +0 -0
  126. {hessboost-0.2.1 → hessboost-0.2.2}/examples/tree_diffusion.rs +0 -0
  127. {hessboost-0.2.1 → hessboost-0.2.2}/examples/virtual_ensembles.rs +0 -0
  128. {hessboost-0.2.1 → hessboost-0.2.2}/pyproject.toml +0 -0
  129. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_core.py +0 -0
  130. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_exceptions.py +0 -0
  131. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_model_io.py +0 -0
  132. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_sklearn_base.pyi +0 -0
  133. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/_sklearn_common.py +0 -0
  134. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/conformal.py +0 -0
  135. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/diffusion/__init__.py +0 -0
  136. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/diffusion/forest.py +0 -0
  137. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/ebm.py +0 -0
  138. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/folds.py +0 -0
  139. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/inference.py +0 -0
  140. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/py.typed +0 -0
  141. {hessboost-0.2.1 → hessboost-0.2.2}/python/hessboost/sklearn.py +0 -0
  142. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/codec.rs +0 -0
  143. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/conformal.rs +0 -0
  144. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/diffusion.rs +0 -0
  145. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/dist.rs +0 -0
  146. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/ebm.rs +0 -0
  147. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/errors.rs +0 -0
  148. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/forest.rs +0 -0
  149. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/gpu.rs +0 -0
  150. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/inference.rs +0 -0
  151. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/online.rs +0 -0
  152. {hessboost-0.2.1 → hessboost-0.2.2}/python/src/params.rs +0 -0
  153. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/conftest.py +0 -0
  154. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_conformal.py +0 -0
  155. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_diffusion.py +0 -0
  156. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_ebm.py +0 -0
  157. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_forest.py +0 -0
  158. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_gpu.py +0 -0
  159. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_inference.py +0 -0
  160. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_online.py +0 -0
  161. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_params.py +0 -0
  162. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_polars.py +0 -0
  163. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_sklearn.py +0 -0
  164. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_stubs.py +0 -0
  165. {hessboost-0.2.1 → hessboost-0.2.2}/python/tests/test_threads.py +0 -0
  166. {hessboost-0.2.1 → hessboost-0.2.2}/src/backend/exact_sum.rs +0 -0
  167. {hessboost-0.2.1 → hessboost-0.2.2}/src/backend/metal.rs +0 -0
  168. {hessboost-0.2.1 → hessboost-0.2.2}/src/backend/mod.rs +0 -0
  169. {hessboost-0.2.1 → hessboost-0.2.2}/src/check.rs +0 -0
  170. {hessboost-0.2.1 → hessboost-0.2.2}/src/config/groups.rs +0 -0
  171. {hessboost-0.2.1 → hessboost-0.2.2}/src/config/mod.rs +0 -0
  172. {hessboost-0.2.1 → hessboost-0.2.2}/src/config/params.rs +0 -0
  173. {hessboost-0.2.1 → hessboost-0.2.2}/src/config/xgboost/emit.rs +0 -0
  174. {hessboost-0.2.1 → hessboost-0.2.2}/src/config/xgboost/mod.rs +0 -0
  175. {hessboost-0.2.1 → hessboost-0.2.2}/src/config/xgboost/parse.rs +0 -0
  176. {hessboost-0.2.1 → hessboost-0.2.2}/src/config/xgboost/schema.rs +0 -0
  177. {hessboost-0.2.1 → hessboost-0.2.2}/src/config/xgboost/tests.rs +0 -0
  178. {hessboost-0.2.1 → hessboost-0.2.2}/src/conformal.rs +0 -0
  179. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/ghist.rs +0 -0
  180. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/loaders.rs +0 -0
  181. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/meta.rs +0 -0
  182. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/mod.rs +0 -0
  183. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/quantile.rs +0 -0
  184. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/sketch.rs +0 -0
  185. {hessboost-0.2.1 → hessboost-0.2.2}/src/data/sort.rs +0 -0
  186. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/fit.rs +0 -0
  187. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/forest/encoding.rs +0 -0
  188. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/forest/fit.rs +0 -0
  189. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/forest/format.rs +0 -0
  190. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/forest/mod.rs +0 -0
  191. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/format.rs +0 -0
  192. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/io.rs +0 -0
  193. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/mod.rs +0 -0
  194. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/process.rs +0 -0
  195. {hessboost-0.2.1 → hessboost-0.2.2}/src/diffusion/sample.rs +0 -0
  196. {hessboost-0.2.1 → hessboost-0.2.2}/src/ebm/grid.rs +0 -0
  197. {hessboost-0.2.1 → hessboost-0.2.2}/src/ebm/mod.rs +0 -0
  198. {hessboost-0.2.1 → hessboost-0.2.2}/src/error.rs +0 -0
  199. {hessboost-0.2.1 → hessboost-0.2.2}/src/inference/ebm.rs +0 -0
  200. {hessboost-0.2.1 → hessboost-0.2.2}/src/inference/kernel.rs +0 -0
  201. {hessboost-0.2.1 → hessboost-0.2.2}/src/inference/linalg.rs +0 -0
  202. {hessboost-0.2.1 → hessboost-0.2.2}/src/inference/mod.rs +0 -0
  203. {hessboost-0.2.1 → hessboost-0.2.2}/src/inference/refit.rs +0 -0
  204. {hessboost-0.2.1 → hessboost-0.2.2}/src/inference/solver.rs +0 -0
  205. {hessboost-0.2.1 → hessboost-0.2.2}/src/inference/term_kernel.rs +0 -0
  206. {hessboost-0.2.1 → hessboost-0.2.2}/src/metric/curve.rs +0 -0
  207. {hessboost-0.2.1 → hessboost-0.2.2}/src/metric/distributional.rs +0 -0
  208. {hessboost-0.2.1 → hessboost-0.2.2}/src/metric/elementwise.rs +0 -0
  209. {hessboost-0.2.1 → hessboost-0.2.2}/src/metric/factory.rs +0 -0
  210. {hessboost-0.2.1 → hessboost-0.2.2}/src/metric/mod.rs +0 -0
  211. {hessboost-0.2.1 → hessboost-0.2.2}/src/metric/quantile.rs +0 -0
  212. {hessboost-0.2.1 → hessboost-0.2.2}/src/metric/ranking.rs +0 -0
  213. {hessboost-0.2.1 → hessboost-0.2.2}/src/metric/survival.rs +0 -0
  214. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/categories.rs +0 -0
  215. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/compact/bitstream.rs +0 -0
  216. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/compact/decode.rs +0 -0
  217. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/compact/encode.rs +0 -0
  218. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/compact/mod.rs +0 -0
  219. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/compact/tests.rs +0 -0
  220. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/container.rs +0 -0
  221. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/embed.rs +0 -0
  222. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/io.rs +0 -0
  223. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/lightgbm.rs +0 -0
  224. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/mod.rs +0 -0
  225. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/native.rs +0 -0
  226. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/objective.rs +0 -0
  227. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/predict.rs +0 -0
  228. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/predictions.rs +0 -0
  229. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/sections.rs +0 -0
  230. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/serde.rs +0 -0
  231. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/shap.rs +0 -0
  232. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/shrinkage.rs +0 -0
  233. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/slice.rs +0 -0
  234. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/ubjson.rs +0 -0
  235. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/uncertainty.rs +0 -0
  236. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/validate.rs +0 -0
  237. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/xgboost/document.rs +0 -0
  238. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/xgboost/mod.rs +0 -0
  239. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/xgboost/objective.rs +0 -0
  240. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/xgboost/parse.rs +0 -0
  241. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/xgboost/tests.rs +0 -0
  242. {hessboost-0.2.1 → hessboost-0.2.2}/src/model/xgboost/tree.rs +0 -0
  243. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/absolute.rs +0 -0
  244. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/classification.rs +0 -0
  245. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/count.rs +0 -0
  246. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/custom.rs +0 -0
  247. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/distributional/count.rs +0 -0
  248. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/distributional/dist.rs +0 -0
  249. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/distributional/family.rs +0 -0
  250. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/distributional/loss.rs +0 -0
  251. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/distributional/mod.rs +0 -0
  252. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/distributional/special.rs +0 -0
  253. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/distributional/tests.rs +0 -0
  254. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/mod.rs +0 -0
  255. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/multi_target.rs +0 -0
  256. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/multiclass.rs +0 -0
  257. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/params.rs +0 -0
  258. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/quantile.rs +0 -0
  259. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/query.rs +0 -0
  260. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/ranking.rs +0 -0
  261. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/regression.rs +0 -0
  262. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/spec.rs +0 -0
  263. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/survival/aft.rs +0 -0
  264. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/survival/cox.rs +0 -0
  265. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/survival/mod.rs +0 -0
  266. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/survival/tests.rs +0 -0
  267. {hessboost-0.2.1 → hessboost-0.2.2}/src/objective/xendcg.rs +0 -0
  268. {hessboost-0.2.1 → hessboost-0.2.2}/src/rng.rs +0 -0
  269. {hessboost-0.2.1 → hessboost-0.2.2}/src/simd/aarch64/tests.rs +0 -0
  270. {hessboost-0.2.1 → hessboost-0.2.2}/src/simd/aarch64.rs +0 -0
  271. {hessboost-0.2.1 → hessboost-0.2.2}/src/simd/mod.rs +0 -0
  272. {hessboost-0.2.1 → hessboost-0.2.2}/src/simd/scalar.rs +0 -0
  273. {hessboost-0.2.1 → hessboost-0.2.2}/src/simd/tests.rs +0 -0
  274. {hessboost-0.2.1 → hessboost-0.2.2}/src/simd/x86_64.rs +0 -0
  275. {hessboost-0.2.1 → hessboost-0.2.2}/src/test_support.rs +0 -0
  276. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/api.rs +0 -0
  277. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/boulevard.rs +0 -0
  278. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/budget.rs +0 -0
  279. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/continuation.rs +0 -0
  280. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/cv/fold.rs +0 -0
  281. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/dart.rs +0 -0
  282. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/ebm/boulevard.rs +0 -0
  283. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/ebm/classic.rs +0 -0
  284. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/ebm/fast.rs +0 -0
  285. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/ebm/mod.rs +0 -0
  286. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/eval.rs +0 -0
  287. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/gblinear.rs +0 -0
  288. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/margins.rs +0 -0
  289. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/mod.rs +0 -0
  290. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/multi_output.rs +0 -0
  291. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/prepare.rs +0 -0
  292. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/refresh.rs +0 -0
  293. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/round.rs +0 -0
  294. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/row_sampling.rs +0 -0
  295. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/sampling.rs +0 -0
  296. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/sglb.rs +0 -0
  297. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/train/tests.rs +0 -0
  298. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/train.rs +0 -0
  299. {hessboost-0.2.1 → hessboost-0.2.2}/src/training/validate.rs +0 -0
  300. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/budget.rs +0 -0
  301. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/categorical.rs +0 -0
  302. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/exact.rs +0 -0
  303. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/hist/mod.rs +0 -0
  304. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/hist/search.rs +0 -0
  305. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/lightgbm.rs +0 -0
  306. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/mod.rs +0 -0
  307. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/multi.rs +0 -0
  308. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/oblivious.rs +0 -0
  309. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/online.rs +0 -0
  310. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/partition.rs +0 -0
  311. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/shared.rs +0 -0
  312. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/builder/split.rs +0 -0
  313. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/compact.rs +0 -0
  314. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/constraints.rs +0 -0
  315. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/gain.rs +0 -0
  316. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/hist/mod.rs +0 -0
  317. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/hist/quantized.rs +0 -0
  318. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/hist/walk.rs +0 -0
  319. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/linear.rs +0 -0
  320. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/linear_fit.rs +0 -0
  321. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/mod.rs +0 -0
  322. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/oblivious.rs +0 -0
  323. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/regtree.rs +0 -0
  324. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/reuse.rs +0 -0
  325. {hessboost-0.2.1 → hessboost-0.2.2}/src/tree/sampler.rs +0 -0
  326. {hessboost-0.2.1 → hessboost-0.2.2}/tests/boulevard.rs +0 -0
  327. {hessboost-0.2.1 → hessboost-0.2.2}/tests/budget.rs +0 -0
  328. {hessboost-0.2.1 → hessboost-0.2.2}/tests/common/bits.rs +0 -0
  329. {hessboost-0.2.1 → hessboost-0.2.2}/tests/common/fixtures.rs +0 -0
  330. {hessboost-0.2.1 → hessboost-0.2.2}/tests/common/mod.rs +0 -0
  331. {hessboost-0.2.1 → hessboost-0.2.2}/tests/common/smooth.rs +0 -0
  332. {hessboost-0.2.1 → hessboost-0.2.2}/tests/continuation.rs +0 -0
  333. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/lightgbm-4.7.0-binary.expected.json +0 -0
  334. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/lightgbm-4.7.0-binary.txt +0 -0
  335. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/lightgbm-4.7.0-linear.expected.json +0 -0
  336. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/lightgbm-4.7.0-linear.txt +0 -0
  337. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/aft.bin +0 -0
  338. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/aft.hbtd +0 -0
  339. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/aft.json +0 -0
  340. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/aft.margins +0 -0
  341. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/categorical_splits.bin +0 -0
  342. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/categorical_splits.hbtd +0 -0
  343. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/categorical_splits.json +0 -0
  344. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/categorical_splits.margins +0 -0
  345. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dart.bin +0 -0
  346. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dart.hbtd +0 -0
  347. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dart.json +0 -0
  348. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dart.margins +0 -0
  349. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_negbinomial.bin +0 -0
  350. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_negbinomial.hbtd +0 -0
  351. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_negbinomial.json +0 -0
  352. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_negbinomial.margins +0 -0
  353. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_normal.bin +0 -0
  354. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_normal.hbtd +0 -0
  355. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_normal.json +0 -0
  356. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_normal.margins +0 -0
  357. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_normal_vector_leaves.bin +0 -0
  358. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_normal_vector_leaves.json +0 -0
  359. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/dist_normal_vector_leaves.margins +0 -0
  360. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/early_stopping.bin +0 -0
  361. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/early_stopping.hbtd +0 -0
  362. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/early_stopping.json +0 -0
  363. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/early_stopping.margins +0 -0
  364. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/expectiles.bin +0 -0
  365. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/expectiles.hbtd +0 -0
  366. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/expectiles.json +0 -0
  367. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/expectiles.margins +0 -0
  368. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/gblinear.bin +0 -0
  369. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/gblinear.json +0 -0
  370. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/gblinear.margins +0 -0
  371. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/linear_leaves.bin +0 -0
  372. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/linear_leaves.json +0 -0
  373. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/linear_leaves.margins +0 -0
  374. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/multi_target.bin +0 -0
  375. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/multi_target.hbtd +0 -0
  376. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/multi_target.json +0 -0
  377. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/multi_target.margins +0 -0
  378. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/multiclass_forest.bin +0 -0
  379. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/multiclass_forest.hbtd +0 -0
  380. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/multiclass_forest.json +0 -0
  381. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/multiclass_forest.margins +0 -0
  382. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/quantiles.bin +0 -0
  383. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/quantiles.hbtd +0 -0
  384. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/quantiles.json +0 -0
  385. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/quantiles.margins +0 -0
  386. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/vector_leaves.bin +0 -0
  387. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/vector_leaves.json +0 -0
  388. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.0/vector_leaves.margins +0 -0
  389. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/aft.bin +0 -0
  390. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/aft.hbtd +0 -0
  391. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/aft.json +0 -0
  392. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/aft.margins +0 -0
  393. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/categorical_splits.bin +0 -0
  394. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/categorical_splits.hbtd +0 -0
  395. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/categorical_splits.json +0 -0
  396. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/categorical_splits.margins +0 -0
  397. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dart.bin +0 -0
  398. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dart.hbtd +0 -0
  399. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dart.json +0 -0
  400. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dart.margins +0 -0
  401. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_flow_matching.hbdm +0 -0
  402. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_flow_matching.hbdm.json +0 -0
  403. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_flow_matching.hbdm.probe +0 -0
  404. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_score.hbdm +0 -0
  405. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_score.hbdm.json +0 -0
  406. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_score.hbdm.probe +0 -0
  407. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_treeffuser_vp.hbdm +0 -0
  408. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_treeffuser_vp.hbdm.json +0 -0
  409. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/diffusion_treeffuser_vp.hbdm.probe +0 -0
  410. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_negbinomial.bin +0 -0
  411. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_negbinomial.hbtd +0 -0
  412. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_negbinomial.json +0 -0
  413. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_negbinomial.margins +0 -0
  414. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_normal.bin +0 -0
  415. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_normal.hbtd +0 -0
  416. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_normal.json +0 -0
  417. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_normal.margins +0 -0
  418. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_normal_vector_leaves.bin +0 -0
  419. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_normal_vector_leaves.json +0 -0
  420. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/dist_normal_vector_leaves.margins +0 -0
  421. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/early_stopping.bin +0 -0
  422. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/early_stopping.hbtd +0 -0
  423. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/early_stopping.json +0 -0
  424. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/early_stopping.margins +0 -0
  425. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/expectiles.bin +0 -0
  426. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/expectiles.hbtd +0 -0
  427. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/expectiles.json +0 -0
  428. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/expectiles.margins +0 -0
  429. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/forest_diffusion.hbff +0 -0
  430. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/forest_diffusion.hbff.json +0 -0
  431. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/forest_diffusion.hbff.probe +0 -0
  432. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/forest_flow.hbff +0 -0
  433. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/forest_flow.hbff.json +0 -0
  434. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/forest_flow.hbff.probe +0 -0
  435. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/gblinear.bin +0 -0
  436. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/gblinear.json +0 -0
  437. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/gblinear.margins +0 -0
  438. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/linear_leaves.bin +0 -0
  439. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/linear_leaves.json +0 -0
  440. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/linear_leaves.margins +0 -0
  441. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/multi_target.bin +0 -0
  442. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/multi_target.hbtd +0 -0
  443. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/multi_target.json +0 -0
  444. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/multi_target.margins +0 -0
  445. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/multiclass_forest.bin +0 -0
  446. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/multiclass_forest.hbtd +0 -0
  447. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/multiclass_forest.json +0 -0
  448. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/multiclass_forest.margins +0 -0
  449. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/quantiles.bin +0 -0
  450. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/quantiles.hbtd +0 -0
  451. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/quantiles.json +0 -0
  452. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/quantiles.margins +0 -0
  453. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/vector_leaves.bin +0 -0
  454. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/vector_leaves.json +0 -0
  455. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/saved/0.2.1/vector_leaves.margins +0 -0
  456. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/xgboost-3.4.2-categorical.json +0 -0
  457. {hessboost-0.2.1 → hessboost-0.2.2}/tests/data/xgboost-3.4.2-categorical.ubj +0 -0
  458. {hessboost-0.2.1 → hessboost-0.2.2}/tests/diffusion.rs +0 -0
  459. {hessboost-0.2.1 → hessboost-0.2.2}/tests/distributional.rs +0 -0
  460. {hessboost-0.2.1 → hessboost-0.2.2}/tests/ebm.rs +0 -0
  461. {hessboost-0.2.1 → hessboost-0.2.2}/tests/forest.rs +0 -0
  462. {hessboost-0.2.1 → hessboost-0.2.2}/tests/lightgbm_parity.rs +0 -0
  463. {hessboost-0.2.1 → hessboost-0.2.2}/tests/metal.rs +0 -0
  464. {hessboost-0.2.1 → hessboost-0.2.2}/tests/model_format.rs +0 -0
  465. {hessboost-0.2.1 → hessboost-0.2.2}/tests/multi_output.rs +0 -0
  466. {hessboost-0.2.1 → hessboost-0.2.2}/tests/native_format.rs +0 -0
  467. {hessboost-0.2.1 → hessboost-0.2.2}/tests/parity.rs +0 -0
  468. {hessboost-0.2.1 → hessboost-0.2.2}/tests/properties.rs +0 -0
  469. {hessboost-0.2.1 → hessboost-0.2.2}/tests/quantized.rs +0 -0
  470. {hessboost-0.2.1 → hessboost-0.2.2}/tests/round_hook.rs +0 -0
  471. {hessboost-0.2.1 → hessboost-0.2.2}/tests/sampling.rs +0 -0
  472. {hessboost-0.2.1 → hessboost-0.2.2}/tests/sglb.rs +0 -0
  473. {hessboost-0.2.1 → hessboost-0.2.2}/tests/shap_accumulation.rs +0 -0
  474. {hessboost-0.2.1 → hessboost-0.2.2}/tests/target_stats.rs +0 -0
  475. {hessboost-0.2.1 → hessboost-0.2.2}/tests/tree_options.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "hessboost"
3
- version = "0.2.1"
3
+ version = "0.2.2"
4
4
  edition = "2024"
5
5
  rust-version = "1.93"
6
6
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hessboost
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Intended Audience :: Science/Research
@@ -132,7 +132,11 @@ every `n`-th), `xgb_model` (continued training, or tree refresh with
132
132
  `process_type="update"`), a custom objective `obj`, a `custom_metric`,
133
133
  and `callbacks`. Ctrl-C stops training at the end of the current round
134
134
  and raises `KeyboardInterrupt`. `hessboost.cv` cross-validates over
135
- shuffled folds, explicit folds, or a scikit-learn splitter.
135
+ shuffled folds, explicit folds, or a scikit-learn splitter; on ranking data
136
+ each fold must hold whole query groups (e.g. `GroupKFold` over the query
137
+ ids). `hessboost.train_with_budget(params, dtrain, budget)` trains with one
138
+ fitting budget in place of `eta`, tree limits, and a round count
139
+ (PerpetualBooster's algorithm).
136
140
 
137
141
  Subclass `TrainingCallback` to stop on your own condition; `after_iteration`
138
142
  sees the round and the evaluation history, and returning `True` stops
@@ -445,6 +449,23 @@ gpu = booster.to_gpu()
445
449
  probabilities = gpu.predict(X_test)
446
450
  ```
447
451
 
452
+ ### Compact models
453
+
454
+ `Booster.to_compact()` packs the trees default prediction uses into
455
+ hessboost's bit-packed `HBTD` format (*Boosted Trees on a Diet*), which
456
+ predicts bit-identical values and margins in a fraction of the size;
457
+ training with `toad_penalty_feature`/`toad_penalty_threshold` shrinks it
458
+ further. `Booster.size_report()` compares the two formats:
459
+
460
+ ```python
461
+ from hessboost import CompactModel
462
+
463
+ compact = booster.to_compact()
464
+ compact.save_model("model.hbtd")
465
+ predictions = CompactModel("model.hbtd").predict(X_test)
466
+ print(booster.size_report().compression_ratio)
467
+ ```
468
+
448
469
  ### Validation folds
449
470
 
450
471
  `hessboost.folds` builds `(train_rows, test_rows)` splits for `cv` or custom
@@ -460,6 +481,24 @@ splits = folds.forward_chaining(dtrain.num_row(), 4, gap=24)
460
481
  result = hessboost.cv({"max_depth": 4}, dtrain, 100, folds=splits)
461
482
  ```
462
483
 
484
+ ### Ordered target statistics
485
+
486
+ `hessboost.target_stats.OrderedTargetEncoder` replaces categorical columns
487
+ with CatBoost-style ordered target means: a training row's encoding never
488
+ sees its own label. `label=` supplies the target for a multi-target matrix
489
+ or a class's 0/1 indicator. In `cv`, `target_stats=` fits the encoder on
490
+ each fold's training rows only, so no held-out label reaches an encoding:
491
+
492
+ ```python
493
+ from hessboost.target_stats import OrderedTargetEncoder
494
+
495
+ encoder = OrderedTargetEncoder(seed=7)
496
+ dtrain_encoded, stats = encoder.fit_transform(dtrain, ["city"])
497
+ booster = hessboost.train({"max_depth": 4}, dtrain_encoded, 100)
498
+ predictions = booster.predict(stats.transform(X_test))
499
+ result = hessboost.cv({"max_depth": 4}, dtrain, 100, target_stats=["city"], target_encoder=encoder)
500
+ ```
501
+
463
502
  ### Extra training options
464
503
 
465
504
  Every hessboost training option (`path_smooth`, `extra_trees`,
@@ -134,7 +134,8 @@ runnable programs live in [`examples/`](examples)
134
134
  [`python/`](python) holds the Python package (`pip install hessboost`):
135
135
  `DMatrix`, `train`, `cv`, and `Booster` (taking XGBoost's parameter names),
136
136
  scikit-learn estimators, pandas and polars categorical input, and the conformal,
137
- distributional, tree-diffusion, ForestFlow, and in-place update extras
137
+ distributional, tree-diffusion, ForestFlow, in-place update, ordered target
138
+ statistics, budget training, and compact model extras
138
139
  (on macOS, `Booster.to_gpu()` batch-predicts on the Metal GPU):
139
140
 
140
141
  ```python
@@ -155,8 +156,9 @@ See [`python/README.md`](python/README.md).
155
156
  - **Objectives & metrics:** Regression (squared, log, Huber, quantile, expectile),
156
157
  binary/multiclass classification, ranking (LambdaMART, XE-NDCG), count, and survival (Cox, AFT),
157
158
  plus typed objective and metric APIs and custom loss hooks.
158
- - **Validation & workflow:** Cross-validation (including purged and forward time-series folds),
159
- early stopping, feature importance, SHAP values and interactions, model slicing, and iteration ranges.
159
+ - **Validation & workflow:** Cross-validation (including purged and forward time-series folds,
160
+ whole-query ranking folds, and per-fold target statistics), early stopping, feature importance,
161
+ SHAP values and interactions, model slicing, and iteration ranges.
160
162
  - **Interchange:** Native binary and JSON formats, XGBoost JSON/UBJSON import/export, LightGBM model import, and models embedded in the binary at compile time.
161
163
  - **Modern modeling (opt-in):**
162
164
  - [Conformal intervals](https://docs.rs/hessboost/latest/hessboost/conformal/): Finite-sample coverage guarantees.
@@ -88,7 +88,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
88
88
 
89
89
  [[package]]
90
90
  name = "hessboost"
91
- version = "0.2.1"
91
+ version = "0.2.2"
92
92
  dependencies = [
93
93
  "objc2",
94
94
  "objc2-foundation",
@@ -101,7 +101,7 @@ dependencies = [
101
101
 
102
102
  [[package]]
103
103
  name = "hessboost-python"
104
- version = "0.2.1"
104
+ version = "0.2.2"
105
105
  dependencies = [
106
106
  "hessboost",
107
107
  "numpy",
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  name = "hessboost-python"
3
3
  # Must equal the root crate's version: the wheel version comes from here.
4
- version = "0.2.1"
4
+ version = "0.2.2"
5
5
  authors = ["Brenden Matthews <brenden@brndn.io>"]
6
6
  description = "Python bindings for hessboost"
7
7
  edition = "2024"
@@ -93,7 +93,11 @@ every `n`-th), `xgb_model` (continued training, or tree refresh with
93
93
  `process_type="update"`), a custom objective `obj`, a `custom_metric`,
94
94
  and `callbacks`. Ctrl-C stops training at the end of the current round
95
95
  and raises `KeyboardInterrupt`. `hessboost.cv` cross-validates over
96
- shuffled folds, explicit folds, or a scikit-learn splitter.
96
+ shuffled folds, explicit folds, or a scikit-learn splitter; on ranking data
97
+ each fold must hold whole query groups (e.g. `GroupKFold` over the query
98
+ ids). `hessboost.train_with_budget(params, dtrain, budget)` trains with one
99
+ fitting budget in place of `eta`, tree limits, and a round count
100
+ (PerpetualBooster's algorithm).
97
101
 
98
102
  Subclass `TrainingCallback` to stop on your own condition; `after_iteration`
99
103
  sees the round and the evaluation history, and returning `True` stops
@@ -406,6 +410,23 @@ gpu = booster.to_gpu()
406
410
  probabilities = gpu.predict(X_test)
407
411
  ```
408
412
 
413
+ ### Compact models
414
+
415
+ `Booster.to_compact()` packs the trees default prediction uses into
416
+ hessboost's bit-packed `HBTD` format (*Boosted Trees on a Diet*), which
417
+ predicts bit-identical values and margins in a fraction of the size;
418
+ training with `toad_penalty_feature`/`toad_penalty_threshold` shrinks it
419
+ further. `Booster.size_report()` compares the two formats:
420
+
421
+ ```python
422
+ from hessboost import CompactModel
423
+
424
+ compact = booster.to_compact()
425
+ compact.save_model("model.hbtd")
426
+ predictions = CompactModel("model.hbtd").predict(X_test)
427
+ print(booster.size_report().compression_ratio)
428
+ ```
429
+
409
430
  ### Validation folds
410
431
 
411
432
  `hessboost.folds` builds `(train_rows, test_rows)` splits for `cv` or custom
@@ -421,6 +442,24 @@ splits = folds.forward_chaining(dtrain.num_row(), 4, gap=24)
421
442
  result = hessboost.cv({"max_depth": 4}, dtrain, 100, folds=splits)
422
443
  ```
423
444
 
445
+ ### Ordered target statistics
446
+
447
+ `hessboost.target_stats.OrderedTargetEncoder` replaces categorical columns
448
+ with CatBoost-style ordered target means: a training row's encoding never
449
+ sees its own label. `label=` supplies the target for a multi-target matrix
450
+ or a class's 0/1 indicator. In `cv`, `target_stats=` fits the encoder on
451
+ each fold's training rows only, so no held-out label reaches an encoding:
452
+
453
+ ```python
454
+ from hessboost.target_stats import OrderedTargetEncoder
455
+
456
+ encoder = OrderedTargetEncoder(seed=7)
457
+ dtrain_encoded, stats = encoder.fit_transform(dtrain, ["city"])
458
+ booster = hessboost.train({"max_depth": 4}, dtrain_encoded, 100)
459
+ predictions = booster.predict(stats.transform(X_test))
460
+ result = hessboost.cv({"max_depth": 4}, dtrain, 100, target_stats=["city"], target_encoder=encoder)
461
+ ```
462
+
424
463
  ### Extra training options
425
464
 
426
465
  Every hessboost training option (`path_smooth`, `extra_trees`,
@@ -19,17 +19,20 @@ Submodules:
19
19
  diffusion and flow matching
20
20
  * :mod:`hessboost.folds` -- k-fold and forward-chaining (purged) folds
21
21
  * :mod:`hessboost.online` -- adding and deleting training rows in place
22
+ * :mod:`hessboost.target_stats` -- ordered target statistics for categorical columns
22
23
  """
23
24
 
24
25
  from importlib.metadata import version as _version
25
26
 
26
- from hessboost import conformal, diffusion, ebm, folds, inference, online
27
+ from hessboost import conformal, diffusion, ebm, folds, inference, online, target_stats
27
28
  from hessboost._booster import (
28
29
  Booster,
30
+ CompactModel,
29
31
  Distributions,
30
32
  GpuModel,
31
33
  ImportanceType,
32
34
  ModelFormat,
35
+ ModelSizeReport,
33
36
  )
34
37
  from hessboost._core import Uncertainty
35
38
  from hessboost._exceptions import (
@@ -46,6 +49,7 @@ from hessboost._training import (
46
49
  TrainingCallback,
47
50
  cv,
48
51
  train,
52
+ train_with_budget,
49
53
  )
50
54
 
51
55
  __version__: str = _version("hessboost")
@@ -53,6 +57,7 @@ __version__: str = _version("hessboost")
53
57
 
54
58
  __all__ = [
55
59
  "Booster",
60
+ "CompactModel",
56
61
  "CustomMetric",
57
62
  "DMatrix",
58
63
  "Distributions",
@@ -64,6 +69,7 @@ __all__ = [
64
69
  "InvalidDataError",
65
70
  "ModelFormat",
66
71
  "ModelFormatError",
72
+ "ModelSizeReport",
67
73
  "Objective",
68
74
  "TrainingCallback",
69
75
  "Uncertainty",
@@ -75,5 +81,7 @@ __all__ = [
75
81
  "folds",
76
82
  "inference",
77
83
  "online",
84
+ "target_stats",
78
85
  "train",
86
+ "train_with_budget",
79
87
  ]
@@ -1,10 +1,11 @@
1
1
  """``Booster``, exported from :mod:`hessboost`, with its prediction and
2
- model-format types."""
2
+ model-format types, and the compact and GPU layouts a booster converts to."""
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
6
  import os
7
7
  from collections.abc import Sequence
8
+ from dataclasses import dataclass
8
9
  from typing import TYPE_CHECKING, Any, Literal, TypeAlias, overload
9
10
 
10
11
  import numpy as np
@@ -22,10 +23,12 @@ if TYPE_CHECKING:
22
23
 
23
24
  __all__ = [
24
25
  "Booster",
26
+ "CompactModel",
25
27
  "Distributions",
26
28
  "GpuModel",
27
29
  "ImportanceType",
28
30
  "ModelFormat",
31
+ "ModelSizeReport",
29
32
  ]
30
33
 
31
34
  Distributions = _hessboost.Distributions
@@ -61,6 +64,42 @@ def _format_for(path: PathLike, format: ModelFormat | None) -> ModelFormat:
61
64
  return "binary"
62
65
 
63
66
 
67
+ @dataclass(frozen=True)
68
+ class ModelSizeReport:
69
+ """A booster's size in the native binary and compact formats, with the
70
+ dictionary statistics of the *Trees on a Diet* paper, from
71
+ :meth:`Booster.size_report`."""
72
+
73
+ native_bytes: int
74
+ """The native binary model's size (every tree, covers and gains included)."""
75
+ compact_bytes: int
76
+ """The compact model's size."""
77
+ trees: int
78
+ """The trees the compact model stores (those prediction uses)."""
79
+ splits: int
80
+ """Split nodes across those trees."""
81
+ leaves: int
82
+ """Leaves across those trees."""
83
+ used_features: int
84
+ """Features the trees split on."""
85
+ thresholds: int
86
+ """Distinct thresholds and categorical sets, over every used feature."""
87
+ leaf_values: int
88
+ """Distinct leaf values."""
89
+
90
+ @property
91
+ def compression_ratio(self) -> float:
92
+ """``native_bytes / compact_bytes``."""
93
+ return self.native_bytes / self.compact_bytes
94
+
95
+ @property
96
+ def reuse_factor(self) -> float:
97
+ """Nodes per distinct dictionary entry, ``(splits + leaves) /
98
+ (thresholds + leaf_values)``: how often each threshold or leaf value
99
+ is shared."""
100
+ return (self.splits + self.leaves) / max(self.thresholds + self.leaf_values, 1)
101
+
102
+
64
103
  class Booster(_SchemaState):
65
104
  """A trained gradient-boosting model, as XGBoost's ``xgboost.Booster``.
66
105
 
@@ -160,6 +199,38 @@ class Booster(_SchemaState):
160
199
  """The number of features the model takes."""
161
200
  return self._model.num_features
162
201
 
202
+ def num_trees(self) -> int:
203
+ """The number of trees (``num_boosted_rounds() * trees per
204
+ iteration``; the column count of ``pred_leaf``)."""
205
+ return self._model.num_trees
206
+
207
+ @property
208
+ def num_outputs(self) -> int:
209
+ """Raw outputs (margins) per row: ``num_class`` for multiclass, one
210
+ per target or quantile otherwise."""
211
+ return self._model.num_outputs
212
+
213
+ @property
214
+ def num_targets(self) -> int:
215
+ """Label columns the model was trained on."""
216
+ return self._model.num_targets
217
+
218
+ @property
219
+ def num_parallel_tree(self) -> int:
220
+ """Trees per output per iteration (a boosted forest's size)."""
221
+ return self._model.num_parallel_tree
222
+
223
+ @property
224
+ def base_margins(self) -> list[float]:
225
+ """The per-output intercepts, in margin space."""
226
+ return self._model.base_margins
227
+
228
+ @property
229
+ def vector_leaves(self) -> bool:
230
+ """Whether each tree predicts every output (``multi_strategy=
231
+ "multi_output_tree"``), rather than one output per tree."""
232
+ return self._model.vector_leaves
233
+
163
234
  def _matrix(
164
235
  self, data: object, base_margin: ArrayLike | None, missing: float, validate: bool = True
165
236
  ) -> _hessboost.DMatrix:
@@ -258,6 +329,31 @@ class Booster(_SchemaState):
258
329
  """
259
330
  return GpuModel._wrap(self._model.to_gpu(), self)
260
331
 
332
+ def to_compact(self) -> CompactModel:
333
+ """This model in the bit-packed compact layout (*Boosted Trees on a
334
+ Diet*), for memory-constrained inference: it predicts bit-identical
335
+ values and margins to :meth:`predict` with the default iterations
336
+ (through :attr:`best_iteration`), and stores only those trees,
337
+ without covers and gains. Training with ``toad_penalty_feature`` and
338
+ ``toad_penalty_threshold`` shrinks it further. The compact model
339
+ keeps this booster's feature names and categories.
340
+
341
+ Raises:
342
+ HessboostError: The model is ``gblinear``, has ``linear_tree`` or
343
+ vector leaves, or splits one feature both numerically and
344
+ categorically.
345
+ """
346
+ return CompactModel._wrap(self._model.to_compact(), self)
347
+
348
+ def size_report(self) -> ModelSizeReport:
349
+ """This model's native binary versus compact size, with the compact
350
+ layout's dictionary statistics.
351
+
352
+ Raises:
353
+ HessboostError: As :meth:`to_compact`.
354
+ """
355
+ return ModelSizeReport(**self._model.size_report())
356
+
261
357
  def predict_distribution(
262
358
  self,
263
359
  data: object,
@@ -517,3 +613,151 @@ class GpuModel:
517
613
  matrix = model._matrix(data, base_margin, missing, validate_features)
518
614
  kind = "margin" if output_margin else "value"
519
615
  return self._core.predict(matrix, kind, Booster._range(iteration_range))
616
+
617
+
618
+ class CompactModel(_SchemaState):
619
+ """A tree ensemble in hessboost's bit-packed compact format (``HBTD``,
620
+ *Boosted Trees on a Diet*), predicting bit-identical values and margins
621
+ to the :class:`Booster` it came from while taking a fraction of its
622
+ size. It predicts straight from the packed trees; it has no SHAP, leaf
623
+ or iteration-range predictions (only the trees default prediction uses
624
+ are stored). XGBoost cannot read the format.
625
+
626
+ Get one from :meth:`Booster.to_compact`, or load a saved one with
627
+ ``CompactModel(model_file)``.
628
+
629
+ Args:
630
+ model_file: A path or the bytes of a compact model
631
+ (:meth:`save_model`/:meth:`save_raw`).
632
+
633
+ Raises:
634
+ ModelFormatError: The content is not a valid compact model.
635
+ OSError: The file cannot be read.
636
+ """
637
+
638
+ __module__ = "hessboost"
639
+
640
+ _core: _hessboost.CompactModel
641
+
642
+ def __init__(self, model_file: PathLike | bytes | bytearray | memoryview) -> None:
643
+ data = (
644
+ bytes(model_file)
645
+ if isinstance(model_file, (bytes, bytearray, memoryview))
646
+ else read_bytes(model_file)
647
+ )
648
+ self._core = _hessboost.CompactModel.load(data)
649
+ self._set_schema(None, None, {})
650
+
651
+ @classmethod
652
+ def _wrap(cls, core: _hessboost.CompactModel, booster: Booster) -> CompactModel:
653
+ model = cls.__new__(cls)
654
+ model._core = core
655
+ model._set_schema(booster._feature_names, booster._feature_types, dict(booster._categories))
656
+ return model
657
+
658
+ @property
659
+ def feature_names(self) -> list[str] | None:
660
+ """The training features' names, if known (not stored in the file;
661
+ pickling keeps them). Assignable, as :attr:`Booster.feature_names`."""
662
+ return None if self._feature_names is None else list(self._feature_names)
663
+
664
+ @feature_names.setter
665
+ def feature_names(self, names: Sequence[str] | None) -> None:
666
+ self._feature_names = (
667
+ None if names is None else _data._check_names(names, self.num_features())
668
+ )
669
+
670
+ @property
671
+ def feature_types(self) -> list[str] | None:
672
+ """``"q"``/``"c"`` per training feature, if known."""
673
+ return None if self._feature_types is None else list(self._feature_types)
674
+
675
+ @property
676
+ def objective(self) -> str:
677
+ """The objective that drives :meth:`predict`."""
678
+ return self._core.objective
679
+
680
+ def num_features(self) -> int:
681
+ """The number of features the model takes."""
682
+ return self._core.num_features
683
+
684
+ def num_trees(self) -> int:
685
+ """The number of stored trees."""
686
+ return self._core.num_trees
687
+
688
+ @property
689
+ def num_outputs(self) -> int:
690
+ """Raw outputs (margins) per row."""
691
+ return self._core.num_outputs
692
+
693
+ @property
694
+ def size_bytes(self) -> int:
695
+ """The serialized size in bytes."""
696
+ return self._core.size_bytes
697
+
698
+ @property
699
+ def used_features(self) -> list[int]:
700
+ """The indices of the features the trees split on, ascending."""
701
+ return self._core.used_features
702
+
703
+ @property
704
+ def num_thresholds(self) -> int:
705
+ """Distinct thresholds and categorical sets, over every used feature."""
706
+ return self._core.num_thresholds
707
+
708
+ @property
709
+ def num_leaf_values(self) -> int:
710
+ """Distinct leaf values."""
711
+ return self._core.num_leaf_values
712
+
713
+ def predict(
714
+ self,
715
+ data: object,
716
+ *,
717
+ output_margin: bool = False,
718
+ validate_features: bool = True,
719
+ base_margin: ArrayLike | None = None,
720
+ missing: float = np.nan,
721
+ ) -> NDArray[np.float32]:
722
+ """Predicts every row of ``data`` (a :class:`DMatrix` or anything
723
+ its constructor accepts; frames are re-coded to the model's
724
+ categories): the objective's predictions or, with ``output_margin``,
725
+ raw margins, ``(rows,)`` or ``(rows, K)`` for ``K`` outputs,
726
+ bit-identical to :meth:`Booster.predict`.
727
+
728
+ Args:
729
+ validate_features: Refuse data whose feature names differ from
730
+ the model's.
731
+ base_margin: Starting margins for array input (a
732
+ :class:`DMatrix` carries its own).
733
+ missing: The missing-value marker for array input.
734
+ """
735
+ matrix = _matrix_for(
736
+ data,
737
+ ((self, "the model's"),),
738
+ base_margin=base_margin,
739
+ missing=missing,
740
+ validate_names=validate_features,
741
+ )
742
+ return self._core.predict(matrix._core, output_margin)
743
+
744
+ def save_raw(self) -> bytes:
745
+ """The serialized model."""
746
+ return self._core.save()
747
+
748
+ def save_model(self, fname: PathLike) -> None:
749
+ """Writes the model to ``fname``. Feature names and categories are
750
+ not part of the format; pickle the model to keep them."""
751
+ write_bytes(fname, self.save_raw())
752
+
753
+ def _model_state(self) -> bytes:
754
+ return self._core.save()
755
+
756
+ def _restore_model(self, model: bytes) -> None:
757
+ self._core = _hessboost.CompactModel.load(model)
758
+
759
+ def __repr__(self) -> str:
760
+ return (
761
+ f"CompactModel(objective={self.objective!r}, trees={self.num_trees()}, "
762
+ f"features={self.num_features()}, bytes={self.size_bytes})"
763
+ )
@@ -5,7 +5,7 @@ and polars frames, scipy sparse matrices, array-likes) into the row-major
5
5
  from __future__ import annotations
6
6
 
7
7
  import sys
8
- from collections.abc import Mapping, Sequence
8
+ from collections.abc import Collection, Mapping, Sequence
9
9
  from dataclasses import dataclass
10
10
  from typing import TYPE_CHECKING, Any, TypeAlias, TypeGuard
11
11
 
@@ -130,11 +130,16 @@ def _categorical_columns(feature_types: Sequence[str], n_cols: int) -> list[int]
130
130
 
131
131
 
132
132
  def _pandas_frame_values(
133
- frame: pd.DataFrame, enable_categorical: bool, reference: Categories | None
133
+ frame: pd.DataFrame,
134
+ enable_categorical: bool,
135
+ reference: Categories | None,
136
+ unseen: Collection[int] = (),
134
137
  ) -> tuple[NDArray[np.float32], list[str], FeatureTypes, Categories]:
135
138
  """A pandas frame's values as ``float32``: numeric and boolean columns as is
136
139
  (``NA`` missing), category columns as their codes (``NaN`` missing),
137
- re-coded to the ``reference`` categories of a trained model."""
140
+ re-coded to the ``reference`` categories of a trained model. A value the
141
+ reference lacks is missing, except in the ``unseen`` columns, where it
142
+ gets the code one past the reference's categories."""
138
143
  pd = _pandas()
139
144
  rows, cols = frame.shape
140
145
  values = np.empty((rows, cols), dtype=np.float32)
@@ -151,7 +156,14 @@ def _pandas_frame_values(
151
156
  if wanted is not None and wanted != known:
152
157
  # Old code -> position in the training categories (-1: unseen).
153
158
  recode = pd.Index(wanted).get_indexer(dtype.categories)
154
- codes = np.where(codes >= 0, recode[codes], -1)
159
+ if column in unseen:
160
+ recode = np.where(recode >= 0, recode, len(wanted))
161
+ # Only present codes index `recode`, which is empty when
162
+ # the frame's categories are.
163
+ present = codes >= 0
164
+ recoded = np.full(codes.shape, -1, dtype=np.int64)
165
+ recoded[present] = recode[codes[present]]
166
+ codes = recoded
155
167
  known = wanted
156
168
  column_values = codes.astype(np.float32)
157
169
  column_values[codes < 0] = np.nan
@@ -171,14 +183,19 @@ def _pandas_frame_values(
171
183
 
172
184
 
173
185
  def _polars_frame_values(
174
- frame: pl.DataFrame, enable_categorical: bool, reference: Categories | None
186
+ frame: pl.DataFrame,
187
+ enable_categorical: bool,
188
+ reference: Categories | None,
189
+ unseen: Collection[int] = (),
175
190
  ) -> tuple[NDArray[np.float32], list[str], FeatureTypes, Categories]:
176
191
  """A polars frame's values as ``float32``: numeric and boolean columns as
177
192
  is (null missing), ``Enum`` and ``Categorical`` columns as positions in
178
193
  their categories (null missing), re-coded to the ``reference``
179
- categories of a trained model. An ``Enum``'s categories are its
180
- dtype's; a ``Categorical``'s are its values, sorted (as pandas infers
181
- them), since its physical codes index a pool other columns share."""
194
+ categories of a trained model (a value they lack is missing, except in
195
+ the ``unseen`` columns, where it gets the code one past them). An
196
+ ``Enum``'s categories are its dtype's; a ``Categorical``'s are its
197
+ values, sorted (as pandas infers them), since its physical codes index
198
+ a pool other columns share."""
182
199
  pl = _polars()
183
200
  rows, cols = frame.shape
184
201
  values = np.empty((rows, cols), dtype=np.float32)
@@ -202,13 +219,16 @@ def _polars_frame_values(
202
219
  positions = [
203
220
  (value, code) for code, value in enumerate(known) if isinstance(value, str)
204
221
  ]
222
+ other = float(len(known)) if wanted is not None and column in unseen else None
205
223
  codes = strings.replace_strict(
206
224
  [value for value, _ in positions],
207
225
  [code for _, code in positions],
208
- default=None,
226
+ default=other,
209
227
  return_dtype=pl.Float32,
210
228
  )
211
- column_values = codes.to_numpy()
229
+ column_values = codes.to_numpy(writable=other is not None)
230
+ if other is not None:
231
+ column_values[strings.is_null().to_numpy()] = np.nan
212
232
  types.append("c")
213
233
  categories[column] = known
214
234
  elif dtype.is_numeric() or dtype == pl.Boolean:
@@ -232,10 +252,13 @@ def features(
232
252
  enable_categorical: bool,
233
253
  reference: Categories | None,
234
254
  info: Mapping[str, object],
255
+ unseen: Collection[int] = (),
235
256
  ) -> Features:
236
257
  """Converts ``data`` and builds the native matrix with ``info``
237
258
  attached. ``reference`` holds a trained model's categories, to which
238
- frame categorical columns are re-coded."""
259
+ frame categorical columns are re-coded; values it lacks are missing,
260
+ except in the ``unseen`` columns, where they are coded one past its
261
+ categories (a target encoder's unseen category)."""
239
262
  names: list[str] | None = None
240
263
  types: FeatureTypes | None = None
241
264
  categories: Categories = {}
@@ -244,10 +267,14 @@ def features(
244
267
  n_cols = int(csr.shape[1])
245
268
  values = None
246
269
  elif _is_pandas_frame(data):
247
- values, names, types, categories = _pandas_frame_values(data, enable_categorical, reference)
270
+ values, names, types, categories = _pandas_frame_values(
271
+ data, enable_categorical, reference, unseen
272
+ )
248
273
  n_cols = values.shape[1]
249
274
  elif _is_polars_frame(data):
250
- values, names, types, categories = _polars_frame_values(data, enable_categorical, reference)
275
+ values, names, types, categories = _polars_frame_values(
276
+ data, enable_categorical, reference, unseen
277
+ )
251
278
  n_cols = values.shape[1]
252
279
  else:
253
280
  values = as_float32(data, "data")