各語の説明がある章へのリンク: データキューブと 5 操作(スライス・ダイス・ドリルダウン・ロールアップ・ピボット) | 集約関数と階層保持性 | ブロック別ピボットの手計算 | pandas の pivot_table と CUBE | 比率のロールアップ・次元の呪い | MOLAP・ROLAP・HOLAP とスター・スキーマ | 周辺手法との関係
🍰 まずはやさしく
データの切り口を自由に変える方法です。
答えを素早く見つけるために使います。
店で「いつ・どこで・何が」売れたか調べます。
集計のやり方や便利な道具について読みます。
OLAP/ピボットなど複数次元での集計分析
🍰 まずはやさしく
仕事で使われる分析の土台となる考え方です。
正しい判断をすぐに下すために使います。
都道府県ごとのデータを分析する時に役立ちます。
定義から注意点までを順番に読みます。
ビジネスダッシュボード、 経営会議の資料、 マーケティングレポート — 多次元分析は経営判断のインフラ。 アドホックな質問にすぐ答えられる点で重要。
🍰 まずはやさしく
データを立方体(サイコロ)のように扱う方法です。
多方面からデータを観察するために使います。
年や地域、商品の種類を軸にして考えます。
データを切り出す5つの操作について読みます。
多次元分析の核心は「3 次元以上のデータを、 立方体 (キューブ) として扱う」発想。 2 次元のスプレッドシート (行 × 列) では表現しきれない多側面のデータを、 軸 (次元) ごとに切り出して観察する。
この 3 次元キューブに対して、 以下の 5 操作で多面的にデータを観察する。
従来の Excel ピボットテーブルや SQL の GROUP BY も多次元分析の一種だが、 OLAP では:
SSDSE-B-2026 (47 都道府県 × 12 年 × 100 超指標) は典型的な多次元データ。 「人口」「生産」「医療」など複数の側面を、 「県 × 年」のクロス表に展開して比較できる。 例: 47 県の出生率を 2012-2023 の 12 年で並べると、 全国的な低下傾向と地域差が同時に見える。
多次元分析の核心は「fact 表 (総人口 A1101・出生数 A4101・高齢人口 A1303)」 × 「dimension 表 (都道府県・年)」のキューブで、 ドラッグ操作で集計軸を切り替えながら drill-down する点にある。 SSDSE-B-2026 の 47 都道府県 × 12 年 × 100 指標は、 pandas の pivot_table(index='Prefecture', columns='Year', values='Population') や DuckDB の SQL で簡易キューブとして扱える。
(1) 入力: 縦長 (long format) の SSDSE-B-2026 CSV を読み込み → (2) 処理: pivot で「県 × 年」の人口行列に展開 → (3) 出力: ヒートマップや小さな表 → (4) 解釈: 「東京は右肩上がり、 秋田は加速的減少」のような時空間パターン読み取り、 の 4 段階で多次元分析を実演できる。
次節以降では、 47×12 のピボット行列に対する slice / dice / drill-down 操作を実数値で示し、 同じ集計を pandas と DuckDB の両方で再現する。
🍰 まずはやさしく
複数の軸でデータをまとめる分析手法です。
データの詳細さを変えて調べるために使います。
合計や平均などの計算を組み合わせて使います。
詳しい定義と数式について読みます。
多次元分析(Multi-dimensional Analysis):OLAP・ピボット・データキューブなど、 複数の 次元 (dimension) でデータを集計し、 ドリルダウン / ロールアップ / スライス / ダイス / ピボット の 5 操作で多面的に切り出す分析手法。
同義・関連語:OLAP (Online Analytical Processing)、 データキューブ、 ピボット分析、 クロス集計、 多次元データベース
多次元分析で重要なのが集約関数の階層保持性 (associativity)。 例えば「合計」「最大」「最小」「カウント」は階層を経ても結果が一致するが、 「中央値」「分散」「異なる値の数」は元データから再計算が必要で、 階層をまたぐと値が変わる。 この性質によって、 事前集計の戦略 (どこまでキューブで保持するか) が決まる。
$$ \text{ROLLUP}(C, d_i) = \bigcup_{v \in d_i} C[d_i = v] $$
ロールアップは次元 $d_i$ の全値で部分立方体を取って合併する操作。
$$ \text{SLICE}(C, d_i = v) = \{c \in C \mid c.d_i = v\} $$
スライスは次元 $d_i$ を特定値 $v$ に固定したサブキューブ。
$$ \text{DICE}(C, P) = \{c \in C \mid P(c)\} $$
ダイスは述語 $P$ を満たすセルだけ抽出した部分キューブ。
$k$ 次元・各 $n$ 値のキューブはセル数 $n^k$ となり、 次元数増加で指数的に膨張する (次元の呪い)。 実用システムでは:
SSDSE-B-2026 (47 都道府県 × 年 × 100 超列) は典型的な多次元データ。 次元 = (年, 都道府県, 指標)、 メジャー = 値。 ピボットすると「行=県、 列=年、 セル=人口」のように分析できる。 ロールアップで「県→地方」、 スライスで「2023 年度のみ」、 ダイスで「関東 7 都県 × 2019〜2023 年度」など多面的に切り出せる。
| 記号 | 意味 |
|---|---|
| 次元 (Dimension) | 切り口(年、 地域、 商品など) |
| 尺度 (Measure) | 集計対象(売上、 数量など) |
| キューブ | 次元×次元×… の格子状データ構造 |
| ファクトテーブル | 数値が並ぶ中心テーブル |
📐 の集計式 $\text{Agg}(d_1,\dots,d_k) = f(\{m_i \mid i \in D(d_1,\dots,d_k)\})$ を、 SSDSE-B-2026 に当てはめて読む。
| 記号 | 読み方 | SSDSE-B-2026 では |
|---|---|---|
| $d_1, d_2, d_3$ | 次元(切り口)。 それぞれが取りうる値の集まりを持つ | 年度(2012〜2023 の 12 値)・都道府県(47 値)・指標(総人口 A1101 など約 110 列) |
| $m_i$ | 1 つのセルに入っている値(メジャー) | 「2023 年度・東京都・A1101」のセルなら 14,086,000 人 |
| $D(d_1,\dots,d_k)$ | 指定した次元の値に当てはまるセルの集まり | 「2023 年度・関東・A1101」なら茨城県〜神奈川県の 7 セル |
| $f$ | 集約関数(合計・平均・最大・中央値など) | 合計なら 7 セルを足して 4,352.7 万人。 これが「関東」へのロールアップ |
ここで大事なのが、 $f$ によって「下の階層の集計から上の階層を作れるか」が違う点である(📐 の「階層保持性」)。 合計と最大はそのまま積み上げられる。 8 ブロックの人口合計を足せば全国 12,435.3 万人になり、 ブロックごとの高齢化率の最大値の最大は 47 県の最大(39.06%)と一致する。 一方、 平均と中央値は積み上げられない。 2023 年度の 47 県の高齢化率の中央値は 31.78% だが、 8 ブロックの中央値をさらに中央値にすると 33.00% になる。 県の数がブロックごとに 1〜9 と違うので、 「中央値の中央値」 は全体の中央値ではない。 平均も同じで、 ブロックの平均を平均すると 32.01% になり、 47 県の平均 31.59% とずれる。 平均をロールアップしたいときは、 各セルに合計と件数(比率なら分子と分母)を持たせておき、 上の階層で割り直す。
SSDSE-B-2026 の 2023 年度から 5 都道府県(人口は万人、 高齢化率 = 65 歳以上人口 ÷ 総人口 を % にし、 どちらも小数 1 桁に丸めた値)について、地域×指標の 2 次元集計(ピボット)を手で追ってみる。
集約関数 $f = \text{mean}$、 次元 $d_1 =$ 地域ブロック(東 / 西)、 指標 = 人口(万人)と高齢化率(%)。
| 都道府県 | ブロック | 人口(万人) | 高齢化率(%) |
|---|---|---|---|
| 北海道 | 東 | 509.2 | 33.0 |
| 東京 | 東 | 1408.6 | 22.8 |
| 愛知 | 西 | 747.7 | 25.7 |
| 大阪 | 西 | 876.3 | 27.7 |
| 沖縄 | 西 | 146.8 | 23.8 |
数式:$\text{Agg}(d_1) = \frac{1}{|D(d_1)|}\sum_{i \in D(d_1)} m_i$
Step 1:東ブロック(北海道・東京)の人口ベクトルを取り出す。
$\mathbf{p}_{\text{東}} = [509.2,\ 1408.6]$
Step 2:東ブロックの平均人口を計算する。
$\bar{p}_{\text{東}} = \dfrac{509.2 + 1408.6}{2} = \dfrac{1917.8}{2} = \mathbf{958.9}$ 万人
Step 3:西ブロック(愛知・大阪・沖縄)の人口ベクトルを取り出す。
$\mathbf{p}_{\text{西}} = [747.7,\ 876.3,\ 146.8]$
Step 4:西ブロックの平均人口を計算する。
$\bar{p}_{\text{西}} = \dfrac{747.7 + 876.3 + 146.8}{3} = \dfrac{1770.8}{3} \approx \mathbf{590.27}$ 万人
Step 5:同様に高齢化率の平均を求める。
$\mathbf{a}_{\text{東}} = [33.0,\ 22.8]$、 $\bar{a}_{\text{東}} = \frac{33.0+22.8}{2} = \mathbf{27.90}$%
$\mathbf{a}_{\text{西}} = [25.7,\ 27.7,\ 23.8]$、 $\bar{a}_{\text{西}} = \frac{25.7+27.7+23.8}{3} = \frac{77.2}{3} \approx \mathbf{25.73}$%
Step 6 — 手計算ピボット結果(最終):
| ブロック | 平均人口(万人) | 平均高齢化率(%) |
|---|---|---|
| 東 | 958.9 | 27.90 |
| 西 | 590.27 | 25.73 |
このコードでやること:上記の手計算を pandas の pivot_table で再現し、 東/西ブロック別の平均人口・平均高齢化率を求める。
📥 入力データ(上記 5 行):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import pandas as pd import numpy as np # 手計算と同じデータ(SSDSE-B-2026 の 2023 年度、人口は万人・高齢化率は % を小数 1 桁に丸めた値)を DataFrame に df = pd.DataFrame({ '都道府県': ['北海道', '東京', '愛知', '大阪', '沖縄'], 'ブロック': ['東', '東', '西', '西', '西'], '人口': [509.2, 1408.6, 747.7, 876.3, 146.8], '高齢化率': [33.0, 22.8, 25.7, 27.7, 23.8] }) # ブロック次元で集計(多次元分析の pivot_table) pivot = df.pivot_table(values=['人口', '高齢化率'], index='ブロック', aggfunc='mean') print(pivot.round(2)) print("---") print(f"東:人口= {np.mean([509.2, 1408.6]):.4f}, 高齢= {np.mean([33.0, 22.8]):.4f}") print(f"西:人口= {np.mean([747.7, 876.3, 146.8]):.4f}, 高齢= {np.mean([25.7, 27.7, 23.8]):.4f}") |
📤 実行すると次の出力が得られる:
💬 手計算と Python 出力が一致(東: 人口 958.9 万人・高齢化率 27.90%、 西: 590.27 万人・25.73%)。 東は東京都 1,408.6 万人に引っ張られて平均が大きく、 高齢化率は北海道 33.0% と東京都 22.8% の差が 10 ポイント以上あるので、 平均 27.90% はどちらの都道府県の実態とも離れている。 これが多次元分析の核心 — 次元の値で行をグループ化し、 集約関数を適用するだけで「N 次元キューブのスライス」が実現される。
このコードでやること:SSDSE-B-2026 の都道府県データを読み込み、 最新年度(2023 年度)の 47 都道府県を 8 地方ブロックに分け、 地方ブロック次元で pivot_table(多次元集計)を実行して総人口の平均と都道府県数を得る。
📥 入力データ(SSDSE-B-2026.csv を header=1 で読み、 2023 年度に絞った先頭 3 行):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # ── この抜粋で使うデータを用意します(SSDSE-B の 47 都道府県・最新年度)── import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) df = df[df['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)].copy() df['年度'] = pd.to_numeric(df['年度'], errors='coerce') df = df[df['年度'] == df['年度'].max()] df['総人口'] = pd.to_numeric(df['総人口'], errors='coerce') # ── 47 都道府県を 8 つの地方に分ける ── # 地域コードは R01000(北海道)〜 R47000(沖縄県)の形。 # 2〜3 文字目が都道府県の番号なので、その番号で地方を決める。 def 地方(code): n = int(str(code)[1:3]) if n == 1: return '北海道' if n <= 7: return '東北' if n <= 14: return '関東' if n <= 23: return '中部' if n <= 30: return '近畿' if n <= 35: return '中国' if n <= 39: return '四国' return '九州・沖縄' df['ブロック'] = df['地域コード'].map(地方) # 多次元集計:地方ごとに、総人口の平均と県の数を出す pivot = df.pivot_table(values='総人口', index='ブロック', aggfunc=['mean', 'count']) print(pivot) |
📤 実行すると次の出力が得られる(8 ブロック。 ブロック名の文字コード順に並ぶ):
💬 平均総人口は関東 621.8 万人が最大、 四国 89.5 万人が最小で約 7 倍の開きがある。 北海道は 1 道だけなので平均 509.2 万人はそのまま北海道の値で、 県数(count)を並べておかないと「北海道ブロックは大きい」と誤読しやすい。 関東の平均も東京都 1,408.6 万人に引き上げられているので、 規模を比べるなら合計や中央値も並べる。 ブロック次元でスライスするだけで「地域ごとの規模感」が一覧できる。 これが多次元分析の核心 — 集計の軸(次元)を切り替えることで、 同じデータから異なるインサイトを得られる。
※ data/raw/SSDSE-B-2026.csv は e-Stat SSDSE から取得した実データを想定。
🎯 このコードでやること:SQL の GROUP BY CUBE(年度, ブロック) が返す 4 通りの集計を pandas の groupby で作り、 ブロック → 県とドリルダウンして人口の増減がどこで起きたかを探す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df.rename(columns={'SSDSE-B-2026': '年度'}) df = df[df['年度'].isin([2012, 2023])].copy() # 2 年度 × 47 県 = 94 行 def block(code): n = int(str(code)[1:3]) for upper, name in [(1, '北海道'), (7, '東北'), (14, '関東'), (23, '中部'), (30, '近畿'), (35, '中国'), (39, '四国'), (47, '九州・沖縄')]: if n <= upper: return name df['ブロック'] = df['Code'].map(block) df['人口_万人'] = df['A1101'] / 1e4 # SQL の GROUP BY CUBE(年度, ブロック) と同じ 4 通りの集計(2^2 = 4) sets = {'(年度, ブロック)': ['年度', 'ブロック'], '(年度)': ['年度'], '(ブロック)': ['ブロック'], '()': []} for name, keys in sets.items(): g = df.groupby(keys)['人口_万人'].sum() if keys else pd.Series({'全体': df['人口_万人'].sum()}) print(f'{name:<14} {len(g):>2} 行') # ドリルダウン: 年度 → ブロック別に 2012→2023 の増減を見る wide = df.pivot_table(values='人口_万人', index='ブロック', columns='年度', aggfunc='sum') wide['増減_万人'] = wide[2023] - wide[2012] wide['増減率_%'] = wide['増減_万人'] / wide[2012] * 100 print() print(wide.round(1).sort_values('増減率_%')) tot = wide[[2012, 2023]].sum() print() print(f'ロールアップ(全国): 2012 年度 {tot[2012]:.1f} 万人 → 2023 年度 {tot[2023]:.1f} 万人' f'({tot[2023] - tot[2012]:+.1f} 万人、{(tot[2023] / tot[2012] - 1) * 100:+.2f}%)') # さらにドリルダウン: 関東の中で増えた県・減った県 k = df[df['ブロック'] == '関東'].pivot_table(values='人口_万人', index='Prefecture', columns='年度') k['増減_万人'] = k[2023] - k[2012] print() print(k.round(1).sort_values('増減_万人')) |
💬 2 次元のキューブ(年度 × ブロック)からは、 2² = 4 通りの集計(16 行・2 行・8 行・1 行)が作れる。 全国では 2012 年度 12,758.9 万人から 2023 年度 12,435.3 万人へ 323.6 万人(2.54%)減ったが、 ブロックにドリルダウンすると関東だけが 87.4 万人増え、 東北は 9.2%・四国は 9.0% 減った。 さらに関東を県まで下ろすと、 増加分 87.4 万人のうち東京都が 85.2 万人を占め、 茨城県・栃木県・群馬県はむしろ減っている。 「関東は増えた」 という 1 つ上の階層の結論は、 実際には東京都と南関東 3 県の結論である。
多次元分析は柔軟だが、 設計判断を誤ると性能・正確性・運用性が大幅に低下する。 以下に実務で頻発する 7 つの典型的失敗パターンと対策を示す。
10 次元 × 各 10 値で 10¹⁰ = 100 億セル。 全データ保持は不可能。 対策: スパース表現 (実データがあるセルのみ保持)、 遅延評価 (要求時に集計)、 事前集計の選択的キャッシュ (使用頻度の高い断面のみ Materialized View 化)、 列指向 + 圧縮 (Parquet, Arrow)。
「都道府県の平均」を単純平均すると「全国平均」と一致しない。 重み (人口) を考慮した加重平均が必要。 例: 東京の出生率を 47 県平均で扱うと、 人口比重が無視されて誤った全国像となる。 対策: 集計時に常に「重み」を意識、 上位集計は元データから再計算、 中央値・最頻値も同様に注意。
多次元を 2D グラフに無理に詰めると逆に分かりにくい。 5 次元以上を 1 枚に表現するのは認知的負荷が大きい。 対策: 小倍数 (Small Multiples) (同じグラフを次元別に並べる)、 動的フィルタ (インタラクティブ BI)、 次元削減 (PCA / t-SNE で 2D に投影)、 ファセット分割 (Tableau / Vega-Lite)。
OLAP キューブの更新は重く、 ストリーミング分析とは別物。 リアルタイム集計が必要なら別の技術 (Apache Druid / ClickHouse) を使う。 対策: バッチ集計 + ストリーミング集計の組合せ (Lambda 構造)、 マテリアライズドビューの定期更新、 増分更新可能なクエリエンジン。
「中央値」「分散」「異なる値の数 (COUNT DISTINCT)」は階層をまたぐと値が変わる (元データから再計算が必要)。 事前集計で正しい結果を得るには元データを保持し続ける必要があり、 ストレージコストが増える。 対策: HyperLogLog / T-Digest など近似集計アルゴリズムで階層保持性を確保。
「業種」次元の値「製造業」と「製造」が混在、 「2024 年度」と「2024 年」が異なる定義を持つなど、 次元値の表記揺れで集計結果が誤る。 対策: マスターデータ管理 (MDM)、 ディメンションテーブルでの正規化、 ETL 段階での標準化、 階層辞書の文書化。
同じ OLAP システムでも、 クエリの組合せでパフォーマンスが大きく変動。 簡単な ロールアップは秒で返るが、 複雑な多次元結合は分単位かかることも。 対策: クエリプラン分析、 インデックス戦略、 キャッシュレイヤー (Redis / Memcached)、 パフォーマンステストを本番投入前に実施。
高齢化率のような比率を地方ブロックに集約するとき、 県の比率を平均するか、 分子と分母を合計してから割るかで値が変わる。 どちらも「ブロックの高齢化率」 と呼ばれがちなので、 実データで差を測っておく。
🎯 このコードでやること:2023 年度の 47 県について、 地方ブロックごとの高齢化率を (a) 県の高齢化率の単純平均と (b) 65 歳以上人口の合計 ÷ 総人口の合計の 2 通りで計算し、 差を並べる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].copy() # 2023 年度の 47 都道府県 def block(code): # R01000 → 1 → 北海道 … n = int(str(code)[1:3]) for upper, name in [(1, '北海道'), (7, '東北'), (14, '関東'), (23, '中部'), (30, '近畿'), (35, '中国'), (39, '四国'), (47, '九州・沖縄')]: if n <= upper: return name df['ブロック'] = df['Code'].map(block) df['高齢化率'] = df['A1303'] / df['A1101'] * 100 # 県ごとの比率(%) # (a) 県の比率をそのまま平均する(1 県 1 票) a = df.groupby('ブロック')['高齢化率'].mean() # (b) 分子と分母をそれぞれ合計してから割る(人口で重み付け) s = df.groupby('ブロック')[['A1303', 'A1101']].sum() b = s['A1303'] / s['A1101'] * 100 out = pd.DataFrame({'県数': df.groupby('ブロック').size(), '(a) 県の率の平均': a.round(2), '(b) 合計してから割る': b.round(2)}) out['差 (a)-(b)'] = (out['(a) 県の率の平均'] - out['(b) 合計してから割る']).round(2) print(out.sort_values('(b) 合計してから割る')) print() print(f"全国 (a) 47 県の率の平均 = {df['高齢化率'].mean():.2f} %") print(f"全国 (b) 65 歳以上計 / 総人口計 = {df['A1303'].sum() / df['A1101'].sum() * 100:.2f} %") print(f"全国 (c) ブロックの (a) をさらに平均 = {a.mean():.2f} %") |
💬 8 ブロックのうち 7 つで (a) の方が高く、 関東では 27.99% と 26.17% で 1.82 ポイント違う。 関東は人口の多い東京都(22.75%)・神奈川県が低く、 人口の少ない茨城県・栃木県・群馬県が高いので、 1 県 1 票の (a) は高く出る。 全国でも (a) 31.59% と (b) 29.13% で 2.46 ポイント違い、 ブロックの (a) をさらに平均した (c) は 32.01% とまた別の値になる。 「日本の高齢化率」 として報告すべきは人口全体の比率 (b) で、 (a) は「平均的な県の高齢化率」 という別の問いへの答えである。 キューブに比率そのものを入れず、 分子と分母を入れておけば、 どの階層でも (b) を正しく作れる。
多次元分析 がデータサイエンスの体系の中でどこに位置するかを、 3 つの視点で可視化する。
🌐 統計・データサイエンス › 可視化・データ探索 › 多次元分析 (OLAP)
中心の「多次元分析」から前提・並列・発展・応用の関係を SVG で可視化する。
📚 データサイエンス(広い分野)
┣ 可視化・データ探索
┗ 多次元分析 / OLAP(このページ)
┣ スライス(1 次元固定)
┣ ダイス(複数次元固定)
┣ ドリルダウン(細分化)
┗ ロールアップ(集約)
┣ 統計分析(相関・回帰・検定)
┗ 機械学習(予測・分類・クラスタリング)
| 視点 | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係 | 「次に何を学ぶべき?」 |
| ⭕ 包含マップ | 分類体系の入れ子構造 | 「どんなジャンルに属する?」 |
| 🌳 ツリー | 操作・概念の親子関係 | 「ドリルダウンの経路は?」 |
多次元分析(OLAP)と周辺の統計・可視化手法はどう違い、 どう繋がっているか。
単純集計は「全体の合計」だけ。 多次元分析は「N 個の次元で切り出した部分集合」に対して集計する。 Excel の SUM と pivot_table の違いに相当。
| 観点 | 単純集計 | 多次元分析 |
|---|---|---|
| 軸の数 | 0(全体) | 1〜N(任意の次元) |
| 問いへの対応 | 固定 | アドホック(都度変更可) |
| 代表ツール | SQL SUM/COUNT | OLAP cube / pivot_table |
多次元分析は 記述・探索 が目的(何が起きているかを集計して見る)。 機械学習は 予測・分類 が目的(次に何が起きるかを学習する)。 前処理・特徴量エンジニアリングのステップとして多次元分析は機械学習の上流に位置する。
多次元分析は ユーザー定義の次元(年・地域・商品)で集計する。 PCA は データ駆動の次元(分散最大化方向)に変換する。 「どの軸で切るか」が人間が決めるか、 データが決めるかの違い。
| 観点 | 多次元分析 (OLAP) | PCA |
|---|---|---|
| 次元の定義 | ユーザー定義(カテゴリ) | データ駆動(連続値) |
| 出力 | 集計テーブル(平均・合計) | 主成分スコア |
| 解釈性 | 高い(軸の意味が明確) | 低い(数学的な抽象軸) |
「多次元分析(OLAP)を使うべきか」を判断する実用フロー。 分析目的とデータの性質で選び分ける。
| 手法 | 目的 | 次元定義 | 規模 | 解釈性 |
|---|---|---|---|---|
| OLAP (多次元分析) | 記述・集計 | ユーザー定義 | 中〜大 | 高 |
| PCA | 次元削減 | データ駆動 | 中 | 低 |
| クラスタリング | グループ発見 | データ駆動 | 中 | 中 |
| 回帰分析 | 予測 | ユーザー定義 | 中 | 高 |
| BI ツール | 探索・報告 | ユーザー定義 | 大 | 高 |
💡 選択のヒント:多次元分析は「答えを知っている問いを素早く確認する」のに最適。 「どんな問いがあるか自体が不明」の探索的分析では、 散布図・ヒートマップ・PCA と組み合わせて使うのが実務の定石。
多次元分析の理論的基盤は 1970 年代の関係データベース理論 (Edgar F. Codd) に遡る。 1993 年に Codd らが「OLTP (Online Transaction Processing) と OLAP (Online Analytical Processing) は別の最適化が必要」として OLAP という用語と 12 のルールを示した。 その後、 1990 年代に Hyperion (現 Oracle) の Essbase や Microsoft の Analysis Services が商用 OLAP として広く普及。 2000 年代後半からはオープンソースの Mondrian (Pentaho)、 Apache Druid (2011) が登場し、 2010 年代の「ビッグデータ + クラウド」流れで ClickHouse (2016)、 Apache Pinot (2014) など分散 OLAP が主流に。 2020 年代は Snowflake / BigQuery / Databricks Lakehouse などクラウド DWH が標準的位置を占める。
Codd は OLAP システムが満たすべき 12 のルール (後に拡張版で 18 ルール) を提示した。 主要ルール:
OLAP クエリは SQL で表現する場合、 GROUP BY + ROLLUP / CUBE / GROUPING SETS を駆使する。 例: 「年 × 県 × 商品の売上、 ロールアップで全国合計と全期間合計も含めて」は以下のように書ける:
SELECT year, prefecture, product, SUM(sales) AS total FROM fact_sales GROUP BY ROLLUP (year, prefecture, product) ORDER BY year NULLS LAST, prefecture NULLS LAST, product NULLS LAST;
CUBE 演算子は ROLLUP より強力で、 全ての次元組合せの集計を返す。 例えば 3 次元 (年・県・商品) なら 2³ = 8 種類のサブ合計が出力される (全体、 年別、 県別、 商品別、 年×県、 年×商品、 県×商品、 詳細)。
Tableau / Power BI / Looker などの BI ツールは、 多次元分析の GUI フロントエンドを提供する。 ユーザーはドラッグ&ドロップで「行 = 県」「列 = 年」「セル = 売上」のような可視化を組み立てる。 内部的には ROLAP バックエンド (SQL) または専用エンジン (Tableau の Hyper) が処理する。 学習曲線が低く、 ビジネスユーザーが直接データ探索できることが普及の要因。
OLAP クエリのパフォーマンスは、 (1) ストレージ形式 (列指向の Parquet が高速)、 (2) インデックス戦略 (ビットマップ / ZoneMap)、 (3) 事前集計 (Materialized View / Cube)、 (4) パーティショニング (日付や地域でファイル分割)、 (5) クエリエンジン (Spark / Druid / Presto / Trino)、 (6) キャッシュ (Redis / インメモリ) の組合せで決まる。 ベンチマーク (TPC-DS / TPC-H) で性能評価し、 ボトルネックを特定する。
SSDSE-B-2026 (47 都道府県 × 12 年 × 100 超指標) を多次元キューブとして扱う具体例:
OLAP は強力だが限界もある。 (1) 事前集計の更新コスト (キューブ再計算が重い)、 (2) スキーマ変更への弱さ (新次元の追加が大変)、 (3) 非構造化データ (テキスト・画像) との相性が悪い。 次世代の動向: セマンティック層 (dbt + Cube.js) で SQL とBI を統合、 ストリーミング OLAP でリアルタイム集計、 AI + OLAP で自然言語クエリ (例: 「東京の出生率を 5 年で見せて」)、 レイクハウス (Delta Lake / Iceberg) でデータレイクと DWH の統合。
OLAP は分析処理 (集計クエリ・読み取り中心・大量データ・低頻度更新)、 OLTP は取引処理 (高頻度更新・小規模クエリ・整合性重視)。 同じデータベースで両方やると性能が悪化するため、 OLTP の本番 DB から OLAP の DWH に ETL でデータを移すのが標準パターン。
主な高速化要因は (1) 事前集計 (Materialized View / pre-aggregation)、 (2) 列指向ストレージ (集計クエリで読むカラムだけ I/O)、 (3) 圧縮 (列単位で同じデータ型のため高圧縮率)、 (4) ベクトル化処理 (SIMD で同時並列計算)、 (5) インメモリ化 (RAM コストが下がり実用化)。
DWH は構造化済みデータを正規化して保存 (スキーマ・オン・ライト)。 データレイクは生データをそのまま保存 (スキーマ・オン・リード)。 DWH は分析に最適化、 データレイクは柔軟性重視。 最近のレイクハウス (Delta Lake / Iceberg / Hudi) は両者の良いとこ取りを目指す。
従来の OLAP は事前集計に時間がかかるためバッチ処理が主流。 しかし Apache Druid / Pinot / ClickHouse などのストリーミング OLAP では、 取込みから秒〜分単位での集計が可能。 ただし「リアルタイム性」と「複雑な多次元結合」はトレードオフ。
2020 年代はクラウド優位。 理由: (1) 弾性スケーリング (ピーク時のみリソース増)、 (2) 運用負担軽減 (DBA レス)、 (3) 従量課金 (固定資産化不要)、 (4) 最新機能の即時利用。 ただしデータガバナンス / 主権 / 機密度の高い業界 (金融・医療) ではオンプレやプライベートクラウドを選ぶ場合もある。
新規 OLAP システム導入時の判断基準:
新規 OLAP プロジェクトを設計する際の指針を、 実務経験者の知見から整理する。
OLAP システムを実運用する際に頻発する課題と対処法を以下にまとめる。
多次元分析 (OLAP / Multi-dimensional Analysis) は、 「複数の次元 (時間・地域・商品・顧客等) で集計したキューブを、 5 操作 (Slice / Dice / Roll-up / Drill-down / Pivot) で多面的に切り出す」 分析パラダイム。 1993 年に Codd らが OLAP という語を示して以来、 業務データの集計で広く使われており、 2020 年代はクラウド DWH (Snowflake / BigQuery) + 列指向ストレージ (Parquet / Iceberg) + セマンティック層 (dbt + Cube.js) の組合せが主流となっている。
本ページで触れた関連用語を、 用語集の他ページで深掘りできる。 順序は学習の自然な流れを意識した。 まず スプレッドシート → SQL → DWH → BI ツール → データキューブ → 次元モデリング の順で読むのがおすすめ。
多次元分析は単なる集計テクニックではなく、 「データから洞察を引き出し、 意思決定につなげる」全社的な能力を支える基盤技術。 本ページの内容を起点に、 自分の組織やプロジェクトでの実践に活かしてほしい。
多次元分析は知識として読むだけでは身に付かない。 OLAP キューブ・スター/スノーフレークスキーマ・ROLAP/MOLAP/HOLAP の使い分け・SSDSE-B 47 都道府県データでの集計などを実装ステップとして理解しているか、 以下の問いで確認しよう。 各問は 30 秒〜2 分で回答できるレベルに設計してある。
キューブの直感を掴むため、 「都道府県 × 年 × 指標」 の 3 次元構造を立方体として可視化する。 セル 1 つが 1 サマリ値を保持する。
OLAP の物理設計でよく比較される 2 つのスキーマを並べて可視化する。 スター・スキーマは中央のファクトテーブルを次元テーブルが「星状」に取り囲む構造、 スノーフレーク・スキーマは次元テーブルがさらに正規化された構造。
OLAP の代表的な 5 操作を 1 枚にまとめる。 多次元分析では、 ユーザーがこれらの操作を組合せながらデータを「角度を変えて眺める」ことで洞察を得る。
多次元分析の概念は SSDSE-B-2026 のような実データを使った演習で初めて身に付く。 以下に 5 つの段階的な演習を示す。 上から順に取り組むことで、 多次元分析の全体像を体系的に把握できる。
SSDSE-B-2026 を OLAP 化することを想定し、 ファクトテーブルと次元テーブルを設計する。 ファクトテーブルは「都道府県 × 年 × メジャー」の粒度、 次元テーブルは「都道府県マスター (47 行)」「年マスター (7 行)」「指標マスター (N 行)」の 3 つ。 SQL の CREATE TABLE 文を 4 つ書き、 主キー / 外部キー / インデックスを定義せよ。 SSDSE-B-2026 が縦持ち (long format) ではなく横持ち (wide format) で配布されている点も考慮、 まず pandas で melt() してから挿入する手順を整理する。
都道府県 → 8 地方ブロック → 全国 の 3 階層を pandas で表現し、 ロールアップ (集計レベルを上げる) とドリルダウン (集計レベルを下げる) の 2 操作をそれぞれ 1 行ずつで実装する。 SSDSE-B-2026 の人口 (A1101) を集計対象とし、 各レベルでの値を表で出力。 結果として、 全国レベルでは 1 行、 地方ブロックレベルでは 8 行、 都道府県レベルでは 47 行が得られることを確認。
スライスは「特定の年 (例: 2023 年) だけ抜き出す」 1 次元の固定、 ダイスは「2017-2019 の 3 年 × 関東 7 県」のように 2 次元以上を固定して切り出す操作。 これを pandas の query() / loc[] / boolean indexing で実装し、 切り出し前後の行数を比較。 SSDSE-B-2026 (47 県 × 12 年 = 564 行) → スライス後 47 行、 ダイス後 21 行。
SSDSE-B-2026 を「行: 都道府県、 列: 年、 値: 人口」 でピボットし、 さらに「行: 年、 列: 都道府県、 値: 人口」 に転置する。 pandas の pivot_table() と transpose() を使い分け、 BI ツールでの可視化に適した形式に変換する。 結果として、 同じデータでも見え方が大きく変わることを実感する。
最終的に、 多次元分析の結果を意思決定にどう結びつけるかを考察する。 SSDSE-B-2026 から「人口減少率が大きい都道府県 TOP 5」「高齢人口 (A1303) の地方ブロック別シェア」「消費支出 (L3221) の年次推移」 の 3 つの視点でレポートを作成し、 それぞれについて「もし君が市町村政策の意思決定者なら、 何を提案するか」 を 200 文字程度で書く。 多次元分析は単なる集計テクニックではなく、 「データから洞察を引き出し、 意思決定につなげる」 能力を支える基盤技術であることを実感できるだろう。
以上で多次元分析の理解度チェックは終了。 各セットを終えた段階で、 自分の弱点が明確になっているはずだ。 弱点については用語集の関連ページ (RDB / SQL / DWH / BI ツール) を読み返して理解を深めよう。 多次元分析は実践で力を発揮する技術なので、 実プロジェクトで使う機会を見つけて手を動かすことが何より重要だ。
ここでは多次元分析を初学者から実務家へとレベルアップするための深掘り読み物を提示する。 単に技術用語の定義を覚えるだけではなく、 「なぜそのアプローチが生まれたか」「どんな製品で実装されているか」「クラウド時代に何が変わったか」 といった文脈をしっかり理解することで、 自分の組織やプロジェクトで多次元分析をどう導入すべきかの判断軸が身に付く。
OLAP 製品は大きく分けて 4 つのカテゴリに分類できる。 第 1 はオンプレミス OLAP 製品で、 Microsoft SSAS、 Oracle Essbase、 SAP BW などが該当する。 これらは 20-30 年の歴史を持ち、 金融機関や製造業など保守的な業界で根強い導入実績を持つ。 第 2 はクラウドデータウェアハウス系で、 Snowflake、 BigQuery、 Redshift、 Synapse Analytics が該当する。 これらはストレージとコンピュートを分離し、 必要に応じてコンピュートを拡張できる弾力性が魅力。 第 3 はモダン BI 系で、 Tableau、 Power BI、 Looker、 Qlik Sense が該当、 ビジュアル探索と OLAP の中間に位置する。 第 4 はオープンソース系で、 Apache Druid、 ClickHouse、 Apache Pinot などが急速に台頭しており、 リアルタイム分析の領域で強い。
SSDSE-B-2026 のような数十万行レベルの公的データを扱うだけなら、 pandas + DuckDB の組合せで十分。 数億行レベルになると Snowflake、 BigQuery、 ClickHouse のいずれかを選ぶことになる。 選定の判断軸は (1) データ量、 (2) 同時利用ユーザー数、 (3) クエリ複雑度、 (4) 既存技術スタックとの統合性、 (5) コスト、 (6) ベンダーロックインの許容度 の 6 つで考えるのが定石。
日本の政府統計は多次元分析の格好の題材で、 統計法に基づき、 国勢調査、 経済センサス、 家計調査、 労働力調査、 人口動態統計、 学校基本調査、 県民経済計算など、 数百種類のデータセットが e-Stat (政府統計の総合窓口) で公開されている。 SSDSE-B-2026 はこれらを 都道府県 × 年 × 多変数 という多次元構造に整理したもので、 OLAP 入門教材としても理想的。 RESAS (地域経済分析システム) は内閣官房地方創生推進室が運営する OLAP ダッシュボードで、 観光、 産業、 人口、 雇用などのデータを地図やグラフで可視化、 自治体職員や民間企業が政策立案・経営分析に活用している。
政策評価における EBPM (Evidence-Based Policy Making) の文脈でも、 多次元分析は中核技術と位置付けられる。 政策の効果を「年 × 地域 × 対象層」 で集計し、 介入前後で比較するアプローチは、 多次元分析の典型的な活用形態。
多次元分析を実務で運用すると、 教科書に書いていない落とし穴に頻繁に遭遇する。 第 1 は「次元の呪い」で、 次元数が増えると組合せが指数的に増加、 サマリのサイズが爆発する。 対策としては (1) 重要次元のみを採用する、 (2) サマリの事前計算を最低限に抑える、 (3) クエリ時に動的集計する ROLAP 寄りのアプローチを採用する、 などがある。 第 2 は「変更管理の困難」 で、 次元の階層構造が変わると過去のサマリが無効化される。 これは Slowly Changing Dimension (SCD) パターンで対処する。 SCD Type 1 (上書き)、 Type 2 (履歴保持)、 Type 3 (前回値保持) のうち、 多くの場合は Type 2 が選ばれる。
第 3 は「シンプソンのパラドックス」 で、 集計レベルを変えると結論が逆転する。 このページの「⚠️ 落とし穴の深掘り」 では、 SSDSE-B-2026 の実データで、 県を単位に数えるか人口で重み付けするかによって地方の順位が入れ替わる例を示している。 対策はドリルダウン / ロールアップを系統的に行い、 結論の頑健性を確認すること。 第 4 は「キャッシュ無効化」 で、 元データが更新された時にキューブをいつ再構築するかが難しい。 リアルタイム性が求められる場合は streaming OLAP (Apache Druid、 ClickHouse の MaterializedView) を採用する。 第 5 は「セキュリティ」 で、 行レベルセキュリティ (RLS) と列レベルセキュリティ (CLS) を組合せて、 部門別・ロール別にアクセス制御を行う。
多次元分析の理解を深めるため、 国内外の実プロジェクトでの活用事例をさらに整理する。 各事例について、 (1) 背景、 (2) 採用された OLAP 構造、 (3) 成果と学びの 3 点で記述する。
直感 — データの立方体を切り分ける。 ここでは SSDSE-B-2026 の実測値を「地域 × 年 × 指標」の 3 次元キューブとみなし、 次元の割り当て(行 / 列)・スライス(1 年に固定)・ドリルダウン(地方 → 県)・ロールアップ(県 → 地方)・集計関数(合計 / 平均)を切り替える。 操作するたびにピボット表とヒートマップがリアルタイムに再計算・再描画される。 集計は端末側で厳密に計算しており、 上の手計算・Python 出力と同じ規則(グループ化 → 集約関数)で動く。
使用実データ(捏造なし・Python 転記): SSDSE-B-2026 の 15 都道府県(8 地方ブロックから抜粋)× 6 年(2013 / 2015 / 2017 / 2019 / 2021 / 2023)× 3 指標= 総人口 (A1101) / 65歳以上人口 (A1303) / 出生数 (A4101) の実測値。 例: 東京都 2023 年の総人口 = 14,086,000 人、 沖縄県 2013 年の出生数 = 17,209 人。 合計はデモ抜粋 15 県の小計であり全国値ではない点に注意。
濃いほど値が大きい。 セルにカーソル / 指を合わせると値を表示(タッチ対応)。
65歳以上人口 の地方合計は規模を、 平均は 1 県あたりの水準を示す。 集約の選択は分析の問い自体を左右する。 なお総人口の合計はデモ 15 県の小計で全国値ではない。このラボは端末上の pivot_table 相当を手作りしたもの。 実務ではキューブの原料をデータウェアハウス (DWH) に貯め、 中央のファクトテーブルと周辺のディメンションテーブルからなるスタースキーマで次元モデリングし、 BI ツール(Tableau / Power BI / Looker)でドラッグ操作すると裏で SQL の GROUP BY … WITH ROLLUP / CUBE に翻訳される。 身近には スプレッドシートのピボットテーブルが同じ操作を提供し、 可視化の型はデータ可視化の技法に連なる。
上の「直感で掴む」を一歩進める。 多次元分析の核は 「複数の軸(次元)でデータを切り分けて集計する」 一点に尽きる。 キューブとは (次元1 × 次元2 × … × 次元k) の各マスに指標(メジャー)の集計値を入れた格子であり、 セル数は各次元の値数の掛け算で決まる。 SSDSE-B-2026 なら「都道府県(47) × 年 × 指標」がそのまま 3 次元キューブになる。
| 操作 | やること(軸の観点) | SSDSE-B-2026 での例 |
|---|---|---|
| スライス | 1 次元を 1 値に固定し断面を取る | 「2023 年」に固定 → 47 県 × 指標の 2D 表 |
| ダイス | 複数次元を範囲で絞り部分キューブ | 「関東 7 県 × 2017-2023 × 出生数」だけ |
| ドリルダウン | 階層を下げ粒度を細かく | 「地方ブロック → 都道府県」へ展開 |
| ロールアップ | 階層を上げ粒度を粗く | 「都道府県 → 地方ブロック → 全国」へ集約 |
| ピボット | 行と列に割り当てる次元を入替 | 「県 × 年」表を「年 × 県」表へ転置 |
この 5 操作はどれも 「group by する軸をどう選ぶか」 の言い換えにすぎない。 ピボットテーブルで列に何を置くか、 SQL の GROUP BY に何を並べるかを操作しているのと同じ。 多変量の同時把握とは、 この格子の上で複数の指標(メジャー)を並べ、 軸を切り替えながら「規模」「水準」「構成比」を一度に眺めることを指す。
身近なクロス集計表(行カテゴリ × 列カテゴリ × 集計値)は、 多次元キューブを 2 次元に落とした最小形にほかならない。 「地方 × 指標」で 1 枚のクロス表を作れば、 それはキューブから 2 軸を取り出したスライスである。 次節ではこのクロス集計を SSDSE-B-2026 の実測値で作り、 そこに潜む落とし穴を確認する。
多次元分析の危うさは、 「同じデータでも、 どの軸・どの粒度・どの集計関数で切るかで結論が変わる」 点にある。 以下は SSDSE-B-2026(cp932, skiprows=[1])から 2023 年・47 都道府県を 8 地方ブロックに集約した実測クロス集計(地方 × 指標)である。 すべて実データの合計値で、 合成・捏造は含まない。
| 地方ブロック | 県数 | 総人口 A1101 | 65歳以上 A1303 | 出生数 A4101 | 高齢化率 | 粗出生率‰ |
|---|---|---|---|---|---|---|
| 北海道 | 1 | 5,092,000 | 1,681,000 | 24,430 | 33.0% | 4.80 |
| 東北 | 6 | 8,318,000 | 2,790,000 | 41,237 | 33.5% | 4.96 |
| 関東 | 7 | 43,527,000 | 11,390,000 | 252,911 | 26.2% | 5.81 |
| 中部 | 9 | 20,749,000 | 6,161,000 | 121,110 | 29.7% | 5.84 |
| 近畿 | 7 | 21,990,000 | 6,423,000 | 132,406 | 29.2% | 6.02 |
| 中国 | 5 | 7,070,000 | 2,263,000 | 42,468 | 32.0% | 6.01 |
| 四国 | 4 | 3,578,000 | 1,230,000 | 19,598 | 34.4% | 5.48 |
| 九州・沖縄 | 8 | 14,029,000 | 4,291,000 | 93,109 | 30.6% | 6.64 |
| 全国計(47県) | 47 | 124,353,000 | 36,229,000 | 727,269 | 29.1% | 5.85 |
※ 高齢化率 = A1303 / A1101、 粗出生率 = A4101 / A1101 × 1000。 いずれも上表の実測合計から算出。 A1101・A1303 は千人単位に丸めた SSDSE-B-2026 の 2023 年値。
全国の粗出生率を 2 通りで出すと値が食い違う。 (a) 全国の出生数合計 ÷ 人口合計 = 727,269 / 124,353,000 × 1000 ≈ 5.85‰(=正しい加重平均)。 (b) 8 地方ブロックの粗出生率を単純平均 = (4.80+4.96+5.81+5.84+6.02+6.01+5.48+6.64) / 8 ≈ 5.69‰。 差は 0.16‰。 原因は 関東(人口 4,350 万人)と四国(358 万人)を同じ重みで平均してしまうこと。 「平均の平均」は元の平均に一致しない(集約の順序依存・非結合性)。 比率・中央値・分散・異なり数はロールアップで再計算が必要で、 上位集計は必ず元データの合計から取り直す。
上表は「地方(8) × 指標(3)」の 24 セルで全て埋まる。 だが軸に「年齢 5 階級 × 性別 2 × 産業 20」を足すと 8×3×5×2×20 = 4,800 セルへ膨張し、 実データのある行はごく一部(スパース)になる。 都道府県(47)まで下げればさらに増える。 セルが疎になると各セルの標本が小さくなり、 集計値の分散が大きく偶然の凹凸を「発見」しやすい。 対策は重要次元だけ残す、 疎なセルはロールアップで束ねる、 マテリアライズドビューで「よく使う断面」だけ物理化する、 など。
同じ高齢化率でも、 全国 29.1%・地方ブロックでは 26.2%(関東)〜34.4%(四国)・都道府県まで下げるとさらに開く。 粗い粒度は地域差を平準化して隠し、 細かい粒度はスパース化して不安定になる。 ドリルダウンとロールアップを往復して両方の像を確認しなければ、 一つの粒度だけの結論は誤りうる。
クロス集計は軸と指標の組合せを総当たりで作れるため、 つい大量の相関・差の検定を同時に走らせがち。 有意水準 α=0.05 で無関係な比較を 100 回行えば、 期待値で約 5 件が「偶然の有意」になる。 SSDSE-B-2026 の 100 超指標を総当たりすれば偽陽性は容易に量産される。 対策は Bonferroni 補正や FDR 制御、 探索で見つけた仮説は別データ・別期間で確認すること(交差検証の発想)。 相関が出ても因果とは限らない点も併せて注意。
人が一目で読めるのは概ね 2〜3 軸まで。 4 次元以上を 1 枚に詰めると認知負荷で逆に読めない。 実務では小倍数(Small Multiples)で次元別にグラフを並べる、 ヒートマップで 1 軸を色に写す、 並行座標プロットや散布図行列で多変量を分解する、 あるいはPCA等で 2 次元へ投影する、 といった次元を減らす工夫が要る(発展節を参照)。
多次元分析は「人が決めた軸(次元)で集計する」手法だが、 軸が増えて手に負えなくなったら 軸そのものをデータから作り直す・減らす方向へ接続できる。
使い分けの勘所: 解釈が主目的で軸の意味を保ちたいなら OLAP のロールアップ、 軸が多すぎて全体像が掴めないなら次元削減で圧縮。 両者は排他ではなく、 削減後の主成分スコアを新たな「次元」としてキューブに載せ直すこともできる。
2 次元クロス集計(行カテゴリ × 列カテゴリ)は、 多次元キューブを 2 軸に落とした最小スライスであり、 ピボットテーブルで日常的に作るものと同じ。 カテゴリ同士の関連を統計的に検証したいときは、 クロス集計表にカイ二乗検定(独立性の検定)を適用する。 「集計して眺める(記述)」の OLAP と「関連を検定する(推測)」の橋渡しがここにある。 なお クロス集計・OLAP を単独で扱う専用ページは本用語集には未整備のため、 当面は本ページと ピボットテーブル・カイ二乗検定を併読するとよい。