論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
多次元分析
Multi-dimensional Analysis
可視化
別称: OLAP

🔖 キーワード索引

OLAPピボットスライスダイスドリルダウンロールアップcubeBI

各語の説明がある章へのリンク: データキューブと 5 操作(スライス・ダイス・ドリルダウン・ロールアップ・ピボット) | 集約関数と階層保持性 | ブロック別ピボットの手計算 | pandas の pivot_table と CUBE | 比率のロールアップ・次元の呪い | MOLAP・ROLAP・HOLAP とスター・スキーマ | 周辺手法との関係

💡 30秒で分かる結論

🍰 まずはやさしく

データの切り口を自由に変える方法です。

答えを素早く見つけるために使います。

店で「いつ・どこで・何が」売れたか調べます。

集計のやり方や便利な道具について読みます。

OLAP/ピボットなど複数次元での集計分析

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

🍰 まずはやさしく

仕事で使われる分析の土台となる考え方です。

正しい判断をすぐに下すために使います。

都道府県ごとのデータを分析する時に役立ちます。

定義から注意点までを順番に読みます。

ビジネスダッシュボード、 経営会議の資料、 マーケティングレポート — 多次元分析は経営判断のインフラ。 アドホックな質問にすぐ答えられる点で重要。

🎨 直感で掴む

🍰 まずはやさしく

データを立方体(サイコロ)のように扱う方法です。

多方面からデータを観察するために使います。

年や地域、商品の種類を軸にして考えます。

データを切り出す5つの操作について読みます。

多次元分析の核心は「3 次元以上のデータを、 立方体 (キューブ) として扱う」発想。 2 次元のスプレッドシート (行 × 列) では表現しきれない多側面のデータを、 軸 (次元) ごとに切り出して観察する。

3 次元キューブの具体例

  • X 軸 = 年 (2020, 2021, 2022, 2023, 2024)
  • Y 軸 = 地域 (北海道〜沖縄の 47 都道府県)
  • Z 軸 = 商品カテゴリ (食品 / 衣料 / 家電 / 雑貨)
  • セル値 = 売上 (メジャー)

この 3 次元キューブに対して、 以下の 5 操作で多面的にデータを観察する。

5 操作の直感的説明

従来の表形式分析との違い

従来の Excel ピボットテーブルや SQL の GROUP BY も多次元分析の一種だが、 OLAP では:

SSDSE-B-2026 での直感

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)、 データキューブ、 ピボット分析、 クロス集計、 多次元データベース

1. 基本定式化

【多次元集計】
$$ \text{Agg}(d_1, d_2, \dots, d_k) = f\big(\{m_i \mid i \in D(d_1, \dots, d_k)\}\big) $$
次元値 $(d_1, \dots, d_k)$ に該当するセル集合 $D(d_1, ..., d_k)$ に対し、 集約関数 $f$ (合計・平均・最大・最小・標準偏差等) を適用。 次元は階層構造を持つことが多く (例: 年 → 四半期 → 月 → 日)、 階層を上下することで詳細度を変える。

2. データキューブの 5 操作

3. 集約関数の階層保持性

多次元分析で重要なのが集約関数の階層保持性 (associativity)。 例えば「合計」「最大」「最小」「カウント」は階層を経ても結果が一致するが、 「中央値」「分散」「異なる値の数」は元データから再計算が必要で、 階層をまたぐと値が変わる。 この性質によって、 事前集計の戦略 (どこまでキューブで保持するか) が決まる。

4. 関連数式

$$ \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$ を満たすセルだけ抽出した部分キューブ。

5. 計算量と最適化

$k$ 次元・各 $n$ 値のキューブはセル数 $n^k$ となり、 次元数増加で指数的に膨張する (次元の呪い)。 実用システムでは:

6. SSDSE-B-2026 での適用例

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 =$ 地域ブロック(東 / 西)、 指標 = 人口(万人)と高齢化率(%)。

データ(5 都道府県抜粋)

都道府県ブロック人口(万人)高齢化率(%)
北海道東509.233.0
東京東1408.622.8
愛知西747.725.7
大阪西876.327.7
沖縄西146.823.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.927.90
西590.2725.73

Python で同じ計算を再現する

このコードでやること:上記の手計算を pandas の pivot_table で再現し、 東/西ブロック別の平均人口・平均高齢化率を求める。

📥 入力データ(上記 5 行):

都道府県 ブロック 人口 高齢化率 北海道 東 509.2 33.0 東京 東 1408.6 22.8 愛知 西 747.7 25.7 大阪 西 876.3 27.7 沖縄 西 146.8 23.8
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}")

📤 実行すると次の出力が得られる:

人口 高齢化率 ブロック 東 958.90 27.90 西 590.27 25.73 --- 東:人口= 958.9000, 高齢= 27.9000 西:人口= 590.2667, 高齢= 25.7333

💬 手計算と Python 出力が一致(東: 人口 958.9 万人・高齢化率 27.90%、 西: 590.27 万人・25.73%)。 東は東京都 1,408.6 万人に引っ張られて平均が大きく、 高齢化率は北海道 33.0% と東京都 22.8% の差が 10 ポイント以上あるので、 平均 27.90% はどちらの都道府県の実態とも離れている。 これが多次元分析の核心 — 次元の値で行をグループ化し、 集約関数を適用するだけで「N 次元キューブのスライス」が実現される。

✏️ 演習問題

問:上のデータに「東北」ブロック(青森: 人口 118.4 万人, 高齢化率 35.2%)を追加した。 3 ブロック(東/東北/西)の平均高齢化率ピボットを手計算せよ。
また、 「東北の高齢化率が最も高い」という洞察を得るには、 どの次元でスライスすれば良いか。
解答:東北ブロック(青森のみ)の平均高齢化率 = 35.2%。
東 = 27.90%、 西 = 25.73%、 東北 = 35.2%
→ ブロック次元でスライスし、 高齢化率でソートすれば「東北が最高」と一目で分かる。

