{"id":18731,"date":"2024-02-26T00:00:00","date_gmt":"2024-02-26T00:00:00","guid":{"rendered":"https:\/\/thierrymoudiki.github.io\/\/blog\/2024\/02\/26\/python\/r\/julia\/ahead-v0100"},"modified":"2024-02-26T00:00:00","modified_gmt":"2024-02-26T00:00:00","slug":"ahead-forecasting-v0-10-0-fast-time-series-model-calibration-and-python-plots","status":"publish","type":"post","link":"https:\/\/python-bloggers.com\/2024\/02\/ahead-forecasting-v0-10-0-fast-time-series-model-calibration-and-python-plots\/","title":{"rendered":"ahead forecasting (v0.10.0): fast time series model calibration and Python plots"},"content":{"rendered":"<div style=\\\"border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 12px;\\\">\r\n<i>This article was first published on  <strong>\r\n<a href=\"https:\/\/thierrymoudiki.github.io\/\/blog\/2024\/02\/26\/python\/r\/julia\/ahead-v0100\"> T. Moudiki's Webpage - Python <\/a><\/strong>, and kindly contributed to <a href=\/about\/>python-bloggers<\/a>.  (You can report issue about the content on this page <a href=\/contact-us\/>here<\/a>)\r\n<br\/>Want to share your content on python-bloggers?<a href=\/add-your-blog\/> click here<\/a>.<\/i>\r\n<\/div>\n<p><code>ahead<\/code> is an <a href=\"https:\/\/github.com\/Techtonique\/ahead\">R<\/a>, <a href=\"https:\/\/github.com\/Techtonique\/ahead_python\">Python<\/a> and <a href=\"https:\/\/github.com\/Techtonique\/Ahead.jl\">Julia<\/a> package for univariate and multivariate time series forecasting with <strong>uncertainty quantification<\/strong> (including predictive simulation). <a href=\"https:\/\/en.wikipedia.org\/wiki\/MATLAB\">Matlab<\/a> is next. The aim is always to make these implementations of <code>ahead<\/code> as <strong>similar as possible<\/strong>, but that\u2019s a looot of work as you  might guess. Do not hesitate to <a href=\"https:\/\/docs.github.com\/en\/pull-requests\/collaborating-with-pull-requests\/proposing-changes-to-your-work-with-pull-requests\/creating-a-pull-request\">submit a pull request<\/a> to these repositories if you want to help and contribute. You can also <a href=\"https:\/\/docs.github.com\/en\/issues\">signal bugs (constructively)<\/a>.<\/p>\n<p>The main changes in <code>ahead<\/code>\u2019s <code>v0.10.0<\/code> are:<\/p>\n<ol>\n<li><strong>Fast calibration<\/strong> of <a href=\"https:\/\/www.mdpi.com\/2227-9091\/6\/1\/22\"><code>ridge2f<\/code><\/a> using a Leave-One-Out <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cross-validation_(statistics)\">Cross-Validation<\/a> (LOOCV) trick (R for now)<\/li>\n<li><strong>Univariate forecasting<\/strong> with <code>ridge2f<\/code> with external regressors<\/li>\n<li><strong>Plotting functionality<\/strong> in Python version<\/li>\n<\/ol>\n<p>Read on for more details. You can also use <a href=\"https:\/\/github.com\/Techtonique\/ahead_python\/blob\/main\/ahead\/demo\/thierrymoudiki_20240224_ahead_python_and_R.ipynb\">this notebook<\/a> if you want to reproduce the experiments.<\/p>\n<h1 id=\"1-fast-calibration-of-ridge2f\">1. <strong>Fast calibration of <code>ridge2f<\/code>:<\/strong><\/h1>\n<p>The fast calibration of <code>ridge2f<\/code> uses a remarkable result available for linear models\u2019 LOOCV:<\/p>\n<p>\\[LOOCV error = \\frac{1}{n} \\sum_{i=1}^n\\left(y_i-\\hat{f}_{-i}\\left(\\mathbf{z}_i\\right)\\right)^2 = \\frac{1}{n} \\sum_{i=1}^n\\left(\\frac{y_i-\\hat{f}\\left(\\mathbf{z}_i\\right)}{1-\\mathbf{S}_{i i}}\\right)^2\\]<\/p>\n<p>Where \\(\\hat{f}_{-i}\\left(\\mathbf{z}_i\\right)\\) is a model statistical learning model $f$ fitted without the \\(i\\)-th observation, \\(\\mathbf{z}_i\\) is the \\(i\\)-th observation, and \\(\\mathbf{S}_{i i}\\) is the $i$-th diagonal element of the hat matrix (a.k.a smoother, a matrix so that \\(\\hat{y} = \\mathbf{S} y\\)). <strong>LOOCV is <a href=\"https:\/\/robjhyndman.com\/papers\/cv-wp.pdf\">valid for time series<\/a> data<\/strong> because contrary to other <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cross-validation_(statistics)\">cross-validation<\/a> techniques, it does not break the sequential structure of the inputs. <strong>Keep in mind<\/strong>, however, that <a href=\"https:\/\/thierrymoudiki.github.io\/blog\/2020\/03\/27\/r\/misc\/crossval-2\">time series cross-vaidation<\/a> will give different results.<\/p>\n<p>The LOOCV result can be extended further and approximated by <a href=\"https:\/\/pages.stat.wisc.edu\/~wahba\/stat860public\/pdf1\/golub.heath.wahba.pdf\">Generalized Cross-Validation (GCV)<\/a>, still with a closed-form formula available. GCV is used in <code>ahead::ridge2f<\/code>. Indeed, even though <code>ridge2<\/code> is not \u2013 strictly speaking \u2013 linear, it possesses the structure of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Ridge_regression\">ridge regression<\/a> model with <a href=\"https:\/\/www.mdpi.com\/2227-9091\/6\/1\/22\">2 regularization parameters<\/a>; a regularization parameter for the original explanative variables, and a regularization parameter for new, engineered features. These engineered features transform the linear model into a non-linear one.<\/p>\n<p>In the following R example, it\u2019s worth mentioning that <strong>only the 2 regularization parameters are calibrated<\/strong>. Other hyperparameters such as the number of time series lags or the number of nodes in the hidden layer are set to their default values. Feel free try and share other experiments including them.<\/p>\n<pre>%load_ext rpy2.ipython\n<\/pre>\n<pre>%%R\n\noptions(repos = c(\n    techtonique = 'https:\/\/techtonique.r-universe.dev',\n    CRAN = 'https:\/\/cloud.r-project.org'))\n\ninstall.packages(\"ahead\")\ninstall.packages(\"ggplot2\")\ninstall.packages(\"forecast\")\ninstall.packages(\"dfoptim\")\n<\/pre>\n<pre>%%R\n\nlibrary(ahead)\nlibrary(dfoptim)\n<\/pre>\n<pre># Convert to R DataFrame\n%R -i df\n<\/pre>\n<pre>%R df_ts &lt;- as.ts(df)\n<\/pre>\n<pre>%%R\n\nobjective_function &lt;- function(xx)\n{\n    ahead::loocvridge2f(df_ts,\n                        h = 20,\n                        type_pi=\"blockbootstrap\",\n                        lambda_1=10^xx[1],\n                        lambda_2=10^xx[2],\n                        show_progress = FALSE,\n                        )$loocv\n}\nstart &lt;- proc.time()[3]\n(opt &lt;- dfoptim::nmkb(fn=objective_function, lower=c(-10,-10), upper=c(10,10), par=c(0.1, 0.1)))\nprint(proc.time()[3]-start)\n<\/pre>\n<pre>elapsed \n  6.657 \n<\/pre>\n<pre>%%R\n\nstart &lt;- proc.time()[3]\nres &lt;- ahead::ridge2f(df_ts, h = 20,\n                      type_pi=\"blockbootstrap\",\n                      lambda_1=10^opt$par[1], # 'optimal' parameters\n                      lambda_2=10^opt$par[2]) # 'optimal' parameters\nprint(proc.time()[3]-start)\n<\/pre>\n<pre>  |======================================================================| 100%\nelapsed \n  0.805 \n<\/pre>\n<pre>%%R\n\npar(mfrow=c(2, 2))\nplot(res, \"realgovt\", type = \"sims\", main=\"50 predictive simulations \\n of realgovt\")\nplot(res, \"realgovt\", type = \"dist\", main=\"predictive distribution \\n of realgovt\")\nplot(res, \"realgdp\", type = \"sims\", main=\"50 predictive simulations \\n of realgdp\")\nplot(res, \"realgdp\", type = \"dist\", main=\"predictive distribution \\n of realgovt\")\n<\/pre>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/thierrymoudiki.github.io\/images\/2024-02-26\/2024-02-26-image1.png?w=578&#038;ssl=1\" alt=\"xxx\" class=\"img-responsive\" \/><\/p>\n<h1 id=\"2-univariate-forecasting-with-ridge2f-with-external-regressors\">2. <strong>Univariate forecasting with <code>ridge2f<\/code> with external regressors:<\/strong><\/h1>\n<p><code>ridge2f<\/code> was initially designed for multivariate time series forecasting. Nothing prevents it from being used for univariate forecasting. This functionality is now available in <code>ahead<\/code> (R for now). In addition, as in the multivariate case, it is possible to use external regressors in the forecasting process.<\/p>\n<pre>%%R\n\nlibrary(ggplot2)\nlibrary(forecast)\n\nx &lt;- fdeaths\nxreg &lt;- ahead::createtrendseason(x)\n(z &lt;- ahead::ridge2f(x, xreg = xreg, h=20))\nautoplot(z)\n<\/pre>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/thierrymoudiki.github.io\/images\/2024-02-26\/2024-02-26-image2.png?w=578&#038;ssl=1\" alt=\"xxx\" class=\"img-responsive\" \/><\/p>\n<h1 id=\"3-plotting-functionality-in-python-version\">3. <strong>Plotting functionality in Python version:<\/strong><\/h1>\n<p><strong>Install and import packages<\/strong><\/p>\n<pre>!pip install ahead\n<\/pre>\n<pre>import numpy as np\nimport pandas as pd\nimport statsmodels.api as sm\n\nfrom time import time\nfrom ahead import Ridge2Regressor # may take some time to run, ONLY the 1st time it's run\nfrom statsmodels.tsa.base.datetools import dates_from_str\nfrom time import time\n<\/pre>\n<p><strong>Import data<\/strong><\/p>\n<pre># some example data\nmdata = sm.datasets.macrodata.load_pandas().data\n\n# prepare the dates index\ndates = mdata[['year', 'quarter']].astype(int).astype(str)\n\nquarterly = dates[\"year\"] + \"Q\" + dates[\"quarter\"]\n\nquarterly = dates_from_str(quarterly)\n\nmdata = mdata[['realgovt', 'tbilrate', 'cpi', 'realgdp']]\n\nmdata.index = pd.DatetimeIndex(quarterly)\n\ndf = np.log(mdata).diff().dropna()\n\ndisplay(df)\n<\/pre>\n<div id=\"df-f2e345a0-7555-4e1a-ba7c-9f31c295667f\" class=\"colab-df-container\">\n<div>\n<style scoped=\"\">\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n<\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th><\/th>\n<th>realgovt<\/th>\n<th>tbilrate<\/th>\n<th>cpi<\/th>\n<th>realgdp<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>1959-06-30<\/th>\n<td>0.023664<\/td>\n<td>0.088193<\/td>\n<td>0.005849<\/td>\n<td>0.024942<\/td>\n<\/tr>\n<tr>\n<th>1959-09-30<\/th>\n<td>0.020481<\/td>\n<td>0.215321<\/td>\n<td>0.006838<\/td>\n<td>-0.001193<\/td>\n<\/tr>\n<tr>\n<th>1959-12-31<\/th>\n<td>-0.014781<\/td>\n<td>0.125317<\/td>\n<td>0.000681<\/td>\n<td>0.003495<\/td>\n<\/tr>\n<tr>\n<th>1960-03-31<\/th>\n<td>-0.046197<\/td>\n<td>-0.212805<\/td>\n<td>0.005772<\/td>\n<td>0.022190<\/td>\n<\/tr>\n<tr>\n<th>1960-06-30<\/th>\n<td>-0.003900<\/td>\n<td>-0.266946<\/td>\n<td>0.000338<\/td>\n<td>-0.004685<\/td>\n<\/tr>\n<tr>\n<th>&#8230;<\/th>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<td>&#8230;<\/td>\n<\/tr>\n<tr>\n<th>2008-09-30<\/th>\n<td>0.031005<\/td>\n<td>-0.396881<\/td>\n<td>-0.007904<\/td>\n<td>-0.006781<\/td>\n<\/tr>\n<tr>\n<th>2008-12-31<\/th>\n<td>0.015732<\/td>\n<td>-2.277267<\/td>\n<td>-0.021979<\/td>\n<td>-0.013805<\/td>\n<\/tr>\n<tr>\n<th>2009-03-31<\/th>\n<td>-0.010967<\/td>\n<td>0.606136<\/td>\n<td>0.002340<\/td>\n<td>-0.016612<\/td>\n<\/tr>\n<tr>\n<th>2009-06-30<\/th>\n<td>0.026975<\/td>\n<td>-0.200671<\/td>\n<td>0.008419<\/td>\n<td>-0.001851<\/td>\n<\/tr>\n<tr>\n<th>2009-09-30<\/th>\n<td>0.019888<\/td>\n<td>-0.405465<\/td>\n<td>0.008894<\/td>\n<td>0.006862<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>202 rows \u00d7 4 columns<\/p>\n<\/div>\n<div class=\"colab-df-buttons\">\n<div class=\"colab-df-container\">\n    <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-f2e345a0-7555-4e1a-ba7c-9f31c295667f')\" title=\"Convert this dataframe to an interactive table.\" style=\"display:none;\"><\/p>\n<p>  <svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n    <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\" \/>\n  <\/svg><br \/>\n    <\/button><\/p>\n<style>\n    .colab-df-container {\n      display:flex;\n      gap: 12px;\n    }<\/p>\n<p>    .colab-df-convert {\n      background-color: #E8F0FE;\n      border: none;\n      border-radius: 50%;\n      cursor: pointer;\n      display: none;\n      fill: #1967D2;\n      height: 32px;\n      padding: 0 0 0 0;\n      width: 32px;\n    }<\/p>\n<p>    .colab-df-convert:hover {\n      background-color: #E2EBFA;\n      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n      fill: #174EA6;\n    }<\/p>\n<p>    .colab-df-buttons div {\n      margin-bottom: 4px;\n    }<\/p>\n<p>    [theme=dark] .colab-df-convert {\n      background-color: #3B4455;\n      fill: #D2E3FC;\n    }<\/p>\n<p>    [theme=dark] .colab-df-convert:hover {\n      background-color: #434B5C;\n      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n      fill: #FFFFFF;\n    }\n  <\/style>\n<p>    <script>\n      const buttonEl =\n        document.querySelector('#df-f2e345a0-7555-4e1a-ba7c-9f31c295667f button.colab-df-convert');\n      buttonEl.style.display =\n        google.colab.kernel.accessAllowed ? 'block' : 'none';<\/p>\n<p>      async function convertToInteractive(key) {\n        const element = document.querySelector('#df-f2e345a0-7555-4e1a-ba7c-9f31c295667f');\n        const dataTable =\n          await google.colab.kernel.invokeFunction('convertToInteractive',\n                                                    [key], {});\n        if (!dataTable) return;<\/p>\n<p>        const docLinkHtml = 'Like what you see? Visit the ' +\n          '<a  href=https:\/\/colab.research.google.com\/notebooks\/data_table.ipynb>data table notebook<\/a>'\n          + ' to learn more about interactive tables.';\n        element.innerHTML = '';\n        dataTable['output_type'] = 'display_data';\n        await google.colab.output.renderOutput(dataTable, element);\n        const docLink = document.createElement('div');\n        docLink.innerHTML = docLinkHtml;\n        element.appendChild(docLink);\n      }\n    <\/script>\n  <\/div>\n<div id=\"df-71b61756-860a-4500-a599-f25d8e609908\">\n  <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-71b61756-860a-4500-a599-f25d8e609908')\" title=\"Suggest charts\" style=\"display:none;\"><\/p>\n<p>&lt;svg xmlns=&#8221;http:\/\/www.w3.org\/2000\/svg&#8221; height=&#8221;24px&#8221;viewBox=&#8221;0 0 24 24&#8243;<br \/>\n     width=&#8221;24px&#8221;&gt;<br \/>\n    <g>\n        <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\" \/>\n    <\/g><br \/>\n&lt;\/svg&gt;<br \/>\n  <\/button><\/p>\n<style>\n  .colab-df-quickchart {\n      --bg-color: #E8F0FE;\n      --fill-color: #1967D2;\n      --hover-bg-color: #E2EBFA;\n      --hover-fill-color: #174EA6;\n      --disabled-fill-color: #AAA;\n      --disabled-bg-color: #DDD;\n  }<\/p>\n<p>  [theme=dark] .colab-df-quickchart {\n      --bg-color: #3B4455;\n      --fill-color: #D2E3FC;\n      --hover-bg-color: #434B5C;\n      --hover-fill-color: #FFFFFF;\n      --disabled-bg-color: #3B4455;\n      --disabled-fill-color: #666;\n  }<\/p>\n<p>  .colab-df-quickchart {\n    background-color: var(--bg-color);\n    border: none;\n    border-radius: 50%;\n    cursor: pointer;\n    display: none;\n    fill: var(--fill-color);\n    height: 32px;\n    padding: 0;\n    width: 32px;\n  }<\/p>\n<p>  .colab-df-quickchart:hover {\n    background-color: var(--hover-bg-color);\n    box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n    fill: var(--button-hover-fill-color);\n  }<\/p>\n<p>  .colab-df-quickchart-complete:disabled,\n  .colab-df-quickchart-complete:disabled:hover {\n    background-color: var(--disabled-bg-color);\n    fill: var(--disabled-fill-color);\n    box-shadow: none;\n  }<\/p>\n<p>  .colab-df-spinner {\n    border: 2px solid var(--fill-color);\n    border-color: transparent;\n    border-bottom-color: var(--fill-color);\n    animation:\n      spin 1s steps(1) infinite;\n  }<\/p>\n<p>  @keyframes spin {\n    0% {\n      border-color: transparent;\n      border-bottom-color: var(--fill-color);\n      border-left-color: var(--fill-color);\n    }\n    20% {\n      border-color: transparent;\n      border-left-color: var(--fill-color);\n      border-top-color: var(--fill-color);\n    }\n    30% {\n      border-color: transparent;\n      border-left-color: var(--fill-color);\n      border-top-color: var(--fill-color);\n      border-right-color: var(--fill-color);\n    }\n    40% {\n      border-color: transparent;\n      border-right-color: var(--fill-color);\n      border-top-color: var(--fill-color);\n    }\n    60% {\n      border-color: transparent;\n      border-right-color: var(--fill-color);\n    }\n    80% {\n      border-color: transparent;\n      border-right-color: var(--fill-color);\n      border-bottom-color: var(--fill-color);\n    }\n    90% {\n      border-color: transparent;\n      border-bottom-color: var(--fill-color);\n    }\n  }\n<\/style>\n<p>  <script>\n    async function quickchart(key) {\n      const quickchartButtonEl =\n        document.querySelector('#' + key + ' button');\n      quickchartButtonEl.disabled = true;  \/\/ To prevent multiple clicks.\n      quickchartButtonEl.classList.add('colab-df-spinner');\n      try {\n        const charts = await google.colab.kernel.invokeFunction(\n            'suggestCharts', [key], {});\n      } catch (error) {\n        console.error('Error during call to suggestCharts:', error);\n      }\n      quickchartButtonEl.classList.remove('colab-df-spinner');\n      quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n    }\n    (() => {\n      let quickchartButtonEl =\n        document.querySelector('#df-71b61756-860a-4500-a599-f25d8e609908 button');\n      quickchartButtonEl.style.display =\n        google.colab.kernel.accessAllowed ? 'block' : 'none';\n    })();\n  <\/script>\n<\/div>\n<\/p><\/div>\n<\/p><\/div>\n<pre>regr = Ridge2Regressor(h = 20, date_formatting = \"original\",\n                       type_pi=\"blockbootstrap\", # type of simulations for predictive inference\n                       B=50, # number of simulations\n                       seed=1)\n\nstart = time()\nregr.forecast(df)\nprint(f\"Elapsed: {time() - start} s\")\n<\/pre>\n<pre>  |======================================================================| 100%\nElapsed: 0.49063634872436523 s\n<\/pre>\n<pre>regr2 = Ridge2Regressor(h = 20, date_formatting = \"original\",\n                       type_pi=\"gaussian\", # Gaussian prediction intervals\n                       seed=1)\n\nstart = time()\nregr2.forecast(df)\nprint(f\"Elapsed: {time() - start} s\")\n<\/pre>\n<pre>Elapsed: 0.038446664810180664 s\n<\/pre>\n<pre>regr.plot(\"realgovt\")\n<\/pre>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/thierrymoudiki.github.io\/images\/2024-02-26\/2024-02-26-image3.png?w=578&#038;ssl=1\" alt=\"xxx\" class=\"img-responsive\" \/><\/p>\n<pre>regr.plot(\"realgdp\")\n<\/pre>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/thierrymoudiki.github.io\/images\/2024-02-26\/2024-02-26-image4.png?w=578&#038;ssl=1\" alt=\"xxx\" class=\"img-responsive\" \/><\/p>\n<pre>regr2.plot(\"realgovt\")\n<\/pre>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/thierrymoudiki.github.io\/images\/2024-02-26\/2024-02-26-image5.png?w=578&#038;ssl=1\" alt=\"xxx\" class=\"img-responsive\" \/><\/p>\n<pre>regr2.plot(\"realgdp\")\n<\/pre>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/thierrymoudiki.github.io\/images\/2024-02-26\/2024-02-26-image6.png?w=578&#038;ssl=1\" alt=\"xxx\" class=\"img-responsive\" \/><\/p>\n\n\n<div style=\\\"border: 1px solid; background: none repeat scroll 0 0 #EDEDED; margin: 1px; font-size: 13px;\\\">\r\n<div style=\\\"text-align: center;\\\">To <strong>leave a comment<\/strong> for the author, please follow the link and comment on their blog: <strong><a href=\"https:\/\/thierrymoudiki.github.io\/\/blog\/2024\/02\/26\/python\/r\/julia\/ahead-v0100\"> T. Moudiki's Webpage - Python <\/a><\/strong>.<\/div>\r\n<hr \/>\r\nWant to share your content on python-bloggers?<a href=\/add-your-blog\/ rel=\\\"nofollow\\\"> click here<\/a>.\r\n<\/div>","protected":false},"excerpt":{"rendered":"<div style = \"width: 60%; display: inline-block; float:left; \"> ahead version 0.10.0 in R, Python and Julia; univariate and multivariate time series forecasting.<\/div>\n<div style = \"width: 40%; display: inline-block; float:right;\"><img id=\"excerpts_images\" src=' https:\/\/thierrymoudiki.github.io\/images\/2024-02-26\/2024-02-26-image1.png' width = \"200\"  style = \"padding: 10px;\" \/><\/div>\n<div style=\"clear: both;\"><\/div>\n","protected":false},"author":8,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4],"tags":[],"class_list":["post-18731","post","type-post","status-publish","format-standard","hentry","category-data-science"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/posts\/18731","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/comments?post=18731"}],"version-history":[{"count":3,"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/posts\/18731\/revisions"}],"predecessor-version":[{"id":18744,"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/posts\/18731\/revisions\/18744"}],"wp:attachment":[{"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/media?parent=18731"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/categories?post=18731"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/python-bloggers.com\/wp-json\/wp\/v2\/tags?post=18731"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}