From 04d69ed68fd2c262daf300a881a786054bcd4432 Mon Sep 17 00:00:00 2001 From: Evan Ray Date: Thu, 7 Nov 2024 09:01:49 -0500 Subject: [PATCH 1/7] init setup for package repo --- .github/workflows/pythonapp-workflow.yml | 3 - README.md | 58 ++----------------- pyproject.toml | 17 ++---- .../__init__.py | 0 src/reichlab_python_template/app.py | 20 ------- src/reichlab_python_template/util/__init__.py | 0 src/reichlab_python_template/util/date.py | 15 ----- src/reichlab_python_template/util/logs.py | 41 ------------- tests/reichlab_python_template/test_app.py | 8 --- .../unit/util/test_date.py | 10 ---- 10 files changed, 11 insertions(+), 161 deletions(-) rename src/{reichlab_python_template => idmodels}/__init__.py (100%) delete mode 100644 src/reichlab_python_template/app.py delete mode 100644 src/reichlab_python_template/util/__init__.py delete mode 100644 src/reichlab_python_template/util/date.py delete mode 100644 src/reichlab_python_template/util/logs.py delete mode 100644 tests/reichlab_python_template/test_app.py delete mode 100644 tests/reichlab_python_template/unit/util/test_date.py diff --git a/.github/workflows/pythonapp-workflow.yml b/.github/workflows/pythonapp-workflow.yml index 137f0b4..cb321bb 100644 --- a/.github/workflows/pythonapp-workflow.yml +++ b/.github/workflows/pythonapp-workflow.yml @@ -16,9 +16,6 @@ jobs: - name: lint run: | ruff check . - - name: type check - run: | - mypy . - name: run tests run: | pytest diff --git a/README.md b/README.md index 608e3cd..2dd7340 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,16 @@ -# reichlab-python-template +# idmodels -[REPLACE WITH A DESCRIPTION OF YOUR PROJECT] - -A Python template for Reich Lab projects. - -This repo contains a Python package with minimal functionality. It serves as a starting point for new projects (it can be selected as the template when creating a new repo in the Reich Lab org). - -There as some opinionated choices here (explained below) which people should override as needed. The main goal is to have a consistent starting point to get up and running with a new Python code base. - -## Getting started - -[REMOVE THIS SECTION AFTER FOLLOWING THE INSTRUCTIONS BELOW] - -If you're using this repo as a template for a new project, make the following changes: - -1. Rename the `reichlab_python_template` directory (under `src`) to the name of your package (no hyphens!). - -2. Replace all instances of `reichlab-python-template` with the name of your repo/project. - -3. Replace all instances of `reichlab_python_template` with the name of your package (remember that Python module names cannot contain hyphens). - -4. Update [`pyproject.toml`](pyproject.toml). This file is required and will describe several aspects of your project. `pyproject.toml` replaces `setup.py` and is described in detail on [Python's packaging website](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/). - -5. Follow the _Setup for local development_ instructions below to ensure that everything works as expected. +A Python module for modeling infectious disease. Currently supports two classes of models: + - gradient boosting quantile regression (`gbqr`) + - seasonal autoregressive integrated models with exogenous covariates (`sarix`) ## Installing and running the package (no development) To install this package via pip: ```bash -pip install git+[GITHUB LINK TO YOUR REPO] -``` - -To run it: -```bash -reichlab_python_template +pip install git+https://github.com/reichlab/idmodels.git ``` ## Setup for local development @@ -58,7 +33,7 @@ Developers will be using a Python virtual environment that: 2. Change to the repo's root directory: ```bash - cd reichlab-python-template + cd idmodels ``` 3. Make sure the correct version of Python is currently active, and create a Python virtual environment: @@ -106,10 +81,6 @@ Prerequisites: The "lockfile" for this project is simply an annotated requirements.txt that is generated by [uv](https://github.com/astral-sh/uv) (uv is a replacement for [pip-compile](https://pypi.org/project/pip-tools/), which could also be used). There's also a requirements-dev.txt file that contains dependencies needed for development (_e.g._, pytest). -While it's possible to use `pip freeze` to generate a detailed lockfile without a third-party tool like `uv`, the output of `pip freeze` doesn't distinguish between direct and indirect dependencies. This distinction probably doesn't matter for a small project, but on a large project, understanding the dependency graph is critical for resolving conflicts. - -Additionally, `uv` (and `pip-compile`) are able to use the list of high-level dependencies in `pyproject.toml` to generate a detailed requirements.txt file, which is a good workflow for keeping everything in sync. - To add or remove a project dependency: 1. Add or remove the dependency in the `[dependencies]` section of `pyproject.toml` (or in the `dev` section of `[project.optional-dependencies]`, if it's a development dependency). Don't pin a specific version, since that will make it harder for users to install the package. @@ -134,20 +105,3 @@ To add or remove a project dependency: # a handy sync option that will cleanup unused dependencies uv pip sync requirements/requirements-dev.txt && python -m pip install -e . ``` - -## Opinionated notes on Python tooling - -[REMOVE THIS SECTION] - -The Python ecosystem is overwhelming! Current opinionated preferences, subject to change: - -- To install and manage various versions of Python: [pyenv](https://github.com/pyenv/pyenv) + a local .python-version file -- To install Python packages that are available from anywhere on the machine, regardless of which Python environment is activated: [pipx](https://pipx.pypa.io/stable/) -- To create and manage Python virtual environments: [venv](https://docs.python.org/3/library/venv.html). - - It's handy having the environment packages right there in the project directory - - Most third-party tools for managing virtual environments (_e.g._, poetry, PDM, pipenv) do _too much_ and get in the way -- To generate requirements files from `pyproject.toml`: ['uv'](https://github.com/astral-sh/uv?tab=readme-ov-file#getting-started). It's new, but it's orders of magnitude faster than `pip-compile`. -- To install dependencies: uv again (again, mostly due to speed; good old pip is another fine option) -- Logging: [structlog](https://www.structlog.org/en/stable/). Python's built-in logging module is tedious. -- Linting and formatting: [ruff](https://github.com/astral-sh/ruff) because it does both and is fast. -- Pre-commit hooks: [pre-commit](https://pre-commit.com/). diff --git a/pyproject.toml b/pyproject.toml index f6b546b..1dec5c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] -name = "reichlab-python-template" -description = "Python template for Reich Lab projects" +name = "idmodels" +description = "A Python module for modeling infectious disease." license = {text = "MIT License"} readme = "README.md" requires-python = ">=3.9" @@ -28,10 +28,7 @@ dev = [ ] [project.urls] -Repository = "https://github.com/reichlab/reichlab-python-template.git" - -[project.entry-points."console_scripts"] -reichlab_python_template = "reichlab_python_template.app:main" +Repository = "https://github.com/reichlab/idmodels.git" [build-system] # Minimum requirements for the build system to execute. @@ -44,11 +41,7 @@ testpaths = [ ] [tools.setuptools] -packages = ["reichlab_python_template"] - -[tool.reichlab_python_template] -# to write json-formatted logs to disk, uncomment the following line specify the file location -# log_file = "/path/to/log/files/rechlab_python_template.log" +packages = ["idmodels"] [tool.ruff] line-length = 120 @@ -61,4 +54,4 @@ inline-quotes = "double" quote-style = "double" [tool.setuptools.dynamic] -version = {attr = "reichlab_python_template.__version__"} +version = {attr = "idmodels.__version__"} diff --git a/src/reichlab_python_template/__init__.py b/src/idmodels/__init__.py similarity index 100% rename from src/reichlab_python_template/__init__.py rename to src/idmodels/__init__.py diff --git a/src/reichlab_python_template/app.py b/src/reichlab_python_template/app.py deleted file mode 100644 index e7505d6..0000000 --- a/src/reichlab_python_template/app.py +++ /dev/null @@ -1,20 +0,0 @@ -import structlog - -from reichlab_python_template.util.date import get_current_date -from reichlab_python_template.util.logs import setup_logging - -setup_logging() -logger = structlog.get_logger() - - -def main(): - """Application entry point.""" - - today = get_current_date() - logger.info("retrieved the date", date=today) - - return f"Hello, today is {today}!" - - -if __name__ == "__main__": - main() diff --git a/src/reichlab_python_template/util/__init__.py b/src/reichlab_python_template/util/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/reichlab_python_template/util/date.py b/src/reichlab_python_template/util/date.py deleted file mode 100644 index dacc3ff..0000000 --- a/src/reichlab_python_template/util/date.py +++ /dev/null @@ -1,15 +0,0 @@ -import datetime - -import structlog - -logger = structlog.get_logger() - - -def get_current_date() -> str: - """Return current date in human-readable format.""" - - logger.info("getting the current date") - current_date = datetime.datetime.now() - formatted_date = current_date.strftime("%B %d, %Y") - - return formatted_date diff --git a/src/reichlab_python_template/util/logs.py b/src/reichlab_python_template/util/logs.py deleted file mode 100644 index f7d4a37..0000000 --- a/src/reichlab_python_template/util/logs.py +++ /dev/null @@ -1,41 +0,0 @@ -import sys - -import structlog - -import reichlab_python_template - - -def add_custom_info(logger, method_name, event_dict): - event_dict["version"] = reichlab_python_template.__version__ - return event_dict - - -def setup_logging(): - shared_processors = [ - add_custom_info, - structlog.processors.TimeStamper(fmt="iso"), - structlog.processors.add_log_level, - structlog.processors.CallsiteParameterAdder( - [ - structlog.processors.CallsiteParameter.FILENAME, - structlog.processors.CallsiteParameter.FUNC_NAME, - ] - ), - ] - - if sys.stderr.isatty(): - # If we're in a terminal, pretty print the logs. - processors = shared_processors + [ - structlog.dev.ConsoleRenderer(), - ] - else: - # Otherwise, output logs in JSON format - processors = shared_processors + [ - structlog.processors.dict_tracebacks, - structlog.processors.JSONRenderer(), - ] - - structlog.configure( - processors=processors, - cache_logger_on_first_use=True, - ) diff --git a/tests/reichlab_python_template/test_app.py b/tests/reichlab_python_template/test_app.py deleted file mode 100644 index 31181c2..0000000 --- a/tests/reichlab_python_template/test_app.py +++ /dev/null @@ -1,8 +0,0 @@ -from freezegun import freeze_time -from reichlab_python_template.app import main - - -@freeze_time("2019-07-13") -def test_main_date(): - output = main() - assert "July 13, 2019" in output diff --git a/tests/reichlab_python_template/unit/util/test_date.py b/tests/reichlab_python_template/unit/util/test_date.py deleted file mode 100644 index f098854..0000000 --- a/tests/reichlab_python_template/unit/util/test_date.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Unit tests for the date module.""" - -from freezegun import freeze_time -from reichlab_python_template.util.date import get_current_date - - -@freeze_time("2024-01-02") -def test_current_date(): - cd = get_current_date() - assert cd == "January 02, 2024" From 8b4ff07ca50f8df6aaa853689c6d5ea626c89de6 Mon Sep 17 00:00:00 2001 From: Evan Ray Date: Thu, 7 Nov 2024 09:23:38 -0500 Subject: [PATCH 2/7] initial drop of code sourced from flusion-experiments --- src/idmodels/gbq.py | 281 +++++++++++++++++++++++++++++++++++++ src/idmodels/preprocess.py | 132 +++++++++++++++++ src/idmodels/sarix.py | 89 ++++++++++++ src/idmodels/utils.py | 30 ++++ 4 files changed, 532 insertions(+) create mode 100644 src/idmodels/gbq.py create mode 100644 src/idmodels/preprocess.py create mode 100644 src/idmodels/sarix.py create mode 100644 src/idmodels/utils.py diff --git a/src/idmodels/gbq.py b/src/idmodels/gbq.py new file mode 100644 index 0000000..9eab98c --- /dev/null +++ b/src/idmodels/gbq.py @@ -0,0 +1,281 @@ +from tqdm.autonotebook import tqdm +import time + +import numpy as np +import pandas as pd + +import lightgbm as lgb + +from iddata.loader import FluDataLoader +from preprocess import create_features_and_targets + + +def run_gbq_flu_model(model_config, run_config): + ''' + Load flu data, generate predictions from a gbq model, and save them as a csv file. + + Parameters + ---------- + model_config: configuration object with settings for the model + run_config: configuration object with settings for the run + ''' + # load flu data + if model_config.reporting_adj: + ilinet_kwargs = None + flusurvnet_kwargs = None + else: + ilinet_kwargs = {'scale_to_positive': False} + flusurvnet_kwargs = {'burden_adj': False} + + fdl = FluDataLoader() + df = fdl.load_data(nhsn_kwargs={'as_of': run_config.ref_date}, + ilinet_kwargs=ilinet_kwargs, + flusurvnet_kwargs=flusurvnet_kwargs, + sources=model_config.sources, + power_transform=model_config.power_transform) + + # augment data with features and target values + df, feat_names = create_features_and_targets( + df = df, + incl_level_feats=model_config.incl_level_feats, + max_horizon=run_config.max_horizon, + curr_feat_names=['inc_trans_cs', 'season_week', 'log_pop']) + + # keep only rows that are in-season + df = df.query("season_week >= 5 and season_week <= 45") + + # "test set" df used to generate look-ahead predictions + df_test = df.loc[df.wk_end_date == df.wk_end_date.max()] \ + .copy() + + # "train set" df for model fitting; target value non-missing + df_train = df.loc[~df['delta_target'].isna().values] + + # train model and obtain test set predictinos + if model_config.fit_locations_separately: + locations = df_test['location'].unique() + preds_df = [ + _train_gbq_and_predict(model_config, run_config, + df_train, df_test, feat_names, location) \ + for location in locations + ] + preds_df = pd.concat(preds_df, axis=0) + else: + preds_df = _train_gbq_and_predict(model_config, run_config, + df_train, df_test, feat_names) + + # save + save_path = _build_save_path( + root=run_config.output_root, + run_config=run_config, + model_config=model_config + ) + preds_df.to_csv(save_path, index=False) + + +def _train_gbq_and_predict(model_config, run_config, + df_train, df_test, feat_names, location = None): + ''' + Train gbq model and get predictions on the original target scale, + formatted in the FluSight hub format. + + Parameters + ---------- + model_config: configuration object with settings for the model + run_config: configuration object with settings for the run + df_train: data frame with training data + df_test: data frame with test data + feat_names: list of names of columns with features + location: optional string of location to fit to. Default, None, fits to all locations + + Returns + ------- + Pandas data frame with test set predictions in FluSight hub format + ''' + # filter to location if necessary + if location is not None: + df_test = df_test.query(f'location == "{location}"') + df_train = df_train.query(f'location == "{location}"') + + # get x and y + x_test = df_test[feat_names] + x_train = df_train[feat_names] + y_train = df_train['delta_target'] + + # test set predictions: + # same number of rows as df_test, one column per quantile level + test_pred_qs_df = _get_test_quantile_predictions( + model_config, run_config, + df_train, x_train, y_train, x_test + ) + + # add predictions to original test df + df_test.reset_index(drop=True, inplace=True) + df_test_w_preds = pd.concat([df_test, test_pred_qs_df], axis=1) + + # melt to get columns into rows, keeping only the things we need to invert data + # transforms later on + cols_to_keep = ['source', 'location', 'wk_end_date', 'pop', + 'inc_trans_cs', 'horizon', + 'inc_trans_center_factor', 'inc_trans_scale_factor'] + preds_df = df_test_w_preds[cols_to_keep + run_config.q_labels] + preds_df = preds_df.loc[(preds_df['source'] == 'nhsn')] + preds_df = pd.melt(preds_df, + id_vars=cols_to_keep, + var_name='quantile', + value_name = 'delta_hat') + + # build data frame with predictions on the original scale + preds_df['inc_trans_cs_target_hat'] = preds_df['inc_trans_cs'] + preds_df['delta_hat'] + preds_df['inc_trans_target_hat'] = (preds_df['inc_trans_cs_target_hat'] + preds_df['inc_trans_center_factor']) * (preds_df['inc_trans_scale_factor'] + 0.01) + if model_config.power_transform == '4rt': + inv_power = 4 + elif model_config.power_transform is None: + inv_power = 1 + else: + raise ValueError('unsupported power_transform: must be "4rt" or None') + + preds_df['value'] = (np.maximum(preds_df['inc_trans_target_hat'], 0.0) ** inv_power - 0.01 - 0.75**4) * preds_df['pop'] / 100000 + preds_df['value'] = np.maximum(preds_df['value'], 0.0) + + # get predictions into the format needed for FluSight hub submission + preds_df = _format_as_flusight_output(preds_df, run_config.ref_date) + + # sort quantiles to avoid quantile crossing + preds_df = _quantile_noncrossing( + preds_df, + gcols = ['location', 'reference_date', 'horizon', 'target_end_date', + 'target', 'output_type'] + ) + + return preds_df + + +def _get_test_quantile_predictions(model_config, run_config, + df_train, x_train, y_train, x_test): + ''' + Train the model on bagged subsets of the training data and obtain + quantile predictions. This is the heart of the method. + + Parameters + ---------- + model_config: configuration object with settings for the model + run_config: configuration object with settings for the run + df_train: Pandas data frame with training data + x_train: numpy array with training instances in rows, features in columns + y_train: numpy array with target values + x_test: numpy array with test instances in rows, features in columns + + Returns + ------- + Pandas data frame with test set predictions. The number of rows matches + the number of rows of `x_test`. The number of columns matches the number + of quantile levels for predictions as specified in the `run_config`. + Column names are given by `run_config.q_labels`. + ''' + # seed for random number generation, based on reference date + rng_seed = int(time.mktime(run_config.ref_date.timetuple())) + rng = np.random.default_rng(seed=rng_seed) + # seeds for lgb model fits, one per combination of bag and quantile level + lgb_seeds = rng.integers(1e8, size=(model_config.num_bags, len(run_config.q_levels))) + + # training loop over bags + test_preds_by_bag = np.empty((x_test.shape[0], model_config.num_bags, len(run_config.q_levels))) + + train_seasons = df_train['season'].unique() + + feat_importance = list() + + for b in tqdm(range(model_config.num_bags), 'Bag number'): + # get indices of observations that are in bag + bag_seasons = rng.choice( + train_seasons, + size = int(len(train_seasons) * model_config.bag_frac_samples), + replace=False) + bag_obs_inds = df_train['season'].isin(bag_seasons) + + for q_ind, q_level in enumerate(run_config.q_levels): + # fit to bag + model = lgb.LGBMRegressor( + verbosity=-1, + objective='quantile', + alpha=q_level, + random_state=lgb_seeds[b, q_ind]) + model.fit(X=x_train.loc[bag_obs_inds, :], y=y_train.loc[bag_obs_inds]) + + feat_importance.append( + pd.DataFrame({ + 'feat': x_train.columns, + 'importance': model.feature_importances_, + 'b': b, + 'q_level': q_level + }) + ) + + # test set predictions + test_preds_by_bag[:, b, q_ind] = model.predict(X=x_test) + + # combine and save feature importance scores + if run_config.save_feat_importance: + feat_importance = pd.concat(feat_importance, axis=0) + save_path = _build_save_path( + root=run_config.artifact_store_root, + run_config=run_config, + model_config=model_config, + subdir='feat_importance') + feat_importance.to_csv(save_path, index=False) + + # combined predictions across bags: median + test_pred_qs = np.median(test_preds_by_bag, axis=1) + + # test predictions as a data frame, one column per quantile level + test_pred_qs_df = pd.DataFrame(test_pred_qs) + test_pred_qs_df.columns = run_config.q_labels + + return test_pred_qs_df + + +def _format_as_flusight_output(preds_df, ref_date): + # keep just required columns and rename to match hub format + preds_df = preds_df[['location', 'wk_end_date', 'horizon', 'quantile', 'value']] \ + .rename(columns={'quantile': 'output_type_id'}) + + preds_df['target_end_date'] = preds_df['wk_end_date'] + pd.to_timedelta(7*preds_df['horizon'], unit='days') + preds_df['reference_date'] = ref_date + preds_df['horizon'] = preds_df['horizon'] - 2 + preds_df['target'] = 'wk inc flu hosp' + + preds_df['output_type'] = 'quantile' + preds_df.drop(columns='wk_end_date', inplace=True) + + return preds_df + + +def _quantile_noncrossing(preds_df, gcols): + ''' + Sort predictions to be in alignment with quantile levels, to prevent + quantile crossing. + + Parameters + ---------- + preds_df: data frame with quantile predictions + gcols: columns to group by; predictions will be sorted within those groups + + Returns + ------- + Sorted version of preds_df, guaranteed not to have quantile crossing + ''' + g = preds_df.set_index(gcols).groupby(gcols) + preds_df = g[['output_type_id', 'value']] \ + .transform(lambda x: x.sort_values()) \ + .reset_index() + + return preds_df + + +def _build_save_path(root, run_config, model_config, subdir=None): + save_dir = root / f'UMass-{model_config.model_name}' + if subdir is not None: + save_dir = save_dir / subdir + save_dir.mkdir(parents=True, exist_ok=True) + return save_dir / f'{str(run_config.ref_date)}-UMass-{model_config.model_name}.csv' diff --git a/src/idmodels/preprocess.py b/src/idmodels/preprocess.py new file mode 100644 index 0000000..6ac3f59 --- /dev/null +++ b/src/idmodels/preprocess.py @@ -0,0 +1,132 @@ +import fnmatch + +import pandas as pd + +from timeseriesutils import featurize +from data_pipeline.utils import get_holidays + + +def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_names = []): + ''' + Create features and targets for prediction + + Parameters + ---------- + df: pandas dataframe + data frame with data to "featurize" + incl_level_feats: boolean + include features that are a measure of local level of the signal? + max_horizon: int + maximum forecast horizon + curr_feat_names: list of strings + list of names of columns in `df` containing existing features + + Returns + ------- + tuple with: + - the input data frame, augmented with additional columns with feature and + target values + - a list of all feature names, columns in the data frame + ''' + + # current features; will be updated + feat_names = curr_feat_names + + # one-hot encodings of data source, agg_level, and location + for c in ['source', 'agg_level', 'location']: + ohe = pd.get_dummies(df[c], prefix=c) + df = pd.concat([df, ohe], axis=1) + feat_names = feat_names + list(ohe.columns) + + # season week relative to christmas + df = df.merge( + get_holidays() \ + .query("holiday == 'Christmas Day'") \ + .drop(columns=['holiday', 'date']) \ + .rename(columns={'season_week': 'xmas_week'}), + how='left', + on='season') \ + .assign(delta_xmas = lambda x: x['season_week'] - x['xmas_week']) + + feat_names = feat_names + ['delta_xmas'] + + # features summarizing data within each combination of source and location + df, new_feat_names = featurize.featurize_data( + df, group_columns=['source', 'location'], + features = [ + { + 'fun': 'windowed_taylor_coefs', + 'args': { + 'columns': 'inc_trans_cs', + 'taylor_degree': 2, + 'window_align': 'trailing', + 'window_size': [4, 6], + 'fill_edges': False + } + }, + { + 'fun': 'windowed_taylor_coefs', + 'args': { + 'columns': 'inc_trans_cs', + 'taylor_degree': 1, + 'window_align': 'trailing', + 'window_size': [3, 5], + 'fill_edges': False + } + }, + { + 'fun': 'rollmean', + 'args': { + 'columns': 'inc_trans_cs', + 'group_columns': ['location'], + 'window_size': [2, 4] + } + } + ]) + feat_names = feat_names + new_feat_names + + df, new_feat_names = featurize.featurize_data( + df, group_columns=['source', 'location'], + features = [ + { + 'fun': 'lag', + 'args': { + 'columns': ['inc_trans_cs'] + new_feat_names, + 'lags': [1, 2] + } + } + ]) + feat_names = feat_names + new_feat_names + + # add forecast targets + df, new_feat_names = featurize.featurize_data( + df, group_columns=['source', 'location'], + features = [ + { + 'fun': 'horizon_targets', + 'args': { + 'columns': 'inc_trans_cs', + 'horizons': [(i + 1) for i in range(max_horizon)] + } + } + ]) + feat_names = feat_names + new_feat_names + + # we will model the differences between the prediction target and the most + # recent observed value + df['delta_target'] = df['inc_trans_cs_target'] - df['inc_trans_cs'] + + # if requested, drop features that involve absolute level + if not incl_level_feats: + feat_names = _drop_level_feats(feat_names) + + return df, feat_names + + +def _drop_level_feats(feat_names): + level_feats = ['inc_trans_cs', 'inc_trans_cs_lag1', 'inc_trans_cs_lag2'] + \ + fnmatch.filter(feat_names, '*taylor_d?_c0*') + \ + fnmatch.filter(feat_names, '*inc_trans_cs_rollmean*') + feat_names = [f for f in feat_names if f not in level_feats] + return feat_names + diff --git a/src/idmodels/sarix.py b/src/idmodels/sarix.py new file mode 100644 index 0000000..c7e95a6 --- /dev/null +++ b/src/idmodels/sarix.py @@ -0,0 +1,89 @@ +from pathlib import Path + +import numpy as np +import pandas as pd + +from iddata.loader import FluDataLoader +from iddata.utils import get_holidays + +from sarix import sarix +from utils import parse_args, build_save_path + +def get_sarix_preds(model_config, run_config): + fdl = FluDataLoader() + df = fdl.load_data(nhsn_kwargs={'as_of': run_config.ref_date}, + sources=model_config.sources, + power_transform=model_config.power_transform) + + # season week relative to christmas + df = df.merge( + get_holidays() \ + .query("holiday == 'Christmas Day'") \ + .drop(columns=['holiday', 'date']) \ + .rename(columns={'season_week': 'xmas_week'}), + how='left', + on='season') \ + .assign(delta_xmas = lambda x: x['season_week'] - x['xmas_week']) + df['xmas_spike'] = np.maximum(3 - np.abs(df['delta_xmas']), 0) + + xy_colnames = ["inc_trans_cs"] + model_config.x + batched_xy = df[xy_colnames].values.reshape(len(df['location'].unique()), -1, len(xy_colnames)) + + sarix_fit_all_locs_theta_pooled = sarix.SARIX( + xy = batched_xy, + p = model_config.p, + d = model_config.d, + P = model_config.P, + D = model_config.D, + season_period = model_config.season_period, + transform='none', # transformations are handled outside of SARIX + theta_pooling=model_config.theta_pooling, + sigma_pooling=model_config.sigma_pooling, + forecast_horizon = run_config.max_horizon, + num_warmup = run_config.num_warmup, + num_samples = run_config.num_samples, + num_chains = run_config.num_chains) + + pred_qs = np.percentile(sarix_fit_all_locs_theta_pooled.predictions[..., :, :, 0], + np.array(run_config.q_levels) * 100, axis=0) + + df_nhsn_last_obs = df.groupby(['location']).tail(1) + + preds_df = pd.concat([ + pd.DataFrame(pred_qs[i, :, :]) \ + .set_axis(df_nhsn_last_obs['location'], axis='index') \ + .set_axis(np.arange(1, run_config.max_horizon+1), axis='columns') \ + .assign(output_type_id = q_label) \ + for i, q_label in enumerate(run_config.q_labels) + ]) \ + .reset_index() \ + .melt(['location', 'output_type_id'], var_name='horizon') \ + .merge(df_nhsn_last_obs, on='location', how='left') + + # build data frame with predictions on the original scale + preds_df['value'] = (preds_df['value'] + preds_df['inc_trans_center_factor']) * preds_df['inc_trans_scale_factor'] + if model_config.power_transform == '4rt': + preds_df['value'] = np.maximum(preds_df['value'], 0.0) ** 4 + else: + preds_df['value'] = np.maximum(preds_df['value'], 0.0) ** 2 + + preds_df['value'] = (preds_df['value'] - 0.01 - 0.75**4) * preds_df['pop'] / 100000 + preds_df['value'] = np.maximum(preds_df['value'], 0.0) + + # keep just required columns and rename to match hub format + preds_df = preds_df[['location', 'wk_end_date', 'horizon', 'output_type_id', 'value']] + + preds_df['target_end_date'] = preds_df['wk_end_date'] + pd.to_timedelta(7*preds_df['horizon'], unit='days') + preds_df['reference_date'] = run_config.ref_date + preds_df['horizon'] = preds_df['horizon'] - 2 + preds_df['output_type'] = 'quantile' + preds_df['target'] = 'wk inc flu hosp' + preds_df.drop(columns='wk_end_date', inplace=True) + + # save + save_path = build_save_path( + root=run_config.output_root, + run_config=run_config, + model_config=model_config + ) + preds_df.to_csv(save_path, index=False) diff --git a/src/idmodels/utils.py b/src/idmodels/utils.py new file mode 100644 index 0000000..c1fca29 --- /dev/null +++ b/src/idmodels/utils.py @@ -0,0 +1,30 @@ +# This is a copy of ../gbq/utils.py +# with updated model_name choices +# In a future refactor, we should consolidate + +import datetime + +def _validate_ref_date(ref_date): + if ref_date is None: + today = datetime.date.today() + + # next Saturday: weekly forecasts are relative to this date + ref_date = today - datetime.timedelta((today.weekday() + 2) % 7 - 7) + + return ref_date + elif isinstance(ref_date, datetime.date): + # check that it's a Saturday + if ref_date.weekday() != 5: + raise ValueError('ref_date must be a Saturday') + + return ref_date + else: + raise TypeError('ref_date must be a datetime.date object') + + +def build_save_path(root, run_config, model_config, subdir=None): + save_dir = root / f'UMass-{model_config.model_name}' + if subdir is not None: + save_dir = save_dir / subdir + save_dir.mkdir(parents=True, exist_ok=True) + return save_dir / f'{str(run_config.ref_date)}-UMass-{model_config.model_name}.csv' From 8a3a91061a5c49a7ed53fe14f6c1d081ac2139ef Mon Sep 17 00:00:00 2001 From: Evan Ray Date: Thu, 7 Nov 2024 11:25:22 -0500 Subject: [PATCH 3/7] basic setup with some integration tests --- pyproject.toml | 16 +- requirements/requirements-dev.txt | 252 +++++++-- requirements/requirements.txt | 208 +++++++- src/idmodels/gbq.py | 281 ---------- src/idmodels/gbqr.py | 279 ++++++++++ src/idmodels/preprocess.py | 4 +- src/idmodels/sarix.py | 163 +++--- src/idmodels/utils.py | 2 +- ...2024-01-06-UMass-gbqr_no_reporting_adj.csv | 478 ++++++++++++++++++ ...ass-sarix_p6_4rt_thetashared_sigmanone.csv | 478 ++++++++++++++++++ tests/integration/data/plot_test_data.R | 43 ++ tests/integration/test_gbqr.py | 59 +++ tests/integration/test_sarix.py | 65 +++ tests/unit/gbqr/test_drop_level_feats.py | 56 ++ 14 files changed, 1961 insertions(+), 423 deletions(-) delete mode 100644 src/idmodels/gbq.py create mode 100644 src/idmodels/gbqr.py create mode 100644 tests/integration/data/UMass-gbqr_no_reporting_adj/2024-01-06-UMass-gbqr_no_reporting_adj.csv create mode 100644 tests/integration/data/UMass-sarix_p6_4rt_thetashared_sigmanone/2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv create mode 100644 tests/integration/data/plot_test_data.R create mode 100644 tests/integration/test_gbqr.py create mode 100644 tests/integration/test_sarix.py create mode 100644 tests/unit/gbqr/test_drop_level_feats.py diff --git a/pyproject.toml b/pyproject.toml index 1dec5c9..6bdfb3e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,20 +11,22 @@ classifiers = [ dynamic = ["version"] dependencies = [ - "structlog", - "rich", - "toml" + "iddata @ git+https://github.com/reichlab/iddata", + "lightgbm", + "numpy", + "pandas", + "sarix @ git+https://github.com/elray1/sarix", + "scikit-learn", + "tqdm", + "timeseriesutils @ git+https://github.com/reichlab/timeseriesutils" ] [project.optional-dependencies] dev = [ "coverage", - "freezegun", - "mypy", "pre-commit", "pytest", - "ruff", - "types-toml", + "ruff" ] [project.urls] diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index 1bcea02..cc9e902 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -1,65 +1,233 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --extra=dev --output-file=requirements/requirements-dev.txt -# +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml --extra dev -o requirements/requirements-dev.txt +aiobotocore==2.15.2 + # via s3fs +aiohappyeyeballs==2.4.3 + # via aiohttp +aiohttp==3.10.10 + # via + # aiobotocore + # delphi-epidata + # s3fs +aioitertools==0.12.0 + # via aiobotocore +aiosignal==1.3.1 + # via aiohttp +attrs==24.2.0 + # via + # aiohttp + # pymmwr +botocore==1.35.36 + # via aiobotocore +certifi==2024.8.30 + # via + # pyogrio + # pyproj + # requests cfgv==3.4.0 # via pre-commit -coverage==7.5.1 - # via python-app (pyproject.toml) -distlib==0.3.8 +charset-normalizer==3.4.0 + # via requests +contourpy==1.3.0 + # via matplotlib +coverage==7.6.4 + # via idmodels (pyproject.toml) +covidcast==0.1.5 + # via sarix +cycler==0.12.1 + # via matplotlib +delphi-epidata==4.1.25 + # via covidcast +descartes==1.1.0 + # via covidcast +distlib==0.3.9 # via virtualenv -filelock==3.14.0 +epiweeks==2.3.0 + # via covidcast +filelock==3.16.1 # via virtualenv -freezegun==1.5.0 - # via python-app (pyproject.toml) -identify==2.5.36 +fonttools==4.54.1 + # via matplotlib +frozenlist==1.5.0 + # via + # aiohttp + # aiosignal +fsspec==2024.10.0 + # via s3fs +geopandas==1.0.1 + # via covidcast +iddata @ git+https://github.com/reichlab/iddata@34751de1d155637ae93c4ddc35886dd8102e56ef + # via idmodels (pyproject.toml) +identify==2.6.1 # via pre-commit +idna==3.10 + # via + # requests + # yarl +imageio==2.36.0 + # via covidcast +imageio-ffmpeg==0.5.1 + # via covidcast iniconfig==2.0.0 # via pytest +jax==0.4.35 + # via + # numpyro + # sarix +jaxlib==0.4.35 + # via + # jax + # numpyro +jmespath==1.0.1 + # via botocore +joblib==1.4.2 + # via scikit-learn +kiwisolver==1.4.7 + # via matplotlib +lightgbm==4.5.0 + # via idmodels (pyproject.toml) markdown-it-py==3.0.0 # via rich +matplotlib==3.9.2 + # via + # covidcast + # descartes + # sarix mdurl==0.1.2 # via markdown-it-py -mypy==1.10.0 - # via python-app (pyproject.toml) -mypy-extensions==1.0.0 - # via mypy -nodeenv==1.8.0 +ml-dtypes==0.5.0 + # via + # jax + # jaxlib +multidict==6.1.0 + # via + # aiohttp + # yarl +multipledispatch==1.0.0 + # via numpyro +nodeenv==1.9.1 # via pre-commit -packaging==24.0 - # via pytest -platformdirs==4.2.1 +numpy==2.1.3 + # via + # idmodels (pyproject.toml) + # contourpy + # covidcast + # geopandas + # iddata + # imageio + # jax + # jaxlib + # lightgbm + # matplotlib + # ml-dtypes + # numpyro + # pandas + # pyogrio + # sarix + # scikit-learn + # scipy + # shapely + # timeseriesutils +numpyro==0.15.3 + # via sarix +opt-einsum==3.4.0 + # via jax +packaging==24.1 + # via + # geopandas + # matplotlib + # pyogrio + # pytest +pandas==2.2.3 + # via + # idmodels (pyproject.toml) + # covidcast + # geopandas + # iddata + # sarix + # timeseriesutils +pillow==11.0.0 + # via + # imageio + # matplotlib +platformdirs==4.3.6 # via virtualenv pluggy==1.5.0 # via pytest -pre-commit==3.7.0 - # via python-app (pyproject.toml) +pre-commit==4.0.1 + # via idmodels (pyproject.toml) +propcache==0.2.0 + # via yarl pygments==2.18.0 # via rich -pytest==8.2.0 - # via python-app (pyproject.toml) +pymmwr==0.2.2 + # via iddata +pyogrio==0.10.0 + # via geopandas +pyparsing==3.2.0 + # via matplotlib +pyproj==3.7.0 + # via geopandas +pytest==8.3.3 + # via idmodels (pyproject.toml) python-dateutil==2.9.0.post0 - # via freezegun -pyyaml==6.0.1 + # via + # botocore + # matplotlib + # pandas +pytz==2024.2 + # via pandas +pyyaml==6.0.2 # via pre-commit -rich==13.7.1 - # via python-app (pyproject.toml) -ruff==0.4.3 - # via python-app (pyproject.toml) +requests==2.32.3 + # via + # covidcast + # delphi-epidata +rich==13.9.4 + # via iddata +ruff==0.7.2 + # via idmodels (pyproject.toml) +s3fs==2024.10.0 + # via iddata +sarix @ git+https://github.com/elray1/sarix@61a651c8ab5f09b0509a1cecbda4e7cefb42e8cc + # via idmodels (pyproject.toml) +scikit-learn==1.5.2 + # via idmodels (pyproject.toml) +scipy==1.14.1 + # via + # jax + # jaxlib + # lightgbm + # scikit-learn + # timeseriesutils +setuptools==75.3.0 + # via imageio-ffmpeg +shapely==2.0.6 + # via geopandas six==1.16.0 # via python-dateutil -structlog==24.1.0 - # via python-app (pyproject.toml) +tenacity==9.0.0 + # via delphi-epidata +threadpoolctl==3.5.0 + # via scikit-learn +timeseriesutils @ git+https://github.com/reichlab/timeseriesutils@d25f33db30a8d5252329269ec9d205984f980f6c + # via idmodels (pyproject.toml) toml==0.10.2 - # via python-app (pyproject.toml) -types-toml==0.10.8.20240310 - # via python-app (pyproject.toml) -typing-extensions==4.11.0 - # via mypy -virtualenv==20.26.1 + # via iddata +tqdm==4.67.0 + # via + # idmodels (pyproject.toml) + # covidcast + # numpyro +tzdata==2024.2 + # via pandas +urllib3==2.2.3 + # via + # botocore + # requests +virtualenv==20.27.1 # via pre-commit - -# The following packages are considered to be unsafe in a requirements file: -# setuptools +wrapt==1.16.0 + # via aiobotocore +yarl==1.17.1 + # via aiohttp diff --git a/requirements/requirements.txt b/requirements/requirements.txt index f535bab..fcd50f7 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -1,18 +1,204 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile --output-file=requirements/requirements.txt -# +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml -o requirements/requirements.txt +aiobotocore==2.15.2 + # via s3fs +aiohappyeyeballs==2.4.3 + # via aiohttp +aiohttp==3.10.10 + # via + # aiobotocore + # delphi-epidata + # s3fs +aioitertools==0.12.0 + # via aiobotocore +aiosignal==1.3.1 + # via aiohttp +attrs==24.2.0 + # via + # aiohttp + # pymmwr +botocore==1.35.36 + # via aiobotocore +certifi==2024.8.30 + # via + # pyogrio + # pyproj + # requests +charset-normalizer==3.4.0 + # via requests +contourpy==1.3.0 + # via matplotlib +covidcast==0.1.5 + # via sarix +cycler==0.12.1 + # via matplotlib +delphi-epidata==4.1.25 + # via covidcast +descartes==1.1.0 + # via covidcast +epiweeks==2.3.0 + # via covidcast +fonttools==4.54.1 + # via matplotlib +frozenlist==1.5.0 + # via + # aiohttp + # aiosignal +fsspec==2024.10.0 + # via s3fs +geopandas==1.0.1 + # via covidcast +iddata @ git+https://github.com/reichlab/iddata@34751de1d155637ae93c4ddc35886dd8102e56ef + # via idmodels (pyproject.toml) +idna==3.10 + # via + # requests + # yarl +imageio==2.36.0 + # via covidcast +imageio-ffmpeg==0.5.1 + # via covidcast +jax==0.4.35 + # via + # numpyro + # sarix +jaxlib==0.4.35 + # via + # jax + # numpyro +jmespath==1.0.1 + # via botocore +joblib==1.4.2 + # via scikit-learn +kiwisolver==1.4.7 + # via matplotlib +lightgbm==4.5.0 + # via idmodels (pyproject.toml) markdown-it-py==3.0.0 # via rich +matplotlib==3.9.2 + # via + # covidcast + # descartes + # sarix mdurl==0.1.2 # via markdown-it-py +ml-dtypes==0.5.0 + # via + # jax + # jaxlib +multidict==6.1.0 + # via + # aiohttp + # yarl +multipledispatch==1.0.0 + # via numpyro +numpy==2.1.3 + # via + # idmodels (pyproject.toml) + # contourpy + # covidcast + # geopandas + # iddata + # imageio + # jax + # jaxlib + # lightgbm + # matplotlib + # ml-dtypes + # numpyro + # pandas + # pyogrio + # sarix + # scikit-learn + # scipy + # shapely + # timeseriesutils +numpyro==0.15.3 + # via sarix +opt-einsum==3.4.0 + # via jax +packaging==24.1 + # via + # geopandas + # matplotlib + # pyogrio +pandas==2.2.3 + # via + # idmodels (pyproject.toml) + # covidcast + # geopandas + # iddata + # sarix + # timeseriesutils +pillow==11.0.0 + # via + # imageio + # matplotlib +propcache==0.2.0 + # via yarl pygments==2.18.0 # via rich -rich==13.7.1 - # via python-app (pyproject.toml) -structlog==24.1.0 - # via python-app (pyproject.toml) +pymmwr==0.2.2 + # via iddata +pyogrio==0.10.0 + # via geopandas +pyparsing==3.2.0 + # via matplotlib +pyproj==3.7.0 + # via geopandas +python-dateutil==2.9.0.post0 + # via + # botocore + # matplotlib + # pandas +pytz==2024.2 + # via pandas +requests==2.32.3 + # via + # covidcast + # delphi-epidata +rich==13.9.4 + # via iddata +s3fs==2024.10.0 + # via iddata +sarix @ git+https://github.com/elray1/sarix@61a651c8ab5f09b0509a1cecbda4e7cefb42e8cc + # via idmodels (pyproject.toml) +scikit-learn==1.5.2 + # via idmodels (pyproject.toml) +scipy==1.14.1 + # via + # jax + # jaxlib + # lightgbm + # scikit-learn + # timeseriesutils +setuptools==75.3.0 + # via imageio-ffmpeg +shapely==2.0.6 + # via geopandas +six==1.16.0 + # via python-dateutil +tenacity==9.0.0 + # via delphi-epidata +threadpoolctl==3.5.0 + # via scikit-learn +timeseriesutils @ git+https://github.com/reichlab/timeseriesutils@d25f33db30a8d5252329269ec9d205984f980f6c + # via idmodels (pyproject.toml) toml==0.10.2 - # via python-app (pyproject.toml) + # via iddata +tqdm==4.67.0 + # via + # idmodels (pyproject.toml) + # covidcast + # numpyro +tzdata==2024.2 + # via pandas +urllib3==2.2.3 + # via + # botocore + # requests +wrapt==1.16.0 + # via aiobotocore +yarl==1.17.1 + # via aiohttp diff --git a/src/idmodels/gbq.py b/src/idmodels/gbq.py deleted file mode 100644 index 9eab98c..0000000 --- a/src/idmodels/gbq.py +++ /dev/null @@ -1,281 +0,0 @@ -from tqdm.autonotebook import tqdm -import time - -import numpy as np -import pandas as pd - -import lightgbm as lgb - -from iddata.loader import FluDataLoader -from preprocess import create_features_and_targets - - -def run_gbq_flu_model(model_config, run_config): - ''' - Load flu data, generate predictions from a gbq model, and save them as a csv file. - - Parameters - ---------- - model_config: configuration object with settings for the model - run_config: configuration object with settings for the run - ''' - # load flu data - if model_config.reporting_adj: - ilinet_kwargs = None - flusurvnet_kwargs = None - else: - ilinet_kwargs = {'scale_to_positive': False} - flusurvnet_kwargs = {'burden_adj': False} - - fdl = FluDataLoader() - df = fdl.load_data(nhsn_kwargs={'as_of': run_config.ref_date}, - ilinet_kwargs=ilinet_kwargs, - flusurvnet_kwargs=flusurvnet_kwargs, - sources=model_config.sources, - power_transform=model_config.power_transform) - - # augment data with features and target values - df, feat_names = create_features_and_targets( - df = df, - incl_level_feats=model_config.incl_level_feats, - max_horizon=run_config.max_horizon, - curr_feat_names=['inc_trans_cs', 'season_week', 'log_pop']) - - # keep only rows that are in-season - df = df.query("season_week >= 5 and season_week <= 45") - - # "test set" df used to generate look-ahead predictions - df_test = df.loc[df.wk_end_date == df.wk_end_date.max()] \ - .copy() - - # "train set" df for model fitting; target value non-missing - df_train = df.loc[~df['delta_target'].isna().values] - - # train model and obtain test set predictinos - if model_config.fit_locations_separately: - locations = df_test['location'].unique() - preds_df = [ - _train_gbq_and_predict(model_config, run_config, - df_train, df_test, feat_names, location) \ - for location in locations - ] - preds_df = pd.concat(preds_df, axis=0) - else: - preds_df = _train_gbq_and_predict(model_config, run_config, - df_train, df_test, feat_names) - - # save - save_path = _build_save_path( - root=run_config.output_root, - run_config=run_config, - model_config=model_config - ) - preds_df.to_csv(save_path, index=False) - - -def _train_gbq_and_predict(model_config, run_config, - df_train, df_test, feat_names, location = None): - ''' - Train gbq model and get predictions on the original target scale, - formatted in the FluSight hub format. - - Parameters - ---------- - model_config: configuration object with settings for the model - run_config: configuration object with settings for the run - df_train: data frame with training data - df_test: data frame with test data - feat_names: list of names of columns with features - location: optional string of location to fit to. Default, None, fits to all locations - - Returns - ------- - Pandas data frame with test set predictions in FluSight hub format - ''' - # filter to location if necessary - if location is not None: - df_test = df_test.query(f'location == "{location}"') - df_train = df_train.query(f'location == "{location}"') - - # get x and y - x_test = df_test[feat_names] - x_train = df_train[feat_names] - y_train = df_train['delta_target'] - - # test set predictions: - # same number of rows as df_test, one column per quantile level - test_pred_qs_df = _get_test_quantile_predictions( - model_config, run_config, - df_train, x_train, y_train, x_test - ) - - # add predictions to original test df - df_test.reset_index(drop=True, inplace=True) - df_test_w_preds = pd.concat([df_test, test_pred_qs_df], axis=1) - - # melt to get columns into rows, keeping only the things we need to invert data - # transforms later on - cols_to_keep = ['source', 'location', 'wk_end_date', 'pop', - 'inc_trans_cs', 'horizon', - 'inc_trans_center_factor', 'inc_trans_scale_factor'] - preds_df = df_test_w_preds[cols_to_keep + run_config.q_labels] - preds_df = preds_df.loc[(preds_df['source'] == 'nhsn')] - preds_df = pd.melt(preds_df, - id_vars=cols_to_keep, - var_name='quantile', - value_name = 'delta_hat') - - # build data frame with predictions on the original scale - preds_df['inc_trans_cs_target_hat'] = preds_df['inc_trans_cs'] + preds_df['delta_hat'] - preds_df['inc_trans_target_hat'] = (preds_df['inc_trans_cs_target_hat'] + preds_df['inc_trans_center_factor']) * (preds_df['inc_trans_scale_factor'] + 0.01) - if model_config.power_transform == '4rt': - inv_power = 4 - elif model_config.power_transform is None: - inv_power = 1 - else: - raise ValueError('unsupported power_transform: must be "4rt" or None') - - preds_df['value'] = (np.maximum(preds_df['inc_trans_target_hat'], 0.0) ** inv_power - 0.01 - 0.75**4) * preds_df['pop'] / 100000 - preds_df['value'] = np.maximum(preds_df['value'], 0.0) - - # get predictions into the format needed for FluSight hub submission - preds_df = _format_as_flusight_output(preds_df, run_config.ref_date) - - # sort quantiles to avoid quantile crossing - preds_df = _quantile_noncrossing( - preds_df, - gcols = ['location', 'reference_date', 'horizon', 'target_end_date', - 'target', 'output_type'] - ) - - return preds_df - - -def _get_test_quantile_predictions(model_config, run_config, - df_train, x_train, y_train, x_test): - ''' - Train the model on bagged subsets of the training data and obtain - quantile predictions. This is the heart of the method. - - Parameters - ---------- - model_config: configuration object with settings for the model - run_config: configuration object with settings for the run - df_train: Pandas data frame with training data - x_train: numpy array with training instances in rows, features in columns - y_train: numpy array with target values - x_test: numpy array with test instances in rows, features in columns - - Returns - ------- - Pandas data frame with test set predictions. The number of rows matches - the number of rows of `x_test`. The number of columns matches the number - of quantile levels for predictions as specified in the `run_config`. - Column names are given by `run_config.q_labels`. - ''' - # seed for random number generation, based on reference date - rng_seed = int(time.mktime(run_config.ref_date.timetuple())) - rng = np.random.default_rng(seed=rng_seed) - # seeds for lgb model fits, one per combination of bag and quantile level - lgb_seeds = rng.integers(1e8, size=(model_config.num_bags, len(run_config.q_levels))) - - # training loop over bags - test_preds_by_bag = np.empty((x_test.shape[0], model_config.num_bags, len(run_config.q_levels))) - - train_seasons = df_train['season'].unique() - - feat_importance = list() - - for b in tqdm(range(model_config.num_bags), 'Bag number'): - # get indices of observations that are in bag - bag_seasons = rng.choice( - train_seasons, - size = int(len(train_seasons) * model_config.bag_frac_samples), - replace=False) - bag_obs_inds = df_train['season'].isin(bag_seasons) - - for q_ind, q_level in enumerate(run_config.q_levels): - # fit to bag - model = lgb.LGBMRegressor( - verbosity=-1, - objective='quantile', - alpha=q_level, - random_state=lgb_seeds[b, q_ind]) - model.fit(X=x_train.loc[bag_obs_inds, :], y=y_train.loc[bag_obs_inds]) - - feat_importance.append( - pd.DataFrame({ - 'feat': x_train.columns, - 'importance': model.feature_importances_, - 'b': b, - 'q_level': q_level - }) - ) - - # test set predictions - test_preds_by_bag[:, b, q_ind] = model.predict(X=x_test) - - # combine and save feature importance scores - if run_config.save_feat_importance: - feat_importance = pd.concat(feat_importance, axis=0) - save_path = _build_save_path( - root=run_config.artifact_store_root, - run_config=run_config, - model_config=model_config, - subdir='feat_importance') - feat_importance.to_csv(save_path, index=False) - - # combined predictions across bags: median - test_pred_qs = np.median(test_preds_by_bag, axis=1) - - # test predictions as a data frame, one column per quantile level - test_pred_qs_df = pd.DataFrame(test_pred_qs) - test_pred_qs_df.columns = run_config.q_labels - - return test_pred_qs_df - - -def _format_as_flusight_output(preds_df, ref_date): - # keep just required columns and rename to match hub format - preds_df = preds_df[['location', 'wk_end_date', 'horizon', 'quantile', 'value']] \ - .rename(columns={'quantile': 'output_type_id'}) - - preds_df['target_end_date'] = preds_df['wk_end_date'] + pd.to_timedelta(7*preds_df['horizon'], unit='days') - preds_df['reference_date'] = ref_date - preds_df['horizon'] = preds_df['horizon'] - 2 - preds_df['target'] = 'wk inc flu hosp' - - preds_df['output_type'] = 'quantile' - preds_df.drop(columns='wk_end_date', inplace=True) - - return preds_df - - -def _quantile_noncrossing(preds_df, gcols): - ''' - Sort predictions to be in alignment with quantile levels, to prevent - quantile crossing. - - Parameters - ---------- - preds_df: data frame with quantile predictions - gcols: columns to group by; predictions will be sorted within those groups - - Returns - ------- - Sorted version of preds_df, guaranteed not to have quantile crossing - ''' - g = preds_df.set_index(gcols).groupby(gcols) - preds_df = g[['output_type_id', 'value']] \ - .transform(lambda x: x.sort_values()) \ - .reset_index() - - return preds_df - - -def _build_save_path(root, run_config, model_config, subdir=None): - save_dir = root / f'UMass-{model_config.model_name}' - if subdir is not None: - save_dir = save_dir / subdir - save_dir.mkdir(parents=True, exist_ok=True) - return save_dir / f'{str(run_config.ref_date)}-UMass-{model_config.model_name}.csv' diff --git a/src/idmodels/gbqr.py b/src/idmodels/gbqr.py new file mode 100644 index 0000000..b002600 --- /dev/null +++ b/src/idmodels/gbqr.py @@ -0,0 +1,279 @@ +import time + +from tqdm.autonotebook import tqdm + +import numpy as np +import pandas as pd +import lightgbm as lgb + +from iddata.loader import FluDataLoader + +from idmodels.preprocess import create_features_and_targets +from idmodels.utils import build_save_path + +class GBQRModel(): + def __init__(self, model_config): + self.model_config = model_config + + + def run(self, run_config): + ''' + Load flu data, generate predictions from a gbqr model, and save them as a csv file. + + Parameters + ---------- + run_config: configuration object with settings for the run + ''' + # load flu data + if self.model_config.reporting_adj: + ilinet_kwargs = None + flusurvnet_kwargs = None + else: + ilinet_kwargs = {'scale_to_positive': False} + flusurvnet_kwargs = {'burden_adj': False} + + fdl = FluDataLoader() + df = fdl.load_data(nhsn_kwargs={'as_of': run_config.ref_date}, + ilinet_kwargs=ilinet_kwargs, + flusurvnet_kwargs=flusurvnet_kwargs, + sources=self.model_config.sources, + power_transform=self.model_config.power_transform) + + # augment data with features and target values + df, feat_names = create_features_and_targets( + df = df, + incl_level_feats=self.model_config.incl_level_feats, + max_horizon=run_config.max_horizon, + curr_feat_names=['inc_trans_cs', 'season_week', 'log_pop']) + + # keep only rows that are in-season + df = df.query("season_week >= 5 and season_week <= 45") + + # "test set" df used to generate look-ahead predictions + df_test = df.loc[df.wk_end_date == df.wk_end_date.max()] \ + .copy() + + # "train set" df for model fitting; target value non-missing + df_train = df.loc[~df['delta_target'].isna().values] + + # train model and obtain test set predictinos + if self.model_config.fit_locations_separately: + locations = df_test['location'].unique() + preds_df = [ + self._train_gbq_and_predict( + run_config, + df_train, df_test, feat_names, location + ) for location in locations + ] + preds_df = pd.concat(preds_df, axis=0) + else: + preds_df = self._train_gbq_and_predict( + run_config, + df_train, df_test, feat_names + ) + + # save + save_path = build_save_path( + root=run_config.output_root, + run_config=run_config, + model_config=self.model_config + ) + preds_df.to_csv(save_path, index=False) + + + def _train_gbq_and_predict(self, run_config, + df_train, df_test, feat_names, location = None): + ''' + Train gbq model and get predictions on the original target scale, + formatted in the FluSight hub format. + + Parameters + ---------- + run_config: configuration object with settings for the run + df_train: data frame with training data + df_test: data frame with test data + feat_names: list of names of columns with features + location: optional string of location to fit to. Default, None, fits to all locations + + Returns + ------- + Pandas data frame with test set predictions in FluSight hub format + ''' + # filter to location if necessary + if location is not None: + df_test = df_test.query(f'location == "{location}"') + df_train = df_train.query(f'location == "{location}"') + + # get x and y + x_test = df_test[feat_names] + x_train = df_train[feat_names] + y_train = df_train['delta_target'] + + # test set predictions: + # same number of rows as df_test, one column per quantile level + test_pred_qs_df = self._get_test_quantile_predictions( + run_config, + df_train, x_train, y_train, x_test + ) + + # add predictions to original test df + df_test.reset_index(drop=True, inplace=True) + df_test_w_preds = pd.concat([df_test, test_pred_qs_df], axis=1) + + # melt to get columns into rows, keeping only the things we need to invert data + # transforms later on + cols_to_keep = ['source', 'location', 'wk_end_date', 'pop', + 'inc_trans_cs', 'horizon', + 'inc_trans_center_factor', 'inc_trans_scale_factor'] + preds_df = df_test_w_preds[cols_to_keep + run_config.q_labels] + preds_df = preds_df.loc[(preds_df['source'] == 'nhsn')] + preds_df = pd.melt(preds_df, + id_vars=cols_to_keep, + var_name='quantile', + value_name = 'delta_hat') + + # build data frame with predictions on the original scale + preds_df['inc_trans_cs_target_hat'] = preds_df['inc_trans_cs'] + preds_df['delta_hat'] + preds_df['inc_trans_target_hat'] = (preds_df['inc_trans_cs_target_hat'] + preds_df['inc_trans_center_factor']) * (preds_df['inc_trans_scale_factor'] + 0.01) + if self.model_config.power_transform == '4rt': + inv_power = 4 + elif self.model_config.power_transform is None: + inv_power = 1 + else: + raise ValueError('unsupported power_transform: must be "4rt" or None') + + preds_df['value'] = (np.maximum(preds_df['inc_trans_target_hat'], 0.0) ** inv_power - 0.01 - 0.75**4) * preds_df['pop'] / 100000 + preds_df['value'] = np.maximum(preds_df['value'], 0.0) + + # get predictions into the format needed for FluSight hub submission + preds_df = self._format_as_flusight_output(preds_df, run_config.ref_date) + + # sort quantiles to avoid quantile crossing + preds_df = self._quantile_noncrossing( + preds_df, + gcols = ['location', 'reference_date', 'horizon', 'target_end_date', + 'target', 'output_type'] + ) + + return preds_df + + + def _get_test_quantile_predictions(self, run_config, + df_train, x_train, y_train, x_test): + ''' + Train the model on bagged subsets of the training data and obtain + quantile predictions. This is the heart of the method. + + Parameters + ---------- + run_config: configuration object with settings for the run + df_train: Pandas data frame with training data + x_train: numpy array with training instances in rows, features in columns + y_train: numpy array with target values + x_test: numpy array with test instances in rows, features in columns + + Returns + ------- + Pandas data frame with test set predictions. The number of rows matches + the number of rows of `x_test`. The number of columns matches the number + of quantile levels for predictions as specified in the `run_config`. + Column names are given by `run_config.q_labels`. + ''' + # seed for random number generation, based on reference date + rng_seed = int(time.mktime(run_config.ref_date.timetuple())) + rng = np.random.default_rng(seed=rng_seed) + # seeds for lgb model fits, one per combination of bag and quantile level + lgb_seeds = rng.integers(1e8, size=(self.model_config.num_bags, len(run_config.q_levels))) + + # training loop over bags + test_preds_by_bag = np.empty((x_test.shape[0], self.model_config.num_bags, len(run_config.q_levels))) + + train_seasons = df_train['season'].unique() + + feat_importance = list() + + for b in tqdm(range(self.model_config.num_bags), 'Bag number'): + # get indices of observations that are in bag + bag_seasons = rng.choice( + train_seasons, + size = int(len(train_seasons) * self.model_config.bag_frac_samples), + replace=False) + bag_obs_inds = df_train['season'].isin(bag_seasons) + + for q_ind, q_level in enumerate(run_config.q_levels): + # fit to bag + model = lgb.LGBMRegressor( + verbosity=-1, + objective='quantile', + alpha=q_level, + random_state=lgb_seeds[b, q_ind]) + model.fit(X=x_train.loc[bag_obs_inds, :], y=y_train.loc[bag_obs_inds]) + + feat_importance.append( + pd.DataFrame({ + 'feat': x_train.columns, + 'importance': model.feature_importances_, + 'b': b, + 'q_level': q_level + }) + ) + + # test set predictions + test_preds_by_bag[:, b, q_ind] = model.predict(X=x_test) + + # combine and save feature importance scores + if run_config.save_feat_importance: + feat_importance = pd.concat(feat_importance, axis=0) + save_path = _build_save_path( + root=run_config.artifact_store_root, + run_config=run_config, + model_config=self.model_config, + subdir='feat_importance') + feat_importance.to_csv(save_path, index=False) + + # combined predictions across bags: median + test_pred_qs = np.median(test_preds_by_bag, axis=1) + + # test predictions as a data frame, one column per quantile level + test_pred_qs_df = pd.DataFrame(test_pred_qs) + test_pred_qs_df.columns = run_config.q_labels + + return test_pred_qs_df + + + def _format_as_flusight_output(self, preds_df, ref_date): + # keep just required columns and rename to match hub format + preds_df = preds_df[['location', 'wk_end_date', 'horizon', 'quantile', 'value']] \ + .rename(columns={'quantile': 'output_type_id'}) + + preds_df['target_end_date'] = preds_df['wk_end_date'] + pd.to_timedelta(7*preds_df['horizon'], unit='days') + preds_df['reference_date'] = ref_date + preds_df['horizon'] = preds_df['horizon'] - 2 + preds_df['target'] = 'wk inc flu hosp' + + preds_df['output_type'] = 'quantile' + preds_df.drop(columns='wk_end_date', inplace=True) + + return preds_df + + + def _quantile_noncrossing(self, preds_df, gcols): + ''' + Sort predictions to be in alignment with quantile levels, to prevent + quantile crossing. + + Parameters + ---------- + preds_df: data frame with quantile predictions + gcols: columns to group by; predictions will be sorted within those groups + + Returns + ------- + Sorted version of preds_df, guaranteed not to have quantile crossing + ''' + g = preds_df.set_index(gcols).groupby(gcols) + preds_df = g[['output_type_id', 'value']] \ + .transform(lambda x: x.sort_values()) \ + .reset_index() + + return preds_df diff --git a/src/idmodels/preprocess.py b/src/idmodels/preprocess.py index 6ac3f59..46ff0bd 100644 --- a/src/idmodels/preprocess.py +++ b/src/idmodels/preprocess.py @@ -3,7 +3,7 @@ import pandas as pd from timeseriesutils import featurize -from data_pipeline.utils import get_holidays +from iddata.utils import get_holidays def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_names = []): @@ -123,7 +123,7 @@ def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_nam return df, feat_names -def _drop_level_feats(feat_names): +def drop_level_feats(feat_names): level_feats = ['inc_trans_cs', 'inc_trans_cs_lag1', 'inc_trans_cs_lag2'] + \ fnmatch.filter(feat_names, '*taylor_d?_c0*') + \ fnmatch.filter(feat_names, '*inc_trans_cs_rollmean*') diff --git a/src/idmodels/sarix.py b/src/idmodels/sarix.py index c7e95a6..c7bdd37 100644 --- a/src/idmodels/sarix.py +++ b/src/idmodels/sarix.py @@ -7,83 +7,88 @@ from iddata.utils import get_holidays from sarix import sarix -from utils import parse_args, build_save_path +from idmodels.utils import build_save_path -def get_sarix_preds(model_config, run_config): - fdl = FluDataLoader() - df = fdl.load_data(nhsn_kwargs={'as_of': run_config.ref_date}, - sources=model_config.sources, - power_transform=model_config.power_transform) - - # season week relative to christmas - df = df.merge( - get_holidays() \ - .query("holiday == 'Christmas Day'") \ - .drop(columns=['holiday', 'date']) \ - .rename(columns={'season_week': 'xmas_week'}), - how='left', - on='season') \ - .assign(delta_xmas = lambda x: x['season_week'] - x['xmas_week']) - df['xmas_spike'] = np.maximum(3 - np.abs(df['delta_xmas']), 0) - - xy_colnames = ["inc_trans_cs"] + model_config.x - batched_xy = df[xy_colnames].values.reshape(len(df['location'].unique()), -1, len(xy_colnames)) - - sarix_fit_all_locs_theta_pooled = sarix.SARIX( - xy = batched_xy, - p = model_config.p, - d = model_config.d, - P = model_config.P, - D = model_config.D, - season_period = model_config.season_period, - transform='none', # transformations are handled outside of SARIX - theta_pooling=model_config.theta_pooling, - sigma_pooling=model_config.sigma_pooling, - forecast_horizon = run_config.max_horizon, - num_warmup = run_config.num_warmup, - num_samples = run_config.num_samples, - num_chains = run_config.num_chains) - - pred_qs = np.percentile(sarix_fit_all_locs_theta_pooled.predictions[..., :, :, 0], - np.array(run_config.q_levels) * 100, axis=0) - - df_nhsn_last_obs = df.groupby(['location']).tail(1) - - preds_df = pd.concat([ - pd.DataFrame(pred_qs[i, :, :]) \ - .set_axis(df_nhsn_last_obs['location'], axis='index') \ - .set_axis(np.arange(1, run_config.max_horizon+1), axis='columns') \ - .assign(output_type_id = q_label) \ - for i, q_label in enumerate(run_config.q_labels) - ]) \ - .reset_index() \ - .melt(['location', 'output_type_id'], var_name='horizon') \ - .merge(df_nhsn_last_obs, on='location', how='left') - - # build data frame with predictions on the original scale - preds_df['value'] = (preds_df['value'] + preds_df['inc_trans_center_factor']) * preds_df['inc_trans_scale_factor'] - if model_config.power_transform == '4rt': - preds_df['value'] = np.maximum(preds_df['value'], 0.0) ** 4 - else: - preds_df['value'] = np.maximum(preds_df['value'], 0.0) ** 2 - - preds_df['value'] = (preds_df['value'] - 0.01 - 0.75**4) * preds_df['pop'] / 100000 - preds_df['value'] = np.maximum(preds_df['value'], 0.0) - - # keep just required columns and rename to match hub format - preds_df = preds_df[['location', 'wk_end_date', 'horizon', 'output_type_id', 'value']] - - preds_df['target_end_date'] = preds_df['wk_end_date'] + pd.to_timedelta(7*preds_df['horizon'], unit='days') - preds_df['reference_date'] = run_config.ref_date - preds_df['horizon'] = preds_df['horizon'] - 2 - preds_df['output_type'] = 'quantile' - preds_df['target'] = 'wk inc flu hosp' - preds_df.drop(columns='wk_end_date', inplace=True) - - # save - save_path = build_save_path( - root=run_config.output_root, - run_config=run_config, - model_config=model_config - ) - preds_df.to_csv(save_path, index=False) +class SARIXModel(): + def __init__(self, model_config): + self.model_config = model_config + + def run(self, run_config): + fdl = FluDataLoader() + df = fdl.load_data(nhsn_kwargs={'as_of': run_config.ref_date}, + sources=self.model_config.sources, + power_transform=self.model_config.power_transform) + + # season week relative to christmas + df = df.merge( + get_holidays() \ + .query("holiday == 'Christmas Day'") \ + .drop(columns=['holiday', 'date']) \ + .rename(columns={'season_week': 'xmas_week'}), + how='left', + on='season') \ + .assign(delta_xmas = lambda x: x['season_week'] - x['xmas_week']) + df['xmas_spike'] = np.maximum(3 - np.abs(df['delta_xmas']), 0) + + xy_colnames = ["inc_trans_cs"] + self.model_config.x + batched_xy = df[xy_colnames].values.reshape(len(df['location'].unique()), -1, len(xy_colnames)) + + sarix_fit_all_locs_theta_pooled = sarix.SARIX( + xy = batched_xy, + p = self.model_config.p, + d = self.model_config.d, + P = self.model_config.P, + D = self.model_config.D, + season_period = self.model_config.season_period, + transform='none', # transformations are handled outside of SARIX + theta_pooling=self.model_config.theta_pooling, + sigma_pooling=self.model_config.sigma_pooling, + forecast_horizon = run_config.max_horizon, + num_warmup = run_config.num_warmup, + num_samples = run_config.num_samples, + num_chains = run_config.num_chains + ) + + pred_qs = np.percentile(sarix_fit_all_locs_theta_pooled.predictions[..., :, :, 0], + np.array(run_config.q_levels) * 100, axis=0) + + df_nhsn_last_obs = df.groupby(['location']).tail(1) + + preds_df = pd.concat([ + pd.DataFrame(pred_qs[i, :, :]) \ + .set_axis(df_nhsn_last_obs['location'], axis='index') \ + .set_axis(np.arange(1, run_config.max_horizon+1), axis='columns') \ + .assign(output_type_id = q_label) \ + for i, q_label in enumerate(run_config.q_labels) + ]) \ + .reset_index() \ + .melt(['location', 'output_type_id'], var_name='horizon') \ + .merge(df_nhsn_last_obs, on='location', how='left') + + # build data frame with predictions on the original scale + preds_df['value'] = (preds_df['value'] + preds_df['inc_trans_center_factor']) * preds_df['inc_trans_scale_factor'] + if self.model_config.power_transform == '4rt': + preds_df['value'] = np.maximum(preds_df['value'], 0.0) ** 4 + else: + preds_df['value'] = np.maximum(preds_df['value'], 0.0) ** 2 + + preds_df['value'] = (preds_df['value'] - 0.01 - 0.75**4) * preds_df['pop'] / 100000 + preds_df['value'] = np.maximum(preds_df['value'], 0.0) + + # keep just required columns and rename to match hub format + preds_df = preds_df[['location', 'wk_end_date', 'horizon', 'output_type_id', 'value']] + + preds_df['target_end_date'] = preds_df['wk_end_date'] + pd.to_timedelta(7*preds_df['horizon'], unit='days') + preds_df['reference_date'] = run_config.ref_date + preds_df['horizon'] = preds_df['horizon'] - 2 + preds_df['output_type'] = 'quantile' + preds_df['target'] = 'wk inc flu hosp' + preds_df.drop(columns='wk_end_date', inplace=True) + + # save + save_path = build_save_path( + root=run_config.output_root, + run_config=run_config, + model_config=self.model_config + ) + preds_df.to_csv(save_path, index=False) diff --git a/src/idmodels/utils.py b/src/idmodels/utils.py index c1fca29..0435003 100644 --- a/src/idmodels/utils.py +++ b/src/idmodels/utils.py @@ -4,7 +4,7 @@ import datetime -def _validate_ref_date(ref_date): +def validate_ref_date(ref_date): if ref_date is None: today = datetime.date.today() diff --git a/tests/integration/data/UMass-gbqr_no_reporting_adj/2024-01-06-UMass-gbqr_no_reporting_adj.csv b/tests/integration/data/UMass-gbqr_no_reporting_adj/2024-01-06-UMass-gbqr_no_reporting_adj.csv new file mode 100644 index 0000000..e4c3ed5 --- /dev/null +++ b/tests/integration/data/UMass-gbqr_no_reporting_adj/2024-01-06-UMass-gbqr_no_reporting_adj.csv @@ -0,0 +1,478 @@ +location,reference_date,horizon,target_end_date,target,output_type,output_type_id,value +01,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,162.90485624246386 +02,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,0.5191354739434907 +04,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,582.388263268578 +05,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,99.30970290860154 +06,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,943.1664747917166 +08,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,159.11278960345948 +09,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,101.27154487025194 +10,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,24.607568806051546 +11,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,23.52293373464677 +12,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,806.4720062627999 +13,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,376.03938086390525 +15,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,15.57091761278443 +16,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,61.41215067749622 +17,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,314.3444237501799 +18,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,283.6343697602504 +19,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,38.745416023156274 +20,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,50.988197430632134 +21,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,140.4557858010192 +22,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,201.01758814328377 +23,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,22.67768374689756 +24,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,179.96305330170543 +25,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,291.6852841385854 +26,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,315.445146510012 +27,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,96.22152635620085 +28,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,160.24061080119134 +29,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,205.4200725430854 +30,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,56.79884769406052 +31,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,28.0528153177092 +32,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,79.5101907123734 +33,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,28.476563871944826 +34,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,381.2003371960788 +35,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,111.07402445630906 +36,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,716.4720176951782 +37,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,547.7438515332628 +38,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,14.604839143945858 +39,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,351.9110461589118 +40,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,89.85568536606785 +41,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,80.54812038670327 +42,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,599.6824518361395 +44,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,20.15212545995551 +45,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,345.3050784223599 +46,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,22.23405216376215 +47,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,294.27350851867044 +48,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,1145.368366180292 +49,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,41.2390143851054 +50,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,9.259802099164379 +51,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,391.8943354282477 +53,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,137.90890354623022 +54,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,77.64254752192085 +55,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,159.32171266377208 +56,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,29.305456840749855 +72,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,40.73201796592885 +US,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.025,14744.517843558786 +01,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,134.13174069414677 +02,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,0.4758405405686607 +04,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,423.1095292738197 +05,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,92.14033674098069 +06,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,674.5319617901254 +08,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,115.7807382447142 +09,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,78.71785112437556 +10,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,20.127679962999768 +11,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,18.702800916365042 +12,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,608.2415891558973 +13,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,286.40252872859156 +15,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,10.763644552839855 +16,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,46.44399908374616 +17,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,253.64629261485368 +18,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,216.02385149849002 +19,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,30.38455248855651 +20,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,43.71173242404975 +21,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,128.33632936597493 +22,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,153.01892781817108 +23,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,21.485121879931622 +24,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,144.9377731867091 +25,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,231.10987260504686 +26,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,254.93036101354087 +27,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,81.94799875762658 +28,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,129.8122201968004 +29,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,176.76224999901135 +30,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,44.558081601125274 +31,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,26.202859799839345 +32,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,58.41855917960233 +33,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,22.909156835399067 +34,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,317.2173015399419 +35,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,81.71604228891526 +36,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,559.0766717733051 +37,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,421.3413299856142 +38,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,12.958266525715187 +39,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,295.5552140941754 +40,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,80.50408669521444 +41,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,73.2651001903737 +42,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,504.16194937856903 +44,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,16.48394810261429 +45,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,270.9349739410269 +46,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,20.991792740260347 +47,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,235.78964735073424 +48,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,948.1546373127991 +49,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,33.16544049388316 +50,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,8.259165160332087 +51,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,327.7891061769314 +53,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,126.05110161662805 +54,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,70.71065716819592 +55,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,124.83860633800421 +56,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,22.967041775882432 +72,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,38.1667605954239 +US,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.025,12424.45220840472 +01,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,115.86524482002457 +02,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,0.39309742368927625 +04,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,306.59888619893474 +05,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,89.75963502333931 +06,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,544.3493282839505 +08,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,79.84287469851877 +09,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,66.81245610746458 +10,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,17.68661176364523 +11,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,16.383534976466397 +12,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,511.3175913700577 +13,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,213.75412887532636 +15,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,8.527959843647702 +16,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,36.968890105366185 +17,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,220.7655860861796 +18,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,183.53698030567327 +19,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,28.19710278197805 +20,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,39.620443425605785 +21,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,120.23511829274099 +22,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,118.32415177376484 +23,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,20.803326028230348 +24,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,130.89586916062285 +25,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,189.1279617803866 +26,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,222.50532023162316 +27,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,74.9294565448662 +28,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,117.32783475156997 +29,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,156.70441471948308 +30,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,35.375299547904845 +31,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,24.99914543826212 +32,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,47.261428979424956 +33,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,21.190869003441165 +34,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,266.6839613981839 +35,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,68.09108158347279 +36,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,429.9253419686291 +37,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,287.4537783582302 +38,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,12.351343810056557 +39,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,262.8121739577034 +40,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,76.51238747600723 +41,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,67.85435492741374 +42,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,454.8211513740479 +44,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,13.610620048050016 +45,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,200.72238578065478 +46,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,20.473008931366394 +47,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,204.5162273494352 +48,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,824.6032392217622 +49,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,29.187575258921935 +50,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,7.961356321328349 +51,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,278.9506225193256 +53,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,116.13220299296358 +54,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,68.08923075050606 +55,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,107.17446060166823 +56,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,17.772660266537585 +72,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,36.18371875507807 +US,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.025,10940.351100491453 +01,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,269.61253638264554 +02,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,5.2053216056109965 +04,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,911.8574235037494 +05,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,183.56033805020547 +06,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,1379.4261171871417 +08,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,283.04520203260086 +09,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,182.75395261165585 +10,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,55.27135798023176 +11,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,46.089392111569765 +12,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,1124.492916365719 +13,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,588.0290443174217 +15,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,25.34945096195544 +16,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,118.40313146460917 +17,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,503.5075829231775 +18,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,498.12675133230874 +19,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,82.6804486440158 +20,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,96.81182443418288 +21,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,254.54614388321284 +22,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,320.0239493754023 +23,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,53.54922912658371 +24,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,303.1928198164763 +25,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,521.680695250027 +26,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,556.2139362008895 +27,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,180.36054443954308 +28,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,267.39693654816705 +29,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,355.98044077266604 +30,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,105.26478533786018 +31,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,54.74777266753759 +32,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,147.68174532961785 +33,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,55.82379100137326 +34,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,670.8494719111925 +35,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,201.72413490511573 +36,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,1172.5050423059768 +37,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,895.5076652484553 +38,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,35.76863829936243 +39,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,570.7984041086016 +40,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,154.9666870720749 +41,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,153.42326967596242 +42,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,912.9273517188998 +44,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,44.05000453221062 +45,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,540.9787043022772 +46,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,47.652781839683385 +47,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,495.43970003462687 +48,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,1686.7410909681612 +49,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,77.73345709563478 +50,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,20.281791640798307 +51,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,626.6081477290147 +53,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,223.77836313304763 +54,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,145.07520949765689 +55,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,280.85113717118674 +56,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,48.449654049901056 +72,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,58.73721194985927 +US,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.5,18830.18679209815 +01,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,247.22546265531224 +02,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,5.003478473511751 +04,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,757.741794252647 +05,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,200.15620207583498 +06,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,1185.756265232558 +08,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,228.76588487259107 +09,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,169.59178687459558 +10,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,51.676866725783945 +11,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,42.06732028338737 +12,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,1005.7137627413334 +13,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,500.44021977269284 +15,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,21.015932525021658 +16,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,108.96737504513099 +17,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,469.16929633427435 +18,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,465.02876106852466 +19,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,83.44503814702463 +20,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,94.04953408477276 +21,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,265.5320560952342 +22,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,283.9980631691971 +23,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,56.05634396278456 +24,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,285.6095493609118 +25,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,480.9918655814365 +26,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,514.1646407094738 +27,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,175.96513533820755 +28,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,246.64959309089733 +29,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,339.03595458600404 +30,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,88.89368136442349 +31,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,62.60518458033598 +32,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,136.1901986786467 +33,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,52.945271319636916 +34,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,620.2538182952345 +35,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,169.67064324815803 +36,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,1021.8468804173544 +37,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,707.9629333945409 +38,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,39.15150780243309 +39,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,536.2914540542165 +40,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,166.39174644005556 +41,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,169.444073669036 +42,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,853.5204899551628 +44,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,42.117518686224635 +45,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,459.7285460073999 +46,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,53.83856685601113 +47,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,455.4955242497328 +48,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,1580.3541613503846 +49,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,71.97214850106312 +50,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,21.71468686656943 +51,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,572.3767818002632 +53,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,233.20329165866144 +54,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,145.22765542577469 +55,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,257.41385532167124 +56,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,37.24857772376033 +72,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,57.95995570145786 +US,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.5,17630.670720469494 +01,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,236.96721203650247 +02,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,5.834461085233713 +04,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,654.7181267793342 +05,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,214.78103605559662 +06,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,1062.76615615439 +08,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,204.14768254263288 +09,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,148.82082764885132 +10,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,48.50358012913914 +11,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,39.084898461661375 +12,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,914.5491105797784 +13,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,441.0507577052893 +15,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,17.532441700701884 +16,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,100.07270628278522 +17,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,435.8570463894252 +18,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,432.39477439762646 +19,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,88.64984422962952 +20,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,94.33433047733803 +21,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,273.6341770783545 +22,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,258.9197956639701 +23,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,60.265271562716805 +24,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,272.7687824071085 +25,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,436.16890589210175 +26,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,493.89460939156095 +27,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,168.54816408139664 +28,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,237.53771538086283 +29,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,323.2190398395245 +30,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,79.82287346878928 +31,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,68.0882822932319 +32,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,125.06723723234525 +33,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,49.41319072418422 +34,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,573.0102390678247 +35,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,152.062303884378 +36,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,916.7466718945448 +37,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,636.4770904649113 +38,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,40.409614244605 +39,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,502.35568248107614 +40,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,184.81672960301768 +41,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,182.3737796323755 +42,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,825.0127729884969 +44,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,39.56363269649009 +45,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,407.6094703140788 +46,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,56.444108504612174 +47,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,430.4114334566077 +48,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,1453.560548515818 +49,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,69.39915504108426 +50,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,23.13992510739268 +51,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,538.6737401659542 +53,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,250.19967479468244 +54,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,150.78278418074393 +55,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,240.5366234145463 +56,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,31.829985309244112 +72,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,60.22373160902629 +US,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.5,16782.947285938877 +01,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,469.2939438310354 +02,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,16.120675571247517 +04,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,1477.3773924104012 +05,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,336.0420892613866 +06,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,2513.541169031994 +08,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,498.4025484294142 +09,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,329.04040123755345 +10,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,110.3805137759874 +11,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,84.30845007187514 +12,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,1927.2948122463458 +13,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,973.3400925140397 +15,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,51.498196706555184 +16,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,210.57936970638923 +17,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,872.0696746007601 +18,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,850.8301785543688 +19,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,162.91219433963576 +20,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,180.16597334310498 +21,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,473.3121188662641 +22,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,529.6003309404025 +23,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,108.31525750541608 +24,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,539.5989794177949 +25,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,872.8279536397247 +26,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,1000.4472042664747 +27,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,323.76560894090414 +28,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,451.9435457264216 +29,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,623.5573385528174 +30,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,187.45298644905847 +31,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,109.81830070091834 +32,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,264.05293808318083 +33,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,112.87415053894337 +34,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,1109.8435350690188 +35,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,363.6303635446135 +36,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,1960.1661147737843 +37,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,1369.219987327029 +38,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,71.95461798865028 +39,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,1032.709673466656 +40,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,336.75945978139947 +41,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,295.1519844629631 +42,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,1557.3689404307863 +44,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,80.39049455192472 +45,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,814.9480439268666 +46,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,85.34376034112186 +47,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,832.8726531368575 +48,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,2860.3549419540254 +49,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,135.29971374592427 +50,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,38.930460902488 +51,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,983.2778818564965 +53,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,416.319657008327 +54,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,276.6552333592753 +55,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,505.9718478435515 +56,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,112.01044336734874 +72,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,102.77189912299562 +US,2024-01-06,-1,2024-01-06,wk inc flu hosp,quantile,0.975,29124.278680033232 +01,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,525.0602487223749 +02,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,20.4712361790229 +04,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1571.4509970371275 +05,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,428.7136417074407 +06,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,2736.3505832381134 +08,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,527.559212927551 +09,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,399.59564234376774 +10,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,123.93750810548343 +11,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,90.31250037624022 +12,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,2145.936373458496 +13,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1010.4563663723809 +15,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,55.4079274919583 +16,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,222.93055507648506 +17,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1004.3028976637089 +18,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,959.0423484681335 +19,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,207.10531125021006 +20,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,216.9734628724189 +21,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,578.6192807470975 +22,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,567.9208266625832 +23,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,131.9491171237155 +24,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,620.9737805795461 +25,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,940.0150608148738 +26,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1203.565424670973 +27,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,401.830332575453 +28,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,513.5621419929635 +29,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,756.8834097064588 +30,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,190.42120083176508 +31,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,145.3320414975885 +32,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,291.9432768460538 +33,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,130.55106060304388 +34,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1187.6679166485521 +35,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,386.51535141863593 +36,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,2127.415805142083 +37,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1452.6525290776858 +38,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,85.8123909923316 +39,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1186.6557198490982 +40,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,441.21630987099417 +41,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,376.21809346036054 +42,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1811.7932338022076 +44,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,91.6432556606717 +45,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,859.8262656754052 +46,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,105.05029189880824 +47,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,961.0503771796854 +48,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,3227.944218679003 +49,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,154.87385010266297 +50,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,49.1104231714754 +51,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,1081.6794877155403 +53,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,541.0342614451055 +54,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,318.42288804649826 +55,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,609.6431958430319 +56,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,119.01403491225734 +72,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,130.28683459733182 +US,2024-01-06,0,2024-01-13,wk inc flu hosp,quantile,0.975,32123.4916146256 +01,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,546.4181748308702 +02,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,22.52284253050294 +04,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,1509.4232023583209 +05,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,476.70464473403445 +06,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,2713.908178819202 +08,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,526.3244094091165 +09,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,427.0436802850427 +10,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,127.66538174167064 +11,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,90.77193242379542 +12,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,2229.297105676477 +13,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,988.9643577777949 +15,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,61.02214199088736 +16,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,228.07028291032455 +17,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,1041.613384384642 +18,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,982.6384455430615 +19,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,238.9935340514468 +20,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,235.5193723249062 +21,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,636.6473157843619 +22,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,558.1837207186294 +23,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,152.31945852910343 +24,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,633.590821482336 +25,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,960.8768514367445 +26,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,1241.1036880607576 +27,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,423.13458227712005 +28,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,529.4100401338823 +29,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,810.4559242503653 +30,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,193.7467337839657 +31,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,160.61546616451744 +32,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,300.82021433775435 +33,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,140.72041765414738 +34,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,1210.207721458566 +35,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,392.2175103988868 +36,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,2099.8085912315687 +37,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,1389.0743386180463 +38,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,92.06846410829286 +39,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,1249.7036692681634 +40,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,532.254336795406 +41,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,443.063462028936 +42,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,1895.1610027427178 +44,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,94.78833420256892 +45,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,829.880821248248 +46,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,114.77224159275076 +47,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,980.4324704442057 +48,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,3348.135445885129 +49,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,160.24968760401438 +50,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,52.16307010769211 +51,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,1089.2294660502962 +53,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,618.5206150166345 +54,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,344.2575987191045 +55,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,610.0828014791391 +56,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,119.08550631631913 +72,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,148.49096748966303 +US,2024-01-06,1,2024-01-20,wk inc flu hosp,quantile,0.975,32857.21843595795 diff --git a/tests/integration/data/UMass-sarix_p6_4rt_thetashared_sigmanone/2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv b/tests/integration/data/UMass-sarix_p6_4rt_thetashared_sigmanone/2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv new file mode 100644 index 0000000..36b5f83 --- /dev/null +++ b/tests/integration/data/UMass-sarix_p6_4rt_thetashared_sigmanone/2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv @@ -0,0 +1,478 @@ +location,horizon,output_type_id,value,target_end_date,reference_date,output_type,target +01,-1,0.025,222.86039834104474,2024-01-06,2024-01-06,quantile,wk inc flu hosp +02,-1,0.025,0.1217922847114279,2024-01-06,2024-01-06,quantile,wk inc flu hosp +04,-1,0.025,908.3806384751024,2024-01-06,2024-01-06,quantile,wk inc flu hosp +05,-1,0.025,151.05775202787348,2024-01-06,2024-01-06,quantile,wk inc flu hosp +06,-1,0.025,1254.5801890675402,2024-01-06,2024-01-06,quantile,wk inc flu hosp +08,-1,0.025,263.59532315770315,2024-01-06,2024-01-06,quantile,wk inc flu hosp +09,-1,0.025,137.9300484670538,2024-01-06,2024-01-06,quantile,wk inc flu hosp +10,-1,0.025,39.93564307251397,2024-01-06,2024-01-06,quantile,wk inc flu hosp +11,-1,0.025,26.495220930195845,2024-01-06,2024-01-06,quantile,wk inc flu hosp +12,-1,0.025,1030.1693628026244,2024-01-06,2024-01-06,quantile,wk inc flu hosp +13,-1,0.025,600.0014493869987,2024-01-06,2024-01-06,quantile,wk inc flu hosp +15,-1,0.025,13.58089774950754,2024-01-06,2024-01-06,quantile,wk inc flu hosp +16,-1,0.025,71.22511752646841,2024-01-06,2024-01-06,quantile,wk inc flu hosp +17,-1,0.025,426.75806542791366,2024-01-06,2024-01-06,quantile,wk inc flu hosp +18,-1,0.025,406.66077184161725,2024-01-06,2024-01-06,quantile,wk inc flu hosp +19,-1,0.025,45.16919892126759,2024-01-06,2024-01-06,quantile,wk inc flu hosp +20,-1,0.025,70.12803300899955,2024-01-06,2024-01-06,quantile,wk inc flu hosp +21,-1,0.025,176.25980252834378,2024-01-06,2024-01-06,quantile,wk inc flu hosp +22,-1,0.025,279.7733467032604,2024-01-06,2024-01-06,quantile,wk inc flu hosp +23,-1,0.025,35.19173152661814,2024-01-06,2024-01-06,quantile,wk inc flu hosp +24,-1,0.025,282.6454445006594,2024-01-06,2024-01-06,quantile,wk inc flu hosp +25,-1,0.025,494.7957121370486,2024-01-06,2024-01-06,quantile,wk inc flu hosp +26,-1,0.025,514.2244352026454,2024-01-06,2024-01-06,quantile,wk inc flu hosp +27,-1,0.025,157.31384197622648,2024-01-06,2024-01-06,quantile,wk inc flu hosp +28,-1,0.025,224.28655567491603,2024-01-06,2024-01-06,quantile,wk inc flu hosp +29,-1,0.025,275.4492193740111,2024-01-06,2024-01-06,quantile,wk inc flu hosp +30,-1,0.025,89.62391794479123,2024-01-06,2024-01-06,quantile,wk inc flu hosp +31,-1,0.025,32.55983437703612,2024-01-06,2024-01-06,quantile,wk inc flu hosp +32,-1,0.025,112.84602918277932,2024-01-06,2024-01-06,quantile,wk inc flu hosp +33,-1,0.025,40.790335762863954,2024-01-06,2024-01-06,quantile,wk inc flu hosp +34,-1,0.025,592.197938477221,2024-01-06,2024-01-06,quantile,wk inc flu hosp +35,-1,0.025,156.21617282537287,2024-01-06,2024-01-06,quantile,wk inc flu hosp +36,-1,0.025,1143.5827003086386,2024-01-06,2024-01-06,quantile,wk inc flu hosp +37,-1,0.025,922.1861114276963,2024-01-06,2024-01-06,quantile,wk inc flu hosp +38,-1,0.025,16.843014443106643,2024-01-06,2024-01-06,quantile,wk inc flu hosp +39,-1,0.025,544.4158404023027,2024-01-06,2024-01-06,quantile,wk inc flu hosp +40,-1,0.025,79.20082637512016,2024-01-06,2024-01-06,quantile,wk inc flu hosp +41,-1,0.025,102.42436149488128,2024-01-06,2024-01-06,quantile,wk inc flu hosp +42,-1,0.025,860.2431413367547,2024-01-06,2024-01-06,quantile,wk inc flu hosp +44,-1,0.025,28.07606939707131,2024-01-06,2024-01-06,quantile,wk inc flu hosp +45,-1,0.025,530.1766339973597,2024-01-06,2024-01-06,quantile,wk inc flu hosp +46,-1,0.025,28.626893505798034,2024-01-06,2024-01-06,quantile,wk inc flu hosp +47,-1,0.025,460.32551818400293,2024-01-06,2024-01-06,quantile,wk inc flu hosp +48,-1,0.025,1716.8218329307897,2024-01-06,2024-01-06,quantile,wk inc flu hosp +49,-1,0.025,66.04344918217912,2024-01-06,2024-01-06,quantile,wk inc flu hosp +50,-1,0.025,10.860971004643346,2024-01-06,2024-01-06,quantile,wk inc flu hosp +51,-1,0.025,571.5421655468396,2024-01-06,2024-01-06,quantile,wk inc flu hosp +53,-1,0.025,150.08425377903697,2024-01-06,2024-01-06,quantile,wk inc flu hosp +54,-1,0.025,103.48960046142697,2024-01-06,2024-01-06,quantile,wk inc flu hosp +55,-1,0.025,245.2009995336065,2024-01-06,2024-01-06,quantile,wk inc flu hosp +56,-1,0.025,42.15078144696277,2024-01-06,2024-01-06,quantile,wk inc flu hosp +72,-1,0.025,29.554317706575944,2024-01-06,2024-01-06,quantile,wk inc flu hosp +US,-1,0.025,18249.374370285153,2024-01-06,2024-01-06,quantile,wk inc flu hosp +01,-1,0.5,313.2493681304232,2024-01-06,2024-01-06,quantile,wk inc flu hosp +02,-1,0.5,5.786096325237789,2024-01-06,2024-01-06,quantile,wk inc flu hosp +04,-1,0.5,1188.3970542067857,2024-01-06,2024-01-06,quantile,wk inc flu hosp +05,-1,0.5,232.48201339790774,2024-01-06,2024-01-06,quantile,wk inc flu hosp +06,-1,0.5,1706.0627017935071,2024-01-06,2024-01-06,quantile,wk inc flu hosp +08,-1,0.5,345.7386813022488,2024-01-06,2024-01-06,quantile,wk inc flu hosp +09,-1,0.5,208.12626459802664,2024-01-06,2024-01-06,quantile,wk inc flu hosp +10,-1,0.5,73.6355802455411,2024-01-06,2024-01-06,quantile,wk inc flu hosp +11,-1,0.5,56.721664391950256,2024-01-06,2024-01-06,quantile,wk inc flu hosp +12,-1,0.5,1326.977915880036,2024-01-06,2024-01-06,quantile,wk inc flu hosp +13,-1,0.5,736.5013652760694,2024-01-06,2024-01-06,quantile,wk inc flu hosp +15,-1,0.5,30.292613404074054,2024-01-06,2024-01-06,quantile,wk inc flu hosp +16,-1,0.5,144.37170769387458,2024-01-06,2024-01-06,quantile,wk inc flu hosp +17,-1,0.5,585.9674437718979,2024-01-06,2024-01-06,quantile,wk inc flu hosp +18,-1,0.5,605.6819806938705,2024-01-06,2024-01-06,quantile,wk inc flu hosp +19,-1,0.5,78.40700391741875,2024-01-06,2024-01-06,quantile,wk inc flu hosp +20,-1,0.5,104.74925983202179,2024-01-06,2024-01-06,quantile,wk inc flu hosp +21,-1,0.5,310.95270234363375,2024-01-06,2024-01-06,quantile,wk inc flu hosp +22,-1,0.5,401.4240695503723,2024-01-06,2024-01-06,quantile,wk inc flu hosp +23,-1,0.5,65.93706562884708,2024-01-06,2024-01-06,quantile,wk inc flu hosp +24,-1,0.5,391.15792935867665,2024-01-06,2024-01-06,quantile,wk inc flu hosp +25,-1,0.5,668.8458180855038,2024-01-06,2024-01-06,quantile,wk inc flu hosp +26,-1,0.5,689.2237347862883,2024-01-06,2024-01-06,quantile,wk inc flu hosp +27,-1,0.5,223.05239052703607,2024-01-06,2024-01-06,quantile,wk inc flu hosp +28,-1,0.5,328.2621993793904,2024-01-06,2024-01-06,quantile,wk inc flu hosp +29,-1,0.5,415.3841488102241,2024-01-06,2024-01-06,quantile,wk inc flu hosp +30,-1,0.5,132.38482332788763,2024-01-06,2024-01-06,quantile,wk inc flu hosp +31,-1,0.5,64.90842785173585,2024-01-06,2024-01-06,quantile,wk inc flu hosp +32,-1,0.5,165.5133975427556,2024-01-06,2024-01-06,quantile,wk inc flu hosp +33,-1,0.5,70.85244550296453,2024-01-06,2024-01-06,quantile,wk inc flu hosp +34,-1,0.5,865.7224569516708,2024-01-06,2024-01-06,quantile,wk inc flu hosp +35,-1,0.5,245.49471390307076,2024-01-06,2024-01-06,quantile,wk inc flu hosp +36,-1,0.5,1447.0352233472672,2024-01-06,2024-01-06,quantile,wk inc flu hosp +37,-1,0.5,1197.4403503783728,2024-01-06,2024-01-06,quantile,wk inc flu hosp +38,-1,0.5,36.64220915566339,2024-01-06,2024-01-06,quantile,wk inc flu hosp +39,-1,0.5,708.0715727749005,2024-01-06,2024-01-06,quantile,wk inc flu hosp +40,-1,0.5,152.2305090044802,2024-01-06,2024-01-06,quantile,wk inc flu hosp +41,-1,0.5,171.97750853974324,2024-01-06,2024-01-06,quantile,wk inc flu hosp +42,-1,0.5,1156.5761392512431,2024-01-06,2024-01-06,quantile,wk inc flu hosp +44,-1,0.5,55.002638014359164,2024-01-06,2024-01-06,quantile,wk inc flu hosp +45,-1,0.5,690.7766260538461,2024-01-06,2024-01-06,quantile,wk inc flu hosp +46,-1,0.5,58.75804584184191,2024-01-06,2024-01-06,quantile,wk inc flu hosp +47,-1,0.5,618.7862412658325,2024-01-06,2024-01-06,quantile,wk inc flu hosp +48,-1,0.5,2078.348792941679,2024-01-06,2024-01-06,quantile,wk inc flu hosp +49,-1,0.5,98.51276275866691,2024-01-06,2024-01-06,quantile,wk inc flu hosp +50,-1,0.5,22.39640724069841,2024-01-06,2024-01-06,quantile,wk inc flu hosp +51,-1,0.5,771.17199501523,2024-01-06,2024-01-06,quantile,wk inc flu hosp +53,-1,0.5,238.28097995316114,2024-01-06,2024-01-06,quantile,wk inc flu hosp +54,-1,0.5,185.963908096978,2024-01-06,2024-01-06,quantile,wk inc flu hosp +55,-1,0.5,343.3889376216518,2024-01-06,2024-01-06,quantile,wk inc flu hosp +56,-1,0.5,74.61418736371733,2024-01-06,2024-01-06,quantile,wk inc flu hosp +72,-1,0.5,59.61990844633734,2024-01-06,2024-01-06,quantile,wk inc flu hosp +US,-1,0.5,23348.423497767955,2024-01-06,2024-01-06,quantile,wk inc flu hosp +01,-1,0.975,469.66831089913546,2024-01-06,2024-01-06,quantile,wk inc flu hosp +02,-1,0.975,17.897952096673265,2024-01-06,2024-01-06,quantile,wk inc flu hosp +04,-1,0.975,1640.6629410162757,2024-01-06,2024-01-06,quantile,wk inc flu hosp +05,-1,0.975,328.44681657647277,2024-01-06,2024-01-06,quantile,wk inc flu hosp +06,-1,0.975,2414.3997065220824,2024-01-06,2024-01-06,quantile,wk inc flu hosp +08,-1,0.975,460.1896416180778,2024-01-06,2024-01-06,quantile,wk inc flu hosp +09,-1,0.975,324.09191819584476,2024-01-06,2024-01-06,quantile,wk inc flu hosp +10,-1,0.975,130.35938340105452,2024-01-06,2024-01-06,quantile,wk inc flu hosp +11,-1,0.975,95.02802343631119,2024-01-06,2024-01-06,quantile,wk inc flu hosp +12,-1,0.975,1691.1342030583387,2024-01-06,2024-01-06,quantile,wk inc flu hosp +13,-1,0.975,919.99790929378,2024-01-06,2024-01-06,quantile,wk inc flu hosp +15,-1,0.975,58.61866843752571,2024-01-06,2024-01-06,quantile,wk inc flu hosp +16,-1,0.975,224.15859689885352,2024-01-06,2024-01-06,quantile,wk inc flu hosp +17,-1,0.975,799.431942948413,2024-01-06,2024-01-06,quantile,wk inc flu hosp +18,-1,0.975,805.4459798932288,2024-01-06,2024-01-06,quantile,wk inc flu hosp +19,-1,0.975,127.92308101264473,2024-01-06,2024-01-06,quantile,wk inc flu hosp +20,-1,0.975,163.1852119407373,2024-01-06,2024-01-06,quantile,wk inc flu hosp +21,-1,0.975,483.0514854459201,2024-01-06,2024-01-06,quantile,wk inc flu hosp +22,-1,0.975,565.5883597478655,2024-01-06,2024-01-06,quantile,wk inc flu hosp +23,-1,0.975,113.28671367807488,2024-01-06,2024-01-06,quantile,wk inc flu hosp +24,-1,0.975,507.11690358015807,2024-01-06,2024-01-06,quantile,wk inc flu hosp +25,-1,0.975,868.5205467513323,2024-01-06,2024-01-06,quantile,wk inc flu hosp +26,-1,0.975,915.7053053361158,2024-01-06,2024-01-06,quantile,wk inc flu hosp +27,-1,0.975,298.5152493016086,2024-01-06,2024-01-06,quantile,wk inc flu hosp +28,-1,0.975,457.1848657243139,2024-01-06,2024-01-06,quantile,wk inc flu hosp +29,-1,0.975,575.3056648865298,2024-01-06,2024-01-06,quantile,wk inc flu hosp +30,-1,0.975,198.88318583632295,2024-01-06,2024-01-06,quantile,wk inc flu hosp +31,-1,0.975,102.10519933529588,2024-01-06,2024-01-06,quantile,wk inc flu hosp +32,-1,0.975,264.23997056003617,2024-01-06,2024-01-06,quantile,wk inc flu hosp +33,-1,0.975,106.80533582816224,2024-01-06,2024-01-06,quantile,wk inc flu hosp +34,-1,0.975,1129.1689011127528,2024-01-06,2024-01-06,quantile,wk inc flu hosp +35,-1,0.975,377.7051149089471,2024-01-06,2024-01-06,quantile,wk inc flu hosp +36,-1,0.975,1766.796537317255,2024-01-06,2024-01-06,quantile,wk inc flu hosp +37,-1,0.975,1497.5960846775517,2024-01-06,2024-01-06,quantile,wk inc flu hosp +38,-1,0.975,68.6611465898852,2024-01-06,2024-01-06,quantile,wk inc flu hosp +39,-1,0.975,907.9597522696989,2024-01-06,2024-01-06,quantile,wk inc flu hosp +40,-1,0.975,268.7071178702776,2024-01-06,2024-01-06,quantile,wk inc flu hosp +41,-1,0.975,247.566276315383,2024-01-06,2024-01-06,quantile,wk inc flu hosp +42,-1,0.975,1510.8695499424396,2024-01-06,2024-01-06,quantile,wk inc flu hosp +44,-1,0.975,92.08033387087005,2024-01-06,2024-01-06,quantile,wk inc flu hosp +45,-1,0.975,887.9825191629043,2024-01-06,2024-01-06,quantile,wk inc flu hosp +46,-1,0.975,101.64431469932534,2024-01-06,2024-01-06,quantile,wk inc flu hosp +47,-1,0.975,867.1928578738845,2024-01-06,2024-01-06,quantile,wk inc flu hosp +48,-1,0.975,2465.145472668941,2024-01-06,2024-01-06,quantile,wk inc flu hosp +49,-1,0.975,138.05875827835027,2024-01-06,2024-01-06,quantile,wk inc flu hosp +50,-1,0.975,41.834143998285086,2024-01-06,2024-01-06,quantile,wk inc flu hosp +51,-1,0.975,1012.0639686828276,2024-01-06,2024-01-06,quantile,wk inc flu hosp +53,-1,0.975,336.8232566888348,2024-01-06,2024-01-06,quantile,wk inc flu hosp +54,-1,0.975,308.4136623069445,2024-01-06,2024-01-06,quantile,wk inc flu hosp +55,-1,0.975,466.8087497394507,2024-01-06,2024-01-06,quantile,wk inc flu hosp +56,-1,0.975,138.83866956378148,2024-01-06,2024-01-06,quantile,wk inc flu hosp +72,-1,0.975,101.75610512583711,2024-01-06,2024-01-06,quantile,wk inc flu hosp +US,-1,0.975,27996.20422495771,2024-01-06,2024-01-06,quantile,wk inc flu hosp +01,0,0.025,161.98977318848418,2024-01-13,2024-01-06,quantile,wk inc flu hosp +02,0,0.025,0.0,2024-01-13,2024-01-06,quantile,wk inc flu hosp +04,0,0.025,718.2770586486399,2024-01-13,2024-01-06,quantile,wk inc flu hosp +05,0,0.025,153.32893143784727,2024-01-13,2024-01-06,quantile,wk inc flu hosp +06,0,0.025,1090.575972311269,2024-01-13,2024-01-06,quantile,wk inc flu hosp +08,0,0.025,198.78292354758528,2024-01-13,2024-01-06,quantile,wk inc flu hosp +09,0,0.025,114.59358561168797,2024-01-13,2024-01-06,quantile,wk inc flu hosp +10,0,0.025,34.53960952536802,2024-01-13,2024-01-06,quantile,wk inc flu hosp +11,0,0.025,20.26562323935435,2024-01-13,2024-01-06,quantile,wk inc flu hosp +12,0,0.025,858.5550532807882,2024-01-13,2024-01-06,quantile,wk inc flu hosp +13,0,0.025,542.6515659183888,2024-01-13,2024-01-06,quantile,wk inc flu hosp +15,0,0.025,6.419112879721578,2024-01-13,2024-01-06,quantile,wk inc flu hosp +16,0,0.025,57.061647457612075,2024-01-13,2024-01-06,quantile,wk inc flu hosp +17,0,0.025,353.3993169490572,2024-01-13,2024-01-06,quantile,wk inc flu hosp +18,0,0.025,350.63409553657874,2024-01-13,2024-01-06,quantile,wk inc flu hosp +19,0,0.025,29.777693905569514,2024-01-13,2024-01-06,quantile,wk inc flu hosp +20,0,0.025,52.449216603329646,2024-01-13,2024-01-06,quantile,wk inc flu hosp +21,0,0.025,165.19682200344513,2024-01-13,2024-01-06,quantile,wk inc flu hosp +22,0,0.025,224.72190763461572,2024-01-13,2024-01-06,quantile,wk inc flu hosp +23,0,0.025,30.738204585681004,2024-01-13,2024-01-06,quantile,wk inc flu hosp +24,0,0.025,277.9641902477557,2024-01-13,2024-01-06,quantile,wk inc flu hosp +25,0,0.025,450.46951057570277,2024-01-13,2024-01-06,quantile,wk inc flu hosp +26,0,0.025,482.86488555965826,2024-01-13,2024-01-06,quantile,wk inc flu hosp +27,0,0.025,152.56878206922465,2024-01-13,2024-01-06,quantile,wk inc flu hosp +28,0,0.025,190.3182511037544,2024-01-13,2024-01-06,quantile,wk inc flu hosp +29,0,0.025,245.8235911746941,2024-01-13,2024-01-06,quantile,wk inc flu hosp +30,0,0.025,75.80537412375594,2024-01-13,2024-01-06,quantile,wk inc flu hosp +31,0,0.025,26.02722343116899,2024-01-13,2024-01-06,quantile,wk inc flu hosp +32,0,0.025,76.83273350473428,2024-01-13,2024-01-06,quantile,wk inc flu hosp +33,0,0.025,32.26779115244762,2024-01-13,2024-01-06,quantile,wk inc flu hosp +34,0,0.025,550.7470352793802,2024-01-13,2024-01-06,quantile,wk inc flu hosp +35,0,0.025,131.84306501468615,2024-01-13,2024-01-06,quantile,wk inc flu hosp +36,0,0.025,1050.543575918373,2024-01-13,2024-01-06,quantile,wk inc flu hosp +37,0,0.025,827.0356983305664,2024-01-13,2024-01-06,quantile,wk inc flu hosp +38,0,0.025,12.501508962304031,2024-01-13,2024-01-06,quantile,wk inc flu hosp +39,0,0.025,506.4390990516285,2024-01-13,2024-01-06,quantile,wk inc flu hosp +40,0,0.025,56.13782133170803,2024-01-13,2024-01-06,quantile,wk inc flu hosp +41,0,0.025,78.3669395316698,2024-01-13,2024-01-06,quantile,wk inc flu hosp +42,0,0.025,799.7344872537001,2024-01-13,2024-01-06,quantile,wk inc flu hosp +44,0,0.025,22.99242835602421,2024-01-13,2024-01-06,quantile,wk inc flu hosp +45,0,0.025,446.9649235626944,2024-01-13,2024-01-06,quantile,wk inc flu hosp +46,0,0.025,26.08522833263193,2024-01-13,2024-01-06,quantile,wk inc flu hosp +47,0,0.025,418.13099312043516,2024-01-13,2024-01-06,quantile,wk inc flu hosp +48,0,0.025,1458.2564641837635,2024-01-13,2024-01-06,quantile,wk inc flu hosp +49,0,0.025,61.18419516411033,2024-01-13,2024-01-06,quantile,wk inc flu hosp +50,0,0.025,7.126977800255024,2024-01-13,2024-01-06,quantile,wk inc flu hosp +51,0,0.025,580.2492403722347,2024-01-13,2024-01-06,quantile,wk inc flu hosp +53,0,0.025,124.37826487746213,2024-01-13,2024-01-06,quantile,wk inc flu hosp +54,0,0.025,101.34519367571045,2024-01-13,2024-01-06,quantile,wk inc flu hosp +55,0,0.025,216.83474316051957,2024-01-13,2024-01-06,quantile,wk inc flu hosp +56,0,0.025,24.813929606952808,2024-01-13,2024-01-06,quantile,wk inc flu hosp +72,0,0.025,18.546150608682606,2024-01-13,2024-01-06,quantile,wk inc flu hosp +US,0,0.025,17685.423553484692,2024-01-13,2024-01-06,quantile,wk inc flu hosp +01,0,0.5,341.92766892948873,2024-01-13,2024-01-06,quantile,wk inc flu hosp +02,0,0.5,5.73048109480059,2024-01-13,2024-01-06,quantile,wk inc flu hosp +04,0,0.5,1213.7115434636517,2024-01-13,2024-01-06,quantile,wk inc flu hosp +05,0,0.5,263.36042996484605,2024-01-13,2024-01-06,quantile,wk inc flu hosp +06,0,0.5,1718.9689969007054,2024-01-13,2024-01-06,quantile,wk inc flu hosp +08,0,0.5,349.9924868324738,2024-01-13,2024-01-06,quantile,wk inc flu hosp +09,0,0.5,217.32464526262595,2024-01-13,2024-01-06,quantile,wk inc flu hosp +10,0,0.5,88.45429970872493,2024-01-13,2024-01-06,quantile,wk inc flu hosp +11,0,0.5,56.00952958036754,2024-01-13,2024-01-06,quantile,wk inc flu hosp +12,0,0.5,1332.289815070584,2024-01-13,2024-01-06,quantile,wk inc flu hosp +13,0,0.5,763.345011937585,2024-01-13,2024-01-06,quantile,wk inc flu hosp +15,0,0.5,29.66261047066351,2024-01-13,2024-01-06,quantile,wk inc flu hosp +16,0,0.5,144.66743618886608,2024-01-13,2024-01-06,quantile,wk inc flu hosp +17,0,0.5,618.4906970523044,2024-01-13,2024-01-06,quantile,wk inc flu hosp +18,0,0.5,640.5498167691552,2024-01-13,2024-01-06,quantile,wk inc flu hosp +19,0,0.5,82.04234522225111,2024-01-13,2024-01-06,quantile,wk inc flu hosp +20,0,0.5,108.30765985857443,2024-01-13,2024-01-06,quantile,wk inc flu hosp +21,0,0.5,356.3731257114142,2024-01-13,2024-01-06,quantile,wk inc flu hosp +22,0,0.5,415.57809320647965,2024-01-13,2024-01-06,quantile,wk inc flu hosp +23,0,0.5,79.63275817999794,2024-01-13,2024-01-06,quantile,wk inc flu hosp +24,0,0.5,433.1354396952098,2024-01-13,2024-01-06,quantile,wk inc flu hosp +25,0,0.5,750.774446138244,2024-01-13,2024-01-06,quantile,wk inc flu hosp +26,0,0.5,783.7640768512513,2024-01-13,2024-01-06,quantile,wk inc flu hosp +27,0,0.5,247.28768583909977,2024-01-13,2024-01-06,quantile,wk inc flu hosp +28,0,0.5,346.4053849068743,2024-01-13,2024-01-06,quantile,wk inc flu hosp +29,0,0.5,450.43492261658525,2024-01-13,2024-01-06,quantile,wk inc flu hosp +30,0,0.5,147.13859183481011,2024-01-13,2024-01-06,quantile,wk inc flu hosp +31,0,0.5,75.27307568035381,2024-01-13,2024-01-06,quantile,wk inc flu hosp +32,0,0.5,171.37846662641047,2024-01-13,2024-01-06,quantile,wk inc flu hosp +33,0,0.5,75.14916463172618,2024-01-13,2024-01-06,quantile,wk inc flu hosp +34,0,0.5,935.2996679271234,2024-01-13,2024-01-06,quantile,wk inc flu hosp +35,0,0.5,246.21254906127297,2024-01-13,2024-01-06,quantile,wk inc flu hosp +36,0,0.5,1494.7854840655461,2024-01-13,2024-01-06,quantile,wk inc flu hosp +37,0,0.5,1248.555461291688,2024-01-13,2024-01-06,quantile,wk inc flu hosp +38,0,0.5,39.44459447829021,2024-01-13,2024-01-06,quantile,wk inc flu hosp +39,0,0.5,774.8118903577143,2024-01-13,2024-01-06,quantile,wk inc flu hosp +40,0,0.5,162.4690345004577,2024-01-13,2024-01-06,quantile,wk inc flu hosp +41,0,0.5,192.3286275914882,2024-01-13,2024-01-06,quantile,wk inc flu hosp +42,0,0.5,1258.0835214353488,2024-01-13,2024-01-06,quantile,wk inc flu hosp +44,0,0.5,63.30299313806941,2024-01-13,2024-01-06,quantile,wk inc flu hosp +45,0,0.5,728.3385642172466,2024-01-13,2024-01-06,quantile,wk inc flu hosp +46,0,0.5,72.38172080061184,2024-01-13,2024-01-06,quantile,wk inc flu hosp +47,0,0.5,674.6386624182585,2024-01-13,2024-01-06,quantile,wk inc flu hosp +48,0,0.5,2171.9249831972074,2024-01-13,2024-01-06,quantile,wk inc flu hosp +49,0,0.5,106.64088708043046,2024-01-13,2024-01-06,quantile,wk inc flu hosp +50,0,0.5,26.033795688922005,2024-01-13,2024-01-06,quantile,wk inc flu hosp +51,0,0.5,870.5306573695519,2024-01-13,2024-01-06,quantile,wk inc flu hosp +53,0,0.5,243.5513922301584,2024-01-13,2024-01-06,quantile,wk inc flu hosp +54,0,0.5,219.9409307507473,2024-01-13,2024-01-06,quantile,wk inc flu hosp +55,0,0.5,366.13186134873547,2024-01-13,2024-01-06,quantile,wk inc flu hosp +56,0,0.5,77.31090646997357,2024-01-13,2024-01-06,quantile,wk inc flu hosp +72,0,0.5,59.61729447413792,2024-01-13,2024-01-06,quantile,wk inc flu hosp +US,0,0.5,24526.406513515354,2024-01-13,2024-01-06,quantile,wk inc flu hosp +01,0,0.975,587.8306286711197,2024-01-13,2024-01-06,quantile,wk inc flu hosp +02,0,0.975,33.861637476059826,2024-01-13,2024-01-06,quantile,wk inc flu hosp +04,0,0.975,1850.2584340271649,2024-01-13,2024-01-06,quantile,wk inc flu hosp +05,0,0.975,467.47817596282437,2024-01-13,2024-01-06,quantile,wk inc flu hosp +06,0,0.975,2679.4324561990325,2024-01-13,2024-01-06,quantile,wk inc flu hosp +08,0,0.975,561.9276690895598,2024-01-13,2024-01-06,quantile,wk inc flu hosp +09,0,0.975,383.2239914341043,2024-01-13,2024-01-06,quantile,wk inc flu hosp +10,0,0.975,201.17410063104205,2024-01-13,2024-01-06,quantile,wk inc flu hosp +11,0,0.975,126.08717741469962,2024-01-13,2024-01-06,quantile,wk inc flu hosp +12,0,0.975,1915.5076380273154,2024-01-13,2024-01-06,quantile,wk inc flu hosp +13,0,0.975,1016.9566240421439,2024-01-13,2024-01-06,quantile,wk inc flu hosp +15,0,0.975,78.94528177581253,2024-01-13,2024-01-06,quantile,wk inc flu hosp +16,0,0.975,333.8038856577528,2024-01-13,2024-01-06,quantile,wk inc flu hosp +17,0,0.975,1006.4695549593738,2024-01-13,2024-01-06,quantile,wk inc flu hosp +18,0,0.975,1013.4361205863881,2024-01-13,2024-01-06,quantile,wk inc flu hosp +19,0,0.975,166.3662000467881,2024-01-13,2024-01-06,quantile,wk inc flu hosp +20,0,0.975,210.7112417828209,2024-01-13,2024-01-06,quantile,wk inc flu hosp +21,0,0.975,693.6768386752562,2024-01-13,2024-01-06,quantile,wk inc flu hosp +22,0,0.975,689.0632264248054,2024-01-13,2024-01-06,quantile,wk inc flu hosp +23,0,0.975,171.41953069630347,2024-01-13,2024-01-06,quantile,wk inc flu hosp +24,0,0.975,648.6136220797704,2024-01-13,2024-01-06,quantile,wk inc flu hosp +25,0,0.975,1116.893583135438,2024-01-13,2024-01-06,quantile,wk inc flu hosp +26,0,0.975,1229.3160328000263,2024-01-13,2024-01-06,quantile,wk inc flu hosp +27,0,0.975,382.52429245456153,2024-01-13,2024-01-06,quantile,wk inc flu hosp +28,0,0.975,585.9095399239102,2024-01-13,2024-01-06,quantile,wk inc flu hosp +29,0,0.975,766.2543116978095,2024-01-13,2024-01-06,quantile,wk inc flu hosp +30,0,0.975,264.7787658098187,2024-01-13,2024-01-06,quantile,wk inc flu hosp +31,0,0.975,148.28814143312172,2024-01-13,2024-01-06,quantile,wk inc flu hosp +32,0,0.975,333.899576737268,2024-01-13,2024-01-06,quantile,wk inc flu hosp +33,0,0.975,152.97527802334392,2024-01-13,2024-01-06,quantile,wk inc flu hosp +34,0,0.975,1442.7535186454825,2024-01-13,2024-01-06,quantile,wk inc flu hosp +35,0,0.975,462.42775027032934,2024-01-13,2024-01-06,quantile,wk inc flu hosp +36,0,0.975,2082.5949073224797,2024-01-13,2024-01-06,quantile,wk inc flu hosp +37,0,0.975,1822.4521194599322,2024-01-13,2024-01-06,quantile,wk inc flu hosp +38,0,0.975,113.97106798345754,2024-01-13,2024-01-06,quantile,wk inc flu hosp +39,0,0.975,1172.1455896999962,2024-01-13,2024-01-06,quantile,wk inc flu hosp +40,0,0.975,352.623991614508,2024-01-13,2024-01-06,quantile,wk inc flu hosp +41,0,0.975,353.01982796547884,2024-01-13,2024-01-06,quantile,wk inc flu hosp +42,0,0.975,1833.9637136496203,2024-01-13,2024-01-06,quantile,wk inc flu hosp +44,0,0.975,133.5302349363295,2024-01-13,2024-01-06,quantile,wk inc flu hosp +45,0,0.975,1057.073469708893,2024-01-13,2024-01-06,quantile,wk inc flu hosp +46,0,0.975,173.2208468367838,2024-01-13,2024-01-06,quantile,wk inc flu hosp +47,0,0.975,1058.4035498075089,2024-01-13,2024-01-06,quantile,wk inc flu hosp +48,0,0.975,2799.9427336675485,2024-01-13,2024-01-06,quantile,wk inc flu hosp +49,0,0.975,191.8563441958809,2024-01-13,2024-01-06,quantile,wk inc flu hosp +50,0,0.975,65.89923950912251,2024-01-13,2024-01-06,quantile,wk inc flu hosp +51,0,0.975,1347.364689094914,2024-01-13,2024-01-06,quantile,wk inc flu hosp +53,0,0.975,435.5606631361352,2024-01-13,2024-01-06,quantile,wk inc flu hosp +54,0,0.975,443.8936866528619,2024-01-13,2024-01-06,quantile,wk inc flu hosp +55,0,0.975,581.6406447689286,2024-01-13,2024-01-06,quantile,wk inc flu hosp +56,0,0.975,191.72414466090586,2024-01-13,2024-01-06,quantile,wk inc flu hosp +72,0,0.975,133.36980065055963,2024-01-13,2024-01-06,quantile,wk inc flu hosp +US,0,0.975,34057.2402228183,2024-01-13,2024-01-06,quantile,wk inc flu hosp +01,1,0.025,131.90157801901108,2024-01-20,2024-01-06,quantile,wk inc flu hosp +02,1,0.025,0.0,2024-01-20,2024-01-06,quantile,wk inc flu hosp +04,1,0.025,608.3309958178644,2024-01-20,2024-01-06,quantile,wk inc flu hosp +05,1,0.025,144.69070067267373,2024-01-20,2024-01-06,quantile,wk inc flu hosp +06,1,0.025,914.4568955413866,2024-01-20,2024-01-06,quantile,wk inc flu hosp +08,1,0.025,140.86504823468323,2024-01-20,2024-01-06,quantile,wk inc flu hosp +09,1,0.025,94.428237492705,2024-01-20,2024-01-06,quantile,wk inc flu hosp +10,1,0.025,22.43641294463852,2024-01-20,2024-01-06,quantile,wk inc flu hosp +11,1,0.025,13.771553422501912,2024-01-20,2024-01-06,quantile,wk inc flu hosp +12,1,0.025,724.5174996768884,2024-01-20,2024-01-06,quantile,wk inc flu hosp +13,1,0.025,476.6879867403941,2024-01-20,2024-01-06,quantile,wk inc flu hosp +15,1,0.025,2.3019301573446365,2024-01-20,2024-01-06,quantile,wk inc flu hosp +16,1,0.025,32.7237861368642,2024-01-20,2024-01-06,quantile,wk inc flu hosp +17,1,0.025,318.1488607689426,2024-01-20,2024-01-06,quantile,wk inc flu hosp +18,1,0.025,317.2273190806666,2024-01-20,2024-01-06,quantile,wk inc flu hosp +19,1,0.025,14.011885436301755,2024-01-20,2024-01-06,quantile,wk inc flu hosp +20,1,0.025,41.30695215561445,2024-01-20,2024-01-06,quantile,wk inc flu hosp +21,1,0.025,137.88936742715333,2024-01-20,2024-01-06,quantile,wk inc flu hosp +22,1,0.025,185.39352348490735,2024-01-20,2024-01-06,quantile,wk inc flu hosp +23,1,0.025,24.436975422238678,2024-01-20,2024-01-06,quantile,wk inc flu hosp +24,1,0.025,221.32161841542677,2024-01-20,2024-01-06,quantile,wk inc flu hosp +25,1,0.025,398.90033770638877,2024-01-20,2024-01-06,quantile,wk inc flu hosp +26,1,0.025,409.6939820218984,2024-01-20,2024-01-06,quantile,wk inc flu hosp +27,1,0.025,124.39897163337467,2024-01-20,2024-01-06,quantile,wk inc flu hosp +28,1,0.025,175.36402633975484,2024-01-20,2024-01-06,quantile,wk inc flu hosp +29,1,0.025,209.23686847240242,2024-01-20,2024-01-06,quantile,wk inc flu hosp +30,1,0.025,64.50575615762101,2024-01-20,2024-01-06,quantile,wk inc flu hosp +31,1,0.025,29.461009119291756,2024-01-20,2024-01-06,quantile,wk inc flu hosp +32,1,0.025,58.994205192068435,2024-01-20,2024-01-06,quantile,wk inc flu hosp +33,1,0.025,19.83597966188358,2024-01-20,2024-01-06,quantile,wk inc flu hosp +34,1,0.025,522.9064633933519,2024-01-20,2024-01-06,quantile,wk inc flu hosp +35,1,0.025,91.47893236903325,2024-01-20,2024-01-06,quantile,wk inc flu hosp +36,1,0.025,893.9264225034239,2024-01-20,2024-01-06,quantile,wk inc flu hosp +37,1,0.025,749.562825773111,2024-01-20,2024-01-06,quantile,wk inc flu hosp +38,1,0.025,8.271922933956493,2024-01-20,2024-01-06,quantile,wk inc flu hosp +39,1,0.025,441.7944503388599,2024-01-20,2024-01-06,quantile,wk inc flu hosp +40,1,0.025,37.53692685000533,2024-01-20,2024-01-06,quantile,wk inc flu hosp +41,1,0.025,55.354131170070346,2024-01-20,2024-01-06,quantile,wk inc flu hosp +42,1,0.025,696.9573019173299,2024-01-20,2024-01-06,quantile,wk inc flu hosp +44,1,0.025,18.04611811938404,2024-01-20,2024-01-06,quantile,wk inc flu hosp +45,1,0.025,415.1847482383114,2024-01-20,2024-01-06,quantile,wk inc flu hosp +46,1,0.025,19.369131117121597,2024-01-20,2024-01-06,quantile,wk inc flu hosp +47,1,0.025,364.6605217791168,2024-01-20,2024-01-06,quantile,wk inc flu hosp +48,1,0.025,1341.3487119857273,2024-01-20,2024-01-06,quantile,wk inc flu hosp +49,1,0.025,45.75963267924902,2024-01-20,2024-01-06,quantile,wk inc flu hosp +50,1,0.025,3.410320233809545,2024-01-20,2024-01-06,quantile,wk inc flu hosp +51,1,0.025,551.4658987680598,2024-01-20,2024-01-06,quantile,wk inc flu hosp +53,1,0.025,86.86349288134738,2024-01-20,2024-01-06,quantile,wk inc flu hosp +54,1,0.025,82.26183005299774,2024-01-20,2024-01-06,quantile,wk inc flu hosp +55,1,0.025,182.57980775992698,2024-01-20,2024-01-06,quantile,wk inc flu hosp +56,1,0.025,13.581979897690738,2024-01-20,2024-01-06,quantile,wk inc flu hosp +72,1,0.025,11.411690987036465,2024-01-20,2024-01-06,quantile,wk inc flu hosp +US,1,0.025,16197.189036799115,2024-01-20,2024-01-06,quantile,wk inc flu hosp +01,1,0.5,325.16927683140216,2024-01-20,2024-01-06,quantile,wk inc flu hosp +02,1,0.5,5.805695735380118,2024-01-20,2024-01-06,quantile,wk inc flu hosp +04,1,0.5,1184.1074913108318,2024-01-20,2024-01-06,quantile,wk inc flu hosp +05,1,0.5,293.1596972194759,2024-01-20,2024-01-06,quantile,wk inc flu hosp +06,1,0.5,1600.433427770704,2024-01-20,2024-01-06,quantile,wk inc flu hosp +08,1,0.5,331.52946071672113,2024-01-20,2024-01-06,quantile,wk inc flu hosp +09,1,0.5,213.54260032354443,2024-01-20,2024-01-06,quantile,wk inc flu hosp +10,1,0.5,94.43981178802058,2024-01-20,2024-01-06,quantile,wk inc flu hosp +11,1,0.5,58.32739397926988,2024-01-20,2024-01-06,quantile,wk inc flu hosp +12,1,0.5,1246.8425589162066,2024-01-20,2024-01-06,quantile,wk inc flu hosp +13,1,0.5,730.0353343381132,2024-01-20,2024-01-06,quantile,wk inc flu hosp +15,1,0.5,27.10897372842518,2024-01-20,2024-01-06,quantile,wk inc flu hosp +16,1,0.5,135.91951763445186,2024-01-20,2024-01-06,quantile,wk inc flu hosp +17,1,0.5,643.443807351004,2024-01-20,2024-01-06,quantile,wk inc flu hosp +18,1,0.5,632.9959561608149,2024-01-20,2024-01-06,quantile,wk inc flu hosp +19,1,0.5,81.36514710501723,2024-01-20,2024-01-06,quantile,wk inc flu hosp +20,1,0.5,108.46587584909305,2024-01-20,2024-01-06,quantile,wk inc flu hosp +21,1,0.5,404.8943409202851,2024-01-20,2024-01-06,quantile,wk inc flu hosp +22,1,0.5,400.79337925372494,2024-01-20,2024-01-06,quantile,wk inc flu hosp +23,1,0.5,81.80947037166808,2024-01-20,2024-01-06,quantile,wk inc flu hosp +24,1,0.5,463.878603527081,2024-01-20,2024-01-06,quantile,wk inc flu hosp +25,1,0.5,759.1285051162381,2024-01-20,2024-01-06,quantile,wk inc flu hosp +26,1,0.5,801.9758360026536,2024-01-20,2024-01-06,quantile,wk inc flu hosp +27,1,0.5,255.50110656859997,2024-01-20,2024-01-06,quantile,wk inc flu hosp +28,1,0.5,352.5695093602886,2024-01-20,2024-01-06,quantile,wk inc flu hosp +29,1,0.5,453.96939909602554,2024-01-20,2024-01-06,quantile,wk inc flu hosp +30,1,0.5,151.26965893132572,2024-01-20,2024-01-06,quantile,wk inc flu hosp +31,1,0.5,85.29488213947062,2024-01-20,2024-01-06,quantile,wk inc flu hosp +32,1,0.5,161.64556279226446,2024-01-20,2024-01-06,quantile,wk inc flu hosp +33,1,0.5,74.28477943320824,2024-01-20,2024-01-06,quantile,wk inc flu hosp +34,1,0.5,974.6661560731051,2024-01-20,2024-01-06,quantile,wk inc flu hosp +35,1,0.5,238.29923887186044,2024-01-20,2024-01-06,quantile,wk inc flu hosp +36,1,0.5,1485.1908223659507,2024-01-20,2024-01-06,quantile,wk inc flu hosp +37,1,0.5,1216.8952890602802,2024-01-20,2024-01-06,quantile,wk inc flu hosp +38,1,0.5,43.94171042621209,2024-01-20,2024-01-06,quantile,wk inc flu hosp +39,1,0.5,785.7800777494689,2024-01-20,2024-01-06,quantile,wk inc flu hosp +40,1,0.5,161.15492879545238,2024-01-20,2024-01-06,quantile,wk inc flu hosp +41,1,0.5,198.5698026829049,2024-01-20,2024-01-06,quantile,wk inc flu hosp +42,1,0.5,1292.4013480488923,2024-01-20,2024-01-06,quantile,wk inc flu hosp +44,1,0.5,66.74785191253872,2024-01-20,2024-01-06,quantile,wk inc flu hosp +45,1,0.5,717.0940743607227,2024-01-20,2024-01-06,quantile,wk inc flu hosp +46,1,0.5,79.23986027770589,2024-01-20,2024-01-06,quantile,wk inc flu hosp +47,1,0.5,720.6704826619683,2024-01-20,2024-01-06,quantile,wk inc flu hosp +48,1,0.5,2188.6798072432766,2024-01-20,2024-01-06,quantile,wk inc flu hosp +49,1,0.5,114.46290066351298,2024-01-20,2024-01-06,quantile,wk inc flu hosp +50,1,0.5,26.189624889013114,2024-01-20,2024-01-06,quantile,wk inc flu hosp +51,1,0.5,882.923010639335,2024-01-20,2024-01-06,quantile,wk inc flu hosp +53,1,0.5,260.873366716091,2024-01-20,2024-01-06,quantile,wk inc flu hosp +54,1,0.5,255.8238213798698,2024-01-20,2024-01-06,quantile,wk inc flu hosp +55,1,0.5,370.67035671271077,2024-01-20,2024-01-06,quantile,wk inc flu hosp +56,1,0.5,70.48155831683266,2024-01-20,2024-01-06,quantile,wk inc flu hosp +72,1,0.5,57.47915473684022,2024-01-20,2024-01-06,quantile,wk inc flu hosp +US,1,0.5,25332.627062144904,2024-01-20,2024-01-06,quantile,wk inc flu hosp +01,1,0.975,657.4766072440723,2024-01-20,2024-01-06,quantile,wk inc flu hosp +02,1,0.975,51.22024142624463,2024-01-20,2024-01-06,quantile,wk inc flu hosp +04,1,0.975,2050.542196378686,2024-01-20,2024-01-06,quantile,wk inc flu hosp +05,1,0.975,576.1884659172927,2024-01-20,2024-01-06,quantile,wk inc flu hosp +06,1,0.975,3005.6382887343293,2024-01-20,2024-01-06,quantile,wk inc flu hosp +08,1,0.975,561.5406650080793,2024-01-20,2024-01-06,quantile,wk inc flu hosp +09,1,0.975,442.36566240582766,2024-01-20,2024-01-06,quantile,wk inc flu hosp +10,1,0.975,317.27043289868527,2024-01-20,2024-01-06,quantile,wk inc flu hosp +11,1,0.975,168.81616271441337,2024-01-20,2024-01-06,quantile,wk inc flu hosp +12,1,0.975,2105.601320256105,2024-01-20,2024-01-06,quantile,wk inc flu hosp +13,1,0.975,1132.7115925057067,2024-01-20,2024-01-06,quantile,wk inc flu hosp +15,1,0.975,96.5223854582273,2024-01-20,2024-01-06,quantile,wk inc flu hosp +16,1,0.975,356.8056450371509,2024-01-20,2024-01-06,quantile,wk inc flu hosp +17,1,0.975,1154.1859002495048,2024-01-20,2024-01-06,quantile,wk inc flu hosp +18,1,0.975,1229.8945401552255,2024-01-20,2024-01-06,quantile,wk inc flu hosp +19,1,0.975,206.3313192192834,2024-01-20,2024-01-06,quantile,wk inc flu hosp +20,1,0.975,247.7243019549721,2024-01-20,2024-01-06,quantile,wk inc flu hosp +21,1,0.975,861.6019383209459,2024-01-20,2024-01-06,quantile,wk inc flu hosp +22,1,0.975,774.103249625776,2024-01-20,2024-01-06,quantile,wk inc flu hosp +23,1,0.975,220.1600569047099,2024-01-20,2024-01-06,quantile,wk inc flu hosp +24,1,0.975,757.4417743738418,2024-01-20,2024-01-06,quantile,wk inc flu hosp +25,1,0.975,1241.7321267552643,2024-01-20,2024-01-06,quantile,wk inc flu hosp +26,1,0.975,1436.8760612756503,2024-01-20,2024-01-06,quantile,wk inc flu hosp +27,1,0.975,465.10583012009346,2024-01-20,2024-01-06,quantile,wk inc flu hosp +28,1,0.975,758.4296488776324,2024-01-20,2024-01-06,quantile,wk inc flu hosp +29,1,0.975,918.7480239646804,2024-01-20,2024-01-06,quantile,wk inc flu hosp +30,1,0.975,289.08779136629784,2024-01-20,2024-01-06,quantile,wk inc flu hosp +31,1,0.975,187.1994992283615,2024-01-20,2024-01-06,quantile,wk inc flu hosp +32,1,0.975,386.27954061641753,2024-01-20,2024-01-06,quantile,wk inc flu hosp +33,1,0.975,198.6537732249351,2024-01-20,2024-01-06,quantile,wk inc flu hosp +34,1,0.975,1588.7806187229571,2024-01-20,2024-01-06,quantile,wk inc flu hosp +35,1,0.975,600.2617015239209,2024-01-20,2024-01-06,quantile,wk inc flu hosp +36,1,0.975,2387.4188622263455,2024-01-20,2024-01-06,quantile,wk inc flu hosp +37,1,0.975,1911.6204120702776,2024-01-20,2024-01-06,quantile,wk inc flu hosp +38,1,0.975,176.59353883132405,2024-01-20,2024-01-06,quantile,wk inc flu hosp +39,1,0.975,1279.7624446718696,2024-01-20,2024-01-06,quantile,wk inc flu hosp +40,1,0.975,510.9937307185694,2024-01-20,2024-01-06,quantile,wk inc flu hosp +41,1,0.975,458.25509850399544,2024-01-20,2024-01-06,quantile,wk inc flu hosp +42,1,0.975,2035.329914558797,2024-01-20,2024-01-06,quantile,wk inc flu hosp +44,1,0.975,168.80995166552265,2024-01-20,2024-01-06,quantile,wk inc flu hosp +45,1,0.975,1235.2244922327388,2024-01-20,2024-01-06,quantile,wk inc flu hosp +46,1,0.975,236.33124999519856,2024-01-20,2024-01-06,quantile,wk inc flu hosp +47,1,0.975,1274.0982061277762,2024-01-20,2024-01-06,quantile,wk inc flu hosp +48,1,0.975,3171.8381233911823,2024-01-20,2024-01-06,quantile,wk inc flu hosp +49,1,0.975,248.54502054607156,2024-01-20,2024-01-06,quantile,wk inc flu hosp +50,1,0.975,77.250339010357,2024-01-20,2024-01-06,quantile,wk inc flu hosp +51,1,0.975,1571.7647510536885,2024-01-20,2024-01-06,quantile,wk inc flu hosp +53,1,0.975,517.6911594676088,2024-01-20,2024-01-06,quantile,wk inc flu hosp +54,1,0.975,587.6658664124582,2024-01-20,2024-01-06,quantile,wk inc flu hosp +55,1,0.975,660.0030565483804,2024-01-20,2024-01-06,quantile,wk inc flu hosp +56,1,0.975,213.65883760046924,2024-01-20,2024-01-06,quantile,wk inc flu hosp +72,1,0.975,153.01872811186684,2024-01-20,2024-01-06,quantile,wk inc flu hosp +US,1,0.975,38310.00000262484,2024-01-20,2024-01-06,quantile,wk inc flu hosp diff --git a/tests/integration/data/plot_test_data.R b/tests/integration/data/plot_test_data.R new file mode 100644 index 0000000..ae640a6 --- /dev/null +++ b/tests/integration/data/plot_test_data.R @@ -0,0 +1,43 @@ +# You can use this script to verify that the data objects used as expected +# outcomes for integration tests are reasonable. +# This script expects to be run from the repository root. + +library(hubData) +library(hubVis) +library(readr) +library(lubridate) + +ref_date <- as.Date("2024-01-06") + +locations <- read.csv("https://raw.githubusercontent.com/cdcepi/FluSight-forecast-hub/refs/heads/main/auxiliary-data/locations.csv") + +forecasts <- dplyr::bind_rows( + read.csv("tests/integration/data/UMass-gbqr_no_reporting_adj/2024-01-06-UMass-gbqr_no_reporting_adj.csv") |> + dplyr::mutate(model_id = "UMass-gbqr"), + read.csv("tests/integration/data/UMass-sarix_p6_4rt_thetashared_sigmanone/2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv") |> + dplyr::mutate(model_id = "UMass-sarix") +) |> + dplyr::left_join(locations) + +target_data <- readr::read_csv("https://raw.githubusercontent.com/cdcepi/FluSight-forecast-hub/main/target-data/target-hospital-admissions.csv") + +data_start <- ref_date - 6 * 7 +data_end <- ref_date + 6 * 7 + +p <- plot_step_ahead_model_output( + forecasts, + target_data |> + dplyr::filter(date >= data_start, date <= data_end) |> + dplyr::mutate(observation = value), + x_col_name = "target_end_date", + x_target_col_name = "date", + intervals = 0.95, + facet = "location_name", + facet_scales = "free_y", + facet_nrow = 8, + use_median_as_point = TRUE, + interactive = FALSE, + show_plot = FALSE +) + +p diff --git a/tests/integration/test_gbqr.py b/tests/integration/test_gbqr.py new file mode 100644 index 0000000..645c19a --- /dev/null +++ b/tests/integration/test_gbqr.py @@ -0,0 +1,59 @@ +import datetime +from types import SimpleNamespace + +from idmodels.gbqr import GBQRModel + +from pathlib import Path + +import pandas as pd +from pandas.testing import assert_frame_equal + +def test_gbqr(tmp_path): + model_config = SimpleNamespace( + model_class = 'gbqr', + model_name = 'gbqr_no_reporting_adj', + + incl_level_feats = True, + + # bagging setup + num_bags = 10, + bag_frac_samples = 0.7, + + # adjustments to reporting + reporting_adj = False, + + # data sources and adjustments for reporting issues + sources = ['flusurvnet', 'nhsn', 'ilinet'], + + # fit locations separately or jointly + fit_locations_separately = False, + + # power transform applied to surveillance signals + power_transform = '4rt' + ) + + + run_config = SimpleNamespace( + ref_date=datetime.date.fromisoformat('2024-01-06'), + output_root=tmp_path / 'model-output', + artifact_store_root=tmp_path / 'artifact-store', + save_feat_importance=False, + max_horizon=3, + q_levels = [0.025, 0.50, 0.975], + q_labels = ['0.025', '0.5', '0.975'], + num_bags = 10 + ) + + model = GBQRModel(model_config) + model.run(run_config) + + actual_df = pd.read_csv( + run_config.output_root / 'UMass-gbqr_no_reporting_adj' / + '2024-01-06-UMass-gbqr_no_reporting_adj.csv' + ) + expected_df = pd.read_csv( + Path('tests') / 'integration' / 'data' / + 'UMass-gbqr_no_reporting_adj' / + '2024-01-06-UMass-gbqr_no_reporting_adj.csv' + ) + assert_frame_equal(actual_df, expected_df) diff --git a/tests/integration/test_sarix.py b/tests/integration/test_sarix.py new file mode 100644 index 0000000..9910571 --- /dev/null +++ b/tests/integration/test_sarix.py @@ -0,0 +1,65 @@ +from types import SimpleNamespace + +import datetime +from pathlib import Path +from idmodels.sarix import SARIXModel + +import pandas as pd +from pandas.testing import assert_frame_equal + +def test_sarix(tmp_path): + model_config = SimpleNamespace( + model_class = 'sarix', + model_name = 'sarix_p6_4rt_thetashared_sigmanone', + + # data sources and adjustments for reporting issues + sources = ['nhsn'], + + # fit locations separately or jointly + fit_locations_separately = False, + + # SARI model parameters + p = 6, + P = 0, + d = 0, + D = 0, + season_period = 1, + + # power transform applied to surveillance signals + power_transform = '4rt', + + # sharing of information about parameters + theta_pooling='shared', + sigma_pooling='none', + + # covariates + x = [] + ) + + run_config = SimpleNamespace( + ref_date=datetime.date.fromisoformat('2024-01-06'), + # output_root=tmp_path / 'model-output', + output_root=Path('tests/integration/data/'), + artifact_store_root=tmp_path / 'artifact-store', + save_feat_importance=False, + max_horizon=3, + q_levels = [0.025, 0.50, 0.975], + q_labels = ['0.025', '0.5', '0.975'], + num_warmup = 200, + num_samples = 200, + num_chains = 1 + ) + + model = SARIXModel(model_config) + model.run(run_config) + + actual_df = pd.read_csv( + run_config.output_root / 'UMass-sarix_p6_4rt_thetashared_sigmanone' / + '2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv' + ) + expected_df = pd.read_csv( + Path('tests') / 'integration' / 'data' / + 'UMass-sarix_p6_4rt_thetashared_sigmanone' / + '2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv' + ) + assert_frame_equal(actual_df, expected_df) diff --git a/tests/unit/gbqr/test_drop_level_feats.py b/tests/unit/gbqr/test_drop_level_feats.py new file mode 100644 index 0000000..ca7573c --- /dev/null +++ b/tests/unit/gbqr/test_drop_level_feats.py @@ -0,0 +1,56 @@ +from idmodels.preprocess import drop_level_feats + +def test_drop_level_feats(): + # a representative subset of the features used by the gbq_qr model + in_feats = ['inc_trans_cs', 'season_week', 'log_pop', 'source_flusurvnet', + 'source_hhs', 'source_ilinet', 'agg_level_hhs region', + 'agg_level_national', 'agg_level_state', 'location_01', + 'location_02', 'location_04', 'location_05', 'location_06', + 'location_Region 1', 'location_Region 10', 'location_Region 2', + 'location_US', 'delta_xmas', 'inc_trans_cs_taylor_d2_c0_w4t_sNone', + 'inc_trans_cs_taylor_d2_c1_w4t_sNone', 'inc_trans_cs_taylor_d2_c2_w4t_sNone', + 'inc_trans_cs_taylor_d2_c0_w6t_sNone', 'inc_trans_cs_taylor_d2_c1_w6t_sNone', + 'inc_trans_cs_taylor_d2_c2_w6t_sNone', 'inc_trans_cs_taylor_d1_c0_w3t_sNone', + 'inc_trans_cs_taylor_d1_c1_w3t_sNone', 'inc_trans_cs_taylor_d1_c0_w5t_sNone', + 'inc_trans_cs_taylor_d1_c1_w5t_sNone', 'inc_trans_cs_rollmean_w2', + 'inc_trans_cs_rollmean_w4', 'inc_trans_cs_lag1', 'inc_trans_cs_lag2', + 'inc_trans_cs_taylor_d2_c0_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c0_w4t_sNone_lag2', + 'inc_trans_cs_taylor_d2_c1_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c1_w4t_sNone_lag2', + 'inc_trans_cs_taylor_d2_c2_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c2_w4t_sNone_lag2', + 'inc_trans_cs_taylor_d2_c0_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c0_w6t_sNone_lag2', + 'inc_trans_cs_taylor_d2_c1_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c1_w6t_sNone_lag2', + 'inc_trans_cs_taylor_d2_c2_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c2_w6t_sNone_lag2', + 'inc_trans_cs_taylor_d1_c0_w3t_sNone_lag1', 'inc_trans_cs_taylor_d1_c0_w3t_sNone_lag2', + 'inc_trans_cs_taylor_d1_c1_w3t_sNone_lag1', 'inc_trans_cs_taylor_d1_c1_w3t_sNone_lag2', + 'inc_trans_cs_taylor_d1_c0_w5t_sNone_lag1', 'inc_trans_cs_taylor_d1_c0_w5t_sNone_lag2', + 'inc_trans_cs_taylor_d1_c1_w5t_sNone_lag1', 'inc_trans_cs_taylor_d1_c1_w5t_sNone_lag2', + 'inc_trans_cs_rollmean_w2_lag1', 'inc_trans_cs_rollmean_w2_lag2', + 'inc_trans_cs_rollmean_w4_lag1', 'inc_trans_cs_rollmean_w4_lag2', 'horizon'] + + # subset of in_feats expected to be returned by _drop_level_feats: + # I have manually removed any that measure local level of the surveillance signal in some way + # these are 'inc_trans_cs', rolling means of that, and degree 0 coefficients ('c0') + # of Taylor approximations + expected = ['season_week', 'log_pop', 'source_flusurvnet', + 'source_hhs', 'source_ilinet', 'agg_level_hhs region', + 'agg_level_national', 'agg_level_state', 'location_01', + 'location_02', 'location_04', 'location_05', 'location_06', + 'location_Region 1', 'location_Region 10', 'location_Region 2', + 'location_US', 'delta_xmas', + 'inc_trans_cs_taylor_d2_c1_w4t_sNone', 'inc_trans_cs_taylor_d2_c2_w4t_sNone', + 'inc_trans_cs_taylor_d2_c1_w6t_sNone', + 'inc_trans_cs_taylor_d2_c2_w6t_sNone', + 'inc_trans_cs_taylor_d1_c1_w3t_sNone', + 'inc_trans_cs_taylor_d1_c1_w5t_sNone', + 'inc_trans_cs_taylor_d2_c1_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c1_w4t_sNone_lag2', + 'inc_trans_cs_taylor_d2_c2_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c2_w4t_sNone_lag2', + 'inc_trans_cs_taylor_d2_c1_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c1_w6t_sNone_lag2', + 'inc_trans_cs_taylor_d2_c2_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c2_w6t_sNone_lag2', + 'inc_trans_cs_taylor_d1_c1_w3t_sNone_lag1', 'inc_trans_cs_taylor_d1_c1_w3t_sNone_lag2', + 'inc_trans_cs_taylor_d1_c1_w5t_sNone_lag1', 'inc_trans_cs_taylor_d1_c1_w5t_sNone_lag2', + 'horizon'] + + actual = drop_level_feats(in_feats) + + assert len(actual) == len(expected) + assert not set(actual) - set(expected) From e488f6a2b67078feabf7b7fdbd454105eb719014 Mon Sep 17 00:00:00 2001 From: Evan Ray Date: Thu, 7 Nov 2024 11:29:20 -0500 Subject: [PATCH 4/7] ruff fixes --- src/idmodels/gbqr.py | 101 +++++++++++------------ src/idmodels/preprocess.py | 87 ++++++++++--------- src/idmodels/sarix.py | 59 +++++++------ src/idmodels/utils.py | 9 +- tests/integration/test_gbqr.py | 34 ++++---- tests/integration/test_sarix.py | 37 +++++---- tests/unit/gbqr/test_drop_level_feats.py | 85 +++++++++---------- 7 files changed, 206 insertions(+), 206 deletions(-) diff --git a/src/idmodels/gbqr.py b/src/idmodels/gbqr.py index b002600..378122c 100644 --- a/src/idmodels/gbqr.py +++ b/src/idmodels/gbqr.py @@ -1,39 +1,38 @@ import time -from tqdm.autonotebook import tqdm - +import lightgbm as lgb import numpy as np import pandas as pd -import lightgbm as lgb - from iddata.loader import FluDataLoader +from tqdm.autonotebook import tqdm from idmodels.preprocess import create_features_and_targets from idmodels.utils import build_save_path + class GBQRModel(): def __init__(self, model_config): self.model_config = model_config def run(self, run_config): - ''' + """ Load flu data, generate predictions from a gbqr model, and save them as a csv file. Parameters ---------- run_config: configuration object with settings for the run - ''' + """ # load flu data if self.model_config.reporting_adj: ilinet_kwargs = None flusurvnet_kwargs = None else: - ilinet_kwargs = {'scale_to_positive': False} - flusurvnet_kwargs = {'burden_adj': False} + ilinet_kwargs = {"scale_to_positive": False} + flusurvnet_kwargs = {"burden_adj": False} fdl = FluDataLoader() - df = fdl.load_data(nhsn_kwargs={'as_of': run_config.ref_date}, + df = fdl.load_data(nhsn_kwargs={"as_of": run_config.ref_date}, ilinet_kwargs=ilinet_kwargs, flusurvnet_kwargs=flusurvnet_kwargs, sources=self.model_config.sources, @@ -44,7 +43,7 @@ def run(self, run_config): df = df, incl_level_feats=self.model_config.incl_level_feats, max_horizon=run_config.max_horizon, - curr_feat_names=['inc_trans_cs', 'season_week', 'log_pop']) + curr_feat_names=["inc_trans_cs", "season_week", "log_pop"]) # keep only rows that are in-season df = df.query("season_week >= 5 and season_week <= 45") @@ -54,11 +53,11 @@ def run(self, run_config): .copy() # "train set" df for model fitting; target value non-missing - df_train = df.loc[~df['delta_target'].isna().values] + df_train = df.loc[~df["delta_target"].isna().values] # train model and obtain test set predictinos if self.model_config.fit_locations_separately: - locations = df_test['location'].unique() + locations = df_test["location"].unique() preds_df = [ self._train_gbq_and_predict( run_config, @@ -83,7 +82,7 @@ def run(self, run_config): def _train_gbq_and_predict(self, run_config, df_train, df_test, feat_names, location = None): - ''' + """ Train gbq model and get predictions on the original target scale, formatted in the FluSight hub format. @@ -98,7 +97,7 @@ def _train_gbq_and_predict(self, run_config, Returns ------- Pandas data frame with test set predictions in FluSight hub format - ''' + """ # filter to location if necessary if location is not None: df_test = df_test.query(f'location == "{location}"') @@ -107,7 +106,7 @@ def _train_gbq_and_predict(self, run_config, # get x and y x_test = df_test[feat_names] x_train = df_train[feat_names] - y_train = df_train['delta_target'] + y_train = df_train["delta_target"] # test set predictions: # same number of rows as df_test, one column per quantile level @@ -122,28 +121,28 @@ def _train_gbq_and_predict(self, run_config, # melt to get columns into rows, keeping only the things we need to invert data # transforms later on - cols_to_keep = ['source', 'location', 'wk_end_date', 'pop', - 'inc_trans_cs', 'horizon', - 'inc_trans_center_factor', 'inc_trans_scale_factor'] + cols_to_keep = ["source", "location", "wk_end_date", "pop", + "inc_trans_cs", "horizon", + "inc_trans_center_factor", "inc_trans_scale_factor"] preds_df = df_test_w_preds[cols_to_keep + run_config.q_labels] - preds_df = preds_df.loc[(preds_df['source'] == 'nhsn')] + preds_df = preds_df.loc[(preds_df["source"] == "nhsn")] preds_df = pd.melt(preds_df, id_vars=cols_to_keep, - var_name='quantile', - value_name = 'delta_hat') + var_name="quantile", + value_name = "delta_hat") # build data frame with predictions on the original scale - preds_df['inc_trans_cs_target_hat'] = preds_df['inc_trans_cs'] + preds_df['delta_hat'] - preds_df['inc_trans_target_hat'] = (preds_df['inc_trans_cs_target_hat'] + preds_df['inc_trans_center_factor']) * (preds_df['inc_trans_scale_factor'] + 0.01) - if self.model_config.power_transform == '4rt': + preds_df["inc_trans_cs_target_hat"] = preds_df["inc_trans_cs"] + preds_df["delta_hat"] + preds_df["inc_trans_target_hat"] = (preds_df["inc_trans_cs_target_hat"] + preds_df["inc_trans_center_factor"]) * (preds_df["inc_trans_scale_factor"] + 0.01) + if self.model_config.power_transform == "4rt": inv_power = 4 elif self.model_config.power_transform is None: inv_power = 1 else: raise ValueError('unsupported power_transform: must be "4rt" or None') - preds_df['value'] = (np.maximum(preds_df['inc_trans_target_hat'], 0.0) ** inv_power - 0.01 - 0.75**4) * preds_df['pop'] / 100000 - preds_df['value'] = np.maximum(preds_df['value'], 0.0) + preds_df["value"] = (np.maximum(preds_df["inc_trans_target_hat"], 0.0) ** inv_power - 0.01 - 0.75**4) * preds_df["pop"] / 100000 + preds_df["value"] = np.maximum(preds_df["value"], 0.0) # get predictions into the format needed for FluSight hub submission preds_df = self._format_as_flusight_output(preds_df, run_config.ref_date) @@ -151,8 +150,8 @@ def _train_gbq_and_predict(self, run_config, # sort quantiles to avoid quantile crossing preds_df = self._quantile_noncrossing( preds_df, - gcols = ['location', 'reference_date', 'horizon', 'target_end_date', - 'target', 'output_type'] + gcols = ["location", "reference_date", "horizon", "target_end_date", + "target", "output_type"] ) return preds_df @@ -160,7 +159,7 @@ def _train_gbq_and_predict(self, run_config, def _get_test_quantile_predictions(self, run_config, df_train, x_train, y_train, x_test): - ''' + """ Train the model on bagged subsets of the training data and obtain quantile predictions. This is the heart of the method. @@ -178,7 +177,7 @@ def _get_test_quantile_predictions(self, run_config, the number of rows of `x_test`. The number of columns matches the number of quantile levels for predictions as specified in the `run_config`. Column names are given by `run_config.q_labels`. - ''' + """ # seed for random number generation, based on reference date rng_seed = int(time.mktime(run_config.ref_date.timetuple())) rng = np.random.default_rng(seed=rng_seed) @@ -188,33 +187,33 @@ def _get_test_quantile_predictions(self, run_config, # training loop over bags test_preds_by_bag = np.empty((x_test.shape[0], self.model_config.num_bags, len(run_config.q_levels))) - train_seasons = df_train['season'].unique() + train_seasons = df_train["season"].unique() feat_importance = list() - for b in tqdm(range(self.model_config.num_bags), 'Bag number'): + for b in tqdm(range(self.model_config.num_bags), "Bag number"): # get indices of observations that are in bag bag_seasons = rng.choice( train_seasons, size = int(len(train_seasons) * self.model_config.bag_frac_samples), replace=False) - bag_obs_inds = df_train['season'].isin(bag_seasons) + bag_obs_inds = df_train["season"].isin(bag_seasons) for q_ind, q_level in enumerate(run_config.q_levels): # fit to bag model = lgb.LGBMRegressor( verbosity=-1, - objective='quantile', + objective="quantile", alpha=q_level, random_state=lgb_seeds[b, q_ind]) model.fit(X=x_train.loc[bag_obs_inds, :], y=y_train.loc[bag_obs_inds]) feat_importance.append( pd.DataFrame({ - 'feat': x_train.columns, - 'importance': model.feature_importances_, - 'b': b, - 'q_level': q_level + "feat": x_train.columns, + "importance": model.feature_importances_, + "b": b, + "q_level": q_level }) ) @@ -224,11 +223,11 @@ def _get_test_quantile_predictions(self, run_config, # combine and save feature importance scores if run_config.save_feat_importance: feat_importance = pd.concat(feat_importance, axis=0) - save_path = _build_save_path( + save_path = build_save_path( root=run_config.artifact_store_root, run_config=run_config, model_config=self.model_config, - subdir='feat_importance') + subdir="feat_importance") feat_importance.to_csv(save_path, index=False) # combined predictions across bags: median @@ -243,22 +242,22 @@ def _get_test_quantile_predictions(self, run_config, def _format_as_flusight_output(self, preds_df, ref_date): # keep just required columns and rename to match hub format - preds_df = preds_df[['location', 'wk_end_date', 'horizon', 'quantile', 'value']] \ - .rename(columns={'quantile': 'output_type_id'}) + preds_df = preds_df[["location", "wk_end_date", "horizon", "quantile", "value"]] \ + .rename(columns={"quantile": "output_type_id"}) - preds_df['target_end_date'] = preds_df['wk_end_date'] + pd.to_timedelta(7*preds_df['horizon'], unit='days') - preds_df['reference_date'] = ref_date - preds_df['horizon'] = preds_df['horizon'] - 2 - preds_df['target'] = 'wk inc flu hosp' + preds_df["target_end_date"] = preds_df["wk_end_date"] + pd.to_timedelta(7*preds_df["horizon"], unit="days") + preds_df["reference_date"] = ref_date + preds_df["horizon"] = preds_df["horizon"] - 2 + preds_df["target"] = "wk inc flu hosp" - preds_df['output_type'] = 'quantile' - preds_df.drop(columns='wk_end_date', inplace=True) + preds_df["output_type"] = "quantile" + preds_df.drop(columns="wk_end_date", inplace=True) return preds_df def _quantile_noncrossing(self, preds_df, gcols): - ''' + """ Sort predictions to be in alignment with quantile levels, to prevent quantile crossing. @@ -270,9 +269,9 @@ def _quantile_noncrossing(self, preds_df, gcols): Returns ------- Sorted version of preds_df, guaranteed not to have quantile crossing - ''' + """ g = preds_df.set_index(gcols).groupby(gcols) - preds_df = g[['output_type_id', 'value']] \ + preds_df = g[["output_type_id", "value"]] \ .transform(lambda x: x.sort_values()) \ .reset_index() diff --git a/src/idmodels/preprocess.py b/src/idmodels/preprocess.py index 46ff0bd..e080411 100644 --- a/src/idmodels/preprocess.py +++ b/src/idmodels/preprocess.py @@ -1,9 +1,8 @@ import fnmatch import pandas as pd - -from timeseriesutils import featurize from iddata.utils import get_holidays +from timeseriesutils import featurize def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_names = []): @@ -33,7 +32,7 @@ def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_nam feat_names = curr_feat_names # one-hot encodings of data source, agg_level, and location - for c in ['source', 'agg_level', 'location']: + for c in ["source", "agg_level", "location"]: ohe = pd.get_dummies(df[c], prefix=c) df = pd.concat([df, ohe], axis=1) feat_names = feat_names + list(ohe.columns) @@ -42,57 +41,57 @@ def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_nam df = df.merge( get_holidays() \ .query("holiday == 'Christmas Day'") \ - .drop(columns=['holiday', 'date']) \ - .rename(columns={'season_week': 'xmas_week'}), - how='left', - on='season') \ - .assign(delta_xmas = lambda x: x['season_week'] - x['xmas_week']) + .drop(columns=["holiday", "date"]) \ + .rename(columns={"season_week": "xmas_week"}), + how="left", + on="season") \ + .assign(delta_xmas = lambda x: x["season_week"] - x["xmas_week"]) - feat_names = feat_names + ['delta_xmas'] + feat_names = feat_names + ["delta_xmas"] # features summarizing data within each combination of source and location df, new_feat_names = featurize.featurize_data( - df, group_columns=['source', 'location'], + df, group_columns=["source", "location"], features = [ { - 'fun': 'windowed_taylor_coefs', - 'args': { - 'columns': 'inc_trans_cs', - 'taylor_degree': 2, - 'window_align': 'trailing', - 'window_size': [4, 6], - 'fill_edges': False + "fun": "windowed_taylor_coefs", + "args": { + "columns": "inc_trans_cs", + "taylor_degree": 2, + "window_align": "trailing", + "window_size": [4, 6], + "fill_edges": False } }, { - 'fun': 'windowed_taylor_coefs', - 'args': { - 'columns': 'inc_trans_cs', - 'taylor_degree': 1, - 'window_align': 'trailing', - 'window_size': [3, 5], - 'fill_edges': False + "fun": "windowed_taylor_coefs", + "args": { + "columns": "inc_trans_cs", + "taylor_degree": 1, + "window_align": "trailing", + "window_size": [3, 5], + "fill_edges": False } }, { - 'fun': 'rollmean', - 'args': { - 'columns': 'inc_trans_cs', - 'group_columns': ['location'], - 'window_size': [2, 4] + "fun": "rollmean", + "args": { + "columns": "inc_trans_cs", + "group_columns": ["location"], + "window_size": [2, 4] } } ]) feat_names = feat_names + new_feat_names df, new_feat_names = featurize.featurize_data( - df, group_columns=['source', 'location'], + df, group_columns=["source", "location"], features = [ { - 'fun': 'lag', - 'args': { - 'columns': ['inc_trans_cs'] + new_feat_names, - 'lags': [1, 2] + "fun": "lag", + "args": { + "columns": ["inc_trans_cs"] + new_feat_names, + "lags": [1, 2] } } ]) @@ -100,13 +99,13 @@ def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_nam # add forecast targets df, new_feat_names = featurize.featurize_data( - df, group_columns=['source', 'location'], + df, group_columns=["source", "location"], features = [ { - 'fun': 'horizon_targets', - 'args': { - 'columns': 'inc_trans_cs', - 'horizons': [(i + 1) for i in range(max_horizon)] + "fun": "horizon_targets", + "args": { + "columns": "inc_trans_cs", + "horizons": [(i + 1) for i in range(max_horizon)] } } ]) @@ -114,7 +113,7 @@ def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_nam # we will model the differences between the prediction target and the most # recent observed value - df['delta_target'] = df['inc_trans_cs_target'] - df['inc_trans_cs'] + df["delta_target"] = df["inc_trans_cs_target"] - df["inc_trans_cs"] # if requested, drop features that involve absolute level if not incl_level_feats: @@ -123,10 +122,10 @@ def create_features_and_targets(df, incl_level_feats, max_horizon, curr_feat_nam return df, feat_names -def drop_level_feats(feat_names): - level_feats = ['inc_trans_cs', 'inc_trans_cs_lag1', 'inc_trans_cs_lag2'] + \ - fnmatch.filter(feat_names, '*taylor_d?_c0*') + \ - fnmatch.filter(feat_names, '*inc_trans_cs_rollmean*') +def _drop_level_feats(feat_names): + level_feats = ["inc_trans_cs", "inc_trans_cs_lag1", "inc_trans_cs_lag2"] + \ + fnmatch.filter(feat_names, "*taylor_d?_c0*") + \ + fnmatch.filter(feat_names, "*inc_trans_cs_rollmean*") feat_names = [f for f in feat_names if f not in level_feats] return feat_names diff --git a/src/idmodels/sarix.py b/src/idmodels/sarix.py index c7bdd37..5127eea 100644 --- a/src/idmodels/sarix.py +++ b/src/idmodels/sarix.py @@ -1,21 +1,20 @@ -from pathlib import Path import numpy as np import pandas as pd - from iddata.loader import FluDataLoader from iddata.utils import get_holidays - from sarix import sarix + from idmodels.utils import build_save_path + class SARIXModel(): def __init__(self, model_config): self.model_config = model_config def run(self, run_config): fdl = FluDataLoader() - df = fdl.load_data(nhsn_kwargs={'as_of': run_config.ref_date}, + df = fdl.load_data(nhsn_kwargs={"as_of": run_config.ref_date}, sources=self.model_config.sources, power_transform=self.model_config.power_transform) @@ -23,15 +22,15 @@ def run(self, run_config): df = df.merge( get_holidays() \ .query("holiday == 'Christmas Day'") \ - .drop(columns=['holiday', 'date']) \ - .rename(columns={'season_week': 'xmas_week'}), - how='left', - on='season') \ - .assign(delta_xmas = lambda x: x['season_week'] - x['xmas_week']) - df['xmas_spike'] = np.maximum(3 - np.abs(df['delta_xmas']), 0) + .drop(columns=["holiday", "date"]) \ + .rename(columns={"season_week": "xmas_week"}), + how="left", + on="season") \ + .assign(delta_xmas = lambda x: x["season_week"] - x["xmas_week"]) + df["xmas_spike"] = np.maximum(3 - np.abs(df["delta_xmas"]), 0) xy_colnames = ["inc_trans_cs"] + self.model_config.x - batched_xy = df[xy_colnames].values.reshape(len(df['location'].unique()), -1, len(xy_colnames)) + batched_xy = df[xy_colnames].values.reshape(len(df["location"].unique()), -1, len(xy_colnames)) sarix_fit_all_locs_theta_pooled = sarix.SARIX( xy = batched_xy, @@ -40,7 +39,7 @@ def run(self, run_config): P = self.model_config.P, D = self.model_config.D, season_period = self.model_config.season_period, - transform='none', # transformations are handled outside of SARIX + transform="none", # transformations are handled outside of SARIX theta_pooling=self.model_config.theta_pooling, sigma_pooling=self.model_config.sigma_pooling, forecast_horizon = run_config.max_horizon, @@ -52,38 +51,38 @@ def run(self, run_config): pred_qs = np.percentile(sarix_fit_all_locs_theta_pooled.predictions[..., :, :, 0], np.array(run_config.q_levels) * 100, axis=0) - df_nhsn_last_obs = df.groupby(['location']).tail(1) + df_nhsn_last_obs = df.groupby(["location"]).tail(1) preds_df = pd.concat([ pd.DataFrame(pred_qs[i, :, :]) \ - .set_axis(df_nhsn_last_obs['location'], axis='index') \ - .set_axis(np.arange(1, run_config.max_horizon+1), axis='columns') \ + .set_axis(df_nhsn_last_obs["location"], axis="index") \ + .set_axis(np.arange(1, run_config.max_horizon+1), axis="columns") \ .assign(output_type_id = q_label) \ for i, q_label in enumerate(run_config.q_labels) ]) \ .reset_index() \ - .melt(['location', 'output_type_id'], var_name='horizon') \ - .merge(df_nhsn_last_obs, on='location', how='left') + .melt(["location", "output_type_id"], var_name="horizon") \ + .merge(df_nhsn_last_obs, on="location", how="left") # build data frame with predictions on the original scale - preds_df['value'] = (preds_df['value'] + preds_df['inc_trans_center_factor']) * preds_df['inc_trans_scale_factor'] - if self.model_config.power_transform == '4rt': - preds_df['value'] = np.maximum(preds_df['value'], 0.0) ** 4 + preds_df["value"] = (preds_df["value"] + preds_df["inc_trans_center_factor"]) * preds_df["inc_trans_scale_factor"] + if self.model_config.power_transform == "4rt": + preds_df["value"] = np.maximum(preds_df["value"], 0.0) ** 4 else: - preds_df['value'] = np.maximum(preds_df['value'], 0.0) ** 2 + preds_df["value"] = np.maximum(preds_df["value"], 0.0) ** 2 - preds_df['value'] = (preds_df['value'] - 0.01 - 0.75**4) * preds_df['pop'] / 100000 - preds_df['value'] = np.maximum(preds_df['value'], 0.0) + preds_df["value"] = (preds_df["value"] - 0.01 - 0.75**4) * preds_df["pop"] / 100000 + preds_df["value"] = np.maximum(preds_df["value"], 0.0) # keep just required columns and rename to match hub format - preds_df = preds_df[['location', 'wk_end_date', 'horizon', 'output_type_id', 'value']] + preds_df = preds_df[["location", "wk_end_date", "horizon", "output_type_id", "value"]] - preds_df['target_end_date'] = preds_df['wk_end_date'] + pd.to_timedelta(7*preds_df['horizon'], unit='days') - preds_df['reference_date'] = run_config.ref_date - preds_df['horizon'] = preds_df['horizon'] - 2 - preds_df['output_type'] = 'quantile' - preds_df['target'] = 'wk inc flu hosp' - preds_df.drop(columns='wk_end_date', inplace=True) + preds_df["target_end_date"] = preds_df["wk_end_date"] + pd.to_timedelta(7*preds_df["horizon"], unit="days") + preds_df["reference_date"] = run_config.ref_date + preds_df["horizon"] = preds_df["horizon"] - 2 + preds_df["output_type"] = "quantile" + preds_df["target"] = "wk inc flu hosp" + preds_df.drop(columns="wk_end_date", inplace=True) # save save_path = build_save_path( diff --git a/src/idmodels/utils.py b/src/idmodels/utils.py index 0435003..0013d02 100644 --- a/src/idmodels/utils.py +++ b/src/idmodels/utils.py @@ -4,6 +4,7 @@ import datetime + def validate_ref_date(ref_date): if ref_date is None: today = datetime.date.today() @@ -15,16 +16,16 @@ def validate_ref_date(ref_date): elif isinstance(ref_date, datetime.date): # check that it's a Saturday if ref_date.weekday() != 5: - raise ValueError('ref_date must be a Saturday') + raise ValueError("ref_date must be a Saturday") return ref_date else: - raise TypeError('ref_date must be a datetime.date object') + raise TypeError("ref_date must be a datetime.date object") def build_save_path(root, run_config, model_config, subdir=None): - save_dir = root / f'UMass-{model_config.model_name}' + save_dir = root / f"UMass-{model_config.model_name}" if subdir is not None: save_dir = save_dir / subdir save_dir.mkdir(parents=True, exist_ok=True) - return save_dir / f'{str(run_config.ref_date)}-UMass-{model_config.model_name}.csv' + return save_dir / f"{str(run_config.ref_date)}-UMass-{model_config.model_name}.csv" diff --git a/tests/integration/test_gbqr.py b/tests/integration/test_gbqr.py index 645c19a..981c95d 100644 --- a/tests/integration/test_gbqr.py +++ b/tests/integration/test_gbqr.py @@ -1,17 +1,17 @@ import datetime -from types import SimpleNamespace - -from idmodels.gbqr import GBQRModel - from pathlib import Path +from types import SimpleNamespace import pandas as pd from pandas.testing import assert_frame_equal +from idmodels.gbqr import GBQRModel + + def test_gbqr(tmp_path): model_config = SimpleNamespace( - model_class = 'gbqr', - model_name = 'gbqr_no_reporting_adj', + model_class = "gbqr", + model_name = "gbqr_no_reporting_adj", incl_level_feats = True, @@ -23,24 +23,24 @@ def test_gbqr(tmp_path): reporting_adj = False, # data sources and adjustments for reporting issues - sources = ['flusurvnet', 'nhsn', 'ilinet'], + sources = ["flusurvnet", "nhsn", "ilinet"], # fit locations separately or jointly fit_locations_separately = False, # power transform applied to surveillance signals - power_transform = '4rt' + power_transform = "4rt" ) run_config = SimpleNamespace( - ref_date=datetime.date.fromisoformat('2024-01-06'), - output_root=tmp_path / 'model-output', - artifact_store_root=tmp_path / 'artifact-store', + ref_date=datetime.date.fromisoformat("2024-01-06"), + output_root=tmp_path / "model-output", + artifact_store_root=tmp_path / "artifact-store", save_feat_importance=False, max_horizon=3, q_levels = [0.025, 0.50, 0.975], - q_labels = ['0.025', '0.5', '0.975'], + q_labels = ["0.025", "0.5", "0.975"], num_bags = 10 ) @@ -48,12 +48,12 @@ def test_gbqr(tmp_path): model.run(run_config) actual_df = pd.read_csv( - run_config.output_root / 'UMass-gbqr_no_reporting_adj' / - '2024-01-06-UMass-gbqr_no_reporting_adj.csv' + run_config.output_root / "UMass-gbqr_no_reporting_adj" / + "2024-01-06-UMass-gbqr_no_reporting_adj.csv" ) expected_df = pd.read_csv( - Path('tests') / 'integration' / 'data' / - 'UMass-gbqr_no_reporting_adj' / - '2024-01-06-UMass-gbqr_no_reporting_adj.csv' + Path("tests") / "integration" / "data" / + "UMass-gbqr_no_reporting_adj" / + "2024-01-06-UMass-gbqr_no_reporting_adj.csv" ) assert_frame_equal(actual_df, expected_df) diff --git a/tests/integration/test_sarix.py b/tests/integration/test_sarix.py index 9910571..4a36201 100644 --- a/tests/integration/test_sarix.py +++ b/tests/integration/test_sarix.py @@ -1,19 +1,20 @@ -from types import SimpleNamespace - import datetime from pathlib import Path -from idmodels.sarix import SARIXModel +from types import SimpleNamespace import pandas as pd from pandas.testing import assert_frame_equal +from idmodels.sarix import SARIXModel + + def test_sarix(tmp_path): model_config = SimpleNamespace( - model_class = 'sarix', - model_name = 'sarix_p6_4rt_thetashared_sigmanone', + model_class = "sarix", + model_name = "sarix_p6_4rt_thetashared_sigmanone", # data sources and adjustments for reporting issues - sources = ['nhsn'], + sources = ["nhsn"], # fit locations separately or jointly fit_locations_separately = False, @@ -26,25 +27,25 @@ def test_sarix(tmp_path): season_period = 1, # power transform applied to surveillance signals - power_transform = '4rt', + power_transform = "4rt", # sharing of information about parameters - theta_pooling='shared', - sigma_pooling='none', + theta_pooling="shared", + sigma_pooling="none", # covariates x = [] ) run_config = SimpleNamespace( - ref_date=datetime.date.fromisoformat('2024-01-06'), + ref_date=datetime.date.fromisoformat("2024-01-06"), # output_root=tmp_path / 'model-output', - output_root=Path('tests/integration/data/'), - artifact_store_root=tmp_path / 'artifact-store', + output_root=Path("tests/integration/data/"), + artifact_store_root=tmp_path / "artifact-store", save_feat_importance=False, max_horizon=3, q_levels = [0.025, 0.50, 0.975], - q_labels = ['0.025', '0.5', '0.975'], + q_labels = ["0.025", "0.5", "0.975"], num_warmup = 200, num_samples = 200, num_chains = 1 @@ -54,12 +55,12 @@ def test_sarix(tmp_path): model.run(run_config) actual_df = pd.read_csv( - run_config.output_root / 'UMass-sarix_p6_4rt_thetashared_sigmanone' / - '2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv' + run_config.output_root / "UMass-sarix_p6_4rt_thetashared_sigmanone" / + "2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv" ) expected_df = pd.read_csv( - Path('tests') / 'integration' / 'data' / - 'UMass-sarix_p6_4rt_thetashared_sigmanone' / - '2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv' + Path("tests") / "integration" / "data" / + "UMass-sarix_p6_4rt_thetashared_sigmanone" / + "2024-01-06-UMass-sarix_p6_4rt_thetashared_sigmanone.csv" ) assert_frame_equal(actual_df, expected_df) diff --git a/tests/unit/gbqr/test_drop_level_feats.py b/tests/unit/gbqr/test_drop_level_feats.py index ca7573c..337fffe 100644 --- a/tests/unit/gbqr/test_drop_level_feats.py +++ b/tests/unit/gbqr/test_drop_level_feats.py @@ -1,54 +1,55 @@ from idmodels.preprocess import drop_level_feats + def test_drop_level_feats(): # a representative subset of the features used by the gbq_qr model - in_feats = ['inc_trans_cs', 'season_week', 'log_pop', 'source_flusurvnet', - 'source_hhs', 'source_ilinet', 'agg_level_hhs region', - 'agg_level_national', 'agg_level_state', 'location_01', - 'location_02', 'location_04', 'location_05', 'location_06', - 'location_Region 1', 'location_Region 10', 'location_Region 2', - 'location_US', 'delta_xmas', 'inc_trans_cs_taylor_d2_c0_w4t_sNone', - 'inc_trans_cs_taylor_d2_c1_w4t_sNone', 'inc_trans_cs_taylor_d2_c2_w4t_sNone', - 'inc_trans_cs_taylor_d2_c0_w6t_sNone', 'inc_trans_cs_taylor_d2_c1_w6t_sNone', - 'inc_trans_cs_taylor_d2_c2_w6t_sNone', 'inc_trans_cs_taylor_d1_c0_w3t_sNone', - 'inc_trans_cs_taylor_d1_c1_w3t_sNone', 'inc_trans_cs_taylor_d1_c0_w5t_sNone', - 'inc_trans_cs_taylor_d1_c1_w5t_sNone', 'inc_trans_cs_rollmean_w2', - 'inc_trans_cs_rollmean_w4', 'inc_trans_cs_lag1', 'inc_trans_cs_lag2', - 'inc_trans_cs_taylor_d2_c0_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c0_w4t_sNone_lag2', - 'inc_trans_cs_taylor_d2_c1_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c1_w4t_sNone_lag2', - 'inc_trans_cs_taylor_d2_c2_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c2_w4t_sNone_lag2', - 'inc_trans_cs_taylor_d2_c0_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c0_w6t_sNone_lag2', - 'inc_trans_cs_taylor_d2_c1_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c1_w6t_sNone_lag2', - 'inc_trans_cs_taylor_d2_c2_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c2_w6t_sNone_lag2', - 'inc_trans_cs_taylor_d1_c0_w3t_sNone_lag1', 'inc_trans_cs_taylor_d1_c0_w3t_sNone_lag2', - 'inc_trans_cs_taylor_d1_c1_w3t_sNone_lag1', 'inc_trans_cs_taylor_d1_c1_w3t_sNone_lag2', - 'inc_trans_cs_taylor_d1_c0_w5t_sNone_lag1', 'inc_trans_cs_taylor_d1_c0_w5t_sNone_lag2', - 'inc_trans_cs_taylor_d1_c1_w5t_sNone_lag1', 'inc_trans_cs_taylor_d1_c1_w5t_sNone_lag2', - 'inc_trans_cs_rollmean_w2_lag1', 'inc_trans_cs_rollmean_w2_lag2', - 'inc_trans_cs_rollmean_w4_lag1', 'inc_trans_cs_rollmean_w4_lag2', 'horizon'] + in_feats = ["inc_trans_cs", "season_week", "log_pop", "source_flusurvnet", + "source_hhs", "source_ilinet", "agg_level_hhs region", + "agg_level_national", "agg_level_state", "location_01", + "location_02", "location_04", "location_05", "location_06", + "location_Region 1", "location_Region 10", "location_Region 2", + "location_US", "delta_xmas", "inc_trans_cs_taylor_d2_c0_w4t_sNone", + "inc_trans_cs_taylor_d2_c1_w4t_sNone", "inc_trans_cs_taylor_d2_c2_w4t_sNone", + "inc_trans_cs_taylor_d2_c0_w6t_sNone", "inc_trans_cs_taylor_d2_c1_w6t_sNone", + "inc_trans_cs_taylor_d2_c2_w6t_sNone", "inc_trans_cs_taylor_d1_c0_w3t_sNone", + "inc_trans_cs_taylor_d1_c1_w3t_sNone", "inc_trans_cs_taylor_d1_c0_w5t_sNone", + "inc_trans_cs_taylor_d1_c1_w5t_sNone", "inc_trans_cs_rollmean_w2", + "inc_trans_cs_rollmean_w4", "inc_trans_cs_lag1", "inc_trans_cs_lag2", + "inc_trans_cs_taylor_d2_c0_w4t_sNone_lag1", "inc_trans_cs_taylor_d2_c0_w4t_sNone_lag2", + "inc_trans_cs_taylor_d2_c1_w4t_sNone_lag1", "inc_trans_cs_taylor_d2_c1_w4t_sNone_lag2", + "inc_trans_cs_taylor_d2_c2_w4t_sNone_lag1", "inc_trans_cs_taylor_d2_c2_w4t_sNone_lag2", + "inc_trans_cs_taylor_d2_c0_w6t_sNone_lag1", "inc_trans_cs_taylor_d2_c0_w6t_sNone_lag2", + "inc_trans_cs_taylor_d2_c1_w6t_sNone_lag1", "inc_trans_cs_taylor_d2_c1_w6t_sNone_lag2", + "inc_trans_cs_taylor_d2_c2_w6t_sNone_lag1", "inc_trans_cs_taylor_d2_c2_w6t_sNone_lag2", + "inc_trans_cs_taylor_d1_c0_w3t_sNone_lag1", "inc_trans_cs_taylor_d1_c0_w3t_sNone_lag2", + "inc_trans_cs_taylor_d1_c1_w3t_sNone_lag1", "inc_trans_cs_taylor_d1_c1_w3t_sNone_lag2", + "inc_trans_cs_taylor_d1_c0_w5t_sNone_lag1", "inc_trans_cs_taylor_d1_c0_w5t_sNone_lag2", + "inc_trans_cs_taylor_d1_c1_w5t_sNone_lag1", "inc_trans_cs_taylor_d1_c1_w5t_sNone_lag2", + "inc_trans_cs_rollmean_w2_lag1", "inc_trans_cs_rollmean_w2_lag2", + "inc_trans_cs_rollmean_w4_lag1", "inc_trans_cs_rollmean_w4_lag2", "horizon"] # subset of in_feats expected to be returned by _drop_level_feats: # I have manually removed any that measure local level of the surveillance signal in some way # these are 'inc_trans_cs', rolling means of that, and degree 0 coefficients ('c0') # of Taylor approximations - expected = ['season_week', 'log_pop', 'source_flusurvnet', - 'source_hhs', 'source_ilinet', 'agg_level_hhs region', - 'agg_level_national', 'agg_level_state', 'location_01', - 'location_02', 'location_04', 'location_05', 'location_06', - 'location_Region 1', 'location_Region 10', 'location_Region 2', - 'location_US', 'delta_xmas', - 'inc_trans_cs_taylor_d2_c1_w4t_sNone', 'inc_trans_cs_taylor_d2_c2_w4t_sNone', - 'inc_trans_cs_taylor_d2_c1_w6t_sNone', - 'inc_trans_cs_taylor_d2_c2_w6t_sNone', - 'inc_trans_cs_taylor_d1_c1_w3t_sNone', - 'inc_trans_cs_taylor_d1_c1_w5t_sNone', - 'inc_trans_cs_taylor_d2_c1_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c1_w4t_sNone_lag2', - 'inc_trans_cs_taylor_d2_c2_w4t_sNone_lag1', 'inc_trans_cs_taylor_d2_c2_w4t_sNone_lag2', - 'inc_trans_cs_taylor_d2_c1_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c1_w6t_sNone_lag2', - 'inc_trans_cs_taylor_d2_c2_w6t_sNone_lag1', 'inc_trans_cs_taylor_d2_c2_w6t_sNone_lag2', - 'inc_trans_cs_taylor_d1_c1_w3t_sNone_lag1', 'inc_trans_cs_taylor_d1_c1_w3t_sNone_lag2', - 'inc_trans_cs_taylor_d1_c1_w5t_sNone_lag1', 'inc_trans_cs_taylor_d1_c1_w5t_sNone_lag2', - 'horizon'] + expected = ["season_week", "log_pop", "source_flusurvnet", + "source_hhs", "source_ilinet", "agg_level_hhs region", + "agg_level_national", "agg_level_state", "location_01", + "location_02", "location_04", "location_05", "location_06", + "location_Region 1", "location_Region 10", "location_Region 2", + "location_US", "delta_xmas", + "inc_trans_cs_taylor_d2_c1_w4t_sNone", "inc_trans_cs_taylor_d2_c2_w4t_sNone", + "inc_trans_cs_taylor_d2_c1_w6t_sNone", + "inc_trans_cs_taylor_d2_c2_w6t_sNone", + "inc_trans_cs_taylor_d1_c1_w3t_sNone", + "inc_trans_cs_taylor_d1_c1_w5t_sNone", + "inc_trans_cs_taylor_d2_c1_w4t_sNone_lag1", "inc_trans_cs_taylor_d2_c1_w4t_sNone_lag2", + "inc_trans_cs_taylor_d2_c2_w4t_sNone_lag1", "inc_trans_cs_taylor_d2_c2_w4t_sNone_lag2", + "inc_trans_cs_taylor_d2_c1_w6t_sNone_lag1", "inc_trans_cs_taylor_d2_c1_w6t_sNone_lag2", + "inc_trans_cs_taylor_d2_c2_w6t_sNone_lag1", "inc_trans_cs_taylor_d2_c2_w6t_sNone_lag2", + "inc_trans_cs_taylor_d1_c1_w3t_sNone_lag1", "inc_trans_cs_taylor_d1_c1_w3t_sNone_lag2", + "inc_trans_cs_taylor_d1_c1_w5t_sNone_lag1", "inc_trans_cs_taylor_d1_c1_w5t_sNone_lag2", + "horizon"] actual = drop_level_feats(in_feats) From 33d721e09a6a7a856bb273cb2b8074c89c8b50b2 Mon Sep 17 00:00:00 2001 From: Evan Ray Date: Thu, 7 Nov 2024 11:37:11 -0500 Subject: [PATCH 5/7] fix name of _drop_level_feats in test --- tests/unit/gbqr/test_drop_level_feats.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/gbqr/test_drop_level_feats.py b/tests/unit/gbqr/test_drop_level_feats.py index 337fffe..6ddbfa6 100644 --- a/tests/unit/gbqr/test_drop_level_feats.py +++ b/tests/unit/gbqr/test_drop_level_feats.py @@ -1,4 +1,4 @@ -from idmodels.preprocess import drop_level_feats +from idmodels.preprocess import _drop_level_feats def test_drop_level_feats(): @@ -51,7 +51,7 @@ def test_drop_level_feats(): "inc_trans_cs_taylor_d1_c1_w5t_sNone_lag1", "inc_trans_cs_taylor_d1_c1_w5t_sNone_lag2", "horizon"] - actual = drop_level_feats(in_feats) + actual = _drop_level_feats(in_feats) assert len(actual) == len(expected) assert not set(actual) - set(expected) From 82d87c6a4d3cdb915c57b66cbfbf7343beee0a25 Mon Sep 17 00:00:00 2001 From: Evan Ray Date: Thu, 7 Nov 2024 16:26:42 -0500 Subject: [PATCH 6/7] fix path setting for sarix test --- tests/integration/test_sarix.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/integration/test_sarix.py b/tests/integration/test_sarix.py index 4a36201..ae00969 100644 --- a/tests/integration/test_sarix.py +++ b/tests/integration/test_sarix.py @@ -39,8 +39,7 @@ def test_sarix(tmp_path): run_config = SimpleNamespace( ref_date=datetime.date.fromisoformat("2024-01-06"), - # output_root=tmp_path / 'model-output', - output_root=Path("tests/integration/data/"), + output_root=tmp_path / 'model-output', artifact_store_root=tmp_path / "artifact-store", save_feat_importance=False, max_horizon=3, From b4ec705d9ee5304217437655f57fd2940591ef72 Mon Sep 17 00:00:00 2001 From: Evan Ray Date: Thu, 7 Nov 2024 16:32:01 -0500 Subject: [PATCH 7/7] ruff requires double quotes --- tests/integration/test_sarix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_sarix.py b/tests/integration/test_sarix.py index ae00969..be551f2 100644 --- a/tests/integration/test_sarix.py +++ b/tests/integration/test_sarix.py @@ -39,7 +39,7 @@ def test_sarix(tmp_path): run_config = SimpleNamespace( ref_date=datetime.date.fromisoformat("2024-01-06"), - output_root=tmp_path / 'model-output', + output_root=tmp_path / "model-output", artifact_store_root=tmp_path / "artifact-store", save_feat_importance=False, max_horizon=3,