🐍 Python での実装例

このコードでやること:SSDSE-B-2026 の都道府県データを読み込み、 最新年度(2023 年度)の 47 都道府県を 8 地方ブロックに分け、 地方ブロック次元で pivot_table(多次元集計)を実行して総人口の平均と都道府県数を得る。

📥 入力データ(SSDSE-B-2026.csv を header=1 で読み、 2023 年度に絞った先頭 3 行):

年度 地域コード 都道府県 総人口 ... 2023 R01000 北海道 5092000 ... 2023 R02000 青森県 1184000 ... 2023 R03000 岩手県 1163000 ... …(全 47 行)
 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 ブロック。 ブロック名の文字コード順に並ぶ):

mean count 総人口 総人口 ブロック 中国 1.414000e+06 5 中部 2.305444e+06 9 九州・沖縄 1.753625e+06 8 北海道 5.092000e+06 1 四国 8.945000e+05 4 東北 1.386333e+06 6 近畿 3.141429e+06 7 関東 6.218143e+06 7

💬 平均総人口は関東 621.8 万人が最大、 四国 89.5 万人が最小で約 7 倍の開きがある。 北海道は 1 道だけなので平均 509.2 万人はそのまま北海道の値で、 県数(count)を並べておかないと「北海道ブロックは大きい」と誤読しやすい。 関東の平均も東京都 1,408.6 万人に引き上げられているので、 規模を比べるなら合計や中央値も並べる。 ブロック次元でスライスするだけで「地域ごとの規模感」が一覧できる。 これが多次元分析の核心 — 集計の軸(次元)を切り替えることで、 同じデータから異なるインサイトを得られる。

※ data/raw/SSDSE-B-2026.csv は e-Stat SSDSE から取得した実データを想定。

🧪 CUBE とドリルダウンを pandas で確かめる(2012 年度と 2023 年度)

🎯 このコードでやること:SQL の GROUP BY CUBE(年度, ブロック) が返す 4 通りの集計を pandas の groupby で作り、 ブロック → 県とドリルダウンして人口の増減がどこで起きたかを探す。

📥 入力例 SSDSE-B-2026.csv から 2012 年度と 2023 年度の 94 行(47 県 × 2 年度) 年度 Code Prefecture A1101(総人口) 2023 R13000 東京都 14,086,000 2012 R13000 東京都 13,234,000 …(全 94 行。ブロックは地域コードの県番号から作る)
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('増減_万人'))
📤 実行例(実測) (年度, ブロック) 16 行 (年度) 2 行 (ブロック) 8 行 () 1 行 年度 2012 2023 増減_万人 増減率_% ブロック 東北 915.8 831.8 -84.0 -9.2 四国 393.0 357.8 -35.2 -9.0 北海道 546.5 509.2 -37.3 -6.8 中国 751.7 707.0 -44.7 -5.9 中部 2161.3 2074.9 -86.4 -4.0 九州・沖縄 1455.8 1402.9 -52.9 -3.6 近畿 2269.5 2199.0 -70.5 -3.1 関東 4265.3 4352.7 87.4 2.0 ロールアップ(全国): 2012 年度 12758.9 万人 → 2023 年度 12435.3 万人(-323.6 万人、-2.54%) 年度 2012 2023 増減_万人 Prefecture 茨城県 294.7 282.5 -12.2 栃木県 199.2 189.7 -9.5 群馬県 199.4 190.2 -9.2 千葉県 620.0 625.7 5.7 埼玉県 721.6 733.1 11.5 神奈川県 907.0 922.9 15.9 東京都 1323.4 1408.6 85.2

💬 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 つの典型的失敗パターンと対策を示す。

❌ 1. 次元爆発 (Curse of Dimensionality)

10 次元 × 各 10 値で 10¹⁰ = 100 億セル。 全データ保持は不可能。 対策: スパース表現 (実データがあるセルのみ保持)、 遅延評価 (要求時に集計)、 事前集計の選択的キャッシュ (使用頻度の高い断面のみ Materialized View 化)、 列指向 + 圧縮 (Parquet, Arrow)。

