web-dev-qa-db-fra.com

Comment obtenir les résultats d'ajustement numérique lors du traçage d'une régression chez Seaborn?

Si j'utilise la bibliothèque seaborn dans Python pour tracer le résultat d'une régression linéaire, existe-t-il un moyen de connaître les résultats numériques de la régression? Par exemple, je pourrais vouloir connaître le raccord coefficients ou le R2 de l'ajustement.

Je pourrais réexécuter le même ajustement en utilisant l'interface sous-jacente des modèles de statistiques, mais cela semblerait être un effort inutile en double, et de toute façon je voudrais pouvoir comparer les coefficients résultants pour être sûr que les résultats numériques sont les mêmes que ceux que je vois dans l'intrigue.

43
The Photon

Il n'y a aucun moyen de le faire.

À mon avis, demander une bibliothèque de visualisation pour vous donner des résultats de modélisation statistique est à l'envers. statsmodels, une bibliothèque de modélisation, vous permet d'ajuster un modèle, puis de dessiner un tracé qui correspond exactement au modèle que vous ajustez. Si vous voulez cette correspondance exacte, cet ordre des opérations a plus de sens pour moi.

Vous pourriez dire "mais les tracés dans statsmodels n'ont pas autant d'options esthétiques que seaborn". Mais je pense que cela a du sens - statsmodels est une bibliothèque de modélisation qui utilise parfois la visualisation au service de la modélisation. seaborn est une bibliothèque de visualisation qui utilise parfois la modélisation au service de la visualisation. Il est bon de se spécialiser et mauvais d'essayer de tout faire.

Heureusement, seaborn et statsmodels utilisent à la fois données bien rangées . Cela signifie que vous avez vraiment besoin de très peu de duplication d'efforts pour obtenir à la fois des tracés et des modèles via les outils appropriés.

22
mwaskom

En regardant dans le document actuellement disponible, le plus proche que j'ai pu déterminer si cette fonctionnalité peut maintenant être satisfaite est si l'on utilise le module scipy.stats.pearsonr.

r2 = stats.pearsonr("pct", "rdiff", df)

En essayant de le faire fonctionner directement dans une trame de données Pandas, il y a une erreur provoquée par la violation des exigences d'entrée de base scipy:

TypeError: pearsonr() takes exactly 2 arguments (3 given)

J'ai réussi à localiser un autre utilisateur Pandas Seaborn qui l'a évidemment résolu: https://github.com/scipy/scipy/blob/v0.14.0/scipy/stats/stats). py # L2392

sns.regplot("rdiff", "pct", df, corr_func=stats.pearsonr);

Mais, malheureusement, je n'ai pas réussi à faire fonctionner cela car il semble que l'auteur a créé son propre corr_func personnalisé ou qu'il existe une méthode de transmission d'argument Seaborn non documentée qui est disponible en utilisant une méthode plus manuelle:

# x and y should have same length.
    x = np.asarray(x)
    y = np.asarray(y)
    n = len(x)
    mx = x.mean()
    my = y.mean()
    xm, ym = x-mx, y-my
    r_num = np.add.reduce(xm * ym)
    r_den = np.sqrt(ss(xm) * ss(ym))
    r = r_num / r_den

# Presumably, if abs(r) > 1, then it is only some small artifact of floating
# point arithmetic.
r = max(min(r, 1.0), -1.0)
df = n-2
if abs(r) == 1.0:
    prob = 0.0
else:
    t_squared = r*r * (df / ((1.0 - r) * (1.0 + r)))
    prob = betai(0.5*df, 0.5, df / (df + t_squared))
return r, prob

J'espère que cela contribuera à faire avancer cette demande d'origine vers une solution provisoire, car il existe un utilitaire indispensable pour ajouter les statistiques de fitness de régression au package Seaborn en remplacement de ce que l'on peut facilement obtenir à partir de MS-Excel ou d'un lineplot Matplotlib stock.

2
user3741230

Le créateur de Seaborn a malheureusement déclaré qu'il n'ajoutera pas une telle fonctionnalité, alors voici une solution de contournement.

def regplot(*args, **kwargs):
    # this is the class that `sns.regplot` uses
    plotter = sns.regression._RegressionPlotter(*args, **kwargs)

    # this is essentially the code from `sns.regplot`
    ax = kwargs.get("ax", None)
    if ax is None:
        ax = plt.gca()

    scatter_kws = {} if scatter_kws is None else copy.copy(scatter_kws)
    scatter_kws["marker"] = marker
    line_kws = {} if line_kws is None else copy.copy(line_kws)

    plotter.plot(ax, scatter_kws, line_kws)

    # unfortunately the regression results aren't stored, so we rerun
    grid, yhat, err_bands = plotter.fit_regression(plt.gca())

    # also unfortunately, this doesn't return the parameters, so we infer them
    slope = (yhat[-1] - yhat[0]) / (grid[-1] - grid[0])
    intercept = yhat[0] - slope * grid[0]
    return slope, intercept

Notez que cela ne fonctionne que pour la régression linéaire car il déduit simplement la pente et l'interception des résultats de la régression. Ce qui est bien, c'est qu'il utilise la propre classe de régression de seaborn et donc les résultats sont garantis cohérents avec ce qui est montré. L'inconvénient est bien sûr que nous utilisons un détail d'implémentation privé dans seaborn qui peut casser à tout moment.

1
Legendre17