Source code for dojo_ds.time_series

import statsmodels.tsa.api as tsa

[docs] def get_adfuller_results(ts, alpha=.05, label='adfuller', **kwargs): """Uses statsmodels' adfuller function to test a univariate time series for stationarity. Null hypothesis: The time series is NOT stationary. (It "has a unit root".) Interpretation: a p-value less than alpha (.05) means the ts IS stationary. (We reject the null hypothesis that it is not stationary.) Returns ------- results (DataFrame): DataFrame with the following columns/results: - "Test Statistic" : the adfuller test statistic. - "# of Lags Used": The number of lags used in the calculation. - "# of Observations" : The number of observations used. - "p-value" : p-value for hypothesis test. - "alpha": the significance level used for interpretin p-value - "sig/stationary?": simplified interpretation of p-value ADFULLER DOCUMENTATION: For the full adfuller documentation, see: https://www.statsmodels.org/dev/generated/statsmodels.tsa.stattools.adfuller.html """ import pandas as pd # Saving each output (test_stat, pval, nlags, nobs, crit_vals_d, icbest )= tsa.adfuller(ts, **kwargs) adfuller_results = {'Test Statistic': test_stat, "# of Lags Used":nlags, '# of Observations':nobs, 'p-value': round(pval,6), 'alpha': alpha, 'sig/stationary?': pval<alpha} return pd.DataFrame(adfuller_results, index=[label])
# Update to include option for PACF
[docs] def get_sig_lags(ts, type='ACF', nlags=None,alpha=0.5): import pandas as pd if type == 'ACF': # Running the function used by plot_acf corr_values, conf_int = tsa.stattools.acf(ts, alpha=alpha, nlags=nlags) elif type=='PACF': corr_values, conf_int = tsa.stattools.pacf(ts, alpha=alpha, nlags=nlags) else: raise Exception("type must be either 'ACF' or 'PACF'") # Determine lags lags =range(len(corr_values)) # Create a centered version of the acf_df [centered on..0??] corr_df = pd.DataFrame({type:corr_values, 'Lags':lags, 'lower ci': conf_int[:,0]-corr_values, # subtract acf from lower ci to center 'upper ci': conf_int[:,1]-corr_values, # subtact acf to upper ci to center }) corr_df = corr_df.set_index("Lags") # Getting filter for sig lags filter_sig_lags = (corr_df[type] < corr_df['lower ci']) | (corr_df[type] > corr_df['upper ci']) # Get lag #'s sig_lags= corr_df.index[filter_sig_lags] sig_lags = sig_lags[sig_lags!=0] return sig_lags
[docs] def plot_acf_pacf(ts, nlags=40, figsize=(10, 5), annotate_sig=False, alpha=.05, acf_kws={}, pacf_kws={}, annotate_seas=False, m = None, seas_color='black'): import matplotlib.pyplot as plt fig, axes = plt.subplots(nrows=2, figsize=figsize) # Sig lags line style sig_vline_kwargs = dict( ls=':', lw=1, zorder=0, color='red') # ACF tsa.graphics.plot_acf(ts, ax=axes[0], lags=nlags, **acf_kws) ## Annotating sig acf lags if annotate_sig == True: sig_acf_lags = get_sig_lags(ts,nlags=nlags,alpha=alpha, type='ACF') for lag in sig_acf_lags: axes[0].axvline(lag,label='sig', **sig_vline_kwargs ) # PACF tsa.graphics.plot_pacf(ts,ax=axes[1], lags=nlags, **pacf_kws) ## Annotating sig pacf lags if annotate_sig == True: ## ANNOTATING SIG LAGS sig_pacf_lags = get_sig_lags(ts,nlags=nlags,alpha=alpha, type='PACF') for lag in sig_pacf_lags: axes[1].axvline(lag, label='sig', **sig_vline_kwargs) ### ANNOTATE SEASONS if annotate_seas == True: # Ensure m was defined if m is None: raise Exception("Must define value of m if annotate_seas=True.") ## Calculate number of complete seasons to annotate n_seasons = nlags//m # Seasonal Lines style seas_vline_kwargs = dict( ls='--',lw=1, alpha=.7, color=seas_color, zorder=-1) ## for each season, add a line for i in range(1, n_seasons+1): axes[0].axvline(m*i, **seas_vline_kwargs, label="season") axes[1].axvline(m*i, **seas_vline_kwargs, label="season") fig.tight_layout() return fig
[docs] def regression_metrics_ts(ts_true, ts_pred, label="", verbose=True, output_dict=False,): from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score, mean_absolute_percentage_error # Get metrics mae = mean_absolute_error(ts_true, ts_pred) mse = mean_squared_error(ts_true, ts_pred) rmse = mean_squared_error(ts_true, ts_pred, squared=False) r_squared = r2_score(ts_true, ts_pred) mae_perc = mean_absolute_percentage_error(ts_true, ts_pred) * 100 if verbose == True: # Print Result with label header = "---" * 20 print(header, f"Regression Metrics: {label}", header, sep="\n") print(f"- MAE = {mae:,.3f}") print(f"- MSE = {mse:,.3f}") print(f"- RMSE = {rmse:,.3f}") print(f"- R^2 = {r_squared:,.3f}") print(f"- MAPE = {mae_perc:,.2f}%") if output_dict == True: metrics = { "Label": label, "MAE": mae, "MSE": mse, "RMSE": rmse, "R^2": r_squared, "MAPE(%)": mae_perc, } return metrics