Trying to use fbprophet to find outlier
- Dominant language
- Python
- Stars
- 20.4k
- Forks
- 4.6k
- Avg merge
- 19h 52m
- Merged PRs (30d)
- 1
Description
I'm a complete beginner in data science, but fbprophet has impressed me with its capabilities. I especially like the way it works with holidays, in theory, I will not receive alerts on New Year's Eve and other holidays, as the fbprophet will take these dates into account. So I want to try to improve my system.
I have data on sales per day, expressed in terms of money earned per day. They are updated every night.
I am trying to run a 1-day forecast using fbprophet.
Logic:
1. After updating the data, I download the whole time series.
2. I cut off some of the data along the green line because I thought it was unnecessary at the time, there were very small sales there and I thought it might have a bad impact on the mall as a whole. (The data is in kopecks, so y does not match the graphs below, where everything is already formatted to whole units of money.)
3. I forecast the last day's data and compare it with the existing data
- I use boxcox, and get better accuracy metrics with it:
- I also use a holiday dictionary for the country. Because it's one country.
- and added a regressor for web page views, which is advertising sales. That's why views showed the best result. When I tested different regressors.
```
boxcox = df.copy()
boxcox['y'], lmbd1 = stats.boxcox(boxcox[f'y'])
boxcox['r0'], lmbd2 = stats.boxcox(boxcox[f'r0'])
predictions = 1
train_df = boxcox[:-predictions]
m = Prophet(holidays=df_holidays, daily_seasonality=True, weekly_seasonality=True, yearly_seasonality=True,
changepoint_prior_scale=0.1, seasonality_prior_scale=0.1, holidays_prior_scale=7,
seasonality_mode='multiplicative',interval_width=0.80,changepoint_range=0.95)
m.add_regressor('r0')
m.fit(train_df)
future = m.make_future_dataframe(periods=predictions, freq='D')
future = future.merge(boxcox[['ds','r0']], on='ds')
forecast = m.predict(future)
```
Before that, I selected the parameters using the following code:
```
predictions = 1
train_df = boxcox[:-predictions]
param_grid = {
'changepoint_prior_scale': [0.001, 0.01, 0.1,0.4, 0.5],
'seasonality_prior_scale': [0.01, 0.1, 1.0,3,5,7, 10.0],
'holidays_prior_scale': [0.01, 0.1, 1.0,3,5,7, 10.0]
}
all_params = [dict(zip(param_grid.keys(), v)) for v in itertools.product(*param_grid.values())]
mapes = []
for params in tqdm(all_params):
m = Prophet(**params, holidays=df_holidays, daily_seasonality=True, weekly_seasonality=True,\
yearly_seasonality=True,
seasonality_mode='multiplicative',interval_width=0.95, changepoint_range=0.95)\
.add_regressor('r0').fit(boxcox) # Fit model with given params
df_cv = cross_validation(m, horizon = '1 day',period="20 day", initial='560 day', parallel="processes")
df_p = performance_metrics(df_cv, rolling_window=1)
mapes.append(df_p['mape'].values[0])
tuning_results = pd.DataFrame(all_params)
tuning_results['mape'] = mapes
print(tuning_results)
best_params = all_params[np.argmin(mapes)]
print(best_params)
```
With these parameters, I run the simulation, cut off the data from 2022-11-01 and add 1 day to the DataFrame, and try to predict this value. Then I check the true value of "y" with yhat_upper and yhat_lower and if it goes beyond the marker that it is an outlier.:
- It gives me the following results:
- I came up with an idea to fix this result. I added a function that calculates for each red dot how much the change has occurred. If the last drop was more than 20%, I then mark it red. (The drop can occur in one day or three in total, etc.) Here's how it affected the result:
It looks a little "better". But in general, the picture is not very good. In the end, it did not catch the anomaly, because the drop was 18%, not 20%, but the growth was already 20+%.
The following questions arose at the design stage:
1. What period is better to choose for my task? maybe a year? or still full 2 years + up to now data
2. How to choose the right parameters for the model, do I have the right values in the arguments for the period and horizon, etc.?
3. Will one parameter fitting every 3 months be enough for me to avoid fitting parameters every day?
4. Did I do a good job of using the boxcox transformation?
5. Did I choose the right regressor?
6. How can I improve my forecasts to avoid using the 20% threshold kurtosis?
7. Does this system even exist? Perhaps fbprophet should not be used in such systems.
8. If there are any tips on how to improve this system, I will be very happy to hear.
Contributor guide
Assessment
This issue has not been assessed yet.