論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
データ圧縮
Data Compression
データエンジニアリング

🔖 キーワード索引

可逆圧縮非可逆圧縮HuffmanZIPgzipJPEGPNGParquetSnappy圧縮率

別名・略称:(なし)

💡 30秒で分かる結論

データ圧縮(Data Compression):ストレージ・通信量を減らす変換

📍 あなたが今見ているもの

大量のデータを扱うとき、 圧縮は避けて通れない要素技術。 SSDSE データのような数 MB の CSV なら無圧縮で良いですが、 数 GB を超える DWH のテーブルや log データは圧縮しないと ストレージ費・転送費・読み込み時間 が膨大になります。 Pandas で read_csv()read_parquet() を使う時、 知らないうちに圧縮が動いています。

🎨 直感で掴む

圧縮形式の選び方

形式圧縮率速度用途
gzip汎用、 CSV/JSON
bzip2非常に高アーカイブ
LZ4非常に速リアルタイム処理
SnappyParquet標準
Zstd汎用、 推奨

📐 定義 / 数式

【圧縮率】
$$\text{圧縮率} = \frac{\text{圧縮後サイズ}}{\text{元のサイズ}}$$
小さいほど圧縮が効いている(例: 0.3 なら 70% 削減)
【シャノンのエントロピー】
$$H(X) = -\sum_{i} p_i \log_2 p_i \quad \text{(bit / symbol)}$$
圧縮の理論的下限。 これより小さくはできない。

🔬 記号・式を言葉で読み解く

可逆圧縮
完全に元に戻せる。 テキスト・プログラム・数値データ用。
非可逆圧縮
完全には戻せないが、 知覚的に問題ない範囲で大幅圧縮。 画像/音声/動画用。
Huffman 符号
出現頻度の高い記号に短い符号を割り当てる古典手法。
辞書式(LZ77/LZ78)
繰り返しパターンを「ここまで戻って何文字コピー」と表現。 gzip 内部で使用。
カラムナ形式
Parquet/ORC。 列毎にデータ型と分布が一様 → 圧縮率が良い。

🧮 実データで計算してみる

SSDSE-B-2026.csv(約 100 KB)を各形式で保存:

形式サイズ圧縮率
CSV(無圧縮)100 KB1.00
CSV.gz25 KB0.25
Parquet+Snappy18 KB0.18
Parquet+Zstd12 KB0.12

🐍 Python 実装

SSDSE-B-2026(47 都道府県・2023 年データ)を題材にした最小コード:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)

# gzip 圧縮で保存
df.to_csv('data/processed/ssdse.csv.gz', index=False, compression='gzip')

# Parquet(Snappy 圧縮、 デフォルト)
df.to_parquet('data/processed/ssdse.parquet', index=False)

# Parquet + Zstd(より高圧縮)
df.to_parquet('data/processed/ssdse_zstd.parquet', compression='zstd')

⚠️ よくある落とし穴

⚠️ 圧縮形式の互換性
Parquet+Snappy は環境によって読めない。 → Pandas+pyarrow が標準。
⚠️ 複数回圧縮しても効かない
圧縮済みファイルを再圧縮しても、 ほぼ縮まない。
⚠️ CPU と I/O のトレードオフ
高圧縮は CPU を食う。 ストリーミングなら LZ4/Snappy が良い。
⚠️ 非可逆圧縮の繰り返し
JPEG を編集→保存を繰り返すと劣化が累積。
⚠️ 暗号化との順序
「暗号化 → 圧縮」は意味なし。 「圧縮 → 暗号化」の順で。

🌐 関連手法・この用語を使う論文

📄 大規模データを扱う論文
ビッグデータ系の論文では Parquet 形式での読み込みが頻出します。

🔖 詳細キーワード索引

アルゴリズム 列指向 Python深掘り 落とし穴 情報理論 事例 歴史 FAQ

🎨 直感で掴む(深掘り)

圧縮を一言で言えば「パターンを見つけて短く書く」。 「AAAAA」と書く代わりに「A×5」と書けば短くなる、 という発想です。

日本語にも例えれば「あいうえおあいうえおあいうえお」を「[あいうえお]×3」と表現できる。 アルゴリズムごとに「どんなパターンを探すか」が異なります:

📍 文脈 ── データ基盤の中で

データ圧縮は データレイク 設計、 分散処理、 ネットワーク転送、 メモリ効率の全てで効いてくる横断的技術。 「CPU を使ってでも、 ディスク IO / ネットワークを減らす」のが現代的トレードオフ。

分析パイプライン上では、 収集 直後の Bronze 層から最初に適用し、 Silver/Gold まで一貫させます。 列指向+圧縮で 10〜30 倍縮むのが普通で、 ストレージ費・クエリ費の双方を削減します。

