diff --git a/numalogic/config/factory.py b/numalogic/config/factory.py index cd16e603..41d73328 100644 --- a/numalogic/config/factory.py +++ b/numalogic/config/factory.py @@ -52,7 +52,7 @@ class PreprocessFactory(_ObjectFactory): DifferenceTransform, FlattenVector, PercentileScaler, - ExpMovingAverage + ExpMovingAverage, ) _CLS_MAP: ClassVar[dict] = { @@ -68,7 +68,7 @@ class PreprocessFactory(_ObjectFactory): "DifferenceTransform": DifferenceTransform, "FlattenVector": FlattenVector, "PercentileScaler": PercentileScaler, - "ExpMovingAverage": ExpMovingAverage + "ExpMovingAverage": ExpMovingAverage, } def get_pipeline_instance(self, objs_info: list[ModelInfo]): @@ -88,7 +88,11 @@ class PostprocessFactory(_ObjectFactory): from numalogic.transforms import TanhNorm, ExpMovingAverage, SigmoidNorm - _CLS_MAP: ClassVar[dict] = {"TanhNorm": TanhNorm, "ExpMovingAverage": ExpMovingAverage, "SigmoidNorm": SigmoidNorm} + _CLS_MAP: ClassVar[dict] = { + "TanhNorm": TanhNorm, + "ExpMovingAverage": ExpMovingAverage, + "SigmoidNorm": SigmoidNorm, + } class ThresholdFactory(_ObjectFactory): diff --git a/numalogic/transforms/__init__.py b/numalogic/transforms/__init__.py index f237435d..80a2f426 100644 --- a/numalogic/transforms/__init__.py +++ b/numalogic/transforms/__init__.py @@ -39,5 +39,5 @@ "DifferenceTransform", "FlattenVector", "PercentileScaler", - "SigmoidNorm" + "SigmoidNorm", ] diff --git a/numalogic/transforms/_movavg.py b/numalogic/transforms/_movavg.py index c431d61c..3465f178 100644 --- a/numalogic/transforms/_movavg.py +++ b/numalogic/transforms/_movavg.py @@ -111,5 +111,6 @@ def transform(self, input_: npt.NDArray[float], **__) -> npt.NDArray[float]: ------ InvalidDataShapeError: if input array is not single featured """ - x_df = pd.DataFrame(input_) - return x_df.ewm(alpha=self.alpha).mean().to_numpy(dtype=np.float32) + x_df = pd.DataFrame(input_, dtype=np.float32, copy=True) + x_smoothed = x_df.ewm(alpha=self.alpha).mean().to_numpy(dtype=np.float32) + return np.ascontiguousarray(x_smoothed, dtype=np.float32) diff --git a/numalogic/transforms/_postprocess.py b/numalogic/transforms/_postprocess.py index f921889c..899fe1cc 100644 --- a/numalogic/transforms/_postprocess.py +++ b/numalogic/transforms/_postprocess.py @@ -51,10 +51,10 @@ def transform(self, input_: npt.NDArray[float], **__) -> npt.NDArray[float]: class SigmoidNorm(StatelessTransformer): - def __init__(self, scale_factor: float = 10., smooth_factor: float = 0.5): + def __init__(self, scale_factor: float = 10.0, smooth_factor: float = 0.5): super().__init__() self.scale_factor = scale_factor self.smooth_factor = smooth_factor def transform(self, x: npt.NDArray[float], **__) -> npt.NDArray[float]: - return self.scale_factor / (1.0 + np.exp(5 - (self.smooth_factor * x))) \ No newline at end of file + return self.scale_factor / (1.0 + np.exp(5 - (self.smooth_factor * x))) diff --git a/numalogic/transforms/_scaler.py b/numalogic/transforms/_scaler.py index 355013a6..49e092aa 100644 --- a/numalogic/transforms/_scaler.py +++ b/numalogic/transforms/_scaler.py @@ -89,7 +89,9 @@ class PercentileScaler(BaseTransformer): Default is None. """ - def __init__(self, max_percentile: float = 99, min_percentile: Optional[float] = None, eps: float = 1e-2): + def __init__( + self, max_percentile: float = 99, min_percentile: Optional[float] = None, eps: float = 1e-2 + ): self._max_px = max_percentile self._min_px = min_percentile self.tx = MinMaxScaler() @@ -120,8 +122,9 @@ def fit(self, x: npt.NDArray[float]) -> Self: for idx, _range in enumerate(p_ranges): if _range <= self._eps: LOGGER.warning( - "Max and Min percentile difference is less than " - "epsilon: %s for column %s", self._eps, idx + "Max and Min percentile difference is less than " "epsilon: %s for column %s", + self._eps, + idx, ) data_max_px[idx] = data_max[idx] diff --git a/tests/transforms/test_postprocess.py b/tests/transforms/test_postprocess.py index b1249005..5acac28d 100644 --- a/tests/transforms/test_postprocess.py +++ b/tests/transforms/test_postprocess.py @@ -4,7 +4,6 @@ from sklearn.pipeline import make_pipeline from numalogic.transforms import tanh_norm, TanhNorm, ExpMovingAverage, expmov_avg_aggregator -from numalogic.tools.exceptions import InvalidDataShapeError class TestPostprocess(unittest.TestCase): @@ -22,21 +21,17 @@ def test_tanh_norm_clf(self): self.assertTupleEqual(arr.shape, scores.shape) self.assertAlmostEqual(np.sum(scores), 39.52, places=2) - def test_exp_mov_avg_estimator_01(self): + def test_exp_mov_avg_estimator(self): + beta = 0.9 arr = np.arange(1, 11).reshape(-1, 1) - clf = ExpMovingAverage(0.9) + clf = ExpMovingAverage(beta) out = clf.fit_transform(arr) - self.assertTupleEqual(arr.shape, out.shape) - self.assertAlmostEqual(expmov_avg_aggregator(arr, 0.9), out[-1].item(), places=3) - def test_exp_mov_avg_estimator_02(self): - arr = np.arange(1, 11).reshape(-1, 1) - clf = ExpMovingAverage(0.9, bias_correction=False) - out = clf.fit_transform(arr) + expected = expmov_avg_aggregator(arr, beta) + self.assertTupleEqual(arr.shape, out.shape) - self.assertAlmostEqual( - expmov_avg_aggregator(arr, 0.9, bias_correction=False), out[-1].item(), places=3 - ) + self.assertAlmostEqual(expected, out[-1].item(), places=2) + self.assertTrue(out.data.c_contiguous) def test_exp_mov_avg_estimator_err(self): with self.assertRaises(ValueError): @@ -48,14 +43,6 @@ def test_exp_mov_avg_estimator_err(self): with self.assertRaises(ValueError): ExpMovingAverage(1.0) - with self.assertRaises(InvalidDataShapeError): - clf = ExpMovingAverage(0.1) - clf.fit_transform(np.arange(10).reshape(1, -1)) - - with self.assertRaises(InvalidDataShapeError): - clf = ExpMovingAverage(0.1) - clf.fit_transform(np.arange(12).reshape((2, 3, -1))) - def test_exp_mov_avg_agg(self): arr = np.arange(1, 11) val = expmov_avg_aggregator(arr, 0.9)