Spaces:
Runtime error
Runtime error
import pandas as pd | |
from dateutil.relativedelta import relativedelta | |
import matplotlib.pyplot as plt | |
from prophet.serialize import model_from_json | |
def get_forecast(serie: str, periods, percent_change: int): | |
if serie == 'SOM': | |
model_file, data_file = 'som_model.json', 'som_data.csv' | |
elif serie == 'Volumen': | |
model_file, data_file = 'volumen_model.json', 'volumen_data.csv' | |
else: | |
raise ValueError('Input not valid') | |
# load model files | |
with open('models/' + model_file, 'r') as fin: | |
model = model_from_json(fin.read()) | |
history = pd.read_csv('data/' + data_file, encoding = 'utf-8-sig', sep = ';') | |
history['ds'] = pd.to_datetime(history['ds']) | |
# make future dataframe | |
future = model.make_future_dataframe(periods = periods, freq = 'MS') | |
future = future.tail(periods) | |
# filter prices last year | |
last_year_dates = future.ds.apply(lambda x: x - relativedelta(years=1)) | |
past_prices = history[history['ds'].isin(last_year_dates)]['precio_hl'].values | |
# generate new_prices | |
percent_change = percent_change / 100 | |
new_prices = past_prices * (1 + percent_change) | |
future['precio_hl'] = new_prices | |
# prediction | |
forecast = model.predict(future) | |
future_values = forecast[['ds', 'yhat']] | |
# aux to plot | |
last_obs = history.iloc[-1:][['ds', 'y']].rename(columns = {'y': 'yhat'}) | |
future_aux = pd.concat([last_obs, future_values]) | |
# 0 price change scenario | |
future_0 = future.copy() | |
future_0['precio_hl'] = past_prices | |
forecast_0 = model.predict(future_0) | |
values_0 = forecast_0[['ds', 'yhat']] | |
aux_0 = pd.concat([last_obs, values_0]) | |
# arrange dataframe | |
df_future = future_values.rename(columns = {'ds': 'Date', 'yhat': f'{serie} changing prices'}).copy() | |
df_future['Date'] = df_future['Date'].apply(lambda x: x.date()) | |
df_future[f'{serie} holding prices'] = values_0.rename(columns = {'ds': 'Date', 'yhat': serie})[serie] | |
df_future['Diff'] = df_future[f'{serie} changing prices'] - df_future[f'{serie} holding prices'] | |
# round values to 4 decimals | |
df_future[f'{serie} changing prices'] = df_future[f'{serie} changing prices'].apply(lambda x: round(x, 4)) | |
df_future[f'{serie} holding prices'] = df_future[f'{serie} holding prices'].apply(lambda x: round(x, 4)) | |
df_future['Diff'] = df_future['Diff'].apply(lambda x: round(x, 4)) | |
# plot | |
fig = plt.figure() | |
plt.plot(future_aux['ds'], future_aux['yhat'], label = 'Price Policy Change Forecast', marker = '.', color = 'C1') | |
plt.plot(aux_0['ds'], aux_0['yhat'], label = 'No Policy Change Forecast', marker = '.', color = 'C2') | |
plt.plot(history['ds'], history['y'], label = 'Historic data', marker = '.', color = 'C0') | |
plt.xticks(rotation = 45) | |
plt.ylabel(serie) | |
plt.tight_layout() | |
plt.legend() | |
return fig, df_future |