| name | time-series |
| description | Time series analysis techniques for analyzing and forecasting temporal data, including decomposition, smoothing, ARIMA models, and deep learning approaches. |
| category | data-science |
| keywords | ["time-series","forecasting","arima","prophet","decomposition","seasonal","trend","stationarity","autocorrelation","lstm"] |
| difficulty | advanced |
| related_skills | ["pandas","numpy","statistics","scikit-learn"] |
Time Series
What I do
I provide techniques for analyzing and forecasting temporal data. I enable decomposition of time series into trend, seasonal, and residual components, testing for stationarity, building statistical and machine learning forecasting models, and evaluating forecast performance. Time series analysis is essential for demand forecasting, financial prediction, and anomaly detection.
When to use me
- Forecasting sales, demand, or resource utilization
- Analyzing trends and seasonal patterns
- Detecting anomalies and regime changes
- Understanding autocorrelation in data
- Building predictive models for temporal data
- Capacity planning and resource allocation
- Financial time series analysis
- Sensor data and IoT analytics
Core Concepts
Time Series Components
- Trend: Long-term movement in data
- Seasonality: Repeating patterns at fixed intervals
- Cyclical: Irregular long-term cycles
- Residual: Random variation after decomposition
Stationarity
- Definition: Constant mean, variance, and autocorrelation
- Types: Trend-stationary vs. difference-stationary
- Tests: ADF test, KPSS test
- Transformations: Differencing, log transformation
Decomposition
- Additive: Y = Trend + Seasonal + Residual
- Multiplicative: Y = Trend × Seasonal × Residual
- Methods: Classical, STL, X-13
Autocorrelation
- ACF: Autocorrelation Function
- PACF: Partial Autocorrelation Function
- Interpretation: Identify MA and AR orders
- Uses: Model identification, lag selection
Forecasting Models
- Statistical: ARIMA, SARIMA, Exponential Smoothing
- Machine Learning: Random Forest, Gradient Boosting
- Deep Learning: LSTM, GRU, Transformer
- Probabilistic: Prophet, Bayesian methods
Code Examples (Python)
import pandas as pd
import numpy as np
from statsmodels.tsa.seasonal import seasonal_decompose, STL
from statsmodels.tsa.stattools import adfuller, kpss, acf, pacf
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.holtwinters import ExponentialSmoothing
from pmdarima import auto_arima
from sklearn.metrics import mean_absolute_error, mean_squared_error
import warnings
warnings.filterwarnings('ignore')
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')
df = df.sort_index()
monthly = df.resample('M').sum()
quarterly = df.resample('Q').mean()
daily = df.resample('D').sum()
complete_idx = pd.date_range(start=df.index.min(), end=df.index.max(), freq='D')
df = df.reindex(complete_idx)
df = df.asfreq('D')
df = df.ffill()
df = df.bfill()
df = df.interpolate(method='linear')
def test_stationarity(series):
adf_result = adfuller(series.dropna(), autolag=)
()
()
()
kpss_result = kpss(series.dropna(), regression=, nlags=)
()
()
adf_result[] <
decomposition = seasonal_decompose(df[], model=, period=)
trend = decomposition.trend
seasonal = decomposition.seasonal
residual = decomposition.resid
stl = STL(df[], period=, robust=)
result = stl.fit()
trend = result.trend
seasonal = result.seasonal
residual = result.resid
plot_acf(df[].dropna(), lags=)
plot_pacf(df[].dropna(), lags=)
acf_values = acf(df[].dropna(), nlags=)
pacf_values = pacf(df[].dropna(), nlags=)
model = ARIMA(df[], order=(, , ))
fitted_model = model.fit()
(fitted_model.summary())
auto_model = auto_arima(
df[],
start_p=, start_q=,
max_p=, max_q=,
m=,
start_P=, seasonal=,
d=, D=,
trace=,
error_action=,
suppress_warnings=,
stepwise=
)
(auto_model.summary())
sarima_model = auto_arima(
df[],
seasonal=,
m=,
stepwise=,
suppress_warnings=
)
hw_model = ExponentialSmoothing(
df[],
trend=,
seasonal=,
seasonal_periods=,
damped_trend=
).fit()
ses_model = SimpleExpSmoothing(df[]).fit()
holt_model = Holt(df[], damped_trend=).fit()
prophet Prophet
prophet_df = df.reset_index()[[, ]].rename(
columns={: , : }
)
prophet_model = Prophet(
yearly_seasonality=,
weekly_seasonality=,
daily_seasonality=,
seasonality_mode=
)
prophet_model.fit(prophet_df)
future = prophet_model.make_future_dataframe(periods=)
forecast = prophet_model.predict(future)
():
result = df.copy()
lag lags:
result[] = result[target_col].shift(lag)
result
():
result = df.copy()
window windows:
result[] = result[target_col].shift().rolling(window).mean()
result[] = result[target_col].shift().rolling(window).std()
result
df_features = df.copy()
df_features = create_lag_features(df_features, , [, , , ])
df_features = create_rolling_features(df_features, , [, , ])
df_features[] = df_features.index.dayofweek
df_features[] = df_features.index.month
df_features[] = df_features.index.quarter
df_features = df_features.dropna()
X = df_features.drop(, axis=)
y = df_features[]
sklearn.ensemble GradientBoostingRegressor
model = GradientBoostingRegressor(
n_estimators=,
max_depth=,
learning_rate=
)
model.fit(X, y)
tensorflow.keras.models Sequential
tensorflow.keras.layers LSTM, Dense, Dropout
tensorflow.keras.preprocessing.sequence TimeseriesGenerator
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(df[].values.reshape(-, ))
look_back =
generator = TimeseriesGenerator(scaled_data, scaled_data,
length=look_back, batch_size=)
model = Sequential([
LSTM(, return_sequences=, input_shape=(look_back, )),
Dropout(),
LSTM(, return_sequences=),
Dropout(),
Dense(),
Dense()
])
model.(optimizer=, loss=)
model.fit(generator, epochs=, verbose=)
():
forecast = model.forecast(steps=steps)
forecast
():
predictions = []
intervals = []
i (, (df) - train_size - horizon + , horizon):
train = df.iloc[:train_size + i]
test = df.iloc[train_size + i:train_size + i + horizon]
model = model_class(train, seasonal=, m=)
fitted = model.fit()
forecast = fitted.forecast(steps=horizon)
pred = forecast.iloc[]
predictions.append(pred)
ci = fitted.get_forecast(steps=horizon).conf_int()
intervals.append(ci)
predictions, intervals
():
mae = mean_absolute_error(actual, predicted)
rmse = np.sqrt(mean_squared_error(actual, predicted))
mape = np.mean(np.((actual - predicted) / actual)) *
mase = mae / np.mean(np.(np.diff(actual)))
{: mae, : rmse, : mape, : mase}
():
z_scores = (df[column] - df[column].mean()) / df[column].std()
anomalies = df[np.(z_scores) > threshold]
anomalies
ruptures Pelt
model = Pelt(model=, min_size=, jump=).fit(df[].values)
breakpoints = model.predict(pen=)
Best Practices
-
Understand the data frequency: Match modeling approach to data characteristics.
-
Check stationarity: Transform non-stationary data (differencing, log) before modeling.
-
Use appropriate seasonal periods: Monthly (12), weekly (52), daily (7), quarterly (4).
-
Validate temporally: Use time-aware cross-validation (no future data in training).
-
Combine methods: Ensemble statistical and ML models for robust forecasts.
-
Monitor drift: Track forecast accuracy over time; retrain as needed.
-
Use confidence intervals: Report uncertainty, not just point estimates.
-
Handle holidays: Include special events (holidays, promotions) as regressors.
Common Patterns
Pattern 1: Complete Time Series Analysis Pipeline
def time_series_analysis_pipeline(df, target_col, freq='D', periods=365):
"""Complete time series analysis and forecasting pipeline."""
df = df.set_index('date').sort_index()
df = df.asfreq(freq).fillna(method='ffill')
decomp = STL(df[target_col], period=periods).fit()
trend = decomp.trend
seasonal = decomp.seasonal
resid = decomp.resid
is_stationary = test_stationarity(df[target_col])
auto_model = auto_arima(
df[target_col],
seasonal=True,
m=periods,
stepwise=True,
suppress_warnings=True
)
forecast = auto_model.predict(n_periods=90)
train_size = int(len(df) * 0.8)
train, test = df[target_col][:train_size], df[target_col][train_size:]
eval_model = auto_arima(train, seasonal=True, m=periods)
predictions = eval_model.predict(n_periods=len(test))
metrics = evaluate_forecast(test.values, predictions)
return {
'decomposition': {'trend': trend, 'seasonal': seasonal, 'residual': resid},
'model': auto_model,
'forecast': forecast,
'metrics': metrics,
'stationary': is_stationary
}
Pattern 2: Feature Engineering for Time Series ML
def advanced_ts_features(df, target_col):
"""Create comprehensive time series features."""
df = df.copy()
df['hour'] = df.index.hour
df['day'] = df.index.day
df['dayofweek'] = df.index.dayofweek
df['month'] = df.index.month
df['quarter'] = df.index.quarter
df['year'] = df.index.year
df['weekofyear'] = df.index.isocalendar().week
df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)
df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)
df['day_sin'] = np.sin(2 * np.pi * df['dayofweek'] / 7)
df['day_cos'] = np.cos(2 * np.pi * df['dayofweek'] / 7)
for lag in [1, 2, 3, 7, 14, 21, 28]:
df[f'lag_{lag}'] = df[target_col].shift(lag)
window [, , ]:
df[] = df[target_col].shift().rolling(window).mean()
df[] = df[target_col].shift().rolling(window).std()
df[] = df[target_col].shift().rolling(window).()
df[] = df[target_col].shift().rolling(window).()
span [, , ]:
df[] = df[target_col].shift().ewm(span=span).mean()
df[] = df[target_col].diff()
df[] = df[target_col].diff()
df[] = df[target_col].pct_change()
df[] = df[target_col].diff().rolling().mean()
df[] = df[target_col] / (df[target_col].shift().rolling().mean() + )
df[] = df[target_col] / (df[target_col].shift().rolling().mean() + )
df[] = df[target_col].shift()
df[] = df[target_col].shift()
df.dropna()
Pattern 3: Model Ensemble for Robust Forecasting
def ensemble_forecast(df, target_col, forecast_horizon=30):
"""Combine multiple forecasting models."""
forecasts = {}
arima_model = auto_arima(df[target_col], seasonal=True, m=12, stepwise=True)
forecasts['arima'] = arima_model.predict(n_periods=forecast_horizon)
hw_model = ExponentialSmoothing(
df[target_col], trend='add', seasonal='add', seasonal_periods=12
).fit()
forecasts['hw'] = hw_model.forecast(forecast_horizon)
prophet_df = df.reset_index()[['date', target_col]].rename(
columns={'date': 'ds', target_col: 'y'}
)
prophet_model = Prophet(yearly_seasonality=True, weekly_seasonality=True)
prophet_model.fit(prophet_df)
future = prophet_model.make_future_dataframe(periods=forecast_horizon)
prophet_forecast = prophet_model.predict(future)['yhat'].iloc[-forecast_horizon:]
forecasts['prophet'] = prophet_forecast.values
X, y = prepare_features(df, target_col)
X_train, y_train = X[:-forecast_horizon], y[:-forecast_horizon]
X_test = X[-forecast_horizon:]
ml_model = GradientBoostingRegressor(n_estimators=100, max_depth=5)
ml_model.fit(X_train, y_train)
forecasts['ml'] = ml_model.predict(X_test)
weights = {'arima': 0.25, 'hw': 0.25, 'prophet': 0.25, 'ml': 0.25}
ensemble = (weights[k] * forecasts[k] k weights)
forecast_df = pd.DataFrame(forecasts)
ensemble_ci = {
: forecast_df.quantile(, axis=),
: forecast_df.quantile(, axis=)
}
{
: ensemble,
: forecasts,
: ensemble_ci,
: weights
}