Compression des données à virgule flottante

26

Existe-t-il des outils spécialement conçus pour compresser les données scientifiques en virgule flottante?

Si une fonction est lisse, il y a évidemment beaucoup de corrélation entre les nombres représentant cette fonction, donc les données doivent bien se compresser. Zipper / gzipper des données binaires en virgule flottante ne les comprime pas si bien cependant. Je me demande s'il existe une méthode spécifiquement développée pour compresser les données à virgule flottante.

Exigences:

  • Soit une compression sans perte ou la possibilité de spécifier un nombre minimum de chiffres à conserver (pour certaines applications, cela doublepeut être plus que ce dont nous avons besoin alors floatque la précision peut ne pas être suffisante).

  • Outil de travail bien testé (c'est-à-dire pas seulement un article décrivant une méthode théorique).

  • Convient pour compresser des données numériques 1D (comme une série chronologique)

  • Multiplateforme (doit fonctionner sous Windows)

  • Il doit être rapide - de préférence pas beaucoup plus lent que gzip. J'ai constaté que si j'ai les numéros stockés en ASCII, le compresser le fichier peut accélérer la lecture et le traitement (car l'opération peut être liée aux E / S).

J'aimerais particulièrement entendre des gens qui ont effectivement utilisé un tel outil.

Szabolcs
la source
Cela a été en partie inspiré par l'existence de FLAC , ce qui suggère qu'une méthode spécialisée devrait faire (beaucoup?) Mieux que gzip.
Szabolcs
Je regarde ça maintenant.
Szabolcs
Soigné. Je vais donner un tourbillon à celui-ci.
meawoppl

Réponses:

22

Essayez Blosc . Dans de nombreux cas, il est plus rapide que memcopy . Réfléchissez y un peu. . . méchant.

Il est super stable, hautement contrôlé, multiplateforme et fonctionne comme un champion.

meawoppl
la source
oh wow, c'est vraiment cool (et nouveau pour moi!)
Aron Ahmadia
Le lien est rompu. Avez-vous une chance de savoir où il se trouve maintenant?
Alexis Wilke
1
@AlexisWilke J'ai corrigé le lien. C'était le premier résultat d'une recherche google pour Blosc.
Doug Lipinski
1
Blosc est peut-être rapide mais son taux de compression sur les tableaux flottants est un désastre. Avec la meilleure compression qu'il offre, il en résulte environ 98% de la taille d'origine. Merci pour l'astuce en tout cas.
La compression sur les tableaux flottants dépend fortement du contenu. Je soupçonne qu'il y a peu d'informations (structurées) dans les bits que vous compressez. De plus, blosc est toujours en développement actif 5 ans plus tard!
meawoppl
7

J'ai obtenu de bons résultats en utilisant HDF5 et son filtre GZIP.

Le HDF5 fournit également un filtre SZIP qui permet d'obtenir de meilleurs résultats pour certains ensembles de données scientifica.

D'après mon expérience, le choix des compressions dépend fortement du type de données et l'analyse comparative est probablement le seul moyen de faire un bon choix.

BTW, les filtres tiers pour HDF5 incluent BLOSC, BZIP2, LZO, LZF, MAFISC.

f3lix
la source
Merci pour la réponse! Je n'ai pas beaucoup utilisé HDF5. Est-il exact que l'utilisation du filtre gzip avec le format HDF5 me donnera le même taux de compression que l'écriture de tout le nombre dans un fichier binaire plat et son exécution via gzip? (Ignorez la possibilité / l'inconvénient d'utiliser HDF5 pour le moment.) En ce qui concerne SZIP, est-il en quelque sorte optimisé pour les jeux de données à virgule flottante? (Je suis curieux et ce n'est pas clair en parcourant la page que vous avez liée.) La page dit que le principal avantage de SZIP est la vitesse. GZIP est également assez vif (généralement la décompression gzip prend négligeable pour moi).
Szabolcs
Un fichier binaire plat compressé sera probablement plus petit qu'un fichier HDF5 avec filtre gzip, car HDF5 est plus que des données brutes. Parfois, le prétraitement avec un filtre aléatoire peut améliorer les résultats gzip. Mais vous avez raison, les avantages sont en effet plus plutôt pratiques. Avec HDF5, je trouve facile de changer le filtre de compression (essayez différents réglages) et HDF5 fournit une fonction pour accéder à des sous-ensembles de vos données (intervalles dans les séries temporelles).
f3lix
1
Si vous suivez cette route, consultez pyTables . Cela ne fait que quelques lignes de code ci-dessus. Maintenu (au moins auparavant) par l'auteur Blosc.
meawoppl
6

[-1,1]

Selon la fonction sous-jacente, vous pourrez peut-être ajuster les données à une forme fonctionnelle sans erreur, nécessitant moins de coefficients pour décrire la forme fonctionnelle que vous n'en avez de point de données (conduisant à la compression). Des résultats d'erreur existent pour certaines de ces méthodes, même si je ne sais pas si l'une d'elles vous donnera des limites ou des estimations a priori (ou a posteriori ) de l'erreur.

Vous pouvez également consulter des méthodes développées spécifiquement pour la compression de nombres à virgule flottante, comme le FPC et les algorithmes associés. Voir les articles ici , ici , ici , ici et ici , ainsi qu'une page Web contenant l'ancien code source ici .

Geoff Oxberry
la source
En fait, je suis intéressé par des outils prêts à l'emploi similaires à gzip qui ne nécessitent aucun travail de ma part, surtout pas le développement et le réglage de ma propre méthode. De plus, il serait avantageux d'avoir une méthode qui ne nécessite pas de lire le tout en mémoire avant de le décompresser car je pourrais avoir de très gros fichiers de données qui peuvent être traités séquentiellement (cela fonctionne avec gzip, mais pas si j'utilise un Fourier transformer, à moins que je ne tranche moi-même les données en morceaux, ce qui complique encore plus le tout) Quelque chose qui suppose que mon fichier de données n'est qu'une série de doubles binaires serait excellent.
Szabolcs
Ce sont aussi des transformations 1: 1 pas vraiment des techniques de compression. Ils peuvent être utilisés pour créer des données avec lesquelles un algorithme de compression naïf peut faire mieux, mais ce n'est pas une solution autonome.
meawoppl
Certaines de ces méthodes constituent la base mathématique des algorithmes de compression utilisés dans le traitement du signal, ce qui était l'idée derrière la réponse. Ces transformations ne sont généralement pas 1: 1, sauf dans des circonstances spéciales.
Geoff Oxberry
3

HDF5 peut utiliser un algorithme de "réarrangement" où les octets pour N nombres à virgule flottante sont réorganisés de sorte que les premiers octets des N nombres viennent en premier, puis le 2e, et ainsi de suite. Cela produit de meilleurs taux de compression après l'application de gzip, car il est plus susceptible de produire des séquences plus longues de la même valeur. Voir ici pour quelques repères .

xioxox
la source
1

SZ (développé par Argonne en 2016) pourrait être un bon choix.

SZ: Compresseur de données à virgule flottante délimité par des erreurs rapides pour les applications scientifiques https://collab.cels.anl.gov/display/ESR/SZ

Linda
la source
Pourquoi pensez-vous que cela pourrait être un bon choix? Quelles sont ses capacités par rapport à d'autres techniques de compression?
Paul
1

Méthodes possibles pouvant être utilisées pour la compression à virgule flottante:

  • Transposer 4xN pour float et 8xN pour double + lz77
    Implémentation: Compression à virgule flottante dans TurboTranspose
    voir aussi compression avec perte avec limites d'erreur

  • Predictor (ex. Finite Context Method) + encodage (ex. "Compression entière").
    Implémentation: Compression à virgule flottante dans TurboPFor
    incluant une compression spéciale pour les séries chronologiques.

  • lorsque cela est possible, convertissez tous les nombres à virgule flottante en entiers (ex. 1,63 -> 163), puis utilisez la compression entière

  • Vous pouvez tester toutes ces méthodes avec vos données à l'aide de l' outil icapp pour Linux et Windows.

powturbo
la source
1

Nous utilisons ZFP avec HDF5 pour nos données d'imagerie médicale. Il est conçu pour une compression à virgule flottante avec perte.

Nous l'exécutons littéralement sur tout et avons plus de 40 To de données stockées (et utilisées!). Il est assez rapide pour sauvegarder nos données en temps réel, et nous pouvons spécifier la précision requise, donc bien que le format soit avec perte, nous ne voyons aucune différence dans nos sorties finales.

LKlevin
la source
0

Si une fonction est lisse, il y a évidemment beaucoup de corrélation entre les nombres représentant cette fonction, donc les données doivent bien se compresser.

Peut-être que le format dont vous avez besoin doit stocker uniquement les décalages de la valeur à la valeur voisine.

Alternativement, vous pouvez peut-être utiliser le domaine fréquentiel, peut-être même enregistrer ces valeurs sous forme de fichier audio sans perte tel que "flac lossless", car vous avez besoin des mêmes propriétés pour un son.

Cependant, je vais adopter une approche différente pour tenter de répondre à la question qui, je l'espère, pourra être utile. Comme vous le dites également, la longueur minimale de description pour représenter ces données est inférieure à la fourniture de tous les points de données.

https://en.wikipedia.org/wiki/Minimum_description_length

En fait, un programme, le code informatique, est un bon exemple. Et si cela ne vous dérange pas que quelque chose soit principalement des données fonctionnant en exécutant, et donc aussi du code, vous pouvez compresser vos valeurs à virgule flottante en quelque chose comme une fonction ou des formules.

Faire cela particulièrement bien automatiquement et dans une quantité réaliste de calcul est au-delà de la difficulté. Cependant, Wolfram Language fournit certaines fonctionnalités pour tenter cela:

https://reference.wolfram.com/language/ref/FindSequenceFunction.html https://reference.wolfram.com/language/ref/FindGeneratingFunction.html https://reference.wolfram.com/language/ref/FindFormula. html

https://reference.wolfram.com/language/ref/RSolve.html

alan2here
la source
0

Pourquoi ne pas simplement enregistrer float32 / float16? En numpy,

A.astype( np.float32 )  # 100M: 200 msec imac
A.astype( np.float16 )  # 100M: 700 msec

Cela ne fonctionnera pas si vous simulez l' effet papillon dans la théorie du chaos, mais ils sont compréhensibles, portables, "ne nécessitent aucun travail de ma part". Et la compression 2: 1/4: 1 sur float64 est difficile à battre :)

Remarques:

"Le type de tableau float16 n'est pas pris en charge dans np.linalg"; vous devrez l'étendre à 32 ou 64 après l'avoir lu.

Pour voir comment les paramètres à virgule flottante diffèrent,

import numpy as np
for f in [np.float64, np.float32, np.float16]:
    print np.finfo(f)

Pour un tracé d'un cas de test trivial comparant les flottants 64 32 et 16, voir ici .

denis
la source