OracleStatistiqueTests d'hypothèses

ANOVA à un facteur avec Oracle

Je suis tombé récemment sur un article décrivant la concurrence acharnée entre les grandes surfaces et les stations-service sur le marché du carburant. Cela m’a donné envie d’en savoir davantage et surtout de vérifier par moi-même si cette guerre des prix était « visible » lorsqu’on s’intéressait globalement aux tarifs à la pompe.

Les prix de vente des carburants font l’objet d’un suivi permanent par le ministère de l’économie qui met à disposition un relevé quotidien: http://www.prix-carburants.gouv.fr/rubrique/opendata/

Une réutilisation de ces données incluant la marque des stations-services (à partir des données GPS j’imagine) est accessible via le portail OpenDataSoft:
http://public.opendatasoft.com/explore/dataset/prix_des_carburants_j_7/?tab=metas

Avec l’information de la marque des stations, on peut réaliser des groupements en fonction du type de distributeur: « Grande Distribution » (enseignes comme Carrefour, Leclerc etc…), « Distributeur » (enseignes de vente des sociétés pétrolières comme Total, BP etc…), « Distributeur Low-Cost » (enseignes automatisées des sociétés pétrolières comme Total Access et Esso Express) et Autres pour le reste (Distributeurs Indépendants, petites chaines non-affiliées etc…). On peut ensuite réaliser des comparaisons du prix moyen de vente pour chacun de ces groupes.

Pour cela, j’utilise un test ANOVA qui permet de déterminer s’il existe des différences de moyenne statistiquement significatives entre les échantillons (i.e. H0: les échantillons sont issus d’une même population). Comme le test permet de traiter plusieurs groupes simultanément, on évite ainsi la multiplication de tests t (et l’augmentation associée du risque alpha de première espèce).

L’ANOVA repose sur l’équation d’analyse de variance SCT = SCE + SCR avec:

  • SCT: Somme des Carrés Totaux ou Variance Totale
  • SCE: Somme des Carrés des Ecarts Interclasse ou Variance Intergroupes
  • SCR: Somme des Carrés des Résidus (Ecarts Intraclasse) ou Variance Intragroupe

Les conditions d’utilisation du test sont l’indépendance, la normalité et l’homoscédasticité des échantillons comparés. L’indépendance dépend du mode opératoire et la normalité est peu problématique si l’effectif est grand.

En revanche, la condition d’homoscédasticité est plus épineuse (et ce d’autant plus que les effectifs des échantillons sont différents). En pratique:

  • si les plus petits échantillons proviennent d’une population avec la variance la plus importante, le test devient plus « libéral » = fausse significativité
  • si les plus petits échantillons proviennent d’une population avec la variance la moins importante, le test devient plus « conservatif » = mauvaise détection

La règle approximative est que l’ANOVA est robuste pour des échantillons dont le rapport de variance n’excède pas 4:1. Au-delà, dans la limite du raisonnable, on peut essayer de compenser en diminuant le niveau alpha du test.

Oracle propose la fonction STATS_ONE_WAY_ANOVA pour réaliser des test ANOVA a un facteur.
Le fichier de données utilisé dans cette analyse est disponible ici: prix_des_carburants_j_7

Chargement des données via une table externe

SQL> CREATE TABLE exttab_carburants
  2  (
  3     Id          NUMBER,
  4     CP          VARCHAR2 (20),
  5     Axe         VARCHAR2 (5),
  6     Adresse     VARCHAR2 (200),
  7     Ville       VARCHAR2 (50),
  8     HO          VARCHAR2 (30),
  9     HF          VARCHAR2 (30),
 10     JF          VARCHAR2 (200),
 11     TF          VARCHAR2 (50),
 12     DF          VARCHAR2 (20),
 13     FF          VARCHAR2 (20),
 14     Carburant   VARCHAR2 (50),
 15     Rupture     VARCHAR2 (30),
 16     MAJ         VARCHAR2 (30),
 17     PGazole     VARCHAR2 (30),
 18     PSP95       VARCHAR2 (30),
 19     PSP98       VARCHAR2 (30),
 20     PGPL        VARCHAR2 (30),
 21     PE10        VARCHAR2 (30),
 22     PE85        VARCHAR2 (30),
 23     Services    VARCHAR2 (500),
 24     Marque      VARCHAR2 (500),
 25     Nom         VARCHAR2 (500),
 26     GeoPoint    VARCHAR2 (50)
 27  )
 28  ORGANIZATION EXTERNAL
 29     (TYPE oracle_loader
 30           DEFAULT DIRECTORY datadir
 31              ACCESS PARAMETERS
 32                  (
 33                  RECORDS DELIMITED BY NEWLINE
 34                  SKIP 1
 35                  FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"'
 36                  MISSING FIELD VALUES ARE NULL)
 37           LOCATION ('prix_des_carburants_j_7.csv'));

Table created.

SQL>

Groupement des données par une vue

