machinegnostics 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. __init__.py +0 -0
  2. machinegnostics/__init__.py +24 -0
  3. machinegnostics/magcal/__init__.py +37 -0
  4. machinegnostics/magcal/characteristics.py +460 -0
  5. machinegnostics/magcal/criteria_eval.py +268 -0
  6. machinegnostics/magcal/criterion.py +140 -0
  7. machinegnostics/magcal/data_conversion.py +381 -0
  8. machinegnostics/magcal/gcor.py +64 -0
  9. machinegnostics/magcal/gdf/__init__.py +2 -0
  10. machinegnostics/magcal/gdf/base_df.py +39 -0
  11. machinegnostics/magcal/gdf/base_distfunc.py +1202 -0
  12. machinegnostics/magcal/gdf/base_egdf.py +823 -0
  13. machinegnostics/magcal/gdf/base_eldf.py +830 -0
  14. machinegnostics/magcal/gdf/base_qgdf.py +1234 -0
  15. machinegnostics/magcal/gdf/base_qldf.py +1019 -0
  16. machinegnostics/magcal/gdf/cluster_analysis.py +456 -0
  17. machinegnostics/magcal/gdf/data_cluster.py +975 -0
  18. machinegnostics/magcal/gdf/data_intervals.py +853 -0
  19. machinegnostics/magcal/gdf/data_membership.py +536 -0
  20. machinegnostics/magcal/gdf/der_egdf.py +243 -0
  21. machinegnostics/magcal/gdf/distfunc_engine.py +841 -0
  22. machinegnostics/magcal/gdf/egdf.py +324 -0
  23. machinegnostics/magcal/gdf/eldf.py +297 -0
  24. machinegnostics/magcal/gdf/eldf_intv.py +609 -0
  25. machinegnostics/magcal/gdf/eldf_ma.py +627 -0
  26. machinegnostics/magcal/gdf/homogeneity.py +1218 -0
  27. machinegnostics/magcal/gdf/intv_engine.py +1523 -0
  28. machinegnostics/magcal/gdf/marginal_intv_analysis.py +558 -0
  29. machinegnostics/magcal/gdf/qgdf.py +289 -0
  30. machinegnostics/magcal/gdf/qldf.py +296 -0
  31. machinegnostics/magcal/gdf/scedasticity.py +197 -0
  32. machinegnostics/magcal/gdf/wedf.py +181 -0
  33. machinegnostics/magcal/gdf/z0_estimator.py +1047 -0
  34. machinegnostics/magcal/layer_base.py +42 -0
  35. machinegnostics/magcal/layer_history_base.py +74 -0
  36. machinegnostics/magcal/layer_io_process_base.py +238 -0
  37. machinegnostics/magcal/layer_param_base.py +448 -0
  38. machinegnostics/magcal/mg_weights.py +36 -0
  39. machinegnostics/magcal/sample_characteristics.py +532 -0
  40. machinegnostics/magcal/scale_optimization.py +185 -0
  41. machinegnostics/magcal/scale_param.py +313 -0
  42. machinegnostics/magcal/util/__init__.py +0 -0
  43. machinegnostics/magcal/util/dis_docstring.py +18 -0
  44. machinegnostics/magcal/util/logging.py +24 -0
  45. machinegnostics/magcal/util/min_max_float.py +34 -0
  46. machinegnostics/magnet/__init__.py +0 -0
  47. machinegnostics/metrics/__init__.py +28 -0
  48. machinegnostics/metrics/accu.py +61 -0
  49. machinegnostics/metrics/accuracy.py +67 -0
  50. machinegnostics/metrics/auto_correlation.py +183 -0
  51. machinegnostics/metrics/auto_covariance.py +204 -0
  52. machinegnostics/metrics/cls_report.py +130 -0
  53. machinegnostics/metrics/conf_matrix.py +93 -0
  54. machinegnostics/metrics/correlation.py +178 -0
  55. machinegnostics/metrics/cross_variance.py +167 -0
  56. machinegnostics/metrics/divi.py +82 -0
  57. machinegnostics/metrics/evalmet.py +109 -0
  58. machinegnostics/metrics/f1_score.py +128 -0
  59. machinegnostics/metrics/gmmfe.py +108 -0
  60. machinegnostics/metrics/hc.py +141 -0
  61. machinegnostics/metrics/mae.py +72 -0
  62. machinegnostics/metrics/mean.py +117 -0
  63. machinegnostics/metrics/median.py +122 -0
  64. machinegnostics/metrics/mg_r2.py +167 -0
  65. machinegnostics/metrics/mse.py +78 -0
  66. machinegnostics/metrics/precision.py +119 -0
  67. machinegnostics/metrics/r2.py +122 -0
  68. machinegnostics/metrics/recall.py +108 -0
  69. machinegnostics/metrics/rmse.py +77 -0
  70. machinegnostics/metrics/robr2.py +119 -0
  71. machinegnostics/metrics/std.py +144 -0
  72. machinegnostics/metrics/variance.py +101 -0
  73. machinegnostics/models/__init__.py +2 -0
  74. machinegnostics/models/classification/__init__.py +1 -0
  75. machinegnostics/models/classification/layer_history_log_reg.py +121 -0
  76. machinegnostics/models/classification/layer_io_process_log_reg.py +98 -0
  77. machinegnostics/models/classification/layer_mlflow_log_reg.py +107 -0
  78. machinegnostics/models/classification/layer_param_log_reg.py +275 -0
  79. machinegnostics/models/classification/mg_log_reg.py +273 -0
  80. machinegnostics/models/cross_validation.py +118 -0
  81. machinegnostics/models/data_split.py +106 -0
  82. machinegnostics/models/regression/__init__.py +2 -0
  83. machinegnostics/models/regression/layer_histroy_rob_reg.py +139 -0
  84. machinegnostics/models/regression/layer_io_process_rob_rig.py +88 -0
  85. machinegnostics/models/regression/layer_mlflow_rob_reg.py +134 -0
  86. machinegnostics/models/regression/layer_param_rob_reg.py +212 -0
  87. machinegnostics/models/regression/mg_lin_reg.py +253 -0
  88. machinegnostics/models/regression/mg_poly_reg.py +258 -0
  89. machinegnostics-0.0.1.dist-info/METADATA +246 -0
  90. machinegnostics-0.0.1.dist-info/RECORD +93 -0
  91. machinegnostics-0.0.1.dist-info/WHEEL +5 -0
  92. machinegnostics-0.0.1.dist-info/licenses/LICENSE +674 -0
  93. machinegnostics-0.0.1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,212 @@
1
+ '''
2
+ Machine Gnostics - Machine Gnostics Library
3
+ Copyright (C) 2025 Machine Gnostics Team
4
+
5
+ This work is licensed under the terms of the GNU General Public License version 3.0.
6
+
7
+ Author: Nirmal Parmar
8
+ Date: 2025-05-31
9
+
10
+ Description:
11
+ Regressor param base class that can be used for robust regression models.
12
+ - linear regression
13
+ - polynomial regression
14
+
15
+ '''
16
+
17
+ import numpy as np
18
+ from machinegnostics.magcal import (ScaleParam,
19
+ GnosticsWeights,
20
+ ParamBase)
21
+ from machinegnostics.magcal.util.min_max_float import np_max_float, np_min_float
22
+ import logging
23
+
24
+ class ParamRobustRegressorBase(ParamBase):
25
+ """
26
+ Parameters for the Robust Regressor model.
27
+
28
+ Attributes
29
+ ----------
30
+ scale_param : ScaleParam
31
+ Scaling parameters for the model.
32
+ gnostics_weights : GnosticsWeights
33
+ Weights for the model.
34
+ """
35
+
36
+ def __init__(self,
37
+ degree: int = 1,
38
+ max_iter: int = 100,
39
+ tol: float = 1e-3,
40
+ mg_loss: str = 'hi',
41
+ early_stopping: bool = True,
42
+ verbose: bool = False,
43
+ scale: 'str | int | float' = 'auto',
44
+ data_form: str = 'a',
45
+ gnostic_characteristics:bool=True,
46
+ history: bool = True):
47
+ super().__init__(
48
+ degree=degree,
49
+ max_iter=max_iter,
50
+ tol=tol,
51
+ mg_loss=mg_loss,
52
+ early_stopping=early_stopping,
53
+ verbose=verbose,
54
+ scale=scale,
55
+ data_form=data_form,
56
+ gnostic_characteristics=gnostic_characteristics
57
+ )
58
+ self.degree = degree
59
+ self.max_iter = max_iter
60
+ self.tol = tol
61
+ self.mg_loss = mg_loss
62
+ self.early_stopping = early_stopping
63
+ self.verbose = verbose
64
+ self.scale = scale
65
+ self.data_form = data_form
66
+ self.gnostic_characteristics = gnostic_characteristics
67
+ # history option
68
+ if history:
69
+ self._history = []
70
+ # default history content
71
+ self._history.append({
72
+ 'iteration': 0,
73
+ 'h_loss': None,
74
+ 'coefficients': None,
75
+ 'rentropy': None,
76
+ 'weights': None,
77
+ })
78
+ else:
79
+ self._history = None
80
+
81
+ self.logger.info("ParamRobustRegressorBase initialized.")
82
+
83
+ def _fit(self, X: np.ndarray, y: np.ndarray):
84
+ """
85
+ Fit the model to the data.
86
+
87
+ Parameters
88
+ ----------
89
+ X : np.ndarray
90
+ Input features.
91
+ y : np.ndarray
92
+ Target values.
93
+ """
94
+ self.logger.info("Starting fit process for ParamRobustRegressorBase.")
95
+ # Generate polynomial features
96
+ X_poly = self._generate_polynomial_features(X)
97
+
98
+ # Initialize weights
99
+ self.weights = self._weight_init(d=y, like='one')
100
+
101
+ # Initialize coefficients to zeros
102
+ self.coefficients = np.zeros(X_poly.shape[1])
103
+
104
+ for self._iter in range(self.max_iter):
105
+ self._iter += 1
106
+ self._prev_coef = self.coefficients.copy()
107
+
108
+ try:
109
+ # Weighted least squares
110
+ self.coefficients = self._weighted_least_squares(X_poly, y, self.weights)
111
+
112
+ # Update weights using gnostic approach
113
+ y0 = X_poly @ self.coefficients
114
+ residuals = y0 - y
115
+
116
+ # mg data conversion
117
+ z_y = self._data_conversion(y)
118
+ z_y0 = self._data_conversion(y0)
119
+ zz = z_y0 / z_y
120
+ z = self._data_conversion(residuals)
121
+
122
+ # gnostic weights
123
+ gw = GnosticsWeights()
124
+ gw = gw._get_gnostic_weights(z)
125
+ new_weights = self.weights * gw
126
+
127
+ # Compute scale and loss
128
+ if self.scale == 'auto':
129
+ scale = ScaleParam()
130
+ # avoid division by zero
131
+ zz = np.where(zz == 0, np_min_float(), zz) # Replace zero with a very small value
132
+ # local scale
133
+ s = scale._gscale_loc((2 / (zz + 1/zz)))
134
+ else:
135
+ s = self.scale
136
+ # NOTE z, z_y z_y0 gives different results
137
+ # z and z_y gives good results
138
+ self.loss, self.re, self.hi, self.hj, self.fi, self.fj, \
139
+ self.pi, self.pj, self.ei, self.ej, self.infoi, self.infoj = self._gnostic_criterion(z=z_y0, z0=z_y, s=s)
140
+
141
+ self.weights = new_weights / np.sum(new_weights) # NOTE : Normalizing weights
142
+
143
+ # print loss
144
+ if self.verbose:
145
+ self.logger.info(f'Iteration: {self._iter} - Machine Gnostic loss - {self.mg_loss} : {np.round(self.loss, 4)}, rentropy: {np.round(self.re, 4)}')
146
+
147
+ # capture history and append to history
148
+ # minimal history capture
149
+ if self._history is not None:
150
+ self._history.append({
151
+ 'iteration': self._iter,
152
+ 'h_loss': self.loss,
153
+ 'coefficients': self.coefficients.copy(),
154
+ 'rentropy': self.re,
155
+ 'weights': self.weights.copy()
156
+ })
157
+
158
+ # Check convergence with early stopping and rentropy
159
+ # if entropy value is increasing, stop
160
+ if self.early_stopping and self._history is not None:
161
+ if len(self._history) > 1:
162
+ prev_loss = self._history[-2]['h_loss']
163
+ prev_re = self._history[-2]['rentropy']
164
+ if (prev_loss is not None) and (prev_re is not None):
165
+ if (np.abs(self.loss - prev_loss) < self.tol) or (np.abs(self.re - prev_re) < self.tol):
166
+ if self.verbose:
167
+ self.logger.info(f"Convergence reached at iteration {self._iter} with loss/rentropy change below tolerance.")
168
+ break
169
+
170
+ except (ZeroDivisionError, np.linalg.LinAlgError) as e:
171
+ if self.verbose:
172
+ self.logger.warning(f"Warning: {str(e)}. Using previous coefficients.")
173
+ self.coefficients = self._prev_coef
174
+ break
175
+
176
+ def _predict(self, X: np.ndarray) -> np.ndarray:
177
+ """
178
+ Internal prediction method for base class.
179
+
180
+ Parameters
181
+ ----------
182
+ X : array-like of shape (n_samples, n_features)
183
+ Input features to predict for.
184
+
185
+ Returns
186
+ -------
187
+ ndarray of shape (n_samples,)
188
+ Predicted values.
189
+ """
190
+ self.logger.info("Starting prediction for ParamRobustRegressorBase.")
191
+ # copy iteration for last iteration
192
+
193
+ if self.coefficients is None:
194
+ self.logger.error("Model has not been fitted yet.")
195
+ raise ValueError("Model has not been fitted yet.")
196
+
197
+ # Process input and generate features
198
+ X_poly = self._generate_polynomial_features(X)
199
+
200
+ # Validate dimensions
201
+ n_features_model = X_poly.shape[1]
202
+ if n_features_model != len(self.coefficients):
203
+ self.logger.error(
204
+ f"Feature dimension mismatch. Model expects {len(self.coefficients)} "
205
+ f"features but got {n_features_model} after polynomial expansion."
206
+ )
207
+ raise ValueError(
208
+ f"Feature dimension mismatch. Model expects {len(self.coefficients)} "
209
+ f"features but got {n_features_model} after polynomial expansion."
210
+ )
211
+
212
+ return X_poly @ self.coefficients
@@ -0,0 +1,253 @@
1
+ '''
2
+ Machine Gnostics - Machine Gnostics Library
3
+ Copyright (C) 2025 Machine Gnostics Team
4
+
5
+ This work is licensed under the terms of the GNU General Public License version 3.0.
6
+
7
+ Author: Nirmal Parmar
8
+
9
+ Description:
10
+ This module implements a robust linear regression model using mathematical gnostics principles.
11
+
12
+ '''
13
+
14
+ import numpy as np
15
+ from machinegnostics.models.regression.layer_io_process_rob_rig import DataProcessRobustRegressor
16
+ from machinegnostics.metrics import robr2
17
+ from machinegnostics.magcal import disable_parent_docstring
18
+
19
+ class LinearRegressor(DataProcessRobustRegressor):
20
+ """
21
+ Robust Linear Regression using Mathematical Gnostics principles.
22
+
23
+ This regressor fits a linear model to data using robust, gnostic loss functions
24
+ and adaptive sample weights. It is designed to be resilient to outliers and non-Gaussian noise,
25
+ making it suitable for scientific and engineering applications where data quality may vary.
26
+
27
+ Key Features
28
+ ------------
29
+ - Robust to outliers: Uses gnostic loss functions and adaptive sample weights.
30
+ - Iterative optimization: Supports early stopping and convergence tolerance.
31
+ - Tracks detailed history: Optionally records loss, weights, entropy, and gnostic characteristics at each iteration.
32
+ - Compatible with numpy arrays for input/output.
33
+
34
+ Parameters
35
+ ----------
36
+ scale : {'auto', int, float}, default='auto'
37
+ Scaling method or value for input features.
38
+ max_iter : int, default=100
39
+ Maximum number of optimization iterations.
40
+ tol : float, default=1e-8
41
+ Tolerance for convergence.
42
+ mg_loss : str, default='hi'
43
+ Loss function to use ('hi', 'fi', etc.).
44
+ early_stopping : bool, default=True
45
+ Whether to stop early if convergence is detected.
46
+ verbose : bool, default=False
47
+ If True, prints progress and diagnostics during fitting.
48
+ data_form : str, default='a'
49
+ Internal data representation format.
50
+ gnostic_characteristics : bool, default=True
51
+ If True, computes and records gnostic properties (fi, hi, etc.).
52
+ history : bool, default=True
53
+ If True, records the optimization history for analysis.
54
+
55
+ Attributes
56
+ ----------
57
+ coefficients : np.ndarray
58
+ Fitted linear coefficients.
59
+ weights : np.ndarray
60
+ Final sample weights after robust fitting.
61
+ params : list of dict
62
+ List of parameter snapshots (loss, weights, gnostic properties) at each iteration.
63
+ _history : list
64
+ Internal optimization history (if enabled).
65
+ All configuration parameters as set at initialization.
66
+
67
+ Methods
68
+ -------
69
+ fit(X, y)
70
+ Fit the linear regressor to input features X and targets y.
71
+ predict(X)
72
+ Predict target values for new input features X.
73
+ score(X, y, case='i')
74
+ Compute the robust R2 score for input features X and true targets y.
75
+
76
+ Example
77
+ -------
78
+ >>> from machinegnostics.models.regression import LinearRegressor
79
+ >>> model = LinearRegressor(max_iter=100, verbose=True)
80
+ >>> model.fit(X_train, y_train)
81
+ >>> y_pred = model.predict(X_test)
82
+ >>> r2 = model.score(X_test, y_test)
83
+
84
+ Notes
85
+ -----
86
+ - This model is part of the Machine Gnostics library, which implements advanced machine learning techniques
87
+ based on mathematical gnostics principles.
88
+ - For more information, visit: https://machinegnostics.info/
89
+ """
90
+ @disable_parent_docstring
91
+ def __init__(
92
+ self,
93
+ scale: str | int | float = 'auto',
94
+ max_iter: int = 100,
95
+ tol: float = 1e-3,
96
+ mg_loss: str = 'hi',
97
+ early_stopping: bool = True,
98
+ verbose: bool = False,
99
+ data_form: str = 'a',
100
+ gnostic_characteristics: bool = True,
101
+ history: bool = True
102
+ ):
103
+ """
104
+ Initialize a LinearRegressor instance with robust, gnostic regression settings.
105
+
106
+ Parameters
107
+ ----------
108
+ scale : {'auto', int, float}, default='auto'
109
+ Scaling method or value for input features.
110
+ max_iter : int, default=100
111
+ Maximum number of optimization iterations.
112
+ tol : float, default=1e-8
113
+ Tolerance for convergence.
114
+ mg_loss : str, default='hi'
115
+ Loss function to use ('hi', 'fi', etc.).
116
+ early_stopping : bool, default=True
117
+ Whether to stop early if convergence is detected.
118
+ verbose : bool, default=False
119
+ If True, prints progress and diagnostics during fitting.
120
+ data_form : str, default='a'
121
+ Internal data representation format.
122
+ gnostic_characteristics : bool, default=True
123
+ If True, computes and records gnostic properties (fi, hi, etc.).
124
+ history : bool, default=True
125
+ If True, records the optimization history for analysis.
126
+
127
+ Notes
128
+ -----
129
+ All configuration parameters are stored as attributes for later reference.
130
+ """
131
+ super().__init__(
132
+ max_iter=max_iter,
133
+ tol=tol,
134
+ mg_loss=mg_loss,
135
+ early_stopping=early_stopping,
136
+ verbose=verbose,
137
+ scale=scale,
138
+ data_form=data_form,
139
+ gnostic_characteristics=gnostic_characteristics,
140
+ history=history
141
+ )
142
+ # # Optionally, set self.degree here as well for safety:
143
+ self.degree = 1 # Default to linear regression
144
+ self.max_iter = max_iter
145
+ self.tol = tol
146
+ self.mg_loss = mg_loss
147
+ self.early_stopping = early_stopping
148
+ self.verbose = verbose
149
+ self.scale = scale
150
+ self.data_form = data_form
151
+ self.gnostic_characteristics = gnostic_characteristics
152
+ self._record_history = history
153
+ self.params = []
154
+ # history option
155
+ if history:
156
+ self._history = []
157
+ else:
158
+ self._history = None
159
+
160
+ # logger
161
+ self.logger.info("LinearRegressor initialized.")
162
+
163
+ def fit(self, X: np.ndarray, y: np.ndarray):
164
+ """
165
+ Fit the robust linear regressor model to the provided data.
166
+
167
+ This method performs robust linear regression using the specified gnostic loss function,
168
+ iteratively optimizing the model coefficients and sample weights to minimize the influence of outliers.
169
+ If history tracking is enabled, it records loss, weights, and gnostic properties at each iteration.
170
+
171
+ Parameters
172
+ ----------
173
+ X : np.ndarray
174
+ Input features of shape (n_samples, n_features).
175
+ y : np.ndarray
176
+ Target values of shape (n_samples,).
177
+
178
+ Returns
179
+ -------
180
+ self : LinearRegressor
181
+ Returns the fitted model instance for chaining or further use.
182
+
183
+ Notes
184
+ -----
185
+ - After fitting, the model's coefficients and sample weights are available in the `coefficients` and `weights` attributes.
186
+ - If `history=True`, the optimization history is available in the `params` and `_history` attributes.
187
+
188
+ Example
189
+ -------
190
+ >>> model = LinearRegressor(max_iter=100, verbose=True)
191
+ >>> model.fit(X_train, y_train)
192
+ >>> print(model.coefficients)
193
+ >>> print(model.weights)
194
+ """
195
+ self.logger.info("Starting fit process for LinearRegressor.")
196
+ # Call the fit method from DataProcessRobustRegressor
197
+ super()._fit(X, y)
198
+
199
+ def predict(self, model_input: np.ndarray) -> np.ndarray:
200
+ """
201
+ Predict target values using the fitted linear regressor model.
202
+
203
+ Parameters
204
+ ----------
205
+ model_input : np.ndarray
206
+ Input features for prediction, shape (n_samples, n_features).
207
+
208
+ Returns
209
+ -------
210
+ y_pred : np.ndarray
211
+ Predicted target values, shape (n_samples,).
212
+
213
+ Example
214
+ -------
215
+ >>> model = LinearRegressor(max_iter=100, verbose=True)
216
+ >>> model.fit(X_train, y_train)
217
+ >>> y_pred = model.predict(X_test)
218
+ """
219
+ self.logger.info("Making predictions with LinearRegressor.")
220
+ # Call the predict method from DataProcessRobustRegressor
221
+ return super()._predict(model_input)
222
+
223
+ def score(self, X: np.ndarray, y: np.ndarray, case:str = 'i') -> float:
224
+ """
225
+ Compute the robust (gnostic) R2 score for the linear regressor model.
226
+
227
+ Parameters
228
+ ----------
229
+ X : np.ndarray
230
+ Input features for scoring, shape (n_samples, n_features).
231
+ y : np.ndarray
232
+ True target values, shape (n_samples,).
233
+ case : str, default='i'
234
+ Specifies the case or variant of the R2 score to compute.
235
+
236
+ Returns
237
+ -------
238
+ score : float
239
+ Robust R2 score of the model on the provided data.
240
+
241
+ Example
242
+ -------
243
+ >>> model = LinearRegressor(max_iter=100, verbose=True)
244
+ >>> model.fit(X_train, y_train)
245
+ >>> r2 = model.score(X_test, y_test)
246
+ >>> print(f"Robust R2 score: {r2}")
247
+ """
248
+ self.logger.info("Calculating robust R2 score with LinearRegressor.")
249
+ # prediction
250
+ y_pred = self.predict(X)
251
+ # Call the score method from DataProcessRobustRegressor
252
+ r2 = robr2(y, y_pred, w=self.weights)
253
+ return r2