Instructions to use Zipeng365/WISP with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Scikit-learn
How to use Zipeng365/WISP with Scikit-learn:
from huggingface_hub import hf_hub_download import joblib model = joblib.load( hf_hub_download("Zipeng365/WISP", "sklearn_model.joblib") ) # only load pickle files from sources you trust # read more about it here https://skops.readthedocs.io/en/stable/persistence.html - Notebooks
- Google Colab
- Kaggle
Download src/wisp/cpu/algorithms.py from Zipeng365/WISP: direct link, hf CLI and curl.
- Browser
- Download file 22.7 kB
-
https://huggingface.co/Zipeng365/WISP/resolve/main/src/wisp/cpu/algorithms.py
- Command line
-
hf download hf://Zipeng365/WISP/src/wisp/cpu/algorithms.py
-
curl -L -o algorithms.py https://huggingface.co/Zipeng365/WISP/resolve/main/src/wisp/cpu/algorithms.py
22.7 kB
| # Paper-scoped implementation; see SOURCE_PROVENANCE.json. | |
| from __future__ import annotations | |
| import pickle | |
| import time | |
| from dataclasses import dataclass, field | |
| from typing import Any, Literal | |
| import numpy as np | |
| from numpy.typing import NDArray | |
| from sklearn.base import BaseEstimator, ClassifierMixin, clone | |
| from sklearn.ensemble import ExtraTreesClassifier, RandomForestClassifier | |
| from sklearn.linear_model import LogisticRegression, RidgeClassifierCV | |
| from sklearn.pipeline import Pipeline | |
| from sklearn.preprocessing import StandardScaler | |
| from sklearn.utils.class_weight import compute_sample_weight | |
| from .features import IntervalDistributionSketch, InvariantPhysicsFeatureExtractor, RandomConvSketch, RandomShapeletSketch, WearableFeatureExtractor | |
| from .hmm import TransitionSmoother | |
| from .probability import estimator_proba, global_classes, labels_from_proba | |
| def _softmax(z: NDArray[np.float64]) -> NDArray[np.float64]: | |
| z = np.asarray(z, dtype=np.float64) | |
| z = z - np.max(z, axis=1, keepdims=True) | |
| e = np.exp(z) | |
| return e / np.sum(e, axis=1, keepdims=True) | |
| def _classifier(kind: str, *, seed: int, n_jobs: int=-1) -> Any: | |
| if kind == 'extratrees': | |
| return ExtraTreesClassifier(n_estimators=120, max_features='sqrt', min_samples_leaf=1, class_weight='balanced', random_state=seed, n_jobs=n_jobs) | |
| if kind == 'rf': | |
| return RandomForestClassifier(n_estimators=120, max_features='sqrt', min_samples_leaf=1, class_weight='balanced_subsample', random_state=seed, n_jobs=n_jobs) | |
| if kind == 'logreg': | |
| return LogisticRegression(C=2.0, max_iter=2000, class_weight='balanced', solver='lbfgs', random_state=seed) | |
| if kind == 'ridge': | |
| return RidgeClassifierCV(alphas=np.logspace(-3, 3, 9)) | |
| raise ValueError(f'Unknown classifier kind: {kind}') | |
| class _HMMMixin: | |
| use_hmm: bool | |
| smoother_: TransitionSmoother | None | |
| classes_: NDArray[np.int64] | None | |
| trained_classes_: NDArray[np.int64] | None | |
| def _set_classes(self, y: Any, n_classes: int | None) -> None: | |
| yy = np.asarray(y, dtype=np.int64) | |
| self.classes_ = global_classes(yy, n_classes) | |
| self.trained_classes_ = np.unique(yy) | |
| def _fit_smoother(self, y: NDArray[np.int64], groups: Any | None, time_index: Any | None) -> None: | |
| self.smoother_ = None | |
| if self.use_hmm: | |
| if self.classes_ is None: | |
| raise RuntimeError('Global class axis is not initialized') | |
| self.smoother_ = TransitionSmoother().fit(y, groups=groups, time_index=time_index, n_classes=int(self.classes_.size)) | |
| def _maybe_smooth(self, proba: NDArray[np.float64], groups: Any | None, time_index: Any | None) -> NDArray[np.int64]: | |
| if self.classes_ is None: | |
| raise RuntimeError('Global class axis is not initialized') | |
| if getattr(self, 'smoother_', None) is not None and groups is not None: | |
| return self.smoother_.predict_from_proba(proba, groups=groups, time_index=time_index) | |
| return labels_from_proba(proba, self.classes_) | |
| class HarSculptForestHMM(BaseEstimator, ClassifierMixin, _HMMMixin): | |
| classifier: Literal['extratrees', 'rf', 'logreg'] = 'extratrees' | |
| use_hmm: bool = True | |
| segment_sizes: tuple[int, ...] = (4, 8, 16) | |
| symbolic_bins: int = 6 | |
| seed: int = 42 | |
| n_jobs: int = -1 | |
| feature_extractor_: WearableFeatureExtractor | None = field(default=None, init=False) | |
| model_: Any = field(default=None, init=False) | |
| smoother_: TransitionSmoother | None = field(default=None, init=False) | |
| classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| trained_classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| fit_seconds_: float = field(default=0.0, init=False) | |
| def fit(self, X: Any, y: Any, *, groups: Any | None=None, time_index: Any | None=None, n_classes: int | None=None) -> 'HarSculptForestHMM': | |
| start = time.perf_counter() | |
| y = np.asarray(y, dtype=np.int64) | |
| self._set_classes(y, n_classes) | |
| self.feature_extractor_ = WearableFeatureExtractor(segment_sizes=self.segment_sizes, symbolic_bins=self.symbolic_bins) | |
| F = self.feature_extractor_.fit_transform(X, y) | |
| clf = _classifier(self.classifier, seed=self.seed, n_jobs=self.n_jobs) | |
| if self.classifier == 'logreg': | |
| self.model_ = Pipeline([('scale', StandardScaler()), ('clf', clf)]) | |
| else: | |
| self.model_ = clf | |
| self.model_.fit(F, y) | |
| self._fit_smoother(y, groups, time_index) | |
| self.fit_seconds_ = time.perf_counter() - start | |
| return self | |
| def predict_proba(self, X: Any) -> NDArray[np.float64]: | |
| if self.model_ is None or self.feature_extractor_ is None or self.classes_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| F = self.feature_extractor_.transform(X) | |
| return estimator_proba(self.model_, F, self.classes_) | |
| def predict(self, X: Any, *, groups: Any | None=None, time_index: Any | None=None) -> NDArray[np.int64]: | |
| return self._maybe_smooth(self.predict_proba(X), groups, time_index) | |
| def design_profile(self) -> dict[str, Any]: | |
| return {'name': 'har_sculpt_forest_hmm', 'route': 'cpu', 'operators': ['zscore', 'magnitude', 'jerk', 'multiscale_interval_stats', 'fft_bandpower', 'autocorr', 'symbolic_transition', 'extratrees', 'hmm' if self.use_hmm else 'argmax'], 'motifs': ['orientation_invariance', 'local_periodicity', 'transition_smoothing', 'tail_class_bias']} | |
| class RocketSketchRidgeHMM(BaseEstimator, ClassifierMixin, _HMMMixin): | |
| n_kernels: int = 384 | |
| classifier: Literal['ridge', 'logreg'] = 'ridge' | |
| use_hmm: bool = True | |
| seed: int = 42 | |
| n_jobs: int = -1 | |
| sketch_: RandomConvSketch | None = field(default=None, init=False) | |
| model_: Any = field(default=None, init=False) | |
| smoother_: TransitionSmoother | None = field(default=None, init=False) | |
| classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| trained_classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| fit_seconds_: float = field(default=0.0, init=False) | |
| def fit(self, X: Any, y: Any, *, groups: Any | None=None, time_index: Any | None=None, n_classes: int | None=None) -> 'RocketSketchRidgeHMM': | |
| start = time.perf_counter() | |
| y = np.asarray(y, dtype=np.int64) | |
| self._set_classes(y, n_classes) | |
| self.sketch_ = RandomConvSketch(n_kernels=self.n_kernels, random_state=self.seed) | |
| F = self.sketch_.fit_transform(X, y) | |
| clf = _classifier(self.classifier, seed=self.seed, n_jobs=self.n_jobs) | |
| self.model_ = Pipeline([('scale', StandardScaler()), ('clf', clf)]) | |
| sample_weight = compute_sample_weight('balanced', y) if self.classifier == 'ridge' else None | |
| if sample_weight is not None: | |
| self.model_.fit(F, y, clf__sample_weight=sample_weight) | |
| else: | |
| self.model_.fit(F, y) | |
| self._fit_smoother(y, groups, time_index) | |
| self.fit_seconds_ = time.perf_counter() - start | |
| return self | |
| def predict_proba(self, X: Any) -> NDArray[np.float64]: | |
| if self.model_ is None or self.sketch_ is None or self.classes_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| F = self.sketch_.transform(X) | |
| return estimator_proba(self.model_, F, self.classes_) | |
| def predict(self, X: Any, *, groups: Any | None=None, time_index: Any | None=None) -> NDArray[np.int64]: | |
| return self._maybe_smooth(self.predict_proba(X), groups, time_index) | |
| def design_profile(self) -> dict[str, Any]: | |
| return {'name': 'rocket_sketch_ridge_hmm', 'route': 'cpu', 'operators': ['zscore', 'random_conv', 'ppv_pool', 'ridge', 'hmm' if self.use_hmm else 'argmax'], 'motifs': ['phase_tolerant_local_shape', 'fast_cpu', 'transition_smoothing']} | |
| class SymbolicIntervalForest(BaseEstimator, ClassifierMixin, _HMMMixin): | |
| use_hmm: bool = True | |
| seed: int = 42 | |
| n_jobs: int = -1 | |
| feature_extractor_: WearableFeatureExtractor | None = field(default=None, init=False) | |
| model_: Any = field(default=None, init=False) | |
| smoother_: TransitionSmoother | None = field(default=None, init=False) | |
| classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| trained_classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| fit_seconds_: float = field(default=0.0, init=False) | |
| def fit(self, X: Any, y: Any, *, groups: Any | None=None, time_index: Any | None=None, n_classes: int | None=None) -> 'SymbolicIntervalForest': | |
| start = time.perf_counter() | |
| y = np.asarray(y, dtype=np.int64) | |
| self._set_classes(y, n_classes) | |
| self.feature_extractor_ = WearableFeatureExtractor(include_raw_stats=True, include_magnitude=True, include_jerk=False, include_multiscale=True, segment_sizes=(5, 10, 20), include_spectral=False, include_autocorr=False, include_cross_channel=True, include_symbolic=True, symbolic_bins=8) | |
| F = self.feature_extractor_.fit_transform(X, y) | |
| self.model_ = ExtraTreesClassifier(n_estimators=160, max_features='sqrt', class_weight='balanced', random_state=self.seed, n_jobs=self.n_jobs) | |
| self.model_.fit(F, y) | |
| self._fit_smoother(y, groups, time_index) | |
| self.fit_seconds_ = time.perf_counter() - start | |
| return self | |
| def predict_proba(self, X: Any) -> NDArray[np.float64]: | |
| if self.model_ is None or self.feature_extractor_ is None or self.classes_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| F = self.feature_extractor_.transform(X) | |
| return estimator_proba(self.model_, F, self.classes_) | |
| def predict(self, X: Any, *, groups: Any | None=None, time_index: Any | None=None) -> NDArray[np.int64]: | |
| return self._maybe_smooth(self.predict_proba(X), groups, time_index) | |
| def design_profile(self) -> dict[str, Any]: | |
| return {'name': 'symbolic_interval_forest', 'route': 'cpu', 'operators': ['segment', 'aggregate_stats', 'quantize', 'transition_histogram', 'forest', 'hmm' if self.use_hmm else 'argmax'], 'motifs': ['interpretable_symbols', 'micro_pattern', 'transition_smoothing']} | |
| class HybridCPUEnsemble(BaseEstimator, ClassifierMixin): | |
| use_hmm: bool = True | |
| seed: int = 42 | |
| n_jobs: int = -1 | |
| members_: list[Any] = field(default_factory=list, init=False) | |
| classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| trained_classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| fit_seconds_: float = field(default=0.0, init=False) | |
| def fit(self, X: Any, y: Any, *, groups: Any | None=None, time_index: Any | None=None, n_classes: int | None=None) -> 'HybridCPUEnsemble': | |
| start = time.perf_counter() | |
| yy = np.asarray(y, dtype=np.int64) | |
| self.classes_ = global_classes(yy, n_classes) | |
| self.trained_classes_ = np.unique(yy) | |
| self.members_ = [HarSculptForestHMM(classifier='extratrees', use_hmm=False, seed=self.seed, n_jobs=self.n_jobs), RocketSketchRidgeHMM(n_kernels=256, classifier='ridge', use_hmm=False, seed=self.seed + 1, n_jobs=self.n_jobs), SymbolicIntervalForest(use_hmm=False, seed=self.seed + 2, n_jobs=self.n_jobs)] | |
| for m in self.members_: | |
| m.fit(X, yy, groups=groups, time_index=time_index, n_classes=int(self.classes_.size)) | |
| self.smoother_ = TransitionSmoother().fit(yy, groups=groups, time_index=time_index, n_classes=int(self.classes_.size)) if self.use_hmm else None | |
| self.fit_seconds_ = time.perf_counter() - start | |
| return self | |
| def predict_proba(self, X: Any) -> NDArray[np.float64]: | |
| if not self.members_ or self.classes_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| out = np.mean([m.predict_proba(X) for m in self.members_], axis=0) | |
| return out / np.maximum(out.sum(axis=1, keepdims=True), 1e-12) | |
| def predict(self, X: Any, *, groups: Any | None=None, time_index: Any | None=None) -> NDArray[np.int64]: | |
| P = self.predict_proba(X) | |
| if getattr(self, 'smoother_', None) is not None and groups is not None: | |
| return self.smoother_.predict_from_proba(P, groups=groups, time_index=time_index) | |
| return labels_from_proba(P, self.classes_) | |
| def design_profile(self) -> dict[str, Any]: | |
| return {'name': 'hybrid_cpu_ensemble', 'route': 'cpu', 'operators': ['feature_union', 'random_conv', 'symbolic', 'probability_average', 'hmm' if self.use_hmm else 'argmax'], 'motifs': ['multi_view_cpu', 'robustness_by_diversity', 'transition_smoothing']} | |
| class InvariantIntervalShapeForest(BaseEstimator, ClassifierMixin, _HMMMixin): | |
| classifier: Literal['extratrees', 'rf', 'logreg'] = 'extratrees' | |
| use_hmm: bool = True | |
| segment_sizes: tuple[int, ...] = (4, 8, 16) | |
| symbolic_bins: int = 6 | |
| n_shapelets: int = 32 | |
| seed: int = 42 | |
| n_jobs: int = -1 | |
| physics_: InvariantPhysicsFeatureExtractor | None = field(default=None, init=False) | |
| shapelets_: RandomShapeletSketch | None = field(default=None, init=False) | |
| model_: Any = field(default=None, init=False) | |
| smoother_: TransitionSmoother | None = field(default=None, init=False) | |
| classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| trained_classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| fit_seconds_: float = field(default=0.0, init=False) | |
| def fit(self, X: Any, y: Any, *, groups: Any | None=None, time_index: Any | None=None, n_classes: int | None=None) -> 'InvariantIntervalShapeForest': | |
| start = time.perf_counter() | |
| y = np.asarray(y, dtype=np.int64) | |
| self._set_classes(y, n_classes) | |
| self.physics_ = InvariantPhysicsFeatureExtractor(segment_sizes=self.segment_sizes, symbolic_bins=int(self.symbolic_bins), random_intervals=24, random_state=self.seed, include_axis_features=True).fit(X, y) | |
| self.shapelets_ = RandomShapeletSketch(n_shapelets=int(self.n_shapelets), random_state=self.seed + 17).fit(X, y) | |
| F = np.concatenate([self.physics_.transform(X), self.shapelets_.transform(X)], axis=1) | |
| clf = _classifier(self.classifier, seed=self.seed, n_jobs=self.n_jobs) | |
| self.model_ = Pipeline([('scale', StandardScaler()), ('clf', clf)]) if self.classifier == 'logreg' else clf | |
| self.model_.fit(F, y) | |
| self._fit_smoother(y, groups, time_index) | |
| self.fit_seconds_ = time.perf_counter() - start | |
| return self | |
| def _features(self, X: Any) -> NDArray[np.float64]: | |
| if self.physics_ is None or self.shapelets_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| return np.concatenate([self.physics_.transform(X), self.shapelets_.transform(X)], axis=1) | |
| def predict_proba(self, X: Any) -> NDArray[np.float64]: | |
| if self.model_ is None or self.classes_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| return estimator_proba(self.model_, self._features(X), self.classes_) | |
| def predict(self, X: Any, *, groups: Any | None=None, time_index: Any | None=None) -> NDArray[np.int64]: | |
| return self._maybe_smooth(self.predict_proba(X), groups, time_index) | |
| def design_profile(self) -> dict[str, Any]: | |
| return {'name': 'invariant_interval_shape_forest', 'route': 'cpu', 'operators': ['zscore', 'magnitude', 'jerk', 'gram_eig', 'dyadic_intervals', 'quantile_distribution', 'random_shapelet', 'extratrees', 'hmm' if self.use_hmm else 'argmax'], 'motifs': ['orientation_invariance', 'device_shift_robustness', 'interval_distribution', 'local_shape', 'transition_smoothing']} | |
| class StateRocketIntervalHMM(BaseEstimator, ClassifierMixin, _HMMMixin): | |
| n_kernels: int = 384 | |
| n_intervals: int = 24 | |
| classifier: Literal['ridge', 'logreg'] = 'ridge' | |
| use_hmm: bool = True | |
| seed: int = 42 | |
| n_jobs: int = -1 | |
| rocket_: RandomConvSketch | None = field(default=None, init=False) | |
| interval_: IntervalDistributionSketch | None = field(default=None, init=False) | |
| state_: WearableFeatureExtractor | None = field(default=None, init=False) | |
| model_: Any = field(default=None, init=False) | |
| smoother_: TransitionSmoother | None = field(default=None, init=False) | |
| classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| trained_classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| fit_seconds_: float = field(default=0.0, init=False) | |
| def fit(self, X: Any, y: Any, *, groups: Any | None=None, time_index: Any | None=None, n_classes: int | None=None) -> 'StateRocketIntervalHMM': | |
| start = time.perf_counter() | |
| y = np.asarray(y, dtype=np.int64) | |
| self._set_classes(y, n_classes) | |
| self.rocket_ = RandomConvSketch(n_kernels=int(self.n_kernels), random_state=self.seed).fit(X, y) | |
| self.interval_ = IntervalDistributionSketch(n_random_intervals=int(self.n_intervals), random_state=self.seed + 29).fit(X, y) | |
| self.state_ = WearableFeatureExtractor(include_raw_stats=False, include_magnitude=True, include_jerk=True, include_multiscale=False, include_spectral=True, include_autocorr=True, include_cross_channel=True, include_symbolic=True, symbolic_bins=6).fit(X, y) | |
| F = self._features(X) | |
| clf = _classifier(self.classifier, seed=self.seed, n_jobs=self.n_jobs) | |
| self.model_ = Pipeline([('scale', StandardScaler()), ('clf', clf)]) | |
| if self.classifier == 'ridge': | |
| self.model_.fit(F, y, clf__sample_weight=compute_sample_weight('balanced', y)) | |
| else: | |
| self.model_.fit(F, y) | |
| self._fit_smoother(y, groups, time_index) | |
| self.fit_seconds_ = time.perf_counter() - start | |
| return self | |
| def _features(self, X: Any) -> NDArray[np.float64]: | |
| if self.rocket_ is None or self.interval_ is None or self.state_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| return np.concatenate([self.rocket_.transform(X), self.interval_.transform(X), self.state_.transform(X)], axis=1) | |
| def predict_proba(self, X: Any) -> NDArray[np.float64]: | |
| if self.model_ is None or self.classes_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| return estimator_proba(self.model_, self._features(X), self.classes_) | |
| def predict(self, X: Any, *, groups: Any | None=None, time_index: Any | None=None) -> NDArray[np.int64]: | |
| return self._maybe_smooth(self.predict_proba(X), groups, time_index) | |
| def design_profile(self) -> dict[str, Any]: | |
| return {'name': 'state_rocket_interval_hmm', 'route': 'cpu', 'operators': ['zscore', 'random_conv', 'ppv_pool', 'dyadic_intervals', 'quantile_distribution', 'symbolic_transition', 'ridge', 'hmm' if self.use_hmm else 'argmax'], 'motifs': ['phase_tolerant_local_shape', 'interval_distribution', 'state_dynamics', 'fast_cpu', 'transition_smoothing']} | |
| class PosteriorCPUEnsemble(BaseEstimator, ClassifierMixin): | |
| use_hmm: bool = True | |
| seed: int = 42 | |
| n_jobs: int = -1 | |
| weights: tuple[float, ...] = (0.34, 0.33, 0.33) | |
| members_: list[Any] = field(default_factory=list, init=False) | |
| smoother_: TransitionSmoother | None = field(default=None, init=False) | |
| classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| trained_classes_: NDArray[np.int64] | None = field(default=None, init=False) | |
| fit_seconds_: float = field(default=0.0, init=False) | |
| def fit(self, X: Any, y: Any, *, groups: Any | None=None, time_index: Any | None=None, n_classes: int | None=None) -> 'PosteriorCPUEnsemble': | |
| start = time.perf_counter() | |
| yy = np.asarray(y, dtype=np.int64) | |
| self.classes_ = global_classes(yy, n_classes) | |
| self.trained_classes_ = np.unique(yy) | |
| self.members_ = [StateRocketIntervalHMM(n_kernels=256, n_intervals=16, use_hmm=False, seed=self.seed, n_jobs=self.n_jobs), InvariantIntervalShapeForest(n_shapelets=24, use_hmm=False, seed=self.seed + 1, n_jobs=self.n_jobs), SymbolicIntervalForest(use_hmm=False, seed=self.seed + 2, n_jobs=self.n_jobs)] | |
| for member in self.members_: | |
| member.fit(X, yy, groups=groups, time_index=time_index, n_classes=int(self.classes_.size)) | |
| self.smoother_ = TransitionSmoother().fit(yy, groups=groups, time_index=time_index, n_classes=int(self.classes_.size)) if self.use_hmm else None | |
| self.fit_seconds_ = time.perf_counter() - start | |
| return self | |
| def predict_proba(self, X: Any) -> NDArray[np.float64]: | |
| if not self.members_ or self.classes_ is None: | |
| raise RuntimeError('Model is not fitted') | |
| probs = [m.predict_proba(X) for m in self.members_] | |
| w = np.asarray(self.weights, dtype=np.float64) | |
| if w.size != len(probs): | |
| w = np.ones((len(probs),), dtype=np.float64) | |
| w = w / np.maximum(w.sum(), 1e-12) | |
| out = sum((float(wi) * pi for wi, pi in zip(w, probs))) | |
| return out / np.maximum(out.sum(axis=1, keepdims=True), 1e-12) | |
| def predict(self, X: Any, *, groups: Any | None=None, time_index: Any | None=None) -> NDArray[np.int64]: | |
| P = self.predict_proba(X) | |
| if self.smoother_ is not None and groups is not None: | |
| return self.smoother_.predict_from_proba(P, groups=groups, time_index=time_index) | |
| return labels_from_proba(P, self.classes_) | |
| def design_profile(self) -> dict[str, Any]: | |
| return {'name': 'posterior_cpu_ensemble', 'route': 'cpu', 'operators': ['posterior_weighting', 'random_conv', 'invariant_physics', 'symbolic_transition', 'probability_ensemble', 'hmm' if self.use_hmm else 'argmax'], 'motifs': ['multi_view_cpu', 'posterior_over_motifs', 'state_dynamics', 'orientation_invariance', 'transition_smoothing']} | |
| def build_cpu_estimator(spec: dict[str, Any] | str) -> Any: | |
| if isinstance(spec, str): | |
| name = spec | |
| params: dict[str, Any] = {} | |
| else: | |
| name = str(spec.get('name', spec.get('algorithm', 'har_sculpt_forest_hmm'))) | |
| params = dict(spec.get('params', {})) | |
| if name == 'har_sculpt_forest_hmm': | |
| return HarSculptForestHMM(**params) | |
| if name == 'rocket_sketch_ridge_hmm': | |
| return RocketSketchRidgeHMM(**params) | |
| if name == 'symbolic_interval_forest': | |
| return SymbolicIntervalForest(**params) | |
| if name == 'hybrid_cpu_ensemble': | |
| return HybridCPUEnsemble(**params) | |
| if name == 'invariant_interval_shape_forest': | |
| return InvariantIntervalShapeForest(**params) | |
| if name == 'state_rocket_interval_hmm': | |
| return StateRocketIntervalHMM(**params) | |
| if name == 'posterior_cpu_ensemble': | |
| return PosteriorCPUEnsemble(**params) | |
| raise ValueError(f'Unknown CPU estimator: {name}') | |
| def estimate_pickle_size_mb(model: Any) -> float: | |
| return len(pickle.dumps(model)) / (1024.0 * 1024.0) | |