On s’intéresse uniquement aux données récentes (de la semaine passée) hors stations d’autoroute.

SQL> CREATE OR REPLACE VIEW CARBURANTS
  2  AS
  3     SELECT marque,
  4            TO_NUMBER (pgazole) prix_gazole,
  5            CASE
  6               WHEN marque IN ('Agip',
  7                               'Esso',
  8                               'BP',
  9                               'Avia',
 10                               'Total',
 11                               'Elan',
 12                               'Shell',
 13                               'Dyneff',
 14                               'VITO')
 15               THEN
 16                  'Distributeur'
 17               WHEN marque IN ('Intermarché',
 18                               'Système U',
 19                               'Auchan',
 20                               'Leclerc',
 21                               'Carrefour',
 22                               'Carrefour Market',
 23                               'Carrefour Contact',
 24                               'Atac',
 25                               'Casino',
 26                               'Colruyt',
 27                               'CORA',
 28                               'Géant',
 29                               'Netto',
 30                               'Leader Price',
 31                               'Ecomarché',
 32                               'Intermarché Contact',
 33                               'Super Casino',
 34                               'Supermarché Match',
 35                               'Simply Market',
 36                               'Shopi')
 37               THEN
 38                  'Grande Distribution'
 39               WHEN marque IN ('Esso Express', 'Total Access')
 40               THEN
 41                  'Distributeur Low Cost'
 42               ELSE
 43                  'Autre'
 44            END
 45               type_distrib
 46       FROM exttab_carburants
 47      WHERE     TO_DATE (SUBSTR (maj, 1, 10), 'YYYY-MM-DD') >=
 48                   TO_DATE ('03/06/2015', 'DD/MM/YYYY')
 49            AND pgazole IS NOT NULL
 50            AND axe != 'A';

View created.

SQL>

On obtient donc 4 classes:

  • Grande Distribution
  • Distributeur
  • Distributeur Low-Cost
  • Autre

La classe « Autre » représentant une grande hétérogénéité dans ses membres sera ignorée dans la suite.

Vérification de l’homoscédasticité

SQL>   SELECT type_distrib, VAR_SAMP (prix_gazole), COUNT (*)
  2      FROM carburants
  3     WHERE type_distrib != 'Autre'
  4  GROUP BY type_distrib;

TYPE_DISTRIB          VAR_SAMP(PRIX_GAZOLE)   COUNT(*)
--------------------- --------------------- ----------
Distributeur                     .001094295       1203
Distributeur Low Cost            .000223032        358
Grande Distribution              .000717468       3834

SQL>

Ici, les effectifs sont inégaux et le rapport entre les variances min/max est de 4.9:1.
On est donc aux limites d’applicabilité du test.

Réalisation du test

SQL> SELECT STATS_ONE_WAY_ANOVA (type_distrib, prix_gazole, 'SUM_SQUARES_BETWEEN')
  2            SUM_SQUARES_BETWEEN,
  3         STATS_ONE_WAY_ANOVA (type_distrib, prix_gazole, 'SUM_SQUARES_WITHIN')
  4            SUM_SQUARES_WITHIN,
  5         STATS_ONE_WAY_ANOVA (type_distrib, prix_gazole, 'F_RATIO') F_RATIO,
  6         STATS_ONE_WAY_ANOVA (type_distrib, prix_gazole, 'SIG') p_value,
  7           STATS_ONE_WAY_ANOVA (type_distrib,
  8                                prix_gazole,
  9                                'SUM_SQUARES_BETWEEN')
 10         / (  STATS_ONE_WAY_ANOVA (type_distrib,
 11                                   prix_gazole,
 12                                   'SUM_SQUARES_BETWEEN')
 13            + STATS_ONE_WAY_ANOVA (type_distrib,
 14                                   prix_gazole,
 15                                   'SUM_SQUARES_WITHIN'))
 16            eta2
 17    FROM carburants
 18   WHERE type_distrib != 'Autre';

SUM_SQUARES_BETWEEN SUM_SQUARES_WITHIN    F_RATIO    P_VALUE       ETA2
------------------- ------------------ ---------- ---------- ----------
          7.9395189         4.14502067 5164.01356          0 .656998047

SQL>

La valeur p renvoyée est de 0. L’hypothèse H0 est donc rejetée et on peut considérer qu’il y a bien une différence de moyenne entre au moins deux groupes.

Outre les valeurs restituées par la fonction, je calcule le rapport de corrélation eta-2 via la formule SCE/SCT. Celui-ci indique le degré d’association entre le prix moyen et le type de distributeur – ici, 66% de la variance de prix est « expliquée » par le canal de distribution.

A ce stade, on sait donc que 2 classes au-moins ont un prix moyen statistiquement différent mais on ne sait pas dire lesquelles. En pratique, pour aller plus loin dans l’analyse, il faudrait mettre en œuvre un test post-hoc malheureusement, Oracle n’en propose pas en standard.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *