J'ai de nombreux n-uplets (par1, par2), c'est-à-dire des points dans un espace de paramètre bidimensionnel obtenu en répétant une expérience plusieurs fois.
Je cherche une possibilité de calculer et de visualiser des ellipses de confiance (je ne sais pas si c'est le terme qui convient pour cela). Voici un exemple d'intrigue que j'ai trouvé sur le Web pour montrer ce que je veux dire:
source: blogspot.ch/2011/07/classification-and-discrimination-with.html
Donc, en principe, il faut adapter une distribution multivariée normale à un histogramme 2D de points de données, je suppose. Quelqu'un peut-il m'aider avec ça?
On dirait que vous voulez juste l'ellipse 2-sigma de la dispersion de points?
Si tel est le cas, envisagez quelque chose comme ceci (à partir d'un code pour un article ici: https://github.com/joferkington/oost_paper_code/blob/master/error_ellipse.py ):
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse
def plot_point_cov(points, nstd=2, ax=None, **kwargs):
"""
Plots an `nstd` sigma ellipse based on the mean and covariance of a point
"cloud" (points, an Nx2 array).
Parameters
----------
points : An Nx2 array of the data points.
nstd : The radius of the ellipse in numbers of standard deviations.
Defaults to 2 standard deviations.
ax : The axis that the ellipse will be plotted on. Defaults to the
current axis.
Additional keyword arguments are pass on to the ellipse patch.
Returns
-------
A matplotlib ellipse artist
"""
pos = points.mean(axis=0)
cov = np.cov(points, rowvar=False)
return plot_cov_ellipse(cov, pos, nstd, ax, **kwargs)
def plot_cov_ellipse(cov, pos, nstd=2, ax=None, **kwargs):
"""
Plots an `nstd` sigma error ellipse based on the specified covariance
matrix (`cov`). Additional keyword arguments are passed on to the
ellipse patch artist.
Parameters
----------
cov : The 2x2 covariance matrix to base the ellipse on
pos : The location of the center of the ellipse. Expects a 2-element
sequence of [x0, y0].
nstd : The radius of the ellipse in numbers of standard deviations.
Defaults to 2 standard deviations.
ax : The axis that the ellipse will be plotted on. Defaults to the
current axis.
Additional keyword arguments are pass on to the ellipse patch.
Returns
-------
A matplotlib ellipse artist
"""
def eigsorted(cov):
vals, vecs = np.linalg.eigh(cov)
order = vals.argsort()[::-1]
return vals[order], vecs[:,order]
if ax is None:
ax = plt.gca()
vals, vecs = eigsorted(cov)
theta = np.degrees(np.arctan2(*vecs[:,0][::-1]))
# Width and height are "full" widths, not radius
width, height = 2 * nstd * np.sqrt(vals)
ellip = Ellipse(xy=pos, width=width, height=height, angle=theta, **kwargs)
ax.add_artist(ellip)
return ellip
if __== '__main__':
#-- Example usage -----------------------
# Generate some random, correlated data
points = np.random.multivariate_normal(
mean=(1,1), cov=[[0.4, 9],[9, 10]], size=1000
)
# Plot the raw points...
x, y = points.T
plt.plot(x, y, 'ro')
# Plot a transparent 3 standard deviation covariance ellipse
plot_point_cov(points, nstd=3, alpha=0.5, color='green')
plt.show()
Reportez-vous à la publication Comment dessiner une ellipse d'erreur de covariance .
Voici la réalisation python:
import numpy as np
from scipy.stats import norm, chi2
def cov_ellipse(cov, q=None, nsig=None, **kwargs):
"""
Parameters
----------
cov : (2, 2) array
Covariance matrix.
q : float, optional
Confidence level, should be in (0, 1)
nsig : int, optional
Confidence level in unit of standard deviations.
E.g. 1 stands for 68.3% and 2 stands for 95.4%.
Returns
-------
width, height, rotation :
The lengths of two axises and the rotation angle in degree
for the ellipse.
"""
if q is not None:
q = np.asarray(q)
Elif nsig is not None:
q = 2 * norm.cdf(nsig) - 1
else:
raise ValueError('One of `q` and `nsig` should be specified.')
r2 = chi2.ppf(q, 2)
val, vec = np.linalg.eigh(cov)
width, height = 2 * sqrt(val[:, None] * r2)
rotation = np.degrees(arctan2(*vec[::-1, 0]))
return width, height, rotation
La signification de écart type est faux dans la réponse de Joe Kington. Nous utilisons habituellement 1, 2 sigma pour des niveaux de confiance de 68%, 95%, mais l’ellipse de 2 sigma dans sa réponse ne contient pas une probabilité de 95% de la distribution totale. La méthode correcte consiste à utiliser une distribution du chi carré pour estimer la taille de l'ellipse comme indiqué dans le post .
J'ai légèrement modifié l'un des exemples ci-dessus qui trace les contours des zones d'erreur ou de confiance. Maintenant, je pense que cela donne les bons contours.
Cela donnait des contours incorrects parce que la méthode scoreatpercentile était appliquée à l'ensemble de données joint (points bleus + rouges) lorsqu'elle devait être appliquée séparément à chaque ensemble de données.
Le code modifié se trouve ci-dessous:
import numpy
import scipy
import scipy.stats
import matplotlib.pyplot as plt
# generate two normally distributed 2d arrays
x1=numpy.random.multivariate_normal((100,420),[[120,80],[80,80]],400)
x2=numpy.random.multivariate_normal((140,340),[[90,-70],[-70,80]],400)
# fit a KDE to the data
pdf1=scipy.stats.kde.gaussian_kde(x1.T)
pdf2=scipy.stats.kde.gaussian_kde(x2.T)
# create a grid over which we can evaluate pdf
q,w=numpy.meshgrid(range(50,200,10), range(300,500,10))
r1=pdf1([q.flatten(),w.flatten()])
r2=pdf2([q.flatten(),w.flatten()])
# sample the pdf and find the value at the 95th percentile
s1=scipy.stats.scoreatpercentile(pdf1(pdf1.resample(1000)), 5)
s2=scipy.stats.scoreatpercentile(pdf2(pdf2.resample(1000)), 5)
# reshape back to 2d
r1.shape=(20,15)
r2.shape=(20,15)
# plot the contour at the 95th percentile
plt.contour(range(50,200,10), range(300,500,10), r1, [s1],colors='b')
plt.contour(range(50,200,10), range(300,500,10), r2, [s2],colors='r')
# scatter plot the two normal distributions
plt.scatter(x1[:,0],x1[:,1],alpha=0.3)
plt.scatter(x2[:,0],x2[:,1],c='r',alpha=0.3)
Je suppose que ce que vous recherchez, c'est de calculer les régions de confiance .
Je ne sais pas trop quoi faire, mais comme point de départ, je vérifierais l’application sherpa pour python. Au moins, dans leur exposé sur Scipy 2011, les auteurs mentionnent que vous pouvez déterminer et obtenir des régions de confiance avec ce dernier (vous devrez peut-être toutefois disposer d'un modèle pour vos données).
Voir la vidéo et diapositives correspondantes du Sherpa.
HTH