❌ 2. 集計階層の混同 (Simpson's Paradox)

「都道府県の平均」を単純平均すると「全国平均」と一致しない。 重み (人口) を考慮した加重平均が必要。 例: 東京の出生率を 47 県平均で扱うと、 人口比重が無視されて誤った全国像となる。 対策: 集計時に常に「重み」を意識、 上位集計は元データから再計算、 中央値・最頻値も同様に注意。

❌ 3. 可視化過多 (Visualization Overload)

多次元を 2D グラフに無理に詰めると逆に分かりにくい。 5 次元以上を 1 枚に表現するのは認知的負荷が大きい。 対策: 小倍数 (Small Multiples) (同じグラフを次元別に並べる)、 動的フィルタ (インタラクティブ BI)、 次元削減 (PCA / t-SNE で 2D に投影)、 ファセット分割 (Tableau / Vega-Lite)。

❌ 4. リアルタイム性の限界

OLAP キューブの更新は重く、 ストリーミング分析とは別物。 リアルタイム集計が必要なら別の技術 (Apache Druid / ClickHouse) を使う。 対策: バッチ集計 + ストリーミング集計の組合せ (Lambda 構造)、 マテリアライズドビューの定期更新、 増分更新可能なクエリエンジン。

❌ 5. 集約関数の非保持性

「中央値」「分散」「異なる値の数 (COUNT DISTINCT)」は階層をまたぐと値が変わる (元データから再計算が必要)。 事前集計で正しい結果を得るには元データを保持し続ける必要があり、 ストレージコストが増える。 対策: HyperLogLog / T-Digest など近似集計アルゴリズムで階層保持性を確保。

❌ 6. 次元の意味的曖昧さ

「業種」次元の値「製造業」と「製造」が混在、 「2024 年度」と「2024 年」が異なる定義を持つなど、 次元値の表記揺れで集計結果が誤る。 対策: マスターデータ管理 (MDM)、 ディメンションテーブルでの正規化、 ETL 段階での標準化、 階層辞書の文書化。

❌ 7. クエリパフォーマンスの予測困難

同じ OLAP システムでも、 クエリの組合せでパフォーマンスが大きく変動。 簡単な ロールアップは秒で返るが、 複雑な多次元結合は分単位かかることも。 対策: クエリプラン分析、 インデックス戦略、 キャッシュレイヤー (Redis / Memcached)、 パフォーマンステストを本番投入前に実施。

🧪 実データで確かめる: 比率はそのままロールアップできない

高齢化率のような比率を地方ブロックに集約するとき、 県の比率を平均するか、 分子と分母を合計してから割るかで値が変わる。 どちらも「ブロックの高齢化率」 と呼ばれがちなので、 実データで差を測っておく。

🎯 このコードでやること:2023 年度の 47 県について、 地方ブロックごとの高齢化率を (a) 県の高齢化率の単純平均と (b) 65 歳以上人口の合計 ÷ 総人口の合計の 2 通りで計算し、 差を並べる。

📥 入力例 SSDSE-B-2026.csv の 2023 年度 47 行 Code Prefecture A1101(総人口) A1303(65歳以上人口) R01000 北海道 5,092,000 1,681,000 R13000 東京都 14,086,000 3,205,000 R47000 沖縄県 1,468,000 350,000 …(全 47 行)
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} %")
📤 実行例(実測) 県数 (a) 県の率の平均 (b) 合計してから割る 差 (a)-(b) ブロック 関東 7 27.99 26.17 1.82 近畿 7 30.26 29.21 1.05 中部 9 31.26 29.69 1.57 九州・沖縄 8 31.54 30.59 0.95 中国 5 32.95 32.01 0.94 北海道 1 33.01 33.01 0.00 東北 6 34.48 33.54 0.94 四国 4 34.60 34.38 0.22 全国 (a) 47 県の率の平均 = 31.59 % 全国 (b) 65 歳以上計 / 総人口計 = 29.13 % 全国 (c) ブロックの (a) をさらに平均 = 32.01 %

💬 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) 集計・ グループ化 データ ウェアハウス ピボット テーブル BIツール (Tableau) データ マイニング ダッシュ ボード 前提 並列 発展 応用 現在の用語

② 包含関係マップ

📚 データサイエンス(広い分野)

┣ 可視化・データ探索

┗ 多次元分析 / OLAP(このページ)

┣ スライス(1 次元固定)

┣ ダイス(複数次元固定)

┣ ドリルダウン(細分化)

┗ ロールアップ(集約)

┣ 統計分析(相関・回帰・検定)

┗ 機械学習(予測・分類・クラスタリング)

🎯 3 つの視点の使い分け

視点 分かること こんな時に見る
🔗 関係マップ手法間の横の関係「次に何を学ぶべき?」
⭕ 包含マップ分類体系の入れ子構造「どんなジャンルに属する?」
🌳 ツリー操作・概念の親子関係「ドリルダウンの経路は?」

🔗 隣接手法への橋渡し

多次元分析(OLAP)と周辺の統計・可視化手法はどう違い、 どう繋がっているか。

多次元分析 ↔ 単純集計

単純集計は「全体の合計」だけ。 多次元分析は「N 個の次元で切り出した部分集合」に対して集計する。 Excel の SUM と pivot_table の違いに相当。

観点単純集計多次元分析
軸の数0(全体)1〜N(任意の次元)
問いへの対応固定アドホック(都度変更可)
代表ツールSQL SUM/COUNTOLAP cube / pivot_table

多次元分析 ↔ 機械学習

多次元分析は 記述・探索 が目的(何が起きているかを集計して見る)。 機械学習は 予測・分類 が目的(次に何が起きるかを学習する)。 前処理・特徴量エンジニアリングのステップとして多次元分析は機械学習の上流に位置する。

多次元分析 ↔ PCA(主成分分析)

多次元分析は ユーザー定義の次元(年・地域・商品)で集計する。 PCA は データ駆動の次元(分散最大化方向)に変換する。 「どの軸で切るか」が人間が決めるか、 データが決めるかの違い。

観点多次元分析 (OLAP)PCA
次元の定義ユーザー定義(カテゴリ)データ駆動(連続値)
出力集計テーブル(平均・合計)主成分スコア
解釈性高い(軸の意味が明確)低い(数学的な抽象軸)

🌳 手法選択フロー

「多次元分析(OLAP)を使うべきか」を判断する実用フロー。 分析目的とデータの性質で選び分ける。

判断ステップ

  1. 分析目的は「記述・探索」か「予測」か?
    • 「現状把握・集計・KPI 確認」→ 多次元分析(OLAP / BI ツール)
    • 「未来予測・分類・スコアリング」→ 機械学習(回帰・ランダムフォレスト等)
  2. 集計の次元(軸)は事前に決まっているか?
    • 次元が固定(例:年×地域×商品)→ OLAP cube / SQL GROUP BY
    • 次元がアドホック(都度変わる)→ BI ツール(Tableau / Power BI)
    • 次元を自動発見したい → PCA / クラスタリング
  3. データのサイズは?
    • 〜数百万行 → pandas / Excel の pivot_table
    • 億行超 → MOLAP(Redshift / BigQuery / Snowflake)
  4. 次元数(N)はどのくらいか?
    • 2〜5 次元 → OLAP cube が効率的
    • 10 次元超 → スパース問題に注意。 次元削減後に分析
  5. リアルタイム性が必要か?
    • バッチ処理で OK → 伝統的 OLAP
    • リアルタイム → ストリーミング集計(Flink / Spark Streaming)

