> Modules non standards > statsmodels > ANOVA
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