Skip to content

Commit

Permalink
Merge branch 'main' into metrics/from_fork
Browse files Browse the repository at this point in the history
  • Loading branch information
ourownstory authored Oct 6, 2023
2 parents 6ba6855 + 137e347 commit b0f632b
Show file tree
Hide file tree
Showing 12 changed files with 1,350 additions and 1,130 deletions.
15 changes: 14 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,20 @@ Please come join us on our [Slack](https://join.slack.com/t/neuralprophet/shared

## Process
If this is your first time contributing to NeuralProphet, please read our [wiki summary](https://github.com/ourownstory/neural_prophet/wiki#contributing-process) of the steps involved.
## Dev Install

## Dev Install using Poetry
Prerequisite: [install poetry](https://python-poetry.org/docs/#installing-with-the-official-installer).
* Start by cloning the repo with `git clone <copied link from github>`.
* Make sure you have changed directories to your cloned neuralprophet github `cd neural_prophet`. There, run `poetry shell` to (create and) start a (new) poetry virtual environment. If you run `poetry env info --path` you should see the path to the venv.
* To complete the venv setup, install neuralprophet (in editable mode by default) with `poetry install`.
Note: poetry will automatically use the specific dependencies in the `poetry.lock` file for reproducibility. If you want to install the latest dependencies instead, run `poetry update`. This will update all dependencies and update the `poetry.lock` file. Be mindful to not track the `poetry.lock` file with git when commiting, unless the purpose of your pull request is to update it.

Warning, you are still lacking some git hooks to auto-format your code pre-commit and to run pytests pre-push.
Currently these need to be self-added. Simplified instructions to follow.

[Tutorial Link](https://realpython.com/dependency-management-python-poetry/)

## Dev Install (old)
Before starting it's a good idea to first create and activate a new virtual environment:
```
python3 -m venv <path-to-new-env>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pip install neuralprophet[live]
```
This will allow you to enable `plot_live_loss` in the `fit` function to get a live plot of train (and validation) loss.

If you would like the most up to date version, you can instead install direclty from github:
If you would like the most up to date version, you can instead install directly from github:
```shell
git clone <copied link from github>
cd neural_prophet
Expand Down
40 changes: 40 additions & 0 deletions neuralprophet/df_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,46 @@ def add_missing_dates_nan(df, freq):
return df_resampled, num_added


def create_dummy_datestamps(
df, freq="S", startyear=1970, startmonth=1, startday=1, starthour=0, startminute=0, startsecond=0
):
"""
Helper function to create a dummy series of datestamps for equidistant data without ds.
Parameters
----------
df : pd.DataFrame
dataframe with column 'y' and without column 'ds'
freq : str
Frequency of data recording, any valid frequency for pd.date_range, such as ``D`` or ``M``
startyear, startmonth, startday, starthour, startminute, startsecond : int
Defines the first datestamp
Returns
-------
pd.DataFrame
dataframe with dummy equidistant datestamps
Examples
--------
Adding dummy datestamps to a dataframe without datestamps.
To prepare the dataframe for training, import df_utils and insert your prefered dates.
>>> from neuralprophet import df_utils
>>> df_drop = df.drop("ds", axis=1)
>>> df_dummy = df_utils.create_dummy_datestamps(
>>> df_drop, freq="S", startyear=1970, startmonth=1, startday=1, starthour=0, startminute=0, startsecond=0
>>> )
"""
if "ds" in df:
raise ValueError("Column 'ds' in df detected.")
log.info(f"Dummy equidistant datestamps added. Frequency={freq}.")
df_length = len(df)
startdate = pd.Timestamp(
year=startyear, month=startmonth, day=startday, hour=starthour, minute=startminute, second=startsecond
)
datestamps = pd.date_range(startdate, periods=df_length, freq=freq)
df_dummy = pd.DataFrame({"ds": datestamps, "y": df["y"]})
return df_dummy


def fill_linear_then_rolling_avg(series, limit_linear, rolling):
"""Adds missing dates, fills missing values with linear imputation or trend.
Expand Down
2 changes: 1 addition & 1 deletion neuralprophet/forecaster.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ def add_country_holidays(
and create the corresponding configs such as lower, upper windows and the regularization
parameters
Holidays can only be added for a single country. Calling the function
Holidays can only be added for a single country or country list. Calling the function
multiple times will override already added country holidays.
Parameters
Expand Down
58 changes: 32 additions & 26 deletions neuralprophet/plot_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def check_if_configured(m, components, error_flag=False): # move to utils
if "lagged_regressors" in components and m.config_lagged_regressors is None:
components.remove("lagged_regressors")
invalid_components.append("lagged_regressors")
if "events" in components and (m.config_events and m.config_country_holidays) is None:
if "events" in components and (m.config_events is None and m.config_country_holidays is None):
components.remove("events")
invalid_components.append("events")
if "future_regressors" in components and m.config_regressors is None:
Expand Down Expand Up @@ -419,31 +419,37 @@ def get_valid_configuration( # move to utils
if "events" in components:
additive_events_flag = False
muliplicative_events_flag = False
for event, configs in m.config_events.items():
if validator == "plot_components" and configs.mode == "additive":
additive_events_flag = True
elif validator == "plot_components" and configs.mode == "multiplicative":
muliplicative_events_flag = True
elif validator == "plot_parameters":
event_params = m.model.get_event_weights(event)
weight_list = [(key, param.detach().numpy()[quantile_index, :]) for key, param in event_params.items()]
if configs.mode == "additive":
additive_events = additive_events + weight_list
elif configs.mode == "multiplicative":
multiplicative_events = multiplicative_events + weight_list

for country_holiday in m.config_country_holidays.holiday_names:
if validator == "plot_components" and m.config_country_holidays.mode == "additive":
additive_events_flag = True
elif validator == "plot_components" and m.config_country_holidays.mode == "multiplicative":
muliplicative_events_flag = True
elif validator == "plot_parameters":
event_params = m.model.get_event_weights(country_holiday)
weight_list = [(key, param.detach().numpy()[quantile_index, :]) for key, param in event_params.items()]
if m.config_country_holidays.mode == "additive":
additive_events = additive_events + weight_list
elif m.config_country_holidays.mode == "multiplicative":
multiplicative_events = multiplicative_events + weight_list
if m.config_events is not None:
for event, configs in m.config_events.items():
if validator == "plot_components" and configs.mode == "additive":
additive_events_flag = True
elif validator == "plot_components" and configs.mode == "multiplicative":
muliplicative_events_flag = True
elif validator == "plot_parameters":
event_params = m.model.get_event_weights(event)
weight_list = [
(key, param.detach().numpy()[quantile_index, :]) for key, param in event_params.items()
]
if configs.mode == "additive":
additive_events = additive_events + weight_list
elif configs.mode == "multiplicative":
multiplicative_events = multiplicative_events + weight_list

if m.config_country_holidays is not None:
for country_holiday in m.config_country_holidays.holiday_names:
if validator == "plot_components" and m.config_country_holidays.mode == "additive":
additive_events_flag = True
elif validator == "plot_components" and m.config_country_holidays.mode == "multiplicative":
muliplicative_events_flag = True
elif validator == "plot_parameters":
event_params = m.model.get_event_weights(country_holiday)
weight_list = [
(key, param.detach().numpy()[quantile_index, :]) for key, param in event_params.items()
]
if m.config_country_holidays.mode == "additive":
additive_events = additive_events + weight_list
elif m.config_country_holidays.mode == "multiplicative":
multiplicative_events = multiplicative_events + weight_list

if additive_events_flag:
plot_components.append(
Expand Down
9 changes: 5 additions & 4 deletions neuralprophet/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,13 @@ def get_holidays_from_country(country: Union[str, Iterable[str]], df=None):
if isinstance(country, str):
country = [country]

holidays = {}
unique_holidays = {}
for single_country in country:
holidays_country = get_country_holidays(single_country, years)
# only add holiday if it is not already in the dict
holidays.update(holidays_country)
holiday_names = holidays.values()
for date, name in holidays_country.items():
if date not in unique_holidays:
unique_holidays[date] = name
holiday_names = unique_holidays.values()
return set(holiday_names)


Expand Down
Loading

0 comments on commit b0f632b

Please sign in to comment.