Calculs prévisionnels sous Oracle et BO

Il existe différentes manières d’effectuer des prévisions / estimations dans le futur.
Certains logiciels facilitent ce type de calcul, notamment ceux spécialisés en datamining ou/et en calculs statistiques comme SAS,
Par contre d’autres comme Business Objects ne le permettent pas.
Mais on peut s’en passer dans des cas assez simples.
Je propose ici d’utiliser certaines fonctions d’Oracle qui répondent à ce besoin, et de voir comment les implémenter sous BO.

Problématique :
On a un indicateur annuel, on connait un certain historique et on aimerait estimer les valeurs de cet indicateur dans le futur.

Exemple :

select * from test_regr

ANNEE  Y
2007  2
2008  4
2009  6
2010  8

Ici on ajoute 2 à Y chaque année, donc on peut prévoir qu’en 2011 on aurait Y=10, en 2012 Y=12 etc …
Evidemment ici on a une suite logique, c’est un exemple parfait.

Dans la vraie vie ce n’est pas si facile, par exemple on aurait :

ANNEE  Y
2007  1.8
2008  4.2
2009  5.7
2010  8.8

On n’a pas ici la même différence entre 2 années successives, On ne peut déduire la valeur de 2011 ou 2012 simplement.

Oracle propose des fonctions permettant de calculer une droite de régression. En résumé il s’agit d’établir une droite qui représenterait la courbe d’évolution de l’indicateur.

Séquence Nostalgie des cours de stats : La méthode s’appuie sur le calcul des moindres carrés, je ne vais pas rentrer dans les détails, d’autres le faisant mieux que moi comme sur wikipedia.
graphe_regression

L’équation de cette droite est du type y= p x + y0, p étant la pente et y0 l’ordonnée à l’origine.
Sous Oracle la fonction REGR_SLOPE donne la pente, et REGR_INTERCEPT y0.
Une fois qu’on les a déterminés on peut estimer une valeur dans le futur en remplaçant x dans l’équation.

— ce qui donne avec l’exemple

with v as
  (   select 2010 annee, 8 y from dual
union select 2009, 6 from dual
union select 2008, 4 from dual
union select 2007, 2 from dual )
SELECT regr_slope( y, annee ) p, regr_intercept( y, annee ) y0 from v;
 
-- p=2 et y0=-4012

estimation pour 2011 :

y= p *  x   +   y0
 = 2 * 2011 + -4012
 = 10

ou en sql :

with v as
  (   select 2010 annee, 8 y from dual
union select 2009, 6 from dual
union select 2008, 4 from dual
union select 2007, 2 from dual )
SELECT regr_slope( y, annee )*2011 + regr_intercept( y, annee ) from v;

et le tout en one-shot :

with a as
  ( select to_char(sysdate,'YYYY') annee from dual union
    select to_char(add_months(sysdate,-12),'YYYY') annee from dual union
    select to_char(add_months(sysdate,-24),'YYYY') annee from dual union
    select to_char(add_months(sysdate,-36),'YYYY') annee from dual union
    select to_char(add_months(sysdate,+12),'YYYY') annee from dual union
    select to_char(add_months(sysdate,+24),'YYYY') annee from dual union
    select to_char(add_months(sysdate,+36),'YYYY') annee from dual
  ), v as
  (   select 2010 annee, 8 y from dual
union select 2009, 6 from dual
union select 2008, 4 from dual
union select 2007, 2 from dual )
select
  a.annee,  
  v.y  volume,  
  s.p * a.annee + s.y0 estim
from
  v,
  ( select regr_slope( y, annee ) p, regr_intercept( y, annee ) y0 from v ) s,
  a
where v.annee(+)=a.annee
order by a.annee;

Remarques :

  • intuitivement on a une progression linéaire,
    ce qui veut dire que si on sortait le graphe on pourrait tracer une ligne droite pour représenter l’évolution de l’indicateur.
    Sinon les estimations ne donnent pas les bons résultats
  • les fonctions regr sont des fonctions analytiques, on peut les utiliser comme telles avec la clause over( … )
    cela réduit le nombre de passages sur la table d’historique et peut jouer sur les performances

SOUS Business Objects :

On trouve bien les fonctions REGR_% dans l’éditeur des objets BO du designer
fonction regr sous BO

Mais les contraintes réduisent le champ d’action :

  • on peut avoir des sum() en paramètre ( ex : regr_slope( sum( montant ), annee) ), mais la gestion est assez complexe, on mélange 2 fonctions d’agrégation et souvent cela pose problème car il manque une colonne dans le GROUP BY du select généré par BO.
    On oublie donc cela, et on a déjà des tables agrégées dans l’univers.
  • quand on rajoute des dimensions ( dans l’éditeur SQL du rapport ) il faudrait les mettre dans la clause over(partition by (dimensions)) de la formule de l’objet dans Designer.
    Il faut donc être synchro entre l’éditeur de rapport et l’univers.
  • il faut avoir des tables agrégées au grain de la dimension en x. Cela signifie qu’on doit avoir une seule valeur dans la table pour un x donné.

Par exemple si on a 10 opérations pour une année, on n’aura pas d’erreur mais les fonctions se feront sur une sorte de moyenne des indicateurs ( au lieu de la somme ).

annee   montant
2010      2
2010      4
2010      6
2009      4
--> au lieu de sommer pour 2010 et d'avoir 12, les fonctions regr_%() vont traiter les 4 binômes et donc renvoyer une ligne plate ( y=4 )

Cela implique :

  • il faut des tables agrégées au grain de la dimension en x. On peut s’en arranger avec des vues ou des tables dérivées qui font les sommes.
  • il faut exactement les mêmes dimensions dans le fournisseur de données que celles utilisées pour les objets de régression.
  • si on utilise d’autres objets la requête tombera en erreur
    Cela peut donc multiplier le nombre de tables et d’objets dans l’univers.
    Il est donc important de bien connaître les besoins au départ, de se limiter à ce périmètre et d’expliquer les contraintes aux utilisateurs finaux.

En conclusion l’implémentation des fonctions Oracle de régression dans BO pour établir un modèle prévisionnel est assez limitée.
Il faut définir l’état final et à partir de là définir les objets de l’univers en utilisant les fonctions regr_slope() et regr_intercept().
L’univers utilisé est un univers technique, on ne pourra créer facilement d’autres états prévisionnels à partir de celui-ci. Il faudra généralement à chaque fois créer de nouveaux objets.

2 réflexions au sujet de « Calculs prévisionnels sous Oracle et BO »

Répondre à doc malkovich Annuler la réponse.

Votre adresse de messagerie ne sera pas publiée.

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>