クイック比較表

手法 目的 次元定義 規模 解釈性
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 の 12 ルール (1993)

Codd は OLAP システムが満たすべき 12 のルール (後に拡張版で 18 ルール) を提示した。 主要ルール:

OLAP クエリの典型パターン

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 種類のサブ合計が出力される (全体、 年別、 県別、 商品別、 年×県、 年×商品、 県×商品、 詳細)。

BI ツールでの実装例

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 を使った実用例

SSDSE-B-2026 (47 都道府県 × 12 年 × 100 超指標) を多次元キューブとして扱う具体例:

OLAP の限界と次世代

OLAP は強力だが限界もある。 (1) 事前集計の更新コスト (キューブ再計算が重い)、 (2) スキーマ変更への弱さ (新次元の追加が大変)、 (3) 非構造化データ (テキスト・画像) との相性が悪い。 次世代の動向: セマンティック層 (dbt + Cube.js) で SQL とBI を統合、 ストリーミング OLAP でリアルタイム集計、 AI + OLAP で自然言語クエリ (例: 「東京の出生率を 5 年で見せて」)、 レイクハウス (Delta Lake / Iceberg) でデータレイクと DWH の統合。

参考文献・教材

📖 補足: FAQ と業界ベンチマーク

よくある質問 (FAQ)

Q1. OLAP と OLTP の違いは?

OLAP は分析処理 (集計クエリ・読み取り中心・大量データ・低頻度更新)、 OLTP は取引処理 (高頻度更新・小規模クエリ・整合性重視)。 同じデータベースで両方やると性能が悪化するため、 OLTP の本番 DB から OLAP の DWH に ETL でデータを移すのが標準パターン。

Q2. なぜ多次元キューブが速いのか?

主な高速化要因は (1) 事前集計 (Materialized View / pre-aggregation)、 (2) 列指向ストレージ (集計クエリで読むカラムだけ I/O)、 (3) 圧縮 (列単位で同じデータ型のため高圧縮率)、 (4) ベクトル化処理 (SIMD で同時並列計算)、 (5) インメモリ化 (RAM コストが下がり実用化)。

Q3. データレイクと DWH の違いは?

DWH は構造化済みデータを正規化して保存 (スキーマ・オン・ライト)。 データレイクは生データをそのまま保存 (スキーマ・オン・リード)。 DWH は分析に最適化、 データレイクは柔軟性重視。 最近のレイクハウス (Delta Lake / Iceberg / Hudi) は両者の良いとこ取りを目指す。

Q4. リアルタイム OLAP は可能か?

従来の OLAP は事前集計に時間がかかるためバッチ処理が主流。 しかし Apache Druid / Pinot / ClickHouse などのストリーミング OLAP では、 取込みから秒〜分単位での集計が可能。 ただし「リアルタイム性」と「複雑な多次元結合」はトレードオフ。

Q5. クラウドとオンプレ、 どちらを選ぶべきか?

2020 年代はクラウド優位。 理由: (1) 弾性スケーリング (ピーク時のみリソース増)、 (2) 運用負担軽減 (DBA レス)、 (3) 従量課金 (固定資産化不要)、 (4) 最新機能の即時利用。 ただしデータガバナンス / 主権 / 機密度の高い業界 (金融・医療) ではオンプレやプライベートクラウドを選ぶ場合もある。

導入決定フレームワーク

新規 OLAP システム導入時の判断基準:

  1. データ規模: 数 GB ならローカル (DuckDB)、 数 TB ならクラウド DWH、 数 PB なら分散 OLAP (ClickHouse / Druid)
  2. クエリ頻度・並列度: 数人なら DuckDB、 数十〜数百人なら ROLAP / クラウド DWH、 数千人なら専用 OLAP
  3. リアルタイム性: 日次集計で十分なら DWH、 秒〜分単位ならストリーミング OLAP
  4. 更新頻度: 月次・四半期更新なら MOLAP、 リアルタイム更新ならカラムナー DB
  5. 予算: クラウド DWH は従量課金で初期コスト低、 オンプレは固定費高だが TCO で安い場合も
  6. 運用体制: DBA リソースが限られるならマネージドサービス、 専門チームがあるならカスタマイズ可能なオープンソース

典型的なアンチパターン

📖 補足: 実務ベストプラクティス

設計時の指針

新規 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 ツール → データキューブ → 次元モデリング の順で読むのがおすすめ。

多次元分析は単なる集計テクニックではなく、 「データから洞察を引き出し、 意思決定につなげる」全社的な能力を支える基盤技術。 本ページの内容を起点に、 自分の組織やプロジェクトでの実践に活かしてほしい。

✅ 理解度チェック — 1 分で答える確認問題(多次元分析の実装と運用)

多次元分析は知識として読むだけでは身に付かない。 OLAP キューブ・スター/スノーフレークスキーマ・ROLAP/MOLAP/HOLAP の使い分け・SSDSE-B 47 都道府県データでの集計などを実装ステップとして理解しているか、 以下の問いで確認しよう。 各問は 30 秒〜2 分で回答できるレベルに設計してある。

