dragon-ml-toolbox 3.12.1__py3-none-any.whl → 3.12.3__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.

Potentially problematic release.


This version of dragon-ml-toolbox might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dragon-ml-toolbox
3
- Version: 3.12.1
3
+ Version: 3.12.3
4
4
  Summary: A collection of tools for data science and machine learning projects.
5
5
  Author-email: Karl Loza <luigiloza@gmail.com>
6
6
  License-Expression: MIT
@@ -1,7 +1,7 @@
1
- dragon_ml_toolbox-3.12.1.dist-info/licenses/LICENSE,sha256=2uUFNy7D0TLgHim1K5s3DIJ4q_KvxEXVilnU20cWliY,1066
2
- dragon_ml_toolbox-3.12.1.dist-info/licenses/LICENSE-THIRD-PARTY.md,sha256=lY4_rJPnLnMu7YBQaY-_iz1JRDcLdQzNCyeLAF1glJY,1837
1
+ dragon_ml_toolbox-3.12.3.dist-info/licenses/LICENSE,sha256=2uUFNy7D0TLgHim1K5s3DIJ4q_KvxEXVilnU20cWliY,1066
2
+ dragon_ml_toolbox-3.12.3.dist-info/licenses/LICENSE-THIRD-PARTY.md,sha256=lY4_rJPnLnMu7YBQaY-_iz1JRDcLdQzNCyeLAF1glJY,1837
3
3
  ml_tools/ETL_engineering.py,sha256=yeZsW_7zRvEcuMZbM4E2GV1dxwBoWIeJAcFFk2AK0fY,39502
4
- ml_tools/GUI_tools.py,sha256=VonZEizPS0ncm8HWU-ik-SgcXKryJU8eSG7NN0QN9cc,42222
4
+ ml_tools/GUI_tools.py,sha256=gaLL4_fMQoKLreql0Jkz8fiYeeEfCmgxht-zE7pstAU,43024
5
5
  ml_tools/MICE_imputation.py,sha256=7CDsIQxx5Jb_DwPAmWmz3FXcn85sUyH7g9UcZ1_E07s,11412
6
6
  ml_tools/ML_callbacks.py,sha256=g_9nSzoA22UJOQZCPKeDz-Ayh0ECFZLzRd6rZ8SokrE,13080
7
7
  ml_tools/ML_evaluation.py,sha256=oiDV6HItQloUUKCUpltV-2pogubWLBieGpc-VUwosAQ,10106
@@ -16,11 +16,11 @@ ml_tools/data_exploration.py,sha256=ZpjK_lN5mDhjf9iQpvyYNA2SF7M5q4D5m09saln7YFI,
16
16
  ml_tools/datasetmaster.py,sha256=S3PKHNQZ9cyAOck8xQltVLZhaD1gFLfgHFL-aRjz4JU,30077
17
17
  ml_tools/ensemble_learning.py,sha256=D-9IbOKtCvyAB-LbPu3sdSRtdp0RZIcQEZcyMnarHmQ,45758
18
18
  ml_tools/handle_excel.py,sha256=2Q_MBArss4emPQ8p-Uj9x_e7wGg3OoYM2AU_HG59UCY,12978
19
- ml_tools/keys.py,sha256=A3mLrtLZrxL27whAs2F1GPqZ1KzJpxBp6QbhxY5ioPI,636
19
+ ml_tools/keys.py,sha256=3YVbcYARSjE3vKr_6PavJSf7vXvlos7szu3qva4T3Ts,781
20
20
  ml_tools/logger.py,sha256=UkbiU9ihBhw9VKyn3rZzisdClWV94EBV6B09_D0iUU0,6026
21
21
  ml_tools/path_manager.py,sha256=1LD9JFzqVyJQl2kTA7tK930_IV3qxfiV4cMIBzItytY,8309
22
22
  ml_tools/utilities.py,sha256=Vh4ZdI03g8EpgQL7KDwnAw2vtBlHtx6KxCuAATxLvT4,24208
23
- dragon_ml_toolbox-3.12.1.dist-info/METADATA,sha256=vwEN95BhK71LrhuuTuZbxdyfdq_X5VljuP89uXNguok,3274
24
- dragon_ml_toolbox-3.12.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- dragon_ml_toolbox-3.12.1.dist-info/top_level.txt,sha256=wm-oxax3ciyez6VoO4zsFd-gSok2VipYXnbg3TH9PtU,9
26
- dragon_ml_toolbox-3.12.1.dist-info/RECORD,,
23
+ dragon_ml_toolbox-3.12.3.dist-info/METADATA,sha256=bTM7I5KBW1RWC4Sx1KSfx9Lj5KkIOvZ47HPMVNf7S_Y,3274
24
+ dragon_ml_toolbox-3.12.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
+ dragon_ml_toolbox-3.12.3.dist-info/top_level.txt,sha256=wm-oxax3ciyez6VoO4zsFd-gSok2VipYXnbg3TH9PtU,9
26
+ dragon_ml_toolbox-3.12.3.dist-info/RECORD,,
ml_tools/GUI_tools.py CHANGED
@@ -7,6 +7,7 @@ from typing import Any, Dict, Tuple, List, Literal, Union, Optional, Callable
7
7
  from .utilities import _script_info
8
8
  import numpy as np
9
9
  from .logger import _LOGGER
10
+ from .keys import _OneHotOtherPlaceholder
10
11
 
11
12
 
12
13
  __all__ = [
@@ -74,34 +75,35 @@ class ConfigManager:
74
75
  setattr(self, section.lower(), _SectionProxy(parser, section))
75
76
 
76
77
  @staticmethod
77
- def generate_template(file_path: str | Path, force_overwrite: bool = False):
78
+ def generate_template(file_path: str | Path):
78
79
  """
79
80
  Generates a complete, commented .ini template file that works with the GUIFactory.
80
81
 
81
82
  Args:
82
83
  file_path (str | Path): The path where the .ini file will be saved.
83
- force_overwrite (bool): If True, overwrites the file if it already exists.
84
84
  """
85
+ if isinstance(file_path, str):
86
+ if not file_path.endswith(".ini"):
87
+ file_path = file_path + ".ini"
88
+
85
89
  path = Path(file_path)
86
- if path.exists() and not force_overwrite:
87
- _LOGGER.warning(f"⚠️ Configuration file already exists at {path}. Aborting.")
90
+ if path.exists():
91
+ _LOGGER.warning(f"⚠️ Configuration file already exists at {path}, or wrong path provided. Aborting.")
88
92
  return
89
93
 
90
94
  config = configparser.ConfigParser()
91
95
 
92
96
  config['General'] = {
93
- '; The overall theme for the GUI. Find more at https://www.pysimplegui.org/en/latest/call%20reference/#themes-automatic-coloring-of-elements': '',
97
+ '; The overall theme for the GUI.': '',
94
98
  'theme': 'LightGreen6',
95
- '; Default font for the application.': '',
96
- 'font_family': 'Helvetica',
97
99
  '; Title of the main window.': '',
98
100
  'window_title': 'My Application',
99
101
  '; Can the user resize the window? (true/false)': '',
100
102
  'resizable_window': 'false',
101
103
  '; Optional minimum window size (width,height). Leave blank for no minimum.': '',
102
- 'min_size': '800,600',
104
+ 'min_size': '1280,720',
103
105
  '; Optional maximum window size (width,height). Leave blank for no maximum.': '',
104
- 'max_size': ''
106
+ 'max_size': '2048,1152'
105
107
  }
106
108
  config['Layout'] = {
107
109
  '; Default size for continuous input boxes (width,height in characters/rows).': '',
@@ -114,15 +116,17 @@ class ConfigManager:
114
116
  'button_size': '15,2'
115
117
  }
116
118
  config['Fonts'] = {
119
+ '; Default font for the application.': '',
120
+ 'font_family': 'Helvetica',
117
121
  '; Font settings. Style can be "bold", "italic", "underline", or a combination.': '',
118
122
  'label_size': '11',
119
123
  'label_style': 'bold',
120
124
  'range_size': '9',
121
- 'range_style': '',
125
+ 'range_style': '""',
122
126
  'button_size': '14',
123
127
  'button_style': 'bold',
124
128
  'frame_size': '14',
125
- 'frame_style': ''
129
+ 'frame_style': '""'
126
130
  }
127
131
  config['Colors'] = {
128
132
  '; Use standard hex codes (e.g., #FFFFFF) or color names (e.g., white).': '',
@@ -159,7 +163,7 @@ class GUIFactory:
159
163
  """
160
164
  self.config = config
161
165
  sg.theme(self.config.general.theme) # type: ignore
162
- sg.set_options(font=(self.config.general.font_family, 12)) # type: ignore
166
+ sg.set_options(font=(self.config.fonts.font_family, 12)) # type: ignore
163
167
 
164
168
  # --- Atomic Element Generators ---
165
169
  def make_button(self, text: str, key: str, **kwargs) -> sg.Button:
@@ -254,7 +258,7 @@ class GUIFactory:
254
258
  layout = [[label], [element]]
255
259
  else:
256
260
  range_font = (cfg.fonts.font_family, cfg.fonts.range_size) # type: ignore
257
- range_text = sg.Text(f"Range: {int(val_min)}-{int(val_max)}", font=range_font, background_color=bg_color) # type: ignore
261
+ range_text = sg.Text(f"Range: {val_min}-{val_max}", font=range_font, background_color=bg_color) # type: ignore
258
262
  layout = [[label], [element], [range_text]]
259
263
 
260
264
  # each feature is wrapped as a column element
@@ -416,7 +420,7 @@ class FeatureMaster:
416
420
 
417
421
  This class serves as a centralized registry for all features and targets
418
422
  used by a model. It is designed to bridge the gap between a user-facing
419
- application (like a GUI) and the underlying model's data representation.
423
+ application (GUI) and the underlying model's data representation.
420
424
 
421
425
  It takes various types of features (continuous, binary, one-hot encoded,
422
426
  categorical) and targets, processing them into two key formats:
@@ -439,7 +443,8 @@ class FeatureMaster:
439
443
  binary_features: Optional[Dict[str, str]] = None,
440
444
  multi_binary_features: Optional[Dict[str, Dict[str, str]]] = None,
441
445
  one_hot_features: Optional[Dict[str, Dict[str, str]]] = None,
442
- categorical_features: Optional[List[Tuple[str, str, Dict[str, int]]]] = None) -> None:
446
+ categorical_features: Optional[List[Tuple[str, str, Dict[str, int]]]] = None,
447
+ add_one_hot_other_placeholder: bool = True) -> None:
443
448
  """
444
449
  Initializes the FeatureMaster instance by processing feature and target definitions.
445
450
 
@@ -490,6 +495,9 @@ class FeatureMaster:
490
495
  - `[1]` (str): The model's internal feature name.
491
496
  - `[2]` (Dict[str, int]): A dictionary mapping the user-selectable
492
497
  options to their corresponding integer values.
498
+
499
+ add_one_hot_other_placeholder (bool):
500
+ Add a placeholder for the "Other" option. Used if `drop_first` was used when making the one-hot-encoding to prevent multicollinearity.
493
501
  """
494
502
  # Validation
495
503
  if continuous_features is None and binary_features is None and one_hot_features is None and categorical_features is None and multi_binary_features is None:
@@ -526,7 +534,15 @@ class FeatureMaster:
526
534
  self.has_multi_binary = False
527
535
 
528
536
  # one-hot features
537
+ self._has_one_hot_other = False
529
538
  if one_hot_features is not None:
539
+ # Check for add_other
540
+ if add_one_hot_other_placeholder:
541
+ self._has_one_hot_other = True
542
+ # update OTHER value in-place
543
+ for _gui_name, one_hot_dict in one_hot_features.items():
544
+ one_hot_dict.update(_OneHotOtherPlaceholder.OTHER_DICT)
545
+
530
546
  self._one_hot_values = self._handle_one_hot_features(one_hot_features)
531
547
  self._one_hot_mapping = one_hot_features
532
548
  self.has_one_hot = True
@@ -861,11 +877,17 @@ class GUIHandler:
861
877
  _LOGGER.error(f"No matching name for '{gui_feature}' defined as one-hot.")
862
878
  raise e
863
879
  else:
864
- mapped_chosen_value = one_hot_mapping[chosen_value]
865
880
  # base results mapped to 0
866
881
  results = {model_key: 0 for model_key in one_hot_mapping.values()}
882
+ # get mapped key
883
+ mapped_chosen_value = one_hot_mapping[chosen_value]
867
884
  # update chosen value
868
885
  results[mapped_chosen_value] = 1
886
+
887
+ # check if OTHER was added
888
+ if self.master._has_one_hot_other:
889
+ results.pop(_OneHotOtherPlaceholder.OTHER_MODEL)
890
+
869
891
  return results
870
892
 
871
893
  def _process_categorical(self, gui_feature: str, chosen_value: str) -> Tuple[str,int]:
ml_tools/keys.py CHANGED
@@ -26,3 +26,9 @@ class ModelSaveKeys:
26
26
  # Classification keys
27
27
  CLASSIFICATION_LABEL = "label"
28
28
  CLASSIFICATION_PROBABILITIES = "probabilities"
29
+
30
+
31
+ class _OneHotOtherPlaceholder:
32
+ OTHER_GUI = "OTHER"
33
+ OTHER_MODEL = "one hot OTHER placeholder"
34
+ OTHER_DICT = {OTHER_GUI: OTHER_MODEL}