lecrapaud 0.19.1__tar.gz → 0.19.3__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 (48) hide show
  1. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/PKG-INFO +3 -2
  2. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/api.py +3 -0
  3. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/experiment.py +1 -1
  4. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/feature_engineering.py +2 -0
  5. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/model_selection.py +65 -5
  6. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/pyproject.toml +1 -1
  7. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/LICENSE +0 -0
  8. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/README.md +0 -0
  9. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/__init__.py +0 -0
  10. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/config.py +0 -0
  11. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/__init__.py +0 -0
  12. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/README +0 -0
  13. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/env.py +0 -0
  14. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/script.py.mako +0 -0
  15. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/versions/2025_06_23_1748-f089dfb7e3ba_.py +0 -0
  16. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/versions/2025_06_24_1216-c62251b129ed_.py +0 -0
  17. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/versions/2025_06_24_1711-86457e2f333f_.py +0 -0
  18. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/versions/2025_06_25_1759-72aa496ca65b_.py +0 -0
  19. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/versions/2025_08_25_1434-7ed9963e732f_add_best_score_to_model_selection.py +0 -0
  20. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/versions/2025_08_28_1516-c36e9fee22b9_add_avg_precision_to_score.py +0 -0
  21. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic/versions/2025_08_28_1622-8b11c1ba982e_change_name_column.py +0 -0
  22. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/alembic.ini +0 -0
  23. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/__init__.py +0 -0
  24. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/base.py +0 -0
  25. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/experiment.py +0 -0
  26. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/feature.py +0 -0
  27. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/feature_selection.py +0 -0
  28. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/feature_selection_rank.py +0 -0
  29. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/model.py +0 -0
  30. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/model_selection.py +0 -0
  31. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/model_training.py +0 -0
  32. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/score.py +0 -0
  33. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/target.py +0 -0
  34. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/models/utils.py +0 -0
  35. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/db/session.py +0 -0
  36. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/directories.py +0 -0
  37. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/feature_selection.py +0 -0
  38. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/integrations/openai_integration.py +0 -0
  39. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/jobs/__init__.py +0 -0
  40. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/jobs/config.py +0 -0
  41. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/jobs/scheduler.py +0 -0
  42. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/jobs/tasks.py +0 -0
  43. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/misc/tabpfn_tests.ipynb +0 -0
  44. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/misc/test-gpu-bilstm.ipynb +0 -0
  45. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/misc/test-gpu-resnet.ipynb +0 -0
  46. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/misc/test-gpu-transformers.ipynb +0 -0
  47. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/search_space.py +0 -0
  48. {lecrapaud-0.19.1 → lecrapaud-0.19.3}/lecrapaud/utils.py +0 -0
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: lecrapaud
3
- Version: 0.19.1
3
+ Version: 0.19.3
4
4
  Summary: Framework for machine and deep learning, with regression, classification and time series analysis
5
5
  License: Apache License
6
+ License-File: LICENSE
6
7
  Author: Pierre H. Gallet
7
8
  Requires-Python: ==3.12.*
8
9
  Classifier: License :: Other/Proprietary License
@@ -475,6 +475,9 @@ class ExperimentEngine:
475
475
  # For lightgbm models
476
476
  importances = model.feature_importance(importance_type="split")
477
477
  importance_type = "Split"
478
+ elif hasattr(model, "get_feature_importance"):
479
+ importances = model.get_feature_importance()
480
+ importance_type = "Feature importance"
478
481
  elif hasattr(model, "coef_"):
479
482
  # For linear models
480
483
  importances = np.abs(model.coef_.flatten())
