python - comment calculer la corrélation de la matrice avec nans données de la matrice
Je coundn pas trouver une fonction qui calcule une matrice de coefficients de corrélation pour les tableaux contenant les observations de plus de deux variables lorsqu'il y a NaNs les données. Il y a des fonctions de le faire pour les paires de variables (ou juste le masquage des tableaux à l'aide de ~est.nan()). Mais l'utilisation de ces fonctions en boucle sur un grand nombre de variables, le calcul de la corrélation pour chaque paire peut être très coûteuse en temps.
J'ai donc essayé sur mon propre et vite rendu compte que la complexité de la faire, c'est une question de bon normalisation de la Covariance. Je serais très intérêt dans votre opinions sur la façon de le faire.
Voici le code:
def nancorr(X,nanfact=False):
X = X - np.nanmean(X,axis=1,keepdims = True)*np.ones((1,X.shape[1]))
if nanfact:
mask = np.isnan(X).astype(int)
fact = X.shape[1] - np.dot(mask,mask.T) - 1
X[np.isnan(X)] = 0
if nanfact:
cov = np.dot(X,X.T)/fact
else:
cov = np.dot(X,X.T)
d = np.diag(cov)
return cov/np.sqrt(np.multiply.outer(d,d))
La fonction suppose que chaque ligne est une variable. Il s'agit essentiellement d'une adaptation de code à partir de numpy est corrcoeff().
Je crois qu'il y a trois façons de le faire:
(1) Pour chaque paire de variables, vous prenez uniquement les observations pour lesquelles ni l'un ni l'autre variable est NaN. C'est sans doute le plus précis, mais aussi plus difficile à programmer, si vous voulez faire le calcul pour de plus d'une paire simultanément et ne sont pas couverts dans le code ci-dessus. Pourquoi, d'ailleurs, de jeter de l'information sur la moyenne et la variance de chaque variable, juste parce que l'entrée correspondante de l'autre variable est NaN? Par conséquent, les deux autres options.
(2) Nous rabaisser chaque variable, il nanmean et de la variance de chaque variable est son nanvariance. Pour la covariance, chaque observation où l'une ou l'autre variable est NaN, mais pas les deux, est un constat de non-covariation et, par conséquent, la valeur zéro. Le facteur de la covariance est alors 1/(# d'observation où les deux variables sont de NaN - 1), dénoté par n. Les deux écarts dans le dénominateur du coefficient de corrélation sont pondérées par leur nombre correspondant de non-NaN observations moins 1, notée par n1 et n2 respectivement. Ceci est réalisé par la mise en nanfact=True dans la fonction ci-dessus.
(3) On peut souhaiter que la covariance et les écarts ont le même facteur, comme c'est le cas pour le coefficient de corrélation sans NaNs. La seule façon de le faire ici (si l'option (1) n'est pas réalisable), est tout simplement de l'ignorer (1/n)/sqrt(1/n1*n2). Puisque ce nombre est inférieur à un, l'estimation des coefficients de corrélation sera plus grande (en valeur absolue) que dans (2), mais restera entre -1,1. Ceci est réalisé par la mise en nanfact=False.
Je serais très intéressé par vos avis sur les approches (2) et (3) et surtout, j'aimerais beaucoup voir une solution de (1) sans l'utilisation de boucles.
OriginalL'auteur user3820991 | 2014-11-24
Vous devez vous connecter pour publier un commentaire.
Je pense que la méthode que vous cherchez est
corr()
de pandas. Par exemple, un dataframe de la manière suivante. Vous pouvez aussi vous référer à cette question. La façon la plus efficace d'obtenir la matrice de corrélation (valeurs p) d'un bloc de données avec des valeurs NaN?Nan
dans les deux colonnes respectives - même pour le calcul de la moyenne et les écarts. Un problème supplémentaire que je n'ai pas soulevé ci-dessus, c'est que je ne suis pas sûr que cela assure une semi-définie positive Cov. Btw, vous semblez avoir donné la mauvaise corr-matrice à votre exemple dataframe. E. g. le C,D entrée doit lire -0.347928.Correction de la corr-matrice des résultats.
panda.corr est sacrément lent pour des tableaux avec des nans. C'est fondamentalement une main écrit en python la boucle.
OriginalL'auteur ju.