Test t de Student avec Oracle
Le ministère de l’environnement confie la surveillance de la qualité de l’air à des associations agréées. Celles-ci publient régulièrement des relevés de mesure des niveaux de présence de divers polluants.
Pour la région Centre, l’association s’appelle Lig’Air et les données collectées sont accessibles sur leur site internet: http://www.ligair.fr
L’ergonomie du site est très bonne. On peut choisir une station de collecte (toutes n’analysent pas les mêmes polluants) et une période d’analyse. Les résultats peuvent ensuite être visualisés graphiquement ou exportés au format Excel.
Par curiosité, je me suis intéressé aux collectes réalisées en deux points particuliers de l’agglomération de la ville de Tours:
- une zone de trafic routier assez dense en bordure de l’A10: Tours – Pompidou
- une zone plus résidentielle: Tours – La Bruyère
Le niveau de « particules en suspension 10µm » est mesuré par ces deux stations et je cherche ici à déterminer s’il est significativement différent pour les deux zones.
Pour cela, je vais effectuer un test t de Student sur les données collectées la semaine dernière.
Chargement des données
Les données étant récupérées au format Excel, une conversion au format CSV est réalisée en premier lieu. Cf post correspondant.
Le fichier converti utilisé dans cet article est disponible ici: lig-air-derniere-semaine
J’utilise ici la technique de table externe pour « publier » les données (en effet, ces dernières ne sont pas à proprement parler « chargées ») en base:
SQL> CREATE OR REPLACE DIRECTORY datadir AS 'C:\RTI\Stats';
Directory created.
SQL>
SQL> CREATE TABLE exttab_qualite_air
2 (
3 dt DATE,
4 bruyere NUMBER,
5 pompidou NUMBER
6 )
7 ORGANIZATION EXTERNAL
8 (TYPE oracle_loader
9 DEFAULT DIRECTORY datadir
10 ACCESS PARAMETERS
11 (
12 RECORDS DELIMITED BY NEWLINE
13 SKIP 1
14 FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '"'
15 MISSING FIELD VALUES ARE NULL
16 (dt CHAR DATE_FORMAT DATE MASK "DD/MM/YYYY HH24:MI", bruyere, pompidou)
17 )
18 LOCATION ('lig-air-derniere-semaine.csv'));
Table created.
SQL>
Vérification des conditions d’application du test de Student
- Normalité des échantillons
La procédure NORMAL_DIST_FIT du package DBMS_STAT_FUNCS permet de vérifier l’adéquation de la distribution de nos échantillons avec une loi normale. Plusieurs tests sont disponibles (Shapiro-Wilk, Kolmogorov-Smirnov etc..) via le paramètre TEST_TYPE.
Ci-dessous, on teste la normalité de l’échantillon POMPIDOU avec le test de Shapiro-Wilk et celle de l’échantillon BRUYERE avec le test de Kolmogorov-Smirnov :
SQL> SET SERVEROUTPUT ON FORMAT WRAPPED
SQL>
SQL> DECLARE
2 l_mean NUMBER;
3 l_stdev NUMBER;
4 l_sig NUMBER;
5 BEGIN
6 DBMS_OUTPUT.put_line ('-------------------------------------------------');
7 DBMS_OUTPUT.put_line ('- Test de Shapiro - Wilks [POMPIDOU]');
8 DBMS_OUTPUT.put_line ('-------------------------------------------------');
9 DBMS_OUTPUT.put_line (' ');
10
11 DBMS_STAT_FUNCS.NORMAL_DIST_FIT (ownername => USER,
12 tablename => 'EXTTAB_QUALITE_AIR',
13 columnname => 'POMPIDOU',
14 test_type => 'SHAPIRO_WILKS',
15 mean => l_mean,
16 stdev => l_stdev,
17 sig => l_sig);
18 DBMS_OUTPUT.put_line ('p-valeur: ' || ROUND (l_sig, 3));
19 DBMS_OUTPUT.put_line ('Moyenne: ' || ROUND (l_mean, 3));
20 DBMS_OUTPUT.put_line ('Ecart Type: ' || ROUND (l_stdev, 3));
21 DBMS_OUTPUT.put_line (' ');
22
23 l_mean := NULL;
24 l_stdev := NULL;
25 DBMS_OUTPUT.put_line ('-------------------------------------------------');
26 DBMS_OUTPUT.put_line ('- Test de Kolmogorov - Smirnov [BRUYERE]');
27 DBMS_OUTPUT.put_line ('-------------------------------------------------');
28 DBMS_STAT_FUNCS.NORMAL_DIST_FIT (ownername => USER,
29 tablename => 'EXTTAB_QUALITE_AIR',
30 columnname => 'BRUYERE',
31 test_type => 'KOLMOGOROV_SMIRNOV',
32 mean => l_mean,
33 stdev => l_stdev,
34 sig => l_sig);
35 DBMS_OUTPUT.put_line ('p-valeur: ' || ROUND (l_sig, 3));
36 DBMS_OUTPUT.put_line ('Moyenne: ' || ROUND (l_mean, 3));
37 DBMS_OUTPUT.put_line ('Ecart Type: ' || ROUND (l_stdev, 3));
38 DBMS_OUTPUT.put_line (' ');
39 END;
40 /
-------------------------------------------------
- Test de Shapiro - Wilks [POMPIDOU]
-------------------------------------------------
W value : .9888824771661467424766391097812566472472
p-valeur: .22
Moyenne: 12.766
Ecart Type: 5.182
-------------------------------------------------
- Test de Kolmogorov - Smirnov [BRUYERE]
-------------------------------------------------
D value : .083441939506389419096614147948279169237
p-valeur: .189
Moyenne: 10.759
Ecart Type: 5.049
PL/SQL procedure successfully completed.
SQL>
Pour les deux tests, l’hypothèse nulle (H0) correspond au fait que nos échantillons sont extraits d’une population normalement distribuée.
La p-value étant dans les deux cas (BRUYERE & POMPIDOU) supérieure au seuil de 5%, nous ne pouvons pas rejeter H0 et l’hypothèse de normalité est donc compatible avec nos données.
A noter que le nombre d’observation étant relativement important, on aurait pu se passer de cette vérification dans la mesure où en vertu du Théorème Central Limite, les moyennes de variables aléatoires tendent à converger vers une distribution gaussienne pour de « grands » (>30) échantillons.
Un test de Fisher peut être utilisé pour valider la concordance des variances. La fonction STATS_F_TEST permet sa mise en œuvre en base. Cette fonction prend deux champs en argument, le premier sert de critère de regroupement et le second contient les données à analyser.
Pour se ramener dans ce cas de figure, on utilise une clause WITH (subquery factoring) au sein de laquelle les deux colonnes sont fusionnées via un opérateur UNION ALL:
SQL> WITH releves 2 AS (SELECT 'P' station, pompidou val FROM exttab_qualite_air 3 UNION ALL 4 SELECT 'B' station, bruyere val FROM exttab_qualite_air) 5 SELECT STATS_F_TEST (station, 6 val, 7 'STATISTIC', 8 'B') 9 f_value, 10 STATS_F_TEST (station, val, 'TWO_SIDED_SIG') p_value 11 FROM releves; F_VALUE P_VALUE ---------- ---------- .949371992 .739270937 SQL>
Ici, il s’agit d’un test bilatéral (TWO_SIDED_SIG) avec pour hypothèse nulle que les variances des deux populations dont sont prélevés les échantillons sont égales.
Comme la p-valeur est supérieure au seuil de 5%, nous ne rejetons pas H0 et on considère que les données sont compatibles avec l’hypothèse d’homoscédasticité.
Réalisation du test de Student
Une fois les conditions d’utilisation validées, on peut réaliser le test via la fonction STATS_T_TEST_INDEP:
SQL> WITH releves 2 AS (SELECT 'P' station, pompidou val FROM exttab_qualite_air 3 UNION ALL 4 SELECT 'B' station, bruyere val FROM exttab_qualite_air) 5 SELECT STATS_T_TEST_INDEP (station, 6 val, 7 'STATISTIC', 8 'P') 9 t_value, 10 STATS_T_TEST_INDEP (station, 11 val, 12 'ONE_SIDED_SIG', 13 'P') 14 p_value_unilateral 15 FROM releves; T_VALUE P_VALUE_UNILATERAL ---------- ------------------ 3.5687916 .000205995 SQL>
Sous l’hypothèse H0, on considère que les moyennes des niveaux de présence des particules en suspension ne sont pas statistiquement différente entre les deux stations.
La p-valeur du test étant très faible, on rejette H0 au bénéfice de l’hypothèse alternative selon laquelle il y a bien une différence statistiquement significative entre les deux sites.
De plus, comme on a réalisé un test unilatéral avec le site de Pompidou « P » comme référence haute, on peut dire que la moyenne du niveau de présence de particules est significativement plus élevée sur ce site par rapport à celui de Bruyère.