セット A: 基礎概念(10 問)

  1. 次元 (Dimension) とメジャー (Measure) の違い: 「都道府県」「年」「販売額」のうち、 次元はどれでメジャーはどれか。 また理由を 1 行で述べよ。
  2. スター・スキーマ vs スノーフレーク・スキーマ: 両者の構造上の最大の違いを 1 行で述べ、 SSDSE-B-2026 の 47 都道府県 × 12 年 × 多変数構造を OLAP に乗せる場合、 どちらが適切か理由付きで答えよ。
  3. OLAP 5 操作: ロールアップ・ドリルダウン・スライス・ダイス・ピボットの 5 操作のうち、 「47 都道府県の地域ブロック別集計」「2017 年だけ抽出」「縦軸と横軸を入れ替え」の 3 操作はそれぞれ何に該当するか。
  4. ROLAP / MOLAP / HOLAP の使い分け: データ量が 10TB を超え、 同時利用ユーザーが 500 人の場合、 どれを選ぶべきか。 理由を 1-2 行で述べよ。
  5. ファクトテーブルと粒度: 「都道府県 × 年 × 月」 と「都道府県 × 年」 ではファクトテーブルの行数は何倍違うか。 SSDSE-B-2026 (47 県 × 12 年) で実数値で答えよ。
  6. サマリ集計の事前計算: なぜ MOLAP では事前にすべてのロールアップを計算してキューブ化するのか。 トレードオフを 1 行で説明せよ。
  7. ピボットテーブルとの違い: Excel のピボットテーブルと OLAP キューブの本質的な違いを 1 行で述べよ (容量、 速度、 メタデータ管理 のいずれかに着目)。
  8. Slowly Changing Dimension (SCD): 都道府県の市町村合併などで「岡山市」が「岡山市 + 旧建部町 + 旧瀬戸町」に変わった場合、 過去の集計結果を保持するために OLAP では何を導入するか。 用語名 (SCD Type 1/2/3) で答えよ。
  9. カーディナリティと最適化: 都道府県次元 (47 値) と性別次元 (2 値) のうち、 ビットマップインデックスが効くのはどちらか。 理由を 1 行で。
  10. パーティショニング: 7 年分の売上データを高速集計するために、 「年」次元でパーティショニングする場合、 どんなクエリで効果が出るか。 1 例挙げよ。

セット B: SSDSE-B-2026 ハンズオン(10 問)

  1. 地域ブロック集計: pandas で SSDSE-B-2026 を読み込み、 47 都道府県を「北海道 / 東北 6 / 関東 7 / 中部 9 / 近畿 7 / 中国 5 / 四国 4 / 九州沖縄 8」の 8 ブロックに分けて 2023 年の人口 (A1101) を合計するコードを 3 行で書け。
  2. ピボット: 「行: 都道府県、 列: 年 (2017-2023)、 値: 出生数 (A4101)」 という形にピボットするコードを 1 行で書け。
  3. 多年度成長率: 各都道府県の 2017 年と 2023 年の人口比を算出し、 増加率が最も大きい 5 県、 減少率が最も大きい 5 県を抽出するコード骨格を 5 行以内で書け。
  4. 地域 × 年 × 指標 の 3 次元キューブ: 地域ブロック (8) × 年 (7) × 指標 (総人口 A1101/出生数 A4101/高齢人口 A1303) という 3 次元のサマリテーブルを作るコードを 5 行で書け。
  5. シェア計算: 各都道府県の人口が全国に占める割合 (%) を算出するコードを 2 行で書け。 8 ブロック集計を分母にする場合との違いも 1 行で説明せよ。
  6. 変動係数: 47 都道府県の人口の変動係数 (CV = SD / Mean) を 2017 年と 2023 年で比較するコードを 3 行で書け。 結果値も推定で答えよ (人口 SD/Mean が概ね 1.5 前後)。
  7. ローレンツ曲線: 47 都道府県の人口分布のローレンツ曲線を描き、 ジニ係数を算出するコードを 8 行で書け。 (ヒント: ソート → 累積比率 → 面積積分)
  8. 地域ブロック × 年 × 業種別 集計: SSDSE-B-2026 の「業種別事業所数 (J*)」 列を、 地域ブロック × 年 × 業種 で集計するコードを 4 行で書け。
  9. 結合分析 (内部結合): 別の SSDSE データセット (例: 賃金) を 都道府県コードで結合し、 人口あたり賃金 (= 賃金 / 人口) を算出するコードを 3 行で書け。 LEFT JOIN を pandas でどう表現するかも答えよ。
  10. BI ツール エクスポート: 上記サマリを Tableau や Power BI で読めるよう、 縦持ち (long format) に変換するコードを 1 行で書け。 横持ち (wide format) との利点を 1 行で説明。

セット C: 実務応用と落とし穴(10 問)

  1. 集計の二重カウント: 親子関係のある次元 (国 → 地方 → 県) で粒度を混ぜて集計したとき、 何が起きるか。 SSDSE-B-2026 を例に説明せよ。
  2. 欠損値の伝搬: 1 セルでも NaN があると、 集計結果は SUM・MEAN・MEDIAN のどれが NaN になるか。 pandas のデフォルト挙動と skipna オプションの違いを 1 行で。
  3. シンプソンのパラドックス: 多次元分析で集計レベルを変えると結論が逆転する典型例を、 SSDSE-B-2026 の文脈で 1 つ挙げよ。
  4. キューブの肥大化: 次元数を 10 に増やすと、 サマリの組合せは何通りになるか (各次元 5 値と仮定)。 これを「次元の呪い」とどう結びつけるか。
  5. セキュリティ・行列レベル制御: 部門別のデータを部門マネージャーだけが見られるよう、 OLAP でどう制御するか (RLS、 CLS の用語で説明)。
  6. パフォーマンス改善: 集計クエリが 5 秒かかる場合、 OLAP の世界では何を最初に確認するか 3 つ挙げよ (インデックス、 集計表、 キューブ設計 のいずれか)。
  7. キャッシュ無効化: 元データが更新された時、 OLAP キューブのキャッシュをどう無効化するか。 タイミングとトリガーの 2 軸で考察せよ。
  8. BI ダッシュボード設計: 1 画面に何個のチャートを置くのが適切か。 学術的に推奨される認知負荷の上限 (Miller の 7±2) と照らして答えよ。
  9. 因果と相関: 多次元分析で「相関が強い」と分かっても、 因果を主張できない理由を 1 行で。 (交絡変数、 逆因果、 選択バイアス のうち最も典型を 1 つ)
  10. レポート自動化: 毎週月曜に SSDSE-B-2026 から地域別人口推移レポートを自動生成する場合、 Python + cron / Airflow / dbt のどれを使うか。 各選択肢の利点・欠点を 1 行ずつで。

図解 1: OLAP キューブの 3 次元構造

キューブの直感を掴むため、 「都道府県 × 年 × 指標」 の 3 次元構造を立方体として可視化する。 セル 1 つが 1 サマリ値を保持する。

3 次元 OLAP キューブ (都道府県 × 年 × 指標) の構造図

図解 2: スター・スキーマ vs スノーフレーク・スキーマ

OLAP の物理設計でよく比較される 2 つのスキーマを並べて可視化する。 スター・スキーマは中央のファクトテーブルを次元テーブルが「星状」に取り囲む構造、 スノーフレーク・スキーマは次元テーブルがさらに正規化された構造。

スター・スキーマとスノーフレーク・スキーマの比較図

図解 3: OLAP 5 操作(ロールアップ・ドリルダウン・スライス・ダイス・ピボット)

OLAP の代表的な 5 操作を 1 枚にまとめる。 多次元分析では、 ユーザーがこれらの操作を組合せながらデータを「角度を変えて眺める」ことで洞察を得る。

OLAP 5 操作 (ロールアップ・ドリルダウン・スライス・ダイス・ピボット) の概念図

SSDSE-B-2026 を使った深掘り演習

多次元分析の概念は SSDSE-B-2026 のような実データを使った演習で初めて身に付く。 以下に 5 つの段階的な演習を示す。 上から順に取り組むことで、 多次元分析の全体像を体系的に把握できる。

演習 1: スター・スキーマ設計 (15 分)

SSDSE-B-2026 を OLAP 化することを想定し、 ファクトテーブルと次元テーブルを設計する。 ファクトテーブルは「都道府県 × 年 × メジャー」の粒度、 次元テーブルは「都道府県マスター (47 行)」「年マスター (7 行)」「指標マスター (N 行)」の 3 つ。 SQL の CREATE TABLE 文を 4 つ書き、 主キー / 外部キー / インデックスを定義せよ。 SSDSE-B-2026 が縦持ち (long format) ではなく横持ち (wide format) で配布されている点も考慮、 まず pandas で melt() してから挿入する手順を整理する。

演習 2: ロールアップ / ドリルダウン の実装 (20 分)

都道府県 → 8 地方ブロック → 全国 の 3 階層を pandas で表現し、 ロールアップ (集計レベルを上げる) とドリルダウン (集計レベルを下げる) の 2 操作をそれぞれ 1 行ずつで実装する。 SSDSE-B-2026 の人口 (A1101) を集計対象とし、 各レベルでの値を表で出力。 結果として、 全国レベルでは 1 行、 地方ブロックレベルでは 8 行、 都道府県レベルでは 47 行が得られることを確認。

演習 3: スライス / ダイス の比較 (15 分)

スライスは「特定の年 (例: 2023 年) だけ抜き出す」 1 次元の固定、 ダイスは「2017-2019 の 3 年 × 関東 7 県」のように 2 次元以上を固定して切り出す操作。 これを pandas の query() / loc[] / boolean indexing で実装し、 切り出し前後の行数を比較。 SSDSE-B-2026 (47 県 × 12 年 = 564 行) → スライス後 47 行、 ダイス後 21 行。

演習 4: ピボット による軸入れ替え (15 分)

SSDSE-B-2026 を「行: 都道府県、 列: 年、 値: 人口」 でピボットし、 さらに「行: 年、 列: 都道府県、 値: 人口」 に転置する。 pandas の pivot_table() と transpose() を使い分け、 BI ツールでの可視化に適した形式に変換する。 結果として、 同じデータでも見え方が大きく変わることを実感する。

演習 5: 多次元分析の意思決定への接続 (30 分)

最終的に、 多次元分析の結果を意思決定にどう結びつけるかを考察する。 SSDSE-B-2026 から「人口減少率が大きい都道府県 TOP 5」「高齢人口 (A1303) の地方ブロック別シェア」「消費支出 (L3221) の年次推移」 の 3 つの視点でレポートを作成し、 それぞれについて「もし君が市町村政策の意思決定者なら、 何を提案するか」 を 200 文字程度で書く。 多次元分析は単なる集計テクニックではなく、 「データから洞察を引き出し、 意思決定につなげる」 能力を支える基盤技術であることを実感できるだろう。

多次元分析 まとめ — 14 のキーポイント

  1. 多次元分析は OLAP (Online Analytical Processing) の中核技術で、 集計済みデータをキューブ化して高速に集約クエリを実行する。
  2. 次元 (Dimension) は「都道府県」「年」「商品カテゴリ」 のような分類軸、 メジャー (Measure) は「販売額」「人口」 のような集計対象値。
  3. OLAP キューブは 3 次元以上のサマリ集合、 セル 1 つが「次元値の組合せ ↦ メジャー値」 を保持。
  4. スター・スキーマは中央のファクトテーブルを次元テーブルが星状に取り囲む構造、 ジョイン回数が少なく高速。
  5. スノーフレーク・スキーマは次元テーブルがさらに正規化、 ストレージは節約できるが集計時のジョインが増える。
  6. ROLAP は SQL クエリで集計、 大量データに対応するが速度に注意。 MOLAP は事前計算したキューブを保持、 速いが容量が爆発する。 HOLAP は両者の中間。
  7. OLAP 5 操作 (ロールアップ / ドリルダウン / スライス / ダイス / ピボット) はユーザーがデータを「角度を変えて眺める」 ための基本動作。
  8. SSDSE-B-2026 のような縦長 (long format) データは pandas の melt() で長持ちに変換し、 pivot_table() でキューブ風に集計するのが定石。
  9. シンプソンのパラドックスは多次元分析の典型的な落とし穴、 集計レベルによって結論が逆転する。
  10. 「次元の呪い」 はメンバ数が多次元化すると組合せが指数的に増加する問題、 OLAP では事前集計のサイズが肥大化する。
  11. セキュリティは行レベル / 列レベルで制御可能、 BI ツール (Tableau / Power BI / Looker) でも標準機能として提供される。
  12. キャッシュ無効化は OLAP の運用で最も難しい問題の一つ、 ETL のスケジュールに合わせて自動化する。
  13. BI ダッシュボードの設計では、 認知負荷の上限 (Miller の 7±2) を意識し、 1 画面のチャート数を 7 以下に抑えるのが望ましい。
  14. 多次元分析は最終的に「意思決定にどう活かすか」 が問われる、 単なる集計テクニックではなく、 ビジネス価値創出の基盤技術である。

以上で多次元分析の理解度チェックは終了。 各セットを終えた段階で、 自分の弱点が明確になっているはずだ。 弱点については用語集の関連ページ (RDB / SQL / DWH / BI ツール) を読み返して理解を深めよう。 多次元分析は実践で力を発揮する技術なので、 実プロジェクトで使う機会を見つけて手を動かすことが何より重要だ。

📚 多次元分析の深掘り読み物 — 実務での活用と進化の歴史

ここでは多次元分析を初学者から実務家へとレベルアップするための深掘り読み物を提示する。 単に技術用語の定義を覚えるだけではなく、 「なぜそのアプローチが生まれたか」「どんな製品で実装されているか」「クラウド時代に何が変わったか」 といった文脈をしっかり理解することで、 自分の組織やプロジェクトで多次元分析をどう導入すべきかの判断軸が身に付く。

主要 OLAP ベンダー・製品 — 何を選ぶべきか

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 点で記述する。

多次元分析の総合演習問題 — 自分で考える 5 問

  1. SSDSE-B-2026 を使い、 47 都道府県を 8 地方ブロックに分けて、 2017 年と 2023 年の人口変化を地方ブロック別に集計せよ。 結果を表とグラフで示し、 どの地方ブロックで人口減少が顕著かを 100 文字で論評せよ。
  2. SSDSE-B-2026 の出生数 (A4101) と総人口 (A1101) を組合せて、 人口千人あたり出生数(粗出生率 = A4101 / A1101 × 1000)を算出、 都道府県別ランキングを作成。 上位 5 県と下位 5 県の差は何倍か、 また地方ブロック別にどのような傾向があるかを 150 文字で論評せよ。
  3. SSDSE-B-2026 で時系列分析を行うため、 2017 年から 2023 年までの 7 年間の人口変化率を都道府県別に算出、 増加率上位 5 県と減少率上位 5 県を抽出。 地理的・経済的にどのような特徴があるかを 150 文字で論評せよ。
  4. SSDSE-B-2026 を使ったシンプソンのパラドックスの例を 1 つ作れ。 全国レベルでは正の相関だが、 地方ブロック別では負の相関、 という例題を探し、 ピボットテーブルで示せ。 なぜそうなるのかを 100 文字で説明。
  5. SSDSE-B-2026 から得た知見をもとに、 仮想の自治体政策担当者の立場で、 「人口減少地域への支援策」 を 1 つ提案せよ。 OLAP のドリルダウン操作で具体的な課題を特定し、 政策のターゲットと期待効果を 200 文字で説明。

🎮 体感: 簡易 OLAP ラボ(SSDSE-B-2026 実データ)

直感 — データの立方体を切り分ける。 ここでは 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 県の小計であり全国値ではない点に注意。

🔥 ヒートマップ(同じ集計を色で可視化)

濃いほど値が大きい。 セルにカーソル / 指を合わせると値を表示(タッチ対応)。

⚠️ 落とし穴

🚀 発展

このラボは端末上の pivot_table 相当を手作りしたもの。 実務ではキューブの原料をデータウェアハウス (DWH) に貯め、 中央のファクトテーブルと周辺のディメンションテーブルからなるスタースキーマで次元モデリングし、 BI ツール(Tableau / Power BI / Looker)でドラッグ操作すると裏で SQL の GROUP BY … WITH ROLLUP / CUBE に翻訳される。 身近には スプレッドシートのピボットテーブルが同じ操作を提供し、 可視化の型はデータ可視化の技法に連なる。

🎨 直感の深化 — キューブ=「次元 × 指標」、5 操作の再整理

上の「直感で掴む」を一歩進める。 多次元分析の核は 「複数の軸(次元)でデータを切り分けて集計する」 一点に尽きる。 キューブとは (次元1 × 次元2 × … × 次元k) の各マスに指標(メジャー)の集計値を入れた格子であり、 セル数は各次元の値数の掛け算で決まる。 SSDSE-B-2026 なら「都道府県(47) × 年 × 指標」がそのまま 3 次元キューブになる。

5 操作を「何を固定し、 何で集計するか」で捉え直す

操作 やること(軸の観点) SSDSE-B-2026 での例
スライス1 次元を 1 値に固定し断面を取る「2023 年」に固定 → 47 県 × 指標の 2D 表
ダイス複数次元を範囲で絞り部分キューブ「関東 7 県 × 2017-2023 × 出生数」だけ
ドリルダウン階層を下げ粒度を細かく「地方ブロック → 都道府県」へ展開
ロールアップ階層を上げ粒度を粗く「都道府県 → 地方ブロック → 全国」へ集約
ピボット行と列に割り当てる次元を入替「県 × 年」表を「年 × 県」表へ転置

この 5 操作はどれも 「group by する軸をどう選ぶか」 の言い換えにすぎない。 ピボットテーブルで列に何を置くか、 SQL の GROUP BY に何を並べるかを操作しているのと同じ。 多変量の同時把握とは、 この格子の上で複数の指標(メジャー)を並べ、 軸を切り替えながら「規模」「水準」「構成比」を一度に眺めることを指す。

