Le lissage exponentiel simple est une technique de prévision à t+1 s’appliquant à des séries temporelles sans tendance. L’objectif étant de donner plus ou moins d’importance aux dernières observations grâce à un paramètre alpha. Dans le cas d’une série temporelle avec tendance, il est préférable d’utiliser le lissage exponentiel double.

Cet article a pour objectif de présenter une implémentation possible du lissage exponentiel simple en Javascript. Nous aborderons également l’utilisation de l’erreur quadratique pour déterminer la valeur optimale de alpha, ainsi que l’utilisation de la librairie HighchartJs afin de représenter graphiquement nos séries temporelles.

Nos données

Nous utiliserons les données issues de ce site.

Mois CA(k€)
Janvier 25
Février 29
Mars 24
Avril 21
Mai 26
Juin 23
Juillet 27
Août 25
Septembre 21
Octobre 24
Novembre 26
Décembre 29
Janvier 25
Février ?

L'objectif du lissage exponentiel simple sera de déterminer la valeur du chiffre d'affaires pour le dernier mois de Février. La valeur de cette prédiction dépend du paramètre alpha. Nous expliquerons donc également comment sélectionner la valeur optimale d'alpha.

Lissage exponentiel simple

La prédiction en t est égale à l’erreur sur la prédiction précédente (valeur(t-1) - prédiction(t-1)) multipliée par le paramètre alpha, auquel on ajoute la prédiction en t-1.

function les(data, alpha)
{
	var forecast = Array();
	forecast[0] = null;
	//on initialise la premiere valeur du lissage avec la moyenne des deux premiers
	forecast[1] = 0.5*(data[0] + data[1]);
	for(var i = 2; i <= data.length; ++i)
	{
		forecast[i] = alpha*(data[i-1] - forecast[i-1]) + forecast[i-1];
		//forecast[i] = alpha * erreur(t-1) + prédiction(t-1)
	}
	return forecast;
}

Trouver la valeur optimale d'alpha

Pour trouver la meilleure valeur du paramètre alpha, nous cherchons à minimiser l’erreur quadratique. Celle-ci est égale à 1/(n-1)*(valeur[1]-prediction[1] + valeur[2]-prediction[2] + … + valeur[n]-prediction[n]).

En Javascript cela donne :

function computeMeanSquaredError(data, forecast)
{
	var error = 0.0;
	for(var i = 1; i < data.length; ++i)
	{
		error += Math.pow(data[i] - forecast[i], 2);
	}
	return 1/(data.length-1)*error;
}

Pour trouver la meilleure valeur de alpha, on itère entre 0 et 1 avec un pas passé en paramètre à notre fonction. L’objectif est de garder la valeur d’alpha permettant de minimiser l’erreur quadratique.

function findBestAlpha(data, nbIter)
{
	var incr = 1/nbIter;
	var bestAlpha = 0.0;
	var bestError = -1;
	var alpha = bestAlpha;

	while(alpha < 1)
	{
		var forecast = les(data, alpha);
		var error = computeMeanSquaredError(data, forecast);
		if(error < bestError || bestError == -1)
		{
			bestAlpha = alpha;
			bestError = error;
		}
		alpha += incr;
	}
	return bestAlpha;
}

Une fois la valeur optimale de alpha trouvée, il suffit de générer les prédictions :

var bestAlpha = findBestAlpha(data, 20);
var forecast = les(data, bestAlpha);

Représentation graphique avec HighchartJs

Nous allons utiliser la librairie HighchartJs afin de tracer nos deux séries (celle réalisée et celle prédite). Pour cela il suffit d’inclure Jquery, ainsi que le fichier Highcharts.js. Ensuite, nous insérons le code suivant, en modifiant les différents champs en fonction de nos besoins :

<script type="text/javascript">
    $(function () {
        $('#container').highcharts({
            title: {
                text: 'Chiffre d\'affaires mensuel',
                x: -20 //center
            },
            subtitle: {
                text: 'Source: fakeSource.com',
                x: -20
            },
            xAxis: {
                categories: ['Jan', 'Fev', 'Mar', 'Avr', 'Mai', 'Juin',
                    'Juil', 'Aout', 'Sept', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb']
            },
            yAxis: {
                title: {
                    text: 'CA (k€)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: 'k€'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: [{
                name: 'Réalisé',
                data: data
            }, {
                name: 'Prévisions',
                data: forecast
            }]
        });
    });
</script>

<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>

Pour plus de graphiques réalisables avec HighchartJs, n’hésitez pas à vous rendre sur leur site où différents exemples sont présentés.
Nous obtenons le résultat ci-dessous :


Antoine Vastel

French PhD student, working on browser fingerprinting!