File size: 2,914 Bytes
c97655d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aabad01
c97655d
aabad01
c97655d
 
 
 
 
 
 
 
 
 
 
0040742
c97655d
 
 
0040742
c97655d
 
 
 
0040742
c97655d
 
2f96ffc
 
 
 
 
 
 
630939d
 
111b9fa
630939d
111b9fa
 
 
 
 
 
630939d
c97655d
0040742
c97655d
23a5a30
 
c97655d
 
 
 
 
 
0040742
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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