11
votes

Trouver la matrice de corrélation

J'ai une matrice relativement grande (environ 50 000 rangées), et je veux imprimer le coefficient de corrélation entre chaque ligne de la matrice. J'ai écrit du code Python comme celui-ci: xxx

Veuillez noter que je fais une utilisation de la fonction PearsonR disponible à partir du module SCIPY ( http://docs.scipy.org/doc/scipy/reference/generated/scipy. statists.pearsonr.html ).

Ma question est la suivante: Y a-t-il un moyen plus rapide de le faire? Existe-t-il une technique de la partition matricielle que je peux utiliser?

Merci!


0 commentaires

3 Réponses :


0
votes

Vous pouvez utiliser le module Python MultiProcess, en morceaux de vos lignes dans 10 jeux, tampon de vos résultats, puis imprimez le matériel (cela ne ferait que accélérer sur une machine multicœur)

http://docs.python.org/library/multiprorocessing.html

BTW: Vous devrez également transformer votre extrait dans une fonction et vous devez également déterminer comment faire le réassemblage des données. Avoir chaque sous-processus a une liste comme celle-ci ... [startcord, stopcord, buff] .. Peut fonctionner bien xxx


2 commentaires

J'aimerais voir un exemple plus complet de ce que vous voulez dire ici.


Je pense que ma réponse est très éloignée de cette question à ce stade, mais si vous êtes intéressé par MultiProcessiong, consultez: docs.python.org/library/multiprorocessing.html ... essentiellement au lieu de boucler à travers des lignes, vous créez une fonction et une piscine de fil et juste p.map (myfunc, xrange (rangées))



10
votes

nouvelle solution forte>

Après avoir regardé la réponse de Joe Kington, j'ai décidé de regarder le code corcoef () code> et m'a été inspiré pour effectuer la mise en œuvre suivante. P>

r = np.zeros((rows,rows))
ms = data.mean(axis=1)

datam = np.zeros_like(data)
for i in xrange(rows):
    datam[i] = data[i] - ms[i]
datass = scipy.stats.ss(datam,axis=1)
for i in xrange(rows):
    for j in xrange(i,rows):
        r_num = np.add.reduce(datam[i]*datam[j])
        r_den = np.sqrt(datass[i]*datass[j])
        r[i,j] = min((r_num / r_den), 1.0)


0 commentaires

7
votes

Avez-vous essayé simplement d'utiliser Numpy.corCoef ? Voyant que vous n'utilisez pas les valeurs P, cela devrait faire exactement ce que vous voulez, avec aussi peu de devises que possible. (Sauf si je me souviens mal exactement ce que R est le R Pearson, ce qui est tout à fait possible.)

Vérification rapide des résultats sur des données aléatoires, il renvoie exactement la même chose que le code de @justin Peel ci-dessus et exécute environ 100 fois plus vite.

Par exemple, testez des éléments avec 1000 lignes et 10 colonnes de données aléatoires ...: xxx

donne une différence maximale absolue de ~ 3.3e- 16 entre les deux résultats

et les horaires: xxx

Numpy.corCoef doit faire exactement ce que vous voulez, et c'est beaucoup plus vite.


4 commentaires

Tu as plutot raison. Je pensais à corrcoef au début, mais une raison je me suis souvenu qu'il soit plus lent. Se sentant un peu penaud que je faisais confiance à ma mauvaise mémoire plutôt que de l'essayer. Il est plus rapide, car il utilise la matrice multiplications pour éliminer les boucles de python. +1 de moi.


Le problème avec Corcoef est que cela utilise environ deux fois plus de mémoire que nécessaire. Il calcula également presque tous les coefficients deux fois. Cependant, la question plus importante est la mémoire et l'OP devra rompre les données pour éviter les problèmes de mémoire. Cela deviendra essentiellement un gâchis en combinatoire.


@Justin Peel - True, Corcoef crée une copie temporaire supplémentaire de la matrice d'entrée. C'est un compromis entre la vitesse et la quantité de mémoire utilisée. Votre solution est bien meilleure si la mémoire est la principale contrainte et avec 50 000 rangées, elle sera susceptible d'être.


En fait, je pensais plus comment cela calcule réellement chaque coefficient deux fois et les stocke bien que vous avez raison de faire une copie temporaire supplémentaire de l'entrée. Je pense que cela (corcoef) peut être la meilleure façon de le faire, mais vous devrez diviser les données intelligemment et la remettre soigneusement remontées pour obtenir toutes les combinaisons.