dragon-ml-toolbox 3.10.0__py3-none-any.whl → 3.10.2__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.10.0
3
+ Version: 3.10.2
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.10.0.dist-info/licenses/LICENSE,sha256=2uUFNy7D0TLgHim1K5s3DIJ4q_KvxEXVilnU20cWliY,1066
2
- dragon_ml_toolbox-3.10.0.dist-info/licenses/LICENSE-THIRD-PARTY.md,sha256=lY4_rJPnLnMu7YBQaY-_iz1JRDcLdQzNCyeLAF1glJY,1837
1
+ dragon_ml_toolbox-3.10.2.dist-info/licenses/LICENSE,sha256=2uUFNy7D0TLgHim1K5s3DIJ4q_KvxEXVilnU20cWliY,1066
2
+ dragon_ml_toolbox-3.10.2.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=ayLwQMkpkFPoun7TxT2Llq5whVIWDjcHXU_ljENvueM,19118
4
+ ml_tools/GUI_tools.py,sha256=bsav1gBo8Pj6bnGo72Bd5RmlZljzVyZrQLLHf6ZZdjM,21500
5
5
  ml_tools/MICE_imputation.py,sha256=rYqvwQDVtoAJJ0agXWoGzoZEHedWiA6QzcEKEIkiZ08,11388
6
6
  ml_tools/ML_callbacks.py,sha256=g_9nSzoA22UJOQZCPKeDz-Ayh0ECFZLzRd6rZ8SokrE,13080
7
7
  ml_tools/ML_evaluation.py,sha256=oiDV6HItQloUUKCUpltV-2pogubWLBieGpc-VUwosAQ,10106
@@ -14,13 +14,13 @@ ml_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  ml_tools/_pytorch_models.py,sha256=bpWZsrSwCvHJQkR6UfoPpElsMv9AvmiNErNHC8NYB_I,10132
15
15
  ml_tools/data_exploration.py,sha256=M7bn2q5XN9zJZJGAmMMFSFFZh8LGzC2arFelrXw3N6Q,25241
16
16
  ml_tools/datasetmaster.py,sha256=S3PKHNQZ9cyAOck8xQltVLZhaD1gFLfgHFL-aRjz4JU,30077
17
- ml_tools/ensemble_learning.py,sha256=Dp3fAzleQxMuMGOgFU4kiAADseIf7D-RBb05KR4tZp8,45637
17
+ ml_tools/ensemble_learning.py,sha256=0Ld6jwVRthG-IgtEKw68Hh1K5G-Jx1Sk5MdXnmvKL9M,45663
18
18
  ml_tools/handle_excel.py,sha256=lwds7rDLlGSCWiWGI7xNg-Z7kxAepogp0lstSFa0590,12949
19
19
  ml_tools/keys.py,sha256=pwn7IkqQ00r1rspq7vV2fHJVSg5TTOQ_cPTqM-PewGE,536
20
20
  ml_tools/logger.py,sha256=UkbiU9ihBhw9VKyn3rZzisdClWV94EBV6B09_D0iUU0,6026
21
21
  ml_tools/path_manager.py,sha256=OCpESgdftbi6mOxetDMIaHhazt4N-W8pJx11X3-yNOs,8305
22
22
  ml_tools/utilities.py,sha256=FW97hMTLLxjDR1so-C-_yDm_iz2z_YfirRXjG_IwSLo,22843
23
- dragon_ml_toolbox-3.10.0.dist-info/METADATA,sha256=tctE4H4aMB8SVNTEwRMOTVhBp0DsbVPrFUAvEmo_tuY,3274
24
- dragon_ml_toolbox-3.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
- dragon_ml_toolbox-3.10.0.dist-info/top_level.txt,sha256=wm-oxax3ciyez6VoO4zsFd-gSok2VipYXnbg3TH9PtU,9
26
- dragon_ml_toolbox-3.10.0.dist-info/RECORD,,
23
+ dragon_ml_toolbox-3.10.2.dist-info/METADATA,sha256=kBiUOEZa1iZ9jl-VzV71G5vhr-qg4-WcmRoyH_fTFgA,3274
24
+ dragon_ml_toolbox-3.10.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
25
+ dragon_ml_toolbox-3.10.2.dist-info/top_level.txt,sha256=wm-oxax3ciyez6VoO4zsFd-gSok2VipYXnbg3TH9PtU,9
26
+ dragon_ml_toolbox-3.10.2.dist-info/RECORD,,
ml_tools/GUI_tools.py CHANGED
@@ -389,23 +389,73 @@ class BaseFeatureHandler(ABC):
389
389
 
390
390
  Should return a dictionary mapping each GUI input name to its type ('continuous' or 'categorical').
391
391
 
392
+ _Example:_
392
393
  ```python
393
- #Example:
394
- {'temperature': 'continuous', 'material_type': 'categorical'}
394
+ {
395
+ 'Temperature': 'continuous',
396
+ 'Material Type': 'categorical'
397
+ }
398
+ ```
399
+ """
400
+ pass
401
+
402
+ @property
403
+ @abstractmethod
404
+ def map_gui_to_real(self) -> Dict[str,str]:
405
+ """
406
+ Must be implemented by the subclass.
407
+
408
+ Should return a dictionary mapping each GUI continuous feature name to its expected model feature name.
409
+
410
+ _Example:_
411
+ ```python
412
+ {
413
+ 'Temperature (K)': 'temperature_k',
414
+ 'Pressure (Pa)': 'pressure_pa'
415
+ }
395
416
  ```