@@ -35,7 +35,7 @@ def create_experiment(
35
35
  groups = {}
36
36
  if group_column:
37
37
  groups["number_of_groups"] = data[group_column].nunique()
38
- groups["list_of_groups"] = data[group_column].unique().tolist().sort()
38
+ groups["list_of_groups"] = sorted(data[group_column].unique().tolist())
39
39
 
40
40
  with get_db() as db:
41
41
  all_targets = Target.get_all(db=db)
@@ -629,6 +629,7 @@ class PreprocessFeature:
629
629
  """
630
630
 
631
631
  pcas_dict = {}
632
+ index_saved = df.index
632
633
 
633
634
  for pca_cross_sectional in self.pca_cross_sectional:
634
635
  name, index_col, columns_col, value_col = (
@@ -659,6 +660,7 @@ class PreprocessFeature:
659
660
  scores_df = pd.DataFrame(scores, index=pivot.index, columns=cols)
660
661
 
661
662
  df = df.merge(scores_df.reset_index(), on=index_col, how="left")
663
+ df.index = index_saved
662
664
  pcas_dict.update({name: pipe})
663
665
 
664
666
  return df, pcas_dict
@@ -110,6 +110,63 @@ def test_hardware():
110
110
  warnings.filterwarnings("ignore", category=UserWarning, module="pydantic")
111
111
 
112
112
 
113
+ class CatBoostWrapper:
114
+ """
115
+ Transparent proxy for a CatBoost model that accepts arbitrary keyword arguments
116
+ as direct attributes, while forwarding all method calls and properties.
117
+ """
118
+
119
+ __slots__ = ("_model", "_extra_attrs")
120
+
121
+ def __init__(self, model, **kwargs):
122
+ object.__setattr__(self, "_model", model)
123
+ object.__setattr__(self, "_extra_attrs", {})
124
+ # Register kwargs as direct attributes
125
+ for key, value in kwargs.items():
126
+ setattr(self, key, value)
127
+
128
+ # ---- Transparent access ----
129
+ def __getattr__(self, name):
130
+ """Forward attribute access to the underlying model if not found."""
131
+ model = object.__getattribute__(self, "_model")
132
+ if hasattr(model, name):
133
+ return getattr(model, name)
134
+ extra_attrs = object.__getattribute__(self, "_extra_attrs")
135
+ if name in extra_attrs:
136
+ return extra_attrs[name]
137
+ raise AttributeError(f"{type(self).__name__!r} has no attribute {name!r}")
138
+
139
+ def __setattr__(self, name, value):
140
+ """Set to wrapper or forward to model when appropriate."""
141
+ if name in CatBoostWrapper.__slots__:
142
+ object.__setattr__(self, name, value)
143
+ return
144
+
145
+ model = object.__getattribute__(self, "_model")
146
+ if hasattr(model, name):
147
+ setattr(model, name, value)
148
+ else:
149
+ extra_attrs = object.__getattribute__(self, "_extra_attrs")
150
+ extra_attrs[name] = value
151
+
152
+ def __dir__(self):
153
+ """Merge dir() from wrapper, model, and custom attributes."""
154
+ base = set(super().__dir__())
155
+ model_attrs = set(dir(object.__getattribute__(self, "_model")))
156
+ extra_attrs = set(object.__getattribute__(self, "_extra_attrs").keys())
157
+ return sorted(base | model_attrs | extra_attrs)
158
+
159
+ def __repr__(self):
160
+ model = object.__getattribute__(self, "_model")
161
+ extras = object.__getattribute__(self, "_extra_attrs")
162
+ return f"CatBoostWrapper(model={model.__class__.__name__}, extras={extras})"
163
+
164
+ @property
165
+ def model(self):
166
+ """Access the raw CatBoost model."""
167
+ return object.__getattribute__(self, "_model")
168
+
169
+
113
170
  class ModelEngine:
114
171
 
115
172
  def __init__(
@@ -296,12 +353,15 @@ class ModelEngine:
296
353
  )
297
354
 
298
355
  # Attach metadata for consistency with sklearn path
299
- model.model_name = self.model_name
300
- model.target_type = self.target_type
301
- logger.info(f"Successfully created a {model.model_name} at {datetime.now()}")
356
+ model_wrapped = CatBoostWrapper(
357
+ model, model_name=self.model_name, target_type=self.target_type
358
+ )
359
+ logger.info(
360
+ f"Successfully created a {model_wrapped.model_name} at {datetime.now()}"
361
+ )
302
362
 
303
- self._model = model
304
- return model
363
+ self._model = model_wrapped
364
+ return model_wrapped
305
365
 
306
366
  def fit_boosting(self, x_train, y_train, x_val, y_val, params):
307
367
  """
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lecrapaud"
3
- version = "0.19.1"
3
+ version = "0.19.3"
4
4
  description = "Framework for machine and deep learning, with regression, classification and time series analysis"
5
5
  authors = [
6
6
  {name = "Pierre H. Gallet"}
File without changes
File without changes