<jupyter_start><jupyter_text><jupyter_code>!pip install timemachines
!pip install --upgrade statsmodels<jupyter_output><empty_output><jupyter_text>Example of comparing against naive forecastFor a given univariate time-series y, this runs checks against some time-series models in the timemachines library and reports any that beat the naive forecast. We proceed from models that can generate forecasts quickly to others that are more painful. First a quick plot...<jupyter_code>import numpy as np 
y = np.cumsum(np.random.randn(1000)) # <--- Swap this out for your time series 
from timemachines.skatertools.visualization.priorplot import prior_plot
import matplotlib.pyplot as plt
from timemachines.skaters.simple.movingaverage import EMA_SKATERS

# Plot an example
f = EMA_SKATERS[0]
k = 1 
prior_plot(f=f, k=k, y=y, n=450, n_plot=50)
plt.show()
threshold = 0.95     # What constitutes an interesting error, relative to naive
from pprint import pprint
from timemachines.skatertools.evaluation.evaluators import evaluate_mean_squared_error
from timemachines.skaters.simple.movingaverage import empirical_last_value

def report(y,k=1,models=EMA_SKATERS,n_burn=25, threshold=0.98):
  """
       k         - how many step to foreast ahead
       threshold - fraction of naive forecast error that would constitute an interesting finding
       n_burn    - number of points to toss prior to error evaluation, to allow model to warm up
  """
  lv_err = evaluate_mean_squared_error(f=empirical_last_value, y=y, k=k, a=None, t=None, e=None, r=None, n_burn=n_burn)
  interesting = dict()
  for f in models:
      err = evaluate_mean_squared_error(f=f, y=y, k=1, a=None, t=None, e=None, r=None, n_burn=25)
      if err<threshold*lv_err:
        print(f.__name__+' error is '+str(err)+" versus "+str(lv_err)+' for naive forecast ')
        interesting[f.__name__] = err 
  return interesting<jupyter_output><empty_output><jupyter_text>Fast models....<jupyter_code>from timemachines.skaters.simple.thinking import THINKING_SKATERS
from timemachines.skaters.simple.hypocraticensemble import HYPOCRATIC_ENSEMBLE_SKATERS
FAST_MODELS = EMA_SKATERS + THINKING_SKATERS+HYPOCRATIC_ENSEMBLE_SKATERS
report(y=y,k=k,models=EMA_SKATERS + THINKING_SKATERS+HYPOCRATIC_ENSEMBLE_SKATERS)<jupyter_output><empty_output><jupyter_text>Slow models<jupyter_code>from timemachines.skaters.tsa.alltsaskaters import TSA_SKATERS # might also consider DLM
SLOW_MODELS = TSA_SKATERS
report(y=y,k=k,models=SLOW_MODELS)<jupyter_output><empty_output><jupyter_text>Interminable modelsThis is here really to make the point that some models are intended for one-off forecasting on a historical data set. Don't hold your breath waiting for this to run.<jupyter_code>from timemachines.skaters.prop.prophetskaterssingular import fbprophet_univariate
from timemachines.skaters.nproph.nprophetskaters import NPROPHET_UNIVARIATE_SKATERS
INTERMINABLE_MODELS = [fbprophet_univariate] + NPROPHET_UNIVARIATE_SKATERS
report(y=y,k=k,models=INTERMINABLE_MODELS)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08075148319050758, 'fraction_numerical': 0.007580751483190508, 'mean_word_length': 6.209026128266033, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '63553', 'license': 'MIT', 'n_tokens_mistral': 1084, 'n_tokens_neox': 1015, 'n_words': 256, 'path': 'CompareToNaive.ipynb', 'repo_name': 'iklasky/timemachines', 'size': '3034'}