396
417
  """
397
418
  pass
398
419
 
399
420
  @abstractmethod
400
- def process_categorical(self, feature_name: str, chosen_value: Any) -> Dict[str, float]:
421
+ def process_categorical(self, gui_feature_name: str, chosen_value: Any) -> Dict[str, float]:
401
422
  """
402
423
  Must be implemented by the subclass.
403
424
 
404
- Should take a GUI categorical feature name and its chosen value, and return a dictionary mapping the one-hot-encoded feature names to their
425
+ Should take a GUI categorical feature name and its chosen value, and return a dictionary mapping the one-hot-encoded/binary real feature names to their
405
426
  float values (as expected by the inference model).
427
+
428
+ _Example:_
429
+ ```python
430
+ # GUI input: "Material Type"
431
+ # GUI values: "Steel", "Aluminum", "Titanium"
432
+ {
433
+ "is_steel": 0,
434
+ "is_aluminum": 1,
435
+ "is_titanium": 0,
436
+ }
437
+ ```
406
438
  """
407
439
  pass
408
-
440
+
441
+ def _process_continuous(self, gui_feature_name: str, chosen_value: Any) -> Tuple[str, float]:
442
+ """
443
+ Maps GUI names to model expected names and casts the value to float.
444
+
445
+ Should not be overridden by subclasses.
446
+ """
447
+ try:
448
+ real_name = self.map_gui_to_real[gui_feature_name]
449
+ float_value = float(chosen_value)
450
+ except KeyError as e:
451
+ _LOGGER.error(f"No matching name for '{gui_feature_name}'. Check the 'map_gui_to_real' implementation.")
452
+ raise e
453
+ except (ValueError, TypeError) as e2:
454
+ _LOGGER.error(f"Invalid number conversion for '{chosen_value}' of '{gui_feature_name}'.")
455
+ raise e2
456
+ else:
457
+ return real_name, float_value
458
+
409
459
  def __call__(self, window_values: Dict[str, Any]) -> np.ndarray:
410
460
  """
411
461
  Performs the full vector preparation, returning a 1D numpy array.
@@ -416,16 +466,17 @@ class BaseFeatureHandler(ABC):
416
466
  processed_features: Dict[str, float] = {}
417
467
  for gui_name, feature_type in self.gui_input_map.items():
418
468
  chosen_value = window_values.get(gui_name)
419
-
469
+
470
+ # value validation
420
471
  if chosen_value is None or str(chosen_value) == '':
421
472
  raise ValueError(f"GUI input '{gui_name}' is missing a value.")
422
473
 
474
+ # process continuous
423
475
  if feature_type == 'continuous':
424
- try:
425
- processed_features[gui_name] = float(chosen_value)
426
- except (ValueError, TypeError):
427
- raise ValueError(f"Invalid number '{chosen_value}' for '{gui_name}'.")
428
-
476
+ mapped_name, float_value = self._process_continuous(gui_name, chosen_value)
477
+ processed_features[mapped_name] = float_value
478
+
479
+ # process categorical
429
480
  elif feature_type == 'categorical':
430
481
  feature_dict = self.process_categorical(gui_name, chosen_value)
431
482
  processed_features.update(feature_dict)
@@ -446,18 +497,34 @@ class BaseFeatureHandler(ABC):
446
497
  return np.array(final_vector, dtype=np.float32)
447
498
 
448
499
 
449
- def update_target_fields(window: sg.Window, results_dict: Dict[str, Any]):
500
+ def update_target_fields(window: sg.Window, results_dict: Dict[str, Any], map_model_to_gui: Optional[Dict[str,str]]):
450
501
  """
451
502
  Updates the GUI's target fields with inference results.
452
503
 
453
504
  Args:
454
505
  window (sg.Window): The application's window object.
455
- results_dict (dict): A dictionary where keys are target element-keys and values are the predicted results to update.
506
+ results_dict (dict): A dictionary where keys are target names (as expected by the GUI) and values are the predicted results to update.
507
+ map_model_to_gui (dict | None): Map `results_dict.keys()` from model target names to GUI target names, if gui names were customized.
456
508
  """
457
- for target_name, result in results_dict.items():
509
+ if map_model_to_gui is not None:
510
+ # Validation
511
+ if len(map_model_to_gui) != len(results_dict):
512
+ _LOGGER.error(f"Expected a mapping for {len(results_dict)} targets, but received {len(map_model_to_gui)} target map names.")
513
+ raise ValueError
514
+
515
+ # new dictionary with GUI keys and corresponding result values
516
+ display_dict = {
517
+ gui_key: results_dict[model_key]
518
+ for model_key, gui_key in map_model_to_gui.items()
519
+ }
520
+ else:
521
+ # If no map is provided, use given result keys
522
+ display_dict = results_dict
523
+
524
+ for key, result in display_dict.items():
458
525
  # Format numbers to 2 decimal places, leave other types as-is
459
526
  display_value = f"{result:.2f}" if isinstance(result, (int, float)) else result
460
- window[target_name].update(display_value) # type: ignore
527
+ window[key].update(display_value) # type: ignore
461
528
 
462
529
 
463
530
  def info():
@@ -973,9 +973,9 @@ class InferenceHandler:
973
973
  verbose=self.verbose,
974
974
  raise_on_error=True) # type: ignore
975
975
 
976
- model: Any = full_object["model"]
977
- target_name: str = full_object["target_name"]
978
- feature_names_list: List[str] = full_object["feature_names"]
976
+ model: Any = full_object[ModelSaveKeys.MODEL]
977
+ target_name: str = full_object[ModelSaveKeys.TARGET]
978
+ feature_names_list: List[str] = full_object[ModelSaveKeys.FEATURES]
979
979
 
980
980
  # Check that feature names match
981
981
  if self._feature_names is None: