Mis a jour le 2025-04-14, 12:10

ANOVA

anova :
  • on utilise import pandas; df = pandas.DataFrame({'val': [1, 3, 5, 3, 1, 3, 4, 6, 3, 8, 9, 10], 'lab': ['A', 'B', 'B', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C']})
  • il faut d'abord faire le fit des données :
    mdl = statsmodels.formula.api.ols('val ~ lab', data = df)
    res = mdl.fit()
        
  • puis, on calcule l'anova : import statsmodels.api; table = statsmodels.api.stats.anova_lm(res)
  • le résultat est un data frame avec les colonnes : df, sum_sq, mean_sq, F et PR(>F), et les lignes avec Residual et ici, lab :
    
               df     sum_sq    mean_sq        F    PR(>F)
    lab       2.0  85.866667  42.933333  30.1875  0.000102
    Residual  9.0  12.800000   1.422222      NaN       NaN
        
  • statsmodels.stats.anova.anova_lm(fit, robust = 'hc3') : utilise une correction pour l'hétéroscédasticité
  • on peut mesurer l'intensité de l'effet avec omega2 (équivalent pour l'ANOVA du R2) :
    table['mean_sq'] = table['sum_sq'] / table['df']
    table['omega_sq'] = (table[:-1]['sum_sq'] - table[:-1]['df'] * table['mean_sq'][-1])/(sum(table['sum_sq']) + table['mean_sq'][-1])
        
  • tester la normalité des résidus : import scipy.stats; scipy.stats.shapiro(res.resid) (la 2ème valeur est la p-value que les données ne sont pas normales). Mais si beaucoup de données, regarder aussi un q-q plot, car la p-value peut devenir significative alors même que la deviation d'une loi normale est très faible :
    pplot = statsmodels.graphics.gofplots.ProbPlot(res.resid, fit = True)
    pplot.qqplot(line = 's')
        
  • pour tester l'homogénéité de la variance : scipy.stats.levene(df['val'][df['lab'] == 'A'], df['val'][df['lab'] == 'B'], df['val'][df['lab'] == 'C']), mais si beaucoup de données, à nouveau souhaitable d'avoir un examen graphique avec par exemple un boxplot.
Tukey HSD après une ANOVA
  • res = statsmodels.stats.multicomp.pairwise_tukeyhsd(yValues, xValues, alpha = 0.01) où yValues sont des valeurs de type catégorie.
  • res est un objet de la classe statsmodels.sandbox.stats.multicomp.TukeyHSDResults avec notamment une méthode res.summary() qui renvoie un statsmodels.iolib.table.SimpleTable
  • res.summary() a un champ data qui donne une liste de liste correspondant au tableau (pour l'avoir dans un dataframe, on peut faire : df = pandas.DataFrame(result.summary().data[1:], columns = result.summary().data[0]))
  • res.plot_simultaneous() : donne un graphe avec un intervalle pour chaque categorie : les paires significatives sont celles pour lesquelles les intervalles ne se chevauchent pas.

Copyright python-simple.com
programmer en python, tutoriel python, graphes en python, Aymeric Duclert