How to Tune ARIMA Parameters in Python

Last Updated on August 21, 2019

There are many parameters to consider when configuring an ARIMA model with Statsmodels in Python.

In this tutorial, we take a look at a few key parameters (other than the order parameter) that you may be curious about.

Specifically, after completing this tutorial, you will know:

  • How to suppress noisy output from the underlying mathematical libraries when fitting an ARIMA model.
  • The effect of enabling or disabling a trend term in your ARIMA model.
  • The influence of using different mathematical solvers to fit coefficients to your training data.

Note, if you are interested in tuning the order parameter, see the post:

Kick-start your project with my new book Time Series Forecasting With Python, including step-by-step tutorials and the Python source code files for all examples.

Let’s get started.

  • Updated Apr/2019: Updated the link to dataset.

Shampoo Sales Dataset

This dataset describes the monthly number of sales of shampoo over a 3 year period.

The units are a sales count and there are 36 observations. The original dataset is credited to Makridakis, Wheelwright, and Hyndman (1998).

The example below loads and creates a plot of the loaded dataset.

Running the example loads the dataset as a Pandas Series and prints the first 5 rows.

A line plot of the series is then created showing a clear increasing trend.

Line Plot of Monthly Shampoo Sales Dataset

Line Plot of Monthly Shampoo Sales Dataset

Experimental Test-Setup

It is important to evaluate time series forecasting models consistently.

In this section, we will define how we will evaluate the three forecast models in this tutorial.

First, we will hold the last one year of data back and evaluate forecasts on this data. Given the data is monthly, this means that the last 12 observations will be used as test data.

We will use a walk-forward validation method to evaluate model performance. This means that each time step in the test dataset will be enumerated, a model constructed on history data, and the forecast compared to the expected value. The observation will then be added to the training dataset and the process repeated.

Walk-forward validation is a realistic way to evaluate time series forecast models as one would expect models to be updated as new observations are made available.

Finally, forecasts will be evaluated using root mean squared error, or RMSE. The benefit of RMSE is that it penalizes large errors and the scores are in the same units as the forecast values (car sales per month).

An ARIMA(4,1,0) forecast model will be used as the baseline to explore the additional parameters of the model. This may not be the optimal model for the problem, but is generally skillful against some other hand tested configurations.

In summary, the test harness involves:

  • The last 2 years of data used a test set.
  • Walk-forward validation for model evaluation.
  • Root mean squared error used to report model skill.
  • An ARIMA(4,1,0) model will be used as a baseline.

The complete example is listed below.

Running the example spews a lot of convergence information and finishes with an RMSE score of 84.832 monthly shampoo sales.

A plot of the forecast vs the actual observations in the test harness is created to give some context for the model we are working with.

ARIMA Forecast for Monthly Shampoo Sales Dataset

ARIMA Forecast for Monthly Shampoo Sales Dataset

Now let’s dive into some of the other ARIMA parameters.

The “disp” Parameter

The first parameter we will look at is the disp parameter.

This is described as follows:

If True, convergence information is printed. For the default l_bfgs_b solver, disp controls the frequency of the output during the iterations. disp < 0 means no output in this case.

By default, this parameter is set to 1, which shows output.

We are dealing with this first because it is critical in removing all of the convergence output when evaluating the ARIMA model using walk-forward validation.

Setting it to False turns off all of this noise.

The complete example is listed below.

Running this example not only produces a cleaner output, but also is much faster to execute.

We will leave disp=False on all following examples.

The “transparams” Parameter

This parameter controls whether or not to perform a transform on AR parameters.

Specifically, it is described as:

Whether or not to transform the parameters to ensure stationarity. Uses the transformation suggested in Jones (1980). If False, no checking for stationarity or invertibility is done.

By default, transparams is set to True, meaning this transform is performed.

This parameter is also used on the R version of the ARIMA implementation (see docs) and I expect this is why it is here in statsmodels.

The statsmodels doco is weak on this, but you can learn more about the transform in the paper:

The example below demonstrates turning this parameter off.

Running this example results in more convergence warnings from the solver.

The RMSE of the model with transparams turned off also results in slightly worse results on this dataset.

Experiment with this parameter on and off on your dataset and confirm it results in a benefit.

The “trend” Parameter

The trend parameter adds an additional constant term to the model. Think of it like a bias or intercept term.

It is described as:

Whether to include a constant or not. ‘c’ includes constant, ‘nc’ no constant.

