Source code for interpreTS.core.features.feature_stability

import pandas as pd
import numpy as np
from statsmodels.tsa.stattools import acf

[docs] def calculate_stability(data, max_lag=None): """ Calculate the stability of a time series based on autocorrelation. Parameters ---------- data : pd.Series or np.ndarray The time series data for which the stability is to be calculated. max_lag : int, optional The maximum number of lags to consider for autocorrelation. If None, it will be set to `min(12, len(data) - 1)`. Returns ------- float The stability strength, ranging from 0 to 1, where 1 indicates high stability. Examples -------- >>> import pandas as pd >>> data = pd.Series([10, 12, 11, 13, 12, 14, 11, 13, 12, 14, 13]) >>> calculate_stability(data) 0.8410385081084804 >>> # Example with less stable data >>> data = pd.Series([5, 20, 3, 18, 1, 25, 2, 22, 0, 19]) >>> calculate_stability(data) 0.6144144729613819 """ # Convert to pandas Series if it's a numpy array if isinstance(data, np.ndarray): data = pd.Series(data) # Ensure the data is numeric and handle empty series if data.empty: return np.nan if not np.issubdtype(data.dtype, np.number): raise TypeError("Data must contain only numeric values.") # Dynamically determine max_lag if not provided if max_lag is None: max_lag = min(12, len(data) - 1) # Handle insufficient data if len(data) <= max_lag or max_lag < 1: return np.nan # Handle zero variance if data.var() == 0: return 1.0 try: # Calculate the autocorrelation of the data up to the max lag autocorr_values = acf(data, nlags=max_lag, fft=True) # Exclude the first autocorrelation (lag 0) as it is always 1 autocorr_values = autocorr_values[1:] # Calculate stability based on variance of autocorrelation values at higher lags mean_autocorr = np.mean(np.abs(autocorr_values)) variance_autocorr = np.var(autocorr_values) # Combine mean and variance to get a measure of stability stability_strength = 1 - (mean_autocorr + variance_autocorr) / 2 stability_strength = max(0, min(stability_strength, 1)) # Ensure result is within [0, 1] return stability_strength except Exception as e: # Log unexpected exceptions and return NaN print(f"Error calculating stability: {e}") return np.nan