BhalalaDaksh commited on
Commit
64dd111
·
verified ·
1 Parent(s): 48544de

Upload compactts/agent/profiler.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. compactts/agent/profiler.py +102 -0
compactts/agent/profiler.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Series Profiler for CompactTS-Agent.
2
+
3
+ Extracts statistical signatures, spectral characteristics, seasonality,
4
+ trend strength, and volatility profiles from time-series trajectories.
5
+ """
6
+
7
+ from typing import Dict, Any, Optional
8
+ import numpy as np
9
+ import pandas as pd
10
+ from scipy import stats
11
+ from gluonts.time_feature import get_seasonality
12
+
13
+
14
+ class SeriesProfiler:
15
+ """Profiles univariate and multivariate time series for autonomous agent arbitration."""
16
+
17
+ def __init__(self, freq: str = "H"):
18
+ self.freq = freq
19
+ try:
20
+ self.base_seasonality = max(get_seasonality(freq), 1)
21
+ except Exception:
22
+ self.base_seasonality = 1
23
+
24
+ def profile(self, series: np.ndarray) -> Dict[str, Any]:
25
+ """Extract comprehensive statistical and structural characteristics.
26
+
27
+ Parameters
28
+ ----------
29
+ series : np.ndarray
30
+ 1D array of historical observations.
31
+
32
+ Returns
33
+ -------
34
+ Dict[str, Any]
35
+ Dictionary of structural features:
36
+ - length: sequence length
37
+ - mean, std: empirical scale
38
+ - seasonal_period: detected dominant lag
39
+ - seasonal_strength: autocorrelation at seasonal lag
40
+ - trend_strength: relative trend variance ratio
41
+ - kurtosis: tail weight indicator
42
+ - has_missing: boolean indicating gaps or NaNs
43
+ """
44
+ y = np.asarray(series, dtype=np.float32)
45
+ if y.ndim > 1:
46
+ y = y.squeeze()
47
+
48
+ has_missing = bool(np.isnan(y).any() or np.isinf(y).any())
49
+ if has_missing:
50
+ s = pd.Series(y).ffill().bfill().to_numpy()
51
+ y = np.nan_to_num(s, nan=0.0).astype(np.float32)
52
+
53
+ n = len(y)
54
+ if n < 4:
55
+ return {
56
+ "length": n,
57
+ "mean": float(np.mean(y)) if n > 0 else 0.0,
58
+ "std": float(np.std(y)) if n > 0 else 1.0,
59
+ "seasonal_period": self.base_seasonality,
60
+ "seasonal_strength": 0.0,
61
+ "trend_strength": 0.0,
62
+ "kurtosis": 0.0,
63
+ "has_missing": has_missing,
64
+ }
65
+
66
+ mean_val = float(np.mean(y))
67
+ std_val = float(np.std(y))
68
+ if std_val < 1e-8:
69
+ std_val = 1.0
70
+
71
+ # Kurtosis for heavy-tail detection
72
+ try:
73
+ kurt = float(stats.kurtosis(y))
74
+ except Exception:
75
+ kurt = 0.0
76
+
77
+ # Seasonal autocorrelation
78
+ S = self.base_seasonality
79
+ s_corr = 0.0
80
+ if n > 2 * S:
81
+ try:
82
+ c = np.corrcoef(y[S:], y[:-S])[0, 1]
83
+ if np.isfinite(c):
84
+ s_corr = max(0.0, float(c))
85
+ except Exception:
86
+ s_corr = 0.0
87
+
88
+ # Trend strength: ratio of diff variance to raw variance
89
+ diff_var = float(np.var(np.diff(y)))
90
+ raw_var = float(np.var(y))
91
+ trend_ratio = max(0.0, 1.0 - (diff_var / (raw_var + 1e-8)))
92
+
93
+ return {
94
+ "length": n,
95
+ "mean": mean_val,
96
+ "std": std_val,
97
+ "seasonal_period": S,
98
+ "seasonal_strength": s_corr,
99
+ "trend_strength": trend_ratio,
100
+ "kurtosis": kurt,
101
+ "has_missing": has_missing,
102
+ }