Mengompresi data floating point

26

Apakah ada alat yang dirancang khusus untuk mengompresi data ilmiah floating point?

Jika suatu fungsi halus, jelas ada banyak korelasi antara angka-angka yang mewakili fungsi itu, sehingga data harus dikompres dengan baik. Zipping / gzipping data floating point biner tidak kompres dengan baik. Saya bertanya-tanya apakah ada metode yang khusus dikembangkan untuk mengompresi data floating point.

Persyaratan:

  • Baik kompresi lossless atau kemungkinan untuk menentukan jumlah digit minimum untuk dipertahankan (untuk beberapa aplikasi doublemungkin lebih dari apa yang kita butuhkan sementara floatmungkin tidak memiliki cukup presisi).

  • Alat kerja yang teruji dengan baik (yaitu bukan hanya kertas yang menggambarkan metode teoritis).

  • Cocok untuk mengompresi data numerik 1D (seperti deret waktu)

  • Cross platform (harus bekerja di Windows)

  • Itu harus cepat --- lebih disukai tidak lebih lambat dari gzip. Saya menemukan bahwa jika saya memiliki nomor yang disimpan sebagai ASCII, gzipping file dapat mempercepat membaca dan memprosesnya (karena operasi mungkin terikat I / O).

Saya terutama ingin mendengar dari orang-orang yang benar-benar menggunakan alat semacam itu.

Szabolcs
sumber
Ini sebagian terinspirasi oleh keberadaan FLAC , yang menunjukkan bahwa metode khusus harus melakukan (lebih?) Lebih baik daripada gzip.
Szabolcs
Saya melihat ini sekarang.
Szabolcs
Rapi. Saya akan memberikan yang ini berputar.
meawoppl

Jawaban:

22

Cobalah Blosc . Dalam banyak kasus, ini lebih cepat daripada memcopy . Pikirkan itu sebentar. . . jahat.

Ini sangat stabil, sangat diperiksa, lintas platform, dan melakukan seperti juara.

meawoppl
sumber
oh wow, ini sangat keren (dan baru bagi saya!)
Aron Ahmadia
Tautan rusak. Apakah ada kemungkinan Anda akan tahu di mana sekarang?
Alexis Wilke
1
@AlexisWilke saya memperbaiki tautannya. Itu adalah hasil pertama dalam pencarian google untuk Blosc.
Doug Lipinski
1
Blosc mungkin cepat tetapi tingkat kompresinya pada array float adalah bencana. Dengan kompresi terbaik ia menawarkan hasil sekitar 98% dari ukuran aslinya. Terima kasih atas tipnya.
Kompresi pada array float sangat bergantung pada konten. Saya menduga ada sedikit informasi (terstruktur) dalam bit yang Anda kompres. Juga, blosc masih di bawah dev aktif 5 tahun kemudian!
meawoppl
7

Saya mendapat hasil yang baik menggunakan HDF5 dan filter GZIP-nya.

HDF5 juga menyediakan filter SZIP yang mencapai hasil yang lebih baik untuk beberapa set data ilmiah.

Dalam pengalaman saya, pilihan kompresi sangat tergantung pada jenis data dan pembandingan mungkin satu-satunya cara untuk membuat pilihan yang baik.

BTW, filter pihak ketiga untuk HDF5 termasuk BLOSC, BZIP2, LZO, LZF, MAFISC.