2 次元クロス集計 = キューブの 2 次元スライス

身近なクロス集計表(行カテゴリ × 列カテゴリ × 集計値)は、 多次元キューブを 2 次元に落とした最小形にほかならない。 「地方 × 指標」で 1 枚のクロス表を作れば、 それはキューブから 2 軸を取り出したスライスである。 次節ではこのクロス集計を SSDSE-B-2026 の実測値で作り、 そこに潜む落とし穴を確認する。

⚠️ 落とし穴の深掘り — 集約すると結論が変わる(実測クロス集計つき)

多次元分析の危うさは、 「同じデータでも、 どの軸・どの粒度・どの集計関数で切るかで結論が変わる」 点にある。 以下は SSDSE-B-2026(cp932, skiprows=[1])から 2023 年・47 都道府県を 8 地方ブロックに集約した実測クロス集計(地方 × 指標)である。 すべて実データの合計値で、 合成・捏造は含まない。

地方ブロック 県数 総人口 A1101 65歳以上 A1303 出生数 A4101 高齢化率 粗出生率‰
北海道15,092,0001,681,00024,43033.0%4.80
東北68,318,0002,790,00041,23733.5%4.96
関東743,527,00011,390,000252,91126.2%5.81
中部920,749,0006,161,000121,11029.7%5.84
近畿721,990,0006,423,000132,40629.2%6.02
中国57,070,0002,263,00042,46832.0%6.01
四国43,578,0001,230,00019,59834.4%5.48
九州・沖縄814,029,0004,291,00093,10930.6%6.64
全国計(47県)47124,353,00036,229,000727,26929.1%5.85

※ 高齢化率 = A1303 / A1101、 粗出生率 = A4101 / A1101 × 1000。 いずれも上表の実測合計から算出。 A1101・A1303 は千人単位に丸めた SSDSE-B-2026 の 2023 年値。

❌ 1. シンプソンのパラドックス/集約の順序依存(最重要)

全国の粗出生率を 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 万人)を同じ重みで平均してしまうこと。 「平均の平均」は元の平均に一致しない(集約の順序依存・非結合性)。 比率・中央値・分散・異なり数はロールアップで再計算が必要で、 上位集計は必ず元データの合計から取り直す。

❌ 2. 次元の呪い(組合せ爆発とスパース)

上表は「地方(8) × 指標(3)」の 24 セルで全て埋まる。 だが軸に「年齢 5 階級 × 性別 2 × 産業 20」を足すと 8×3×5×2×20 = 4,800 セルへ膨張し、 実データのある行はごく一部(スパース)になる。 都道府県(47)まで下げればさらに増える。 セルが疎になると各セルの標本が小さくなり、 集計値の分散が大きく偶然の凹凸を「発見」しやすい。 対策は重要次元だけ残す、 疎なセルはロールアップで束ねる、 マテリアライズドビューで「よく使う断面」だけ物理化する、 など。

❌ 3. 次元の粒度選択で見える差が変わる

同じ高齢化率でも、 全国 29.1%・地方ブロックでは 26.2%(関東)〜34.4%(四国)・都道府県まで下げるとさらに開く。 粗い粒度は地域差を平準化して隠し、 細かい粒度はスパース化して不安定になる。 ドリルダウンとロールアップを往復して両方の像を確認しなければ、 一つの粒度だけの結論は誤りうる。

❌ 4. 多重比較で「偽の発見」

クロス集計は軸と指標の組合せを総当たりで作れるため、 つい大量の相関・差の検定を同時に走らせがち。 有意水準 α=0.05 で無関係な比較を 100 回行えば、 期待値で約 5 件が「偶然の有意」になる。 SSDSE-B-2026 の 100 超指標を総当たりすれば偽陽性は容易に量産される。 対策は Bonferroni 補正や FDR 制御、 探索で見つけた仮説は別データ・別期間で確認すること(交差検証の発想)。 相関が出ても因果とは限らない点も併せて注意。

❌ 5. 可視化の限界(4 次元以上)

人が一目で読めるのは概ね 2〜3 軸まで。 4 次元以上を 1 枚に詰めると認知負荷で逆に読めない。 実務では小倍数(Small Multiples)で次元別にグラフを並べる、 ヒートマップで 1 軸を色に写す、 並行座標プロットや散布図行列で多変量を分解する、 あるいはPCA等で 2 次元へ投影する、 といった次元を減らす工夫が要る(発展節を参照)。

🚀 発展の深化 — 軸を圧縮する/多変量を可視化する

多次元分析は「人が決めた軸(次元)で集計する」手法だが、 軸が増えて手に負えなくなったら 軸そのものをデータから作り直す・減らす方向へ接続できる。

① 次元削減で軸を圧縮する

使い分けの勘所: 解釈が主目的で軸の意味を保ちたいなら OLAP のロールアップ、 軸が多すぎて全体像が掴めないなら次元削減で圧縮。 両者は排他ではなく、 削減後の主成分スコアを新たな「次元」としてキューブに載せ直すこともできる。

② 多変量可視化 — キューブを目で読む

③ クロス集計との関係

2 次元クロス集計(行カテゴリ × 列カテゴリ)は、 多次元キューブを 2 軸に落とした最小スライスであり、 ピボットテーブルで日常的に作るものと同じ。 カテゴリ同士の関連を統計的に検証したいときは、 クロス集計表にカイ二乗検定(独立性の検定)を適用する。 「集計して眺める(記述)」の OLAP と「関連を検定する(推測)」の橋渡しがここにある。 なお クロス集計・OLAP を単独で扱う専用ページは本用語集には未整備のため、 当面は本ページと ピボットテーブル・カイ二乗検定を併読するとよい。