🌐 関連手法・派生

⚡ パフォーマンスのトレードオフ

圧縮レベルを上げると 圧縮率は向上するが、 CPU 時間が増加します。 全体スループットは IO ボトルネックの解消量とのバランス:

$$ T_{\text{総}} = T_{\text{圧縮}} + T_{\text{IO}} + T_{\text{解凍}} $$

$T_{\text{IO}}$ が支配的(ネットワーク・HDD 書き込み)なら圧縮で総時間短縮。 メモリ内処理が中心なら圧縮はオーバーヘッドになる場合も。

SSD:3GB/s → snappy/lz4 で十分(CPU が追いつく)
HDD/Network:100MB/s 程度 → zstd レベル 3〜6 で IO 短縮効果が CPU コストを上回る

💡 結論(補足)

データ圧縮はデータ基盤の費用・性能を左右する鍵。 「列指向+現代的可逆圧縮」が分析用途の標準。 一次的なシナリオごとに、 圧縮速度・解凍速度・圧縮率のトレードオフを意識すれば、 大半の問題は解決します。

📡 通信プロトコルにおける圧縮

ネットワーク経由のデータ転送でも圧縮は必須。 主要なケース:

プロトコル 圧縮方式 用途
HTTPgzip, brotli, zstdWeb ページ転送
gRPCgzip, snappyマイクロサービス通信
Kafkasnappy, lz4, zstdストリーミング
MQTTアプリ層で gzipIoT センサー
SSHzlibリモート操作

🔬 専門用語の解説

エントロピー $H(X)$
情報量。 圧縮できる理論的下限。 単位は bit/symbol。
符号長 $L$
圧縮後の平均ビット数。 $L \geq H(X)$ がShannon の限界。
圧縮率
元サイズ / 圧縮後サイズ。 「2 倍圧縮」=半分の大きさ。
RLE
Run-Length Encoding。 同じ値の連続を「値×回数」で表現。
辞書符号化
頻出パターンを辞書 ID に置換。 「東京都」→ ID=12 等。
列指向
同じ列の値を連続配置して保存。 圧縮効率と分析効率に有利。
可逆/不可逆
元データを完全復元できるか否か。 分析用は可逆。
スキーマ
列名・型・制約の定義。 Parquet / Avro は内部に保持。

🎯 圧縮の設計指針(決定木)

  1. 用途は? ── 分析(読み多)/アーカイブ(保存多)/転送(速度重視)
  2. 分析なら ── 列指向必須(Parquet/ORC)、 圧縮は snappy or zstd(速)
  3. アーカイブなら ── 圧縮率重視、 xz / brotli / zstd level 19 等
  4. 転送なら ── lz4 / snappy(CPU負荷小)、 ネットワーク 1 GbE 未満なら zstd
  5. 更新が多いなら ── 列指向は不向き、 行指向(Avro)も検討
  6. SQL/BI で頻繁にクエリ ── Parquet+パーティション+snappy が王道
  7. ストリーミング ── 行指向 Avro+snappy がKafka 連携で便利

📊 圧縮ベンチマーク参考値

SSDSE-B 程度の表形式データを各方式で圧縮した場合の代表的な数値(実測値は環境依存):

形式 サイズ(CSV比) 読み速度 書き速度
CSV(基準)100%1.0×1.0×
CSV.gz25%0.8×0.3×
Parquet (snappy)15%
Parquet (zstd)10%
ORC (zstd)9%
Feather/Arrow35%10×10×

🛠 主要な圧縮アルゴリズム

圧縮は 可逆(lossless)不可逆(lossy) に大別されます。 データサイエンスでは可逆が基本:

アルゴリズム タイプ 圧縮率 速度 向く用途
gzip (DEFLATE)可逆汎用、Web
bzip2 (BWT)可逆アーカイブ
xz (LZMA2)可逆極高長期アーカイブ
zstd (Zstandard)可逆現代の汎用最強
snappy可逆極速Parquet, Spark
lz4可逆極速リアルタイム
brotli可逆Web(HTTP)
JPEG不可逆高(10〜100倍)写真
H.264/H.265不可逆極高動画

2025 年現在、 大量データのデフォルトは Parquet + zstd または Parquet + snappy。 zstd は近年急速にシェア拡大。

📊 列指向ストレージと圧縮の相乗効果

分析データは 列指向(columnar) 形式で保存すると圧縮率が劇的に向上します。 同じ列に並ぶ値は型と分布が似ているため、 アルゴリズムが効きやすくなるからです。

$$ \text{圧縮率} = \frac{\text{元サイズ}}{\text{圧縮後サイズ}} $$