f3lix
sumber
Terima kasih untuk jawabannya! Saya belum pernah menggunakan HDF5. Benarkah menggunakan filter gzip dengan format HDF5 akan memberi saya rasio kompresi yang sama dengan menulis semua angka ke dalam file biner datar dan menjalankannya melalui gzip? (Abaikan kemungkinan kenyamanan / ketidaknyamanan menggunakan HDF5 untuk saat ini.) Mengenai SZIP, apakah dengan cara tertentu dioptimalkan untuk dataset floating point? (Saya ingin tahu dan ini tidak jelas dari membaca halaman yang Anda tautkan.) Halaman tersebut mengatakan bahwa keunggulan utama SZIP adalah kecepatan. GZIP juga cukup tajam (biasanya dekompresi gzip tidak berarti bagi saya).
Szabolcs
File biner datar yang di-gzip mungkin akan lebih kecil daripada file HDF5 dengan filter gzip, karena HDF5 lebih dari sekadar data mentah. Terkadang preprocessing dengan shuffle filter dapat meningkatkan hasil gzip. Tapi Anda benar, kelebihannya memang lebih dari kenyamanan. Dengan HDF5 saya merasa mudah untuk mengubah filter kompresi (mencoba pengaturan yang berbeda) dan HDF5 menyediakan fungsi untuk mengakses subset data Anda (interval dalam deret waktu).
f3lix
1
Jika Anda pergi rute ini, periksa pyTables . Itu membuat hanya beberapa baris kode di atas. Dipertahankan (sebelumnya setidaknya) oleh penulis Blosc.
meawoppl
6

Dapat diperdebatkan, Anda dapat menafsirkan metode regresi atau transformasi (Transformasi Fourier, transformasi Chebyshev) sebagai "kompresi" untuk data fungsi time-series atau 1D. Algoritma Remez akan menjadi kandidat lain. Dalam hal itu, menggunakan sesuatu seperti regresi, FFT, atau Chebyshev via FFT akan berfungsi untuk tujuan Anda. Yang mengatakan, tidak ada metode ini bekerja pada data deret waktu dengan struktur sewenang - wenang . Misalnya, dengan FFT, Anda mengasumsikan periodisitas, dan segala jenis diskontinuitas dalam data (atau kurangnya periodisitas) akan mengarah pada fenomena Gibbs . Demikian pula, dengan transformasi Chebyshev, asumsinya adalah bahwa data menggambarkan fungsi pada .[1,1]

Bergantung pada fungsi yang mendasarinya, Anda mungkin dapat menyesuaikan data ke bentuk fungsional tanpa kesalahan, membutuhkan lebih sedikit koefisien untuk menggambarkan bentuk fungsional daripada yang Anda miliki titik data (mengarah ke kompresi). Hasil kesalahan ada untuk beberapa metode ini, meskipun saya tidak tahu apakah ada di antara mereka yang akan memberi Anda apriori (atau posteriori ) batas atau perkiraan kesalahan.

Anda juga bisa melihat metode yang dikembangkan secara khusus untuk kompresi angka floating point, seperti FPC dan algoritma terkait. Lihat makalah di sini , di sini , di sini , di sini , dan di sini , bersama dengan halaman web yang berisi kode sumber lama di sini .

Geoff Oxberry
sumber
Sebenarnya saya tertarik pada alat yang sudah jadi yang mirip dengan gzip yang tidak memerlukan pekerjaan pada bagian saya, terutama tidak mengembangkan dan menyetel metode saya sendiri. Juga, akan menguntungkan untuk memiliki metode yang tidak mengharuskan membaca semuanya ke dalam memori sebelum mendekompresnya karena saya mungkin memiliki file data yang sangat besar yang dapat diproses secara berurutan (ini bekerja dengan gzip, tetapi tidak jika saya menggunakan Fourier mengubah, kecuali saya mengiris data menjadi potongan sendiri, menyulitkan semuanya bahkan lebih) Sesuatu yang mengasumsikan bahwa datafile saya hanya serangkaian ganda biner akan sangat baik.
Szabolcs
Juga ini adalah transformasi 1: 1 bukan teknik kompresi yang sebenarnya. Mereka dapat digunakan untuk membuat data yang dapat dilakukan dengan lebih baik oleh algoritma kompresi naif, tetapi mandiri bukan solusi.
meawoppl
Beberapa metode ini membentuk dasar matematika untuk algoritma kompresi yang digunakan dalam pemrosesan sinyal, yang merupakan ide di balik jawabannya. Transformasi ini biasanya tidak 1: 1 kecuali dalam keadaan khusus.
Geoff Oxberry
3

