Existe-t-il un algorithme permettant d'estimer la médiane, le mode, l'asymétrie et/ou l'aplatissement d'un ensemble de valeurs, mais qui ne nécessite PAS de stocker toutes les valeurs en mémoire en même temps ?
J'aimerais calculer les statistiques de base :
- moyenne : moyenne arithmétique
- variance : moyenne des écarts au carré par rapport à la moyenne.
- écart-type : racine carrée de la variance
- médiane : valeur qui sépare la moitié la plus grande des nombres de la moitié la plus petite.
- mode : valeur la plus fréquente trouvée dans l'ensemble
- asymétrie : tl ; dr
- aplatissement : tl ; dr
Les formules de base pour calculer n'importe lequel de ces éléments relèvent de l'arithmétique de l'école primaire, et je les connais. Il existe de nombreuses bibliothèques de statistiques qui les mettent en œuvre, également.
Mon problème est le grand nombre (des milliards) de valeurs dans les ensembles que je manipule : En travaillant en Python, je ne peux pas simplement créer une liste ou un hachage avec des milliards d'éléments. Même si je l'avais écrit en C, les tableaux de milliards d'éléments ne sont pas très pratiques.
Les données ne sont pas triées. Elles sont produites aléatoirement, à la volée, par d'autres processus. La taille de chaque ensemble est très variable, et les tailles ne sont pas connues à l'avance.
J'ai déjà trouvé comment gérer la moyenne et la variance assez bien, en itérant à travers chaque valeur de l'ensemble dans n'importe quel ordre. (En fait, dans mon cas, je les prends dans l'ordre dans lequel elles sont générées.) Voici l'algorithme que j'utilise, avec courtoisie http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm :
- Initialiser trois variables : le nombre, la somme et la somme des carrés.
- Pour chaque valeur :
- Comptage des incréments.
- Ajoutez la valeur à la somme.
- Ajoutez le carré de la valeur à sum_of_squares.
- Diviser la somme par le nombre, en stockant comme variable la moyenne.
- Diviser la somme des carrés par le nombre, en stockant comme variable la moyenne des carrés.
- Moyenne carrée, stockée comme square_of_mean.
- Soustraire la moyenne_carrée de la moyenne_des_carrés, en la stockant comme variance.
- Moyenne et variance de la sortie.
Cet algorithme "en ligne" présente des faiblesses (par exemple, des problèmes de précision lorsque la somme des carrés dépasse rapidement la plage des entiers ou la précision des flottants), mais il me donne essentiellement ce dont j'ai besoin, sans avoir à stocker chaque valeur de chaque ensemble.
Mais je ne sais pas si des techniques similaires existent pour estimer les statistiques supplémentaires (médiane, mode, asymétrie, aplatissement). Je pourrais m'accommoder d'un estimateur biaisé, ou même d'une méthode qui compromet la précision dans une certaine mesure, tant que la mémoire requise pour traiter N valeurs est sensiblement inférieure à O(N).
Il serait également utile de m'indiquer une bibliothèque de statistiques existante, si celle-ci dispose de fonctions permettant de calculer une ou plusieurs de ces opérations "en ligne".
0 votes
Les données seront-elles transmises triées, et connaîtrez-vous à l'avance le nombre d'entrées ?
0 votes
Lien utile existant sur StackOverflow : stackoverflow.com/questions/895929/
0 votes
S'agit-il de données entières ou de données flottantes ? Avez-vous une valeur maximale ou minimale ?
0 votes
Dmckee : J'utilise en fait la méthode de Welford pour l'écart-type. Mais je ne vois rien dans ce lien concernant le mode, la médiane, l'aplatissement ou l'asymétrie... Est-ce que j'ai manqué quelque chose ?
0 votes
Stephan : Certains ensembles de données sont des entiers, d'autres des flottants. La distribution de la population est assez proche de la normale (gaussienne), nous pouvons donc établir un intervalle de confiance, mais il n'y a pas de limite stricte (sauf x > 0, dans certains cas).
0 votes
@Ryan B. Lynch : Ah. Votre texte décrit l'algorithme naïf de variance à une passe, donc j'ai supposé que vous ne connaissiez pas l'approche de Welform. Et je ne peux pas vous aider sur les autres, non plus. Désolé.
0 votes
On les appelle des algorithmes de streaming, BTW. [ scholar.google.com/scholar?&q=streaming+algorithme Certains sont faciles, d'autres peuvent être approchés à un epsilon près (avec une forte probabilité), et d'autres encore sont difficiles à approcher.
0 votes
Puisque la moyenne, la std, le kurtosis et l'asymétrie ne sont que des moments, je pense que vous pouvez les calculer de la même manière. Quelques questions : Connaissez-vous suffisamment bien votre ensemble de données ? Pensez-vous que les statistiques vont varier dans le temps ? Si oui, et si vous souhaitez capturer cet aspect des données, le problème est beaucoup plus difficile. Si ce n'est pas le cas, je pense qu'il est possible de prendre un échantillon quelconque. (testez-le d'abord plusieurs fois)
0 votes
Une implémentation C++ par stackoverflow.com/users/25188/john-d-cook "Calcul des percentiles dans les applications à mémoire limitée", codeproject.com/KB/recipes/TailKeeper.aspx Voir aussi stackoverflow.com/questions/638030/
0 votes
En ce qui concerne votre demande de bibliothèques, j'ai un paquet Julia pour résoudre exactement ce genre de problèmes : github.com/joshday/OnlineStats.jl OnlineStats implémente des algorithmes en ligne pour la moyenne, la variance, l'asymétrie et l'aplatissement, les histogrammes (à partir desquels les quantiles peuvent être estimés), et plusieurs algorithmes d'approximation pour les quantiles.