jthomperoo/predictive-horizontal-pod-autoscaler

Add ARIMA time series forecasting model

Opened this issue · 3 comments

An ARIMA time series option would be a useful model; there is some literature here that goes into detail explaining what it is and how it works.

Unfortunately I haven't seen any ARIMA implementations in Go, so this could end up being a big task.

@jthomperoo , sorry I could not get the approval from my current employer to contribute on other HoldWinters issues. However, I have done some basic code for this issue. Now I have verbal approval and I can work on it.

Just like HoltWinters, this code is created to train, store, and update the model. Let me know if this works. This is just a basic code to suggest what we are trying to achieve. Let me know if this matches with your plans:

import pandas as pd
from pmdarima.arima import auto_arima
import pickle


from flask import Flask, request, jsonify
app = Flask(__name__)
MODEL_LOCATION='/tmp/arima.pkl'

@app.route('/api/train', methods=['POST'])
def add_message():
    content = request.json
    data = pd.DataFrame.from_dict(content,orient='index').T.set_index('index')   
    print(data)
    stepwise_model = auto_arima(data, start_p=1, start_q=1,
                           max_p=3, max_q=3, m=12,
                           start_P=0, seasonal=True,
                           d=1, D=1, trace=True,
                           error_action='ignore',  
                           suppress_warnings=True, 
                           stepwise=True)
    print(stepwise_model.aic())
    print(stepwise_model.summary())

    # Serialize with Pickle
    with open('/tmp/arima.pkl', 'wb') as pkl:
        pickle.dump(stepwise_model, pkl)
    # print(p)
    return jsonify('{}')

def load_pred(location):
    f  = open(location, 'rb') 
    return pickle.load(f)

def update_model(location, data):
    model = load_pred(location)
    model.update(data)
    with open(location, 'wb') as pkl:
        pickle.dump(model, pkl)
    return model


@app.route('/api/predict', methods=['POST'])
def predict():
    content = request.json
    data = pd.DataFrame.from_dict(content,orient='index').T.set_index('index') 
    model = update_model(MODEL_LOCATION, data)
    prediction, new_conf_int = model.predict(n_periods=10, return_conf_int=True)
    return prediction, new_conf_int



if __name__ == '__main__':
    app.run(host= '0.0.0.0',debug=True)

Brilliant, that looks really good, I think this will tie nicely into the work I'm currently doing as part of #38
You can have a look on this branch:

switch_from_golang_to_python

Specifically, I've added in the conversion for the linear regression to Python, here:

https://github.com/jthomperoo/predictive-horizontal-pod-autoscaler/blob/switch_from_golang_to_python/algorithms/linear_regression/linear_regression.py

So this new ARIMA would be an extra Python script in the /algorithms directory once those changes are added in. I'm going to be looking at switching Holt-Winters across and writing some tests to cover this new Python code.

I have added some code to algorithm directory. Please review that. I would like to improve on that.
Raising pr for review. I would like to understand metrics.go a little more to create a use case around it.