HDF5 dapat menggunakan algoritma "pengocokan" di mana byte untuk angka floating point N diatur ulang sehingga byte pertama dari angka N datang terlebih dahulu, kemudian ke 2, dan seterusnya. Ini menghasilkan rasio kompresi yang lebih baik setelah gzip diterapkan, karena lebih cenderung menghasilkan urutan yang lebih lama dari nilai yang sama. Lihat di sini untuk beberapa tolok ukur .

xioxox
sumber
1

SZ (dikembangkan oleh Argonne pada 2016) bisa menjadi pilihan yang baik.

SZ: Kompresor Data Floating-point Terikat Kesalahan Cepat untuk Aplikasi Ilmiah https://collab.cels.anl.gov/display/ESR/SZ

Linda
sumber
Menurut Anda mengapa itu bisa menjadi pilihan yang baik? Apa kemampuannya dibandingkan dengan teknik kompresi lainnya?
Paul
1

Metode yang mungkin, yang dapat digunakan untuk kompresi floating-point:

  • Transpose 4xN untuk float dan 8xN untuk double + lz77
    Implementasi: Kompresi titik apung di TurboTranspose
    lihat juga kompresi lossy yang terikat kesalahan

  • Predictor (mis. Metode Konteks Hingga) + penyandian (mis. "Kompresi integer").
    Implementasi: Kompresi titik apung di TurboPFor
    termasuk kompresi khusus untuk deret waktu.

  • bila memungkinkan, konversi semua angka floating point ke bilangan bulat (mis. 1,63 -> 163), lalu gunakan kompresi bilangan bulat

  • Anda dapat menguji semua metode ini dengan data Anda menggunakan alat icapp untuk linux dan windows.

powturbo
sumber
1

Kami telah menggunakan ZFP dengan HDF5 untuk data pencitraan medis kami. Itu dibuat untuk kompresi lossy, floating point.

Kami menjalankannya di atas segalanya, dan menyimpan lebih dari 40TB data (dan sedang digunakan!) Cukup cepat untuk menyimpan data kami secara real-time, dan kami dapat menentukan presisi yang diperlukan, jadi sementara formatnya lossy, kami tidak melihat perbedaan dalam hasil akhir kami.

LKlevin
sumber
0

Jika suatu fungsi halus, jelas ada banyak korelasi antara angka-angka yang mewakili fungsi itu, sehingga data harus dikompres dengan baik.

Mungkin format yang Anda perlukan harus menyimpan hanya offset dari nilai ke nilai tetangga.

Sebagai alternatif, mungkin Anda dapat menggunakan domain frekuensi, bahkan mungkin menyimpan nilai-nilai ini sebagai file audio lossless seperti "flac lossless", karena Anda memerlukan beberapa properti yang sama untuk suara.

Namun, saya akan mengambil pendekatan berbeda untuk mencoba menjawab pertanyaan yang saya harap dapat membantu. Seperti yang Anda katakan juga bahwa panjang deskripsi minimum untuk mewakili data ini kurang dari semua poin data.

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

Secara efektif suatu program, kode komputer, adalah contoh yang baik. Dan jika Anda tidak keberatan bahwa sesuatu itu terutama data bekerja dengan mengeksekusi, dan juga menjadi kode, maka Anda bisa mengompresi nilai floating point Anda menjadi sesuatu seperti fungsi atau formuli.

Melakukan ini dengan sangat baik secara otomatis, dan dalam jumlah yang realistis, tidak sulit. Namun Bahasa Wolfram menyediakan beberapa fungsi untuk melakukan ini:

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

juga di sini
sumber
0

Mengapa tidak menyimpan saja float32 / float16? Di numpy,

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

Ini tidak akan dilakukan jika Anda mensimulasikan efek Kupu - kupu dalam teori chaos, tetapi dapat dimengerti, portabel, "tidak memerlukan pekerjaan apa pun di pihak saya". Dan kompresi 2: 1/4: 1 melebihi float64 sulit dikalahkan :)

Catatan:

"Tipe array float16 tidak didukung di np.linalg"; Anda harus mengembangkannya menjadi 32 atau 64 setelah membacanya.

Untuk melihat perbedaan parameter floating-point,

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

Untuk sebidang kasus uji sepele membandingkan float 64 32 dan 16, lihat di sini .

denis
sumber