技法 原理 効果
RLE (Run-Length)同値の連続を回数で表現繰り返し多い列で 100 倍
辞書符号化値を ID に置換カテゴリ列で 5〜20 倍
ビットパッキング最小ビット幅に圧縮整数列で 2〜4 倍
差分符号化 (Delta)隣接値との差を保存時系列で大幅縮小
FOR (Frame of Reference)基準値からのオフセット範囲狭い数値で効く
汎用圧縮(zstd等)を後段エンコード済み列をさらに圧縮最終的に 10〜30 倍

🐍 Python 実装(パフォーマンス比較)

(1) 各圧縮方式の比較

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import pandas as pd
import os, time

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)

for comp in ['snappy', 'gzip', 'brotli', 'zstd', 'lz4']:
    t = time.time()
    df.to_parquet(f'/tmp/test_{comp}.parquet', compression=comp)
    sz = os.path.getsize(f'/tmp/test_{comp}.parquet')
    print(f'{comp}: {sz/1024:.1f} KB, {time.time()-t:.2f}s')

(2) DataFrame の dtype 最適化で圧縮率を上げる

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import numpy as np

# int64 を int32 へ
df['人口総数'] = df['人口総数'].astype('int32')

# object → category
df['都道府県'] = df['都道府県'].astype('category')

# float64 を float32 へ(精度が許せば)
df['高齢化率'] = df['高齢化率'].astype('float32')

print('メモリ使用量:', df.memory_usage(deep=True).sum() / 1024, 'KB')

(3) ストリーミング圧縮(巨大ファイルでメモリ節約)

1
2
3
4
5
6
7
8
9
import gzip, shutil

# 大きな CSV を gzip 圧縮
with open('large.csv', 'rb') as f_in:
    with gzip.open('large.csv.gz', 'wb', compresslevel=6) as f_out:
        shutil.copyfileobj(f_in, f_out)

# pandas で直接読める
df = pd.read_csv('large.csv.gz', encoding='utf-8')

⚠️ 落とし穴(さらに)

❌ 1. 不可逆圧縮の誤用
数値データに JPEG を当てれば情報が失われる。 分析用途は必ず可逆
❌ 2. 過度な圧縮でクエリ遅延
xz レベル 9 は圧縮率高いが解凍が遅い。 「読む頻度=高」なら snappy / zstd 程度に。
❌ 3. 圧縮済データの再圧縮
既に圧縮された画像/動画/Parquet を tar.gz するのは時間の無駄。 圧縮できない。
❌ 4. dtype を最適化しない
int64 のままだと圧縮効率も悪い。 int32/16/8 で十分な列が多い。 categorical を活用。
❌ 5. 圧縮形式のバージョン非互換
古い zstd で圧縮、新版でしか読めない、 等の問題。 標準的なライブラリと互換テスト。

📐 情報理論的限界(Shannon エントロピー)

どんなに優れた可逆圧縮でも、 Shannon エントロピー以下にはできません。 確率分布 $p(x)$ を持つ情報源の理論的下限:

$$ H(X) = -\sum_i p_i \log_2 p_i \quad [\text{bits/symbol}] $$

例:8 ビット文字でも、 ASCII 英文の実効エントロピーは約 4.7 bit/char。 つまり理論上 1.7 倍圧縮できる。 実際の gzip でも 2〜3 倍程度に収まります。

乱数や既に圧縮されたデータはエントロピーが高く、 さらなる圧縮はほぼ不可能。 「圧縮できる」=「データに冗長性がある」ということです。

📖 事例:センサーデータの圧縮戦略

工場で 1 kHz の振動センサーが 100 台稼働する場合、 1 日 8.64 億行。 CSV のままなら 30 GB/日、 月 1 TB。

📜 歴史

❓ よくある質問

Q1. 結局どの圧縮方式が最適?

「分析データ+頻繁にクエリ」なら Parquet + snappy。「アーカイブ用」なら Parquet + zstd(level 9) または xz。 ストリーミング系は lz4

Q2. CSV.gz vs Parquet、どちらが良い?

分析用途なら Parquet 一択。 列単位スキャン、 述語プッシュダウン、 統計情報、 全て備えていて、 多くは 5 倍以上速い。

Q3. 暗号化と併用するときの順序は?

圧縮 → 暗号化」の順。 暗号化済データはエントロピーが高く圧縮できない。 ただし圧縮による情報漏洩攻撃(CRIME, BREACH 等)に注意。

Q4. dtype 最適化はどこまで効果ある?

SSDSE のような中小データでメモリが半分以下、 ストレージも 30% 減程度。 数百万行を超えると違いが顕著。 categorical 化は特に効果が大きい。

Q5. 1 ファイル何 MB が理想?

分析向け Parquet では 100 MB〜1 GB が目安。 小さすぎるとメタデータ操作が重く、 大きすぎると並列度が落ちる。