By default, a trend term is enabled with trend set to ‘c‘.

We can see the effect clearly if we rerun the original example and print the model coefficients for each step of the walk-forward validation and compare the same with the trend term turned off.

The below example prints the coefficients each iteration with the trend constant enabled (the default).

Running the example shows the 4 AR terms specified in the order of the model plus the first term in the array, which is a trend constant.

Note that one set of parameters is printed for each model fit, one for each step of the walk-forward validation.

We can repeat this experiment with the trend term disabled (trend=’nc’), as follows.

Running the example shows a slightly worse RMSE score on this problem, with this ARIMA configuration.

We can see that the constant term ( removed from the array of coefficients each iteration.

Experiment on your own problem and determine whether this constant improves performance.

My own experimentation suggests that ARIMA models may be less likely to converge with the trend term disabled, especially when using more than zero MA terms.

The “solver” Parameter

The solver parameter specifies the numerical optimization method to fit the coefficients to the data.

There is often little reason to tune this parameter other than execution speed if you have a lot of data. The differences will likely be quite minor.

The parameter is described as follows:

Solver to be used. The default is ‘lbfgs’ (limited memory Broyden-Fletcher-Goldfarb-Shanno). Other choices are ‘bfgs’, ‘newton’ (Newton-Raphson), ‘nm’ (Nelder-Mead), ‘cg’ – (conjugate gradient), ‘ncg’ (non-conjugate gradient), and ‘powell’. By default, the limited memory BFGS uses m=12 to approximate the Hessian, projected gradient tolerance of 1e-8 and factr = 1e2. You can change these by using kwargs.

The default is the fast “lbfgs” method (Limited-memory BFGS).

Nevertheless, below is an experiment that compares the RMSE model skill and execution time of each solver.

Running the example prints the RMSE and time in seconds of each solver.

A graph of solver vs RMSE is provided. As expected, there is little difference between the solvers on this small dataset.

You may see different results or different stability of the solvers on your own problem.

ARIMA Model Error vs Solver

ARIMA Model Error (Test RMSE) vs Solver

A graph of solver vs execution time in seconds is also created. The graph shows a marked difference between solvers.

Generally, “lbfgs” and “bfgs” provide good real-world tradeoff between speed, performance, and stability.

ARIMA Execution Time vs Solver

ARIMA Execution Time (seconds) vs Solver

If you do decide to test out solvers, you may also want to vary the “maxiter” that limits the number of iterations before converge, the “tol” parameter that defines the precision of convergence, and the “method” parameter that defines the cost function being optimized.

Additional Resources

This section lists some resources you may find useful alongside this tutorial.


In this tutorial, you discovered some of the finer points in configuring your ARIMA model with Statsmodels in Python.

Specifically, you learned:

  • How to turn off the noisy convergence output from the solver when fitting coefficients.
  • How to evaluate the difference between different solvers to fit your ARIMA model.
  • The effect of enabling and disabling a trend term in your ARIMA model.

Do you have any questions about fitting your ARIMA model in Python?
Ask your question in the comments below and I will do my best to answer.

Want to Develop Time Series Forecasts with Python?

Introduction to Time Series Forecasting With Python

Develop Your Own Forecasts in Minutes

...with just a few lines of python code

Discover how in my new Ebook:
Introduction to Time Series Forecasting With Python

It covers self-study tutorials and end-to-end projects on topics like: Loading data, visualization, modeling, algorithm tuning, and much more...

Finally Bring Time Series Forecasting to
Your Own Projects

Skip the Academics. Just Results.

See What's Inside

46 Responses to How to Tune ARIMA Parameters in Python

  1. Hans June 14, 2017 at 1:55 am #

    Should we use a data row which is not in test nor in train, to forecast an unseen data step with the fitted model? Or should we simply use the last prediction of test?

  2. Hans June 15, 2017 at 3:06 am #

    Thank you, but at least I need one new x (data row) which was not involved in training, to predict something unseen. Is that right?

    • Jason Brownlee June 15, 2017 at 8:48 am #

      Yes, you need one new row of input data to predict a new output.

      In the case of time series, this is often lag observation, but really depends on how you have defined your model (the inputs it expects).

  3. Hans June 15, 2017 at 5:09 am #

    I have found good parameter settings resulting in a RMSE less then 2.5.
    Is there a tutorial available how to finalize, train this model and predict unseen data on a fitted ARIMA model?

    • Jason Brownlee June 15, 2017 at 8:52 am #

      Yes, in the future please use the search feature of the blog (like I just did).

      • Hans June 15, 2017 at 12:01 pm #

        The problem is, I have no seasonal data an no evenly distributed daily data.
        I try to use a fitted model of the example of this site.
        Right after the for loop I say:

        start_index = len(test)
        end_index = len(test)
        forecast = model_fit.predict(start=start_index, end=end_index)


        This gives me a forecast of 0.664 while my data values are between 1.0 and 10.0.
        What do I miss here?

        • Jason Brownlee June 16, 2017 at 7:48 am #

          You must adapt a given tutorial to your specific problem. No one can tell you how – you must use all of the information available to explore the best model for your problem.

          • Hans June 16, 2017 at 12:45 pm #

            I try this since months with more or less success.

            Everything works fine even with own data (training and testings), until it comes to real out of sample forecasts.

            But I’m not talking about problems, I’m talking about coding techniques.

            Is it right to use the test data set to build start and end indexes for the ARIMA prediction?

            Do we have to make special preparations to such inputs, to feed this two parameters?

          • Jason Brownlee June 17, 2017 at 7:21 am #

            The idea of test data goes away when you start making predictions on real data.

            See this post:

          • Hans June 19, 2017 at 5:07 am #

            Then I seem to be on the right way.
            I have training and predictions strictly separated in my batch environment (menu).
            For predictions I always use the complete data, except of one row/x to predict unseen data.
            Is this right in general?

          • Jason Brownlee June 19, 2017 at 8:46 am #


  4. Hans June 15, 2017 at 5:41 am #

    Is this a time series analysis?

    • Jason Brownlee June 15, 2017 at 8:54 am #

      No, a demonstration of how to use ARIMA parameters in statsmodels for forecasting.

  5. Rajesh July 6, 2017 at 3:33 pm #

    Hi jason,
    Thank you very much for your tutorials.

    Here, you selected a base line model for ARIMA(4,1,0)

    But, as per procedure, order need to be decided based on ACF and PACF factors
    I would like to decide order based on data.
    Can you suggest a procedure

  6. Kashif August 15, 2017 at 11:49 pm #

    Hi Sir
    I am applying ARIMA model on my CDR dataset. I have checked that my data is non stationary (Augmented Dickey-Fuller test)
    ADF Statistic: -1.569036
    p-value: 0.499127
    Critical Values:
    1%: -3.478
    10%: -2.578
    5%: -2.882
    Than I have plotted ACF, it showed that my first 15 lag values have autocorrelation value greater then 0.5. so I set ‘p’ parameter 15 (is p =15 is correct ?), and ‘d’ is 1 for stationarity. Could you please guide me how I will find the value of moving average MA(q) q parameter ?
    Can I determine the value of ‘q’ parameter by visualizing ACF plot ?

  7. Terry October 4, 2017 at 3:18 pm #

    Hi Jason,

    Do you have a similar tutorial for ARIMAX?

    • Jason Brownlee October 4, 2017 at 3:40 pm #

      Not at this stage Terry.

      • Terry October 5, 2017 at 11:50 am #

        Would be really keen to see a step by step guide of ARIMAX application to a real-life problem and tuning. If you add this topic to your book, it will be invaluable!

  8. Alex January 7, 2018 at 12:42 am #

    Thank you for your post.
    Maybe I don’t understand that part, but what can you do to fix the “mle_retvals”, ConvergenceWarning? transparams does not seem to affect that.
    Also, have you noticed that .predict predicts one day more than needed?

  9. Justin Lim May 17, 2018 at 1:42 am #

    Thank you for the post.

    With regards to applying an ARIMA model to a training time series data, do we first need to ensure that the data exhibits normality and/or stationarity before apply the ARIMA model?
    Are both normality and stationarity a prerequisite before we can apply ARIMA to fit and forecast?

    thank you!

  10. Naresh K October 3, 2018 at 6:33 am #

    Hello Jason,

    can p and q be 0 in SARIMAX and d as 1?
    I got p and q as 0 from ACF and PACF, is it possible to get time series forecasting using only differencing?


  11. Bella November 19, 2018 at 2:21 pm #

    HI Jason,
    Could I know how to predict 7th day, which means y = train.shift(7) ?
    And can we use multi-dimensional input other than itself only to predict?

  12. Paul December 31, 2018 at 12:49 am #

    great tutorial. I found one problem which may or may not be related to my limited understanding of nn’s:

    I’ve followed the ‘solver’ section of the tutorial and tried to replicate the solver comparisons. Once I reached the #evaluating forecasts part of the code, and tried to execute the rmse = sqrt…line, I received a ValueError: found input variables with inconsistent number of samples:[13, 1]. I’m pretty sure I have to reshape something somewhere – just not sure where. Help is much appreciated.

    • Paul December 31, 2018 at 5:42 am #

      *and when I said nn, I actually meant machine learning as a whole; ARIMA is obviously not an nn 🙂

    • Jason Brownlee December 31, 2018 at 6:12 am #

      Are you able to confirm that your libraries are up to date and that you’re using Python 3?

      • Paul January 1, 2019 at 4:50 am #

        Hello Jason,
        happy new year. I’m using python 3.6.7, with statsmodels version 0.9.0, with pretty much everything else up to date. No worries if it’ll take too much time or trouble to debug btw :).

  13. Jem June 3, 2019 at 5:08 am #

    Hi Jason,

    I followed your tutorial, but I could not find the value p of ARIMA model, because I have too much data (half a million), so the function plot_pacf doesn’t end. I waited 5 hours, but nothing.
    What can I do? Is there another way?


    • Jason Brownlee June 3, 2019 at 6:44 am #

      Perhaps try working with a smaller subset of the data.

  14. Devarshi Goswami February 18, 2020 at 9:17 pm #

    “A plot of the forecast vs the actual observations in the test harness is created to give some context for the model we are working with:”
    plotting ‘ test ‘ and ‘ predictions ‘ are giving me exactly similar plots. How is this possible?

    Also Im getting the ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals
    “Check mle_retvals”, ConvergenceWarning)
    What can i infer from this?

    • Jason Brownlee February 19, 2020 at 8:02 am #

      Perhaps you are making perfect predictions – this is possible if there is a bug or your problem is trivial/easy.

      You can ignore the convergence warning.

  15. Paresh July 22, 2020 at 9:38 pm #

    Hi Jason,
    Thanks a lot for sharing this. However, I am not sure as to why we get different output from:


    Also, instead of passing on the order of ARIMA. I am trying to use auto_arima from pmdarima.arima to fit the model. When I try to use forecast function on this it throws error. So I have to use predict function only.

    Please let me know if I am missing out on anything.
    Thanks a lot,

    • Jason Brownlee July 23, 2020 at 6:07 am #

      You must specify the interval with predict, and forecast includes a prediction interval I believe.

  16. rafael September 13, 2020 at 4:28 am #

    Hi! thanks for this post!

    I have to check ARIMAs for different phis and in R this is so simple but when I try in python it looks quite difficult;

    Anyways, can you please help me to input the phi in the ARIMAs models in python?


  17. azaratou October 15, 2020 at 9:08 am #

    Hi Jason how are you ?
    Thanks for this post, it is very interest.
    Please , I want your helps or suggestion for one methodologie i want to applied for time serie forecast and i want to know if it is possible and make sense . Supposes that i have historical data of 2 years from 01/01/2018 to 01/01/2020 and i want to forecast for 4 months ie from 01/01/2020 to 30/04/2020.
    How do you think of this methodologie in my forecast evaluation to calculate error for 1 month , 2 month, 3 month and 4 month :

    1 forecast : from 01/01/2020 to 31/01/2020 and calcuted error called e11
    2 forecast : from 01/01/2020 to 28/02/2020 and calcuted error called e12
    3 forecast : from 01/01/2020 to 31/03/2020 and calcuted error called e13
    4 forecast : from 01/01/2020 to 30/04/2020 and calcuted error called e14

    5 forecast : from 01/02/2020 to 28/02/2020 and calcuted error called e21
    6 forecast : from 01/02/2020 to 31/03/2020 and calcuted error called e22
    7 forecast : from 01/02/2020 to 30/04/2020 and calcuted error called e23

    8 forecast : from 01/03/2020 to 31/03/2020 and calcuted error called e31
    9 forecast : from 01/03/2020 to 30/04/2020 and calcuted error called e32

    10 forecast : from 01/04/2020 to 30/04/2020 and calcuted error called e41

    error 1 month = mean(e11 + e21 + e31 + e41)
    error 2 month = mean(e12 + e22 + e32)
    error 3 month = mean(e13 + e23
    error 4 month = e14

    Thanks for your helps, i hope that it will be clear for you

Leave a Reply