論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
組合せ
Combination
数学基礎

🔖 キーワード索引

この用語と一緒に検索・参照されやすいタグ。 関連ページに飛ぶときの手がかりにも使えます。

#数学基礎#組合せ#二項係数#場合の数#C(n,k)

組合せに関する用語を 数え方の種類・記号・公式・応用 別に索引化します。「順番を区別するか」「同じものを何度選べるか」の 2 点で分類すると、公式を丸暗記せずに選べます。

カテゴリキーワード(日本語)キーワード(英語)
数え方の種類順列(並べる)、 組合せ(選ぶ)、 重複順列、 重複組合せ、 円順列permutation, combination, repeated permutation, multiset combination, circular permutation
記号nCk、 二項係数、 nPk、 n!(階乗)、 nHk(重複組合せ)nCk, binomial coefficient, nPk, factorial, nHk
基本公式nCk = n! / (k!(n−k)!)、 パスカルの規則、 対称性 nCk = nC(n−k)、 二項定理Pascal rule, symmetry, binomial theorem
図で覚えるパスカルの三角形、 格子路の数え上げ、 樹形図、 玉と仕切り(重複組合せ)Pascal triangle, lattice path, tree diagram, stars and bars
数え上げの道具包除原理、 鳩の巣原理、 母関数、 漸化式、 全単射による証明inclusion-exclusion, pigeonhole, generating function, recurrence, bijective proof
統計での出番二項分布、 超幾何分布、 組合せ爆発、 標本の取り方(何通りあるか)binomial distribution, hypergeometric, combinatorial explosion, sampling
実装math.comb、 math.perm、 itertools.combinations、 scipy.special.combmath.comb, math.perm, itertools.combinations, scipy.special.comb

💡 30秒で分かる結論

🍰 まずはやさしく

組合せは、グループからメンバーを選ぶ方法です。

選ぶ順番を気にせず、数えたいときに使います。

部活の代表者を数人で選ぶときなどに便利です。

ここでは、組合せの基本と計算方法を読みます。

組合せは、 n 個から k 個を順序を区別せず選ぶ方法の数。 確率・統計の根幹。

ここまでが要点です。 ただし実際に使う前に、 このページの「⚠️ よくある落とし穴」で挙げた 階乗オーバーフロー/組合せと順列の混同/0!=1 を忘れる には必ず目を通してください。 つまずくのは知識が無いときより、 知ってはいたが確認を飛ばしたときです。

📍 文脈:「組合せ」はどんな場面で出てくる?

🍰 まずはやさしく

組合せは、統計のあちこちで使われる道具です。

データの選び方や確率を考えるために使います。

スマホのアプリで、おすすめの商品を選ぶときなどです。

この道具がどんな問いに答えるのかを読みます。

確率分布(二項・超幾何)、 検定(Fisher の正確検定)、 機械学習(特徴量サブセット選択)など至る所で登場する基礎概念。

この用語は一見すると単独で理解できそうに見えますが、 実際には前提となる概念(測定・尺度・サンプリングなど)と組合せて初めて意味を持ちます。 「定義を覚える」より「どんな問いに答える道具なのか」を捉えるのが効率的です。

🎨 直感で掴む

🍰 まずはやさしく

組合せは、選んだあとの並び順を気にしないことです。

誰が先に選ばれたかではなく、誰が選ばれたかを見ます。

買い物で、好きな商品をいくつかカゴに入れるときです。

具体的にどういうことか、例を挙げて読みます。

「組合せ」は SSDSE-B-2026(47 都道府県 × 複数年 × 100 超列)に当てはめると、 47 都道府県から 2 県を選ぶ C(47,2)=1081 通り で具体化できます。 以下は実データを使った直感的理解の入口です。

💡 学習のコツ:上の比喩は厳密ではない点に注意。 組合せ の定義は次の「📐 数式」で押さえ、 「🧮 実値で計算」で 47 都道府県から 2 県を選ぶ C(47,2)=1081 通り を使って実感を伴う理解に到達するのが効率的です。

📐 定義・数式

🍰 まずはやさしく

組合せには、計算するための決まった式があります。

数を使って、正確な数を出すために使います。

テストの点数の配分を考えるときのように正確に数えます。

記号の意味と、計算のやり方を詳しく読みます。

やさしい説明で掴んだ感覚を、ここで 組合せの定義 の定義式に対応づけます。下の式は左辺 $\binom{n}{k}$ が何で決まるかを右辺で書き下したもので、分数(割り算) が現れます。それぞれの記号が何の量を指すのかは、次の「🔬 数式を言葉で読み解く」で 1 つずつ確かめてください。

【組合せの定義】
$$ \binom{n}{k} = \frac{n!}{k!\,(n-k)!} $$
n の階乗を、 k の階乗と (n-k) の階乗で割る。 大きな n では scipy.special.comb で計算。
📌 読み方のコツ:数式を見たら「左辺は何を定義しているか」「右辺の各項は何の合計・積・比か」を声に出して読み下してみる。 これだけで理解が大きく進みます。

🔬 数式を言葉で読み解く — 数式を「言葉」に翻訳

数式を眺めるだけでは身につかないので、 各記号がどんな役割を担っているかを言葉で押さえます。 「数式を音読する習慣」がつくと、 論文や教科書を読むスピードが体感で 2 倍ほど上がります。

n
選ぶ全体数
k
選ぶ個数
n!
n の階乗 = 1×2×...×n
C(n, k)
組合せ数(二項係数)
Pascal
パスカルの三角形の各成分
📚 補足:同じ記号でも分野・教科書によって意味が違うことがあります(例: $\hat{y}$ は予測値だが、 統計の文脈では推定量を意味することも)。 不明確なときは、 必ずその文書の記号定義表を確認しましょう。
📝 演習問題(記号の読み取り)

問 1:$\binom{6}{2}$ の n と k をそれぞれ答えよ。

問 2:$\binom{n}{0}$ の値は何か、 理由とともに答えよ。

問 3:$\binom{5}{5}$ の値を求めよ。

▶ 解答を表示
答 1:n = 6、 k = 2(6 個から 2 個を選ぶ)
答 2:$\binom{n}{0} = 1$。 0 個選ぶ方法は「何も選ばない」という 1 通りのみ。 定義式では $0! = 1$ なので $n!/(0! \cdot n!) = 1$。
答 3:$\binom{5}{5} = 1$。 5 個から 5 個全部選ぶ方法は 1 通りだけ。 $\binom{n}{n} = 1$ は一般公式。

🧮 実値で計算してみる

SSDSE-B-2026 の 47 都道府県から 3 県を選ぶ組合せ数 $C(47, 3)$ を、 定義式に実数値を代入して 3 ステップで手計算します。 まず対象となる数値ベクトルを示します:

入力値ベクトル (n, k): [47, 3] 分子の積成分: [47, 46, 45] ← 47 から降順に k=3 個 分母の積成分: [3, 2, 1] ← k! = 3! の各因数 分子 / 分母: [97290, 6] → 97290 ÷ 6 = 16215

Step 1: 階乗を求める

47! / (44!) = 47 × 46 × 45 (分子の約分後の 3 項) 3! = 3 × 2 × 1 = 6 (分母)

Step 2: 数値代入

定義式 $\binom{47}{3} = \dfrac{47!}{3!\,(47-3)!} = \dfrac{47 \times 46 \times 45}{3!}$ に実数値を代入:

47 × 46 = 2,162 2,162 × 45 = 97,290 97,290 ÷ 6 = 16,215

Step 3: パスカルの三角形で検算

C(47,3) = C(46,2) + C(46,3) = 1,035 + 15,180 = 16,215 ✓

手計算の結果 $C(47,3) = 16{,}215$ を Python で確認します(下の「🐍 Python 実装」セクションの comb(47, 3) が同じ値を返すことを確認してください)。

場面数式展開結果
5 人から 2 人5×4 / 2!10
47 都道府県から 3 県47×46×45 / 3!16,215
50 から 550×49×48×47×46 / 5!2,118,760
100 から 10Stirling 近似で推計≈ 1.73×10¹³

💬 手計算 C(47,3)=16,215 は後述の Python の math.comb(47,3) 出力と完全一致します。 「数式とコードの対応関係」がクリアに見えるようになります。

🧮 実値で計算してみる — SSDSE-B-2026(拡張版)

SSDSE-B-2026(公的統計の社会・教育系データセット)を用いて、 組合せ を体感します。 ファイルは data/raw/SSDSE-B-2026.csv。 読み込みコードは下記です。

🎯 このコードでやること:SSDSE-B-2026 を読み込み、 最新年度の 47 都道府県データを抽出する。

📥 入力:data/raw/SSDSE-B-2026.csv(564行 × 112列、 cp932 エンコード)

1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np

# SSDSE-B-2026 を読み込む(cp932 / Shift_JIS)。最初の行は英文ヘッダー、2 行目は日本語ヘッダー
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932')
print('shape:', df.shape)              # (564, 112)
print('years:', sorted(df['SSDSE-B-2026'].unique())[:5])
latest = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy()
print(latest[['Prefecture', 'A1101']].head())
📤 実行結果例:
shape: (564, 112)
years: [2012, 2013, 2014, 2015, 2016]
Prefecture A1101
0 北海道 5092000
12 青森県 1184000
24 岩手県 1163000
36 宮城県 2264000
48 秋田県 914000

💬 最新年度 (2023) の 47 行が latest に格納される。 以降の計算はこの 47 行を対象とする。

使用列 A1101(総人口(人))を中心に、 47 都道府県の最新値で 組合せ を計算します。

🎯 このコードでやること:A1101(総人口)の基本統計量(平均・標準偏差・分位)を計算し、 上位5・下位5県を表示する。

📥 入力:latest['A1101'](47行 × 1列)、 x = latest['A1101'].astype(float).values

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 基本統計:平均・標準偏差・四分位範囲
x = latest['A1101'].astype(float).values
print(f'n = {len(x)}')
print(f'mean = {np.mean(x):,.1f}')
print(f'std  = {np.std(x, ddof=1):,.1f}')
print(f'min  = {np.min(x):,.1f}  max = {np.max(x):,.1f}')
print(f'Q1 = {np.quantile(x, 0.25):,.1f}  Q3 = {np.quantile(x, 0.75):,.1f}')

# 上位 5 県・下位 5 県
top5 = latest.nlargest(5, 'A1101')[['Prefecture', 'A1101']]
bot5 = latest.nsmallest(5, 'A1101')[['Prefecture', 'A1101']]
print('TOP5\n', top5.to_string(index=False))
print('BOTTOM5\n', bot5.to_string(index=False))
📤 実行例(実測) n = 47 mean = 2,645,808.5 std = 2,797,551.4 min = 537,000.0 max = 14,086,000.0 Q1 = 1,034,000.0 Q3 = 2,636,500.0 TOP5 Prefecture A1101 東京都 14086000 神奈川県 9229000 大阪府 8763000 愛知県 7477000 埼玉県 7331000 BOTTOM5 Prefecture A1101 鳥取県 537000 島根県 650000 高知県 666000 徳島県 695000 福井県 744000

💬 平均 264.6 万人に対し中央値は 154.9 万人(Q1 103.4 万〜Q3 263.7 万人)で、平均は中央値の約 1.7 倍に引き上げられている。標準偏差 279.8 万人が平均より大きいのも、東京都 1,408.6 万人(最少の鳥取県 53.7 万人の約 26 倍)が引っ張るため。上位 5 都県だけで全国 1 億 2,435 万人の約 38% を占めるので、県を組み合わせて群を作るときは、どの 5 県を選ぶかで合計人口が桁違いに変わる点に注意する。

上記の結果から、 47 都道府県の 総人口(人) の散らばり方が一目で分かります。 続いて 組合せ の本来の演算を当てはめましょう。

🎯 このコードでやること:A1101(総人口)をzスコア化し、 四分位グループに分けて各群の平均・標準偏差・件数を確認する。

📥 入力:latest['A1101'](47行・総人口(人))

1
2
3
4
5
6
7
8
9
# 標準化(zスコア化)
z = (x - x.mean()) / x.std(ddof=1)
print('z (head 5) =', np.round(z[:5], 3))

# 下位 25% / 中位 50% / 上位 25% の 3 グループに分けて平均差を確認
import pandas as pd
g = pd.qcut(latest['A1101'], q=[0, 0.25, 0.75, 1.0], labels=['low', 'mid', 'high'])
grp = latest.assign(group=g).groupby('group', observed=True)['A1101'].agg(['mean', 'std', 'count'])
print(grp)
📤 実行結果例:
z (head 5) = [ 0.874 -0.523 -0.53 -0.136 -0.619]
mean std count
low 804000 152224.7 12
mid 1603435 414420.4 23
high 6485500 3210209.0 12

💬 qcut の区切りは 25%・75% 点なので、県数は 12・23・12 に分かれる。high 群の平均 648.6 万人は low 群 80.4 万人の約 8 倍で、標準偏差 321.0 万人も突出して大きく、東京都を含む上位 12 県の中でも規模の差が大きいことが分かる。「high から 2 県・low から 1 県を選ぶ」ような層別の選び方なら C(12,2)×C(12,1)=792 通りになる。

🧮 数式に値を入れて手で計算する: 組合せ C(n,k)

n=5, k=2 で C(5,2) を定義通り計算する。

Step 1: 階乗

5! = 120 2! = 2 3! = 6

Step 2: 組合せ

C(5,2) = 5!/(2!·3!) = 120/(2·6) = 120/12 = 10

Step 3: パスカル三角形検算

C(4,1)=4, C(4,2)=6, C(5,2)=C(4,1)+C(4,2)=4+6=10 ✓

🐍 Python で再現

🎯 このコードでやること:上の手計算 (n=5,k=2) を math.comb と factorial で再現し、 手計算との一致を確認する。

📥 入力:n=5, k=2(スカラー)

1
2
3
4
from math import comb, factorial
print(f"5! = {factorial(5)}")
print(f"C(5,2) = {comb(5, 2)}")
print(f"パスカル: C(4,1)+C(4,2) = {comb(4,1)+comb(4,2)}")

📤 実行結果

5! = 120 C(5,2) = 10 パスカル: C(4,1)+C(4,2) = 10

💬 手計算 (Step 2,3) C(5,2)=10 と Python 出力が完全一致。

✅ 理解度チェック — 47 都道府県で組合せを数える

数値はすべて SSDSE-B-2026 の 2023 年度 47 都道府県から数えたもの。 まず自分で計算してから答えを開く。

問 1:47 県から 2 県を選ぶペアは何通りか。 8 地方区分(北海道 1・東北 6・関東 7・中部 9・近畿 7・中国 5・四国 4・九州沖縄 8)で、 同じ地方どうしのペアは何通りか。

C(47,2) = 47×46/2 = 1,081 通り。 同じ地方どうしは C(1,2)+C(6,2)+C(7,2)+C(9,2)+C(7,2)+C(5,2)+C(4,2)+C(8,2) = 0+15+21+36+21+10+6+28 = 137 通りで、 地方をまたぐペアは 1,081 − 137 = 944 通り。 地方ブロックの全ペアを比べる多重比較なら、 8 地方から 2 つで C(8,2) = 28 回になる。

問 2:高齢化率(65 歳以上人口 ÷ 総人口)が 30% 以上の県は 35 県ある。 47 県から無作為に 3 県選んだとき、 3 県とも 30% 以上になる確率は。

C(35,3) / C(47,3) = 6,545 / 16,215 ≈ 0.404。 30% 以上の県が 4 分の 3 を占めるので、 3 県すべてが該当する確率も 4 割ある。 「無作為に選んだ 3 県がどれも高齢化が進んでいた」は、 それだけでは珍しい出来事ではない。

問 3:47 県から 3 県を選び、 訪問する順番まで決める場合と、 順番を問わない場合の数は。

順番あり(順列)は 47×46×45 = 97,290 通り、 順番なしは 97,290 / 3! = 16,215 通り。 同じ 3 県の並べ方 6 通りを 1 つにまとめたのが組合せ。

問 4:アンケートの追加調査を 5 回、 同じ県に何回行ってもよいとして 47 県に割り振る。 回数の割り振り方は何通りか。

重複組合せ H(47,5) = C(47+5−1, 5) = C(51,5) = 2,349,060 通り。 5 個の「調査」と 46 本の仕切りを並べる玉と仕切りの考え方で、 51 か所から調査の 5 か所を選ぶことになる。

問 5:上の全列挙で、 5 県に東京都が入る組合せの割合が 5/47 になるのはなぜか。 パスカルの規則 C(47,2) = C(46,1) + C(46,2) も同じ考えで確かめよ。

東京都を含む組は残り 46 県から 4 県で C(46,4)、 全体は C(47,5)。 C(46,4)/C(47,5) = 5/47(どの県も 5 つの席のどれかに入る確率が等しい)。 パスカルの規則も「東京都を含むペア C(46,1) = 46 通り」と「含まないペア C(46,2) = 1,035 通り」に分けて 46 + 1,035 = 1,081 で、 特定の 1 県を含むか含まないかで場合分けしている。

問 6:ある指標について 47 県の全ペアの差を有意水準 5% で 1 つずつ検定する。 本当はどのペアにも差が無いとき、 偶然「有意」になるペアは平均いくつ出るか。 Bonferroni 補正後の 1 回あたりの有意水準は。

検定の回数は C(47,2) = 1,081 回なので、 1,081 × 0.05 ≈ 54 ペアが偶然有意になる。 1 つでも有意が出る確率は 1 − 0.951,081 でほぼ 1。 Bonferroni 補正では 0.05 / 1,081 ≈ 4.6×10−5 を 1 回あたりの基準にする。 組合せの数がそのまま「偶然の有意」の数を決める(多重検定)。

問 7:47 県を訓練用 37 県・検証用 10 県に分ける分け方は何通りか。 検証用 10 県を 1 通りだけ選んで精度を報告することの危うさは。

検証用 10 県の選び方で決まるので C(47,10) = 5,178,066,751 通り(約 52 億)。 そのうちの 1 通りだけで測った精度は、 東京都が検証側に入るかどうかなどで大きく変わりうる。 交差検証で分け方を何通りか変えて平均とばらつきを見るのは、 この膨大な分け方のうち偏った 1 つを引いてしまう危険を減らすためである。

🎮 触って理解する

スライダーで n(全体の数)と k(選ぶ数)を動かすと、 組合せ $C(n,k)$ と順列 $P(n,k)$ がリアルタイムで更新されます。 n が小さいとき(n ≤ 8)は実際の選び方をすべて列挙し、 パスカルの三角形での位置と対称性 $C(n,k)=C(n,n-k)$ が光ります。 三角形のマスをタップ/クリックすると、 その (n, k) にジャンプします。

🔢 実際の選び方(列挙)
🔺 パスカルの三角形(緑=C(n,k)/橙=C(n,n-k))

🧭 何が起きている?

⚠️ よくある落とし穴

🚀 発展:二項定理と確率へ

🔗 関連ページ: 順列 確率 確率分布 分布 集合論

🐍 Python 実装

公的統計(SSDSE-B-2026)を題材に、 最小限の Python コードで動作させます。 ファイルパス(data/raw/SSDSE-B-2026.csv)は自分の環境に合わせて変更してください。 まずはこのまま動かすことが理解の最短ルートです。

🎯 解説: SSDSE-B-2026 の 47 都道府県から 3 つを選ぶ組合せ数 C(47,3) を計算し、 重複なく順序を区別しない選び方の総数を求める。
📥 入力例: n = 47 (都道府県数) k = 3 (選ぶ数)
1
2
3
4
5
6
from math import comb
from scipy.special import comb as sp_comb

print(comb(5, 2))           # 10
print(comb(47, 3))          # 16215
print(sp_comb(100, 10))     # 1.7310...e+13
📤 実行例: 10 16215 17310309456440.0
💬 読み方: math.comb は整数で 10 と 16215 を返し、手計算の C(47,3)=16,215 と一致する。一方 scipy.special.comb(100, 10) は既定(exact=False)で浮動小数の 17310309456440.0(約 1.73×10¹³)を返す。桁が大きくなると浮動小数では末尾の桁が丸められるので、正確な整数が要るときは exact=True か math.comb を使う。

▶ 実行 を押せばこのページの中でそのまま動きます(ライブラリもデータも同梱済みで、 準備は要りません)。 手元の Python に移して動かすときは pip install matplotlib numpy pandas scikit-learn scipy が必要です。 読んでいるデータは data/raw/SSDSE-B-2026.csv。 日本語を含むので encoding='cp932' の指定を落とさないでください。

本サイトの全コードは 論文一覧ページ から実例として確認できます。 自分のデータで試したい場合は、 列名・欠損記号・単位の違いだけ調整すれば、 ほぼそのまま流用できます。

🐍 Python 実装(拡張版)

pandas・numpy・scipy で、 SSDSE-B-2026 の中にある「組合せの数」を 3 段階で数える。 ① 列の数を確かめ、 ② 47 県から 5 県を選ぶ組合せを超幾何分布と照らし合わせ、 ③ 109 列から 2 列を選ぶ C(109,2) 通りの相関ペアを調べる。

① データ読み込みと前処理

🎯 このコードでやること:SSDSE-B-2026 を読み込み欠損確認と数値列抽出を行う前処理。

📥 入力:data/raw/SSDSE-B-2026.csv

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

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932')
latest = df[df['SSDSE-B-2026'] == df['SSDSE-B-2026'].max()].copy()

# 欠損確認
print('NA per col (top 5):')
print(latest.isna().sum().sort_values(ascending=False).head())

# 数値列のみ抽出
num = latest.select_dtypes(include='number').drop(columns=['SSDSE-B-2026'])
print('numeric cols:', num.shape[1])
📤 実行結果例:
NA per col (top 5):
SSDSE-B-2026 0
Code 0
H1800 0
G7102 0
G7101 0
dtype: int64
numeric cols: 109

💬 欠損数の多い順に並べても先頭 5 列がすべて 0 なので、2023 年度の 47 行には欠損が 1 つもない。年度列を除いた数値列は 109 列で、この 109 列から 2 列を選ぶ相関ペアは C(109,2)=5,886 通りになる(③で使う)。

② 基本的な 組合せ 適用

🎯 このコードでやること:総人口が上位 25%(Q3 以上)の県を「大規模県」とし、 47 県から無作為に 5 県を選んだとき大規模県が k 県入る組合せ数と確率を math.comb で数え、 scipy.stats.hypergeom(超幾何分布)と照合する。

📥 入力:num['A1101'](2023 年度・47行)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from math import comb
from scipy import stats

# 人口上位 25%(四分位 Q3 以上)の県を「大規模県」とする
pop = num['A1101'].dropna()
big = int((pop >= pop.quantile(0.75)).sum())
N, n = len(pop), 5          # 47 県から無作為に 5 県を選ぶ
print(f'N = {N}, 大規模県 K = {big}, 抽出 n = {n}')
print(f'5 県の選び方の総数 C({N},{n}) = {comb(N, n):,}')

# 5 県中に大規模県が k 県入る組合せ数と確率(超幾何分布)
for k in range(n + 1):
    ways = comb(big, k) * comb(N - big, n - k)
    print(f'k={k}: {ways:>9,} 通り  P = {ways / comb(N, n):.4f}  '
          f'scipy = {stats.hypergeom.pmf(k, N, big, n):.4f}')
📤 実行結果例:
N = 47, 大規模県 K = 12, 抽出 n = 5
5 県の選び方の総数 C(47,5) = 1,533,939
k=0: 324,632 通り P = 0.2116 scipy = 0.2116
k=1: 628,320 通り P = 0.4096 scipy = 0.4096
k=2: 431,970 通り P = 0.2816 scipy = 0.2816
k=3: 130,900 通り P = 0.0853 scipy = 0.0853
k=4: 17,325 通り P = 0.0113 scipy = 0.0113
k=5: 792 通り P = 0.0005 scipy = 0.0005

💬 6 行の組合せ数を足すと 324,632+628,320+431,970+130,900+17,325+792=1,533,939 で、C(47,5) にちょうど戻る(バンデルモンドの恒等式)。最も起こりやすいのは大規模県が 1 県だけ入る場合(約 41%)で、5 県すべて大規模県になるのは C(12,5)=792 通り、確率 0.05% にすぎない。組合せ数を数えて割った値と scipy の超幾何分布が小数 4 桁まで一致している。

③ 応用:他指標との結合分析

🎯 このコードでやること:A1101(総人口)と他指標の相関ランキングと、 高相関ペア数(|r|>0.95)を調べる。

📥 入力:num(47行 × 109数値列)

1
2
3
4
5
6
7
8
9
# 主要指標との相関ランキング
target = 'A1101'
corr_with_target = num.corr()[target].drop(target).sort_values(key=abs, ascending=False)
print('|r| 上位 10:')
print(corr_with_target.head(10).round(3))

# 共線性チェック
high_corr = (num.corr().abs() > 0.95) & (num.corr().abs() < 1.0)
print('|r|>0.95 の組:', high_corr.sum().sum() // 2)
📤 実行結果例:
|r| 上位 10:
A1102 1.000
A110201 1.000
...
|r|>0.95 の組: 1564

💬 |r|>0.95 の組が 1,564 組もある。 組合せ C(109,2)=5,886 ペア中の 約 27% が高相関。 特徴選択時に注意が必要。

3 段階とも、 数えた組合せの数(C(47,5) = 1,533,939、 C(109,2) = 5,886)が math.comb の値と一致することを確かめている。 5,886 組の相関を全部調べると、 偶然強く見える組も混ざる点は「🔍 解説深化」で扱う。

🧪 組合せを全部数え上げる — 5 県の合計人口が 2,000 万人を超える確率

このコードでやること:2023 年度の 47 都道府県から 5 県を選ぶ C(47,5) = 1,533,939 通りを itertools.combinations ですべて列挙し、 合計人口が 2,000 万人を超える組合せの割合を厳密に求める。 同じ確率を無作為抽出 10,000 回で近似した値と比べ、 東京都を含む組合せの数が C(46,4) になることも確かめる。

📥 入力例(SSDSE-B-2026 の 2023 年度・47 都道府県、 総人口を万人に換算) 都道府県 総人口(万人) 北海道 509.2 東京都 1,408.6 沖縄県 146.8 …(全 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
import math, itertools
import numpy as np
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=1, encoding='cp932')
d = df[df['年度'] == 2023].reset_index(drop=True)
pop = d['総人口'].to_numpy() / 1e4            # 万人、47 県

# ① 47 県から 5 県を選ぶ全組合せを列挙し、合計人口が 2,000 万人を超える割合を正確に出す
k = 5
n_comb = math.comb(47, k)
sums = np.fromiter((pop[list(c)].sum() for c in itertools.combinations(range(47), k)),
                   dtype=float, count=n_comb)
print(f'C(47,{k}) = {n_comb:,} 通りをすべて列挙')
print(f'合計人口 > 2,000 万人 の割合(厳密): {(sums > 2000).mean():.4f}  ({int((sums > 2000).sum()):,} 通り)')

# ② 同じ確率を無作為抽出 10,000 回で近似する
rng = np.random.default_rng(0)
draws = np.array([pop[rng.choice(47, k, replace=False)].sum() for _ in range(10_000)])
print(f'無作為抽出 10,000 回での近似   : {(draws > 2000).mean():.4f}')

# ③ 東京都を含む組合せ:残り 46 県から 4 県 → C(46,4) 通り
tokyo = int(d.index[d['都道府県'] == '東京都'][0])
others = [i for i in range(47) if i != tokyo]
with_t = np.fromiter((pop[tokyo] + pop[list(c)].sum() for c in itertools.combinations(others, k - 1)),
                     dtype=float, count=math.comb(46, k - 1))
print(f'東京都を含む組合せ: C(46,4) = {len(with_t):,} 通り(全体の {len(with_t)/n_comb:.4f} = 5/47)')
print(f'  そのうち 2,000 万人超の割合: {(with_t > 2000).mean():.4f}')
print(f'  東京都を含まない組合せで 2,000 万人超: {int((sums > 2000).sum()) - int((with_t > 2000).sum()):,} 通り')

# ④ k を増やすと全列挙はすぐ現実的でなくなる
for kk in [5, 10, 15, 23]:
    print(f'C(47,{kk:2d}) = {math.comb(47, kk):>18,}')

📤 実行例(実測)

C(47,5) = 1,533,939 通りをすべて列挙 合計人口 > 2,000 万人 の割合(厳密): 0.1371 (210,265 通り) 無作為抽出 10,000 回での近似 : 0.1326 東京都を含む組合せ: C(46,4) = 163,185 通り(全体の 0.1064 = 5/47) そのうち 2,000 万人超の割合: 0.7514 東京都を含まない組合せで 2,000 万人超: 87,654 通り C(47, 5) = 1,533,939 C(47,10) = 5,178,066,751 C(47,15) = 751,616,304,549 C(47,23) = 16,123,801,841,550

💬 読み方:153 万通りを全部数えると、 合計人口が 2,000 万人を超える 5 県の組は 210,265 通りで、 割合は 0.1371 と誤差なく決まる。 無作為抽出 10,000 回の近似は 0.1326 で、 0.005 ほどずれる。 東京都を含む組は「東京都を固定して残り 46 県から 4 県」なので C(46,4) = 163,185 通り、 全体の 5/47 ≈ 0.1064 にあたり、 そのうち 75% が 2,000 万人を超える。 超える組の約 58%(122,611 通り)は東京都を含むので、 この確率はほぼ「東京都が入るかどうか」で決まっている。 選ぶ県数を 10 にすると C(47,10) は約 52 億通りになり、 全列挙は現実的でなくなる。 そこから先は無作為抽出による近似や、 組合せ最適化 のような探し方に切り替える。

⚠️ よくある落とし穴

この用語を使うときに初学者が踏みやすい失敗パターン。 1 度経験してしまえば次から避けられますが、 先に知っておくに越したことはありません。

❌ 階乗オーバーフロー
n=100 でも 100! は 158 桁。 Python 標準 int は OK だが、 浮動小数では破綻。
❌ 組合せと順列の混同
順序が重要なら nPk = n!/(n-k)!。
❌ 0!=1 を忘れる
計算で 0! が出る場面は多い。
❌ 負の値・非整数
n < k では 0、 非整数では一般化二項係数を使う。
🛡 組合せ固有の防御策:「順序が結果に影響するかを口頭で確認 (例: 47 都道府県から 3 県の "1 位/2 位/3 位" は順列 nPk、 "上位 3 県の集合" は組合せ nCk)」「計算前に math.comb(n, k) で桁数を見積もる (C(47,5)=1,533,939 / 47!≈2.6×1059)」「確率計算では分母・分子それぞれ math.comb で書き、 約分前に値を確認」の 3 点を守れば、 順列との取り違え・浮動小数オーバーフロー・確率計算ミスを防げます。

⚠️ 実データでの誤解 — 564 行から「ペア」を数えると、 同じ県どうしが混ざる

SSDSE-B-2026 の CSV は 47 都道府県 × 12 年度 = 564 行ある。 年度で絞らずに「2 行の組合せ」を数えると C(564,2) = 158,766 通りになり、 県のペア C(47,2) = 1,081 通りの約 147 倍に見える。 しかしその中身は均質ではない。

564 行から選んだ 2 行の種類組合せの数総人口(対数)の差の中央値差が 0.05 未満の割合
同じ県の別の年度47 × C(12,2) = 3,1020.01985.8%
別の県(年度は問わない)155,6640.6893.9%
合計C(564,2) = 158,766——

同じ県の別年度どうしの 3,102 組は、 総人口が 12 年でほとんど変わらないので、 対数の差の中央値が 0.019(約 2%)しかなく、 86% の組が差 0.05 未満に収まる。 別の県どうしでは 0.05 未満は 4% しかない。 つまり 158,766 組は「独立なペア」ではなく、 ほぼ同じ観測を 12 回ずつ数えた組が混ざっている。 ペアの数を検定の回数や標本の大きさとして使うと、 情報量を大きく見積もりすぎる。 県の間の比較なら年度を 1 つに絞って 1,081 組、 年度の変化を見るなら県ごとに C(12,2) = 66 組、 と数える単位を先に決める。 同じ年度どうしのペアだけに限っても 12 × 1,081 = 12,972 組で、 これも県の組が 12 回繰り返されている。

🗺 概念マップ

「組合せ」を中心に、 前提・並列・発展の 3 層で周辺概念を整理します。 矢印(→)は「この概念が使われる・広がる」方向を示します。

🔵 前提 順列 確率 階乗 集合論 ⭕ 組合せ C(n,k) = n!/(k!(n-k)!) 順序を区別しない C(47,2)=1,081 🟠 直接応用 二項分布 多重比較 超幾何分布 特徴選択 🔴 発展 組合せ最適化 ブートストラップ 交差検証 標本抽出論 前提 → 組合せ → 直接応用 → 発展
🔵 前提(基礎)
⭕ 組合せ C(n,k)
$\binom{n}{k} = \frac{n!}{k!(n-k)!}$
順序を区別しない選び方の数
C(47,2)=1,081 ← SSDSE-B の都道府県ペア
🟠 直接応用(→)
🔴 発展・派生(→→)

概念マップの読み方:左から右へ「前提 → 組合せ → 直接応用 → 発展」の流れで理解が深まります。 縦には同じ抽象レベルの概念が並んでいます。

❓ FAQ — 組合せ に関するよくある質問

Q1. 組合せ ₙC_r と順列 ₙP_r の違いは?
A. 並べる順序を区別するかどうかが決定的。 例えば 47 都道府県から 3 県選んで「観光モデルコース」を組むなら順列 (47P3 = 97,290 通り)、 単に「比較対象 3 県」を選ぶなら組合せ (47C3 = 16,215 通り)。 順列は組合せの r! 倍 (3! = 6 倍) になる。
Q2. ₙC_r の計算で 大きな階乗を直接計算すると桁あふれします
A. 階乗は急に大きくなり、 171! 以上は浮動小数点(float64)で表せずエラーになる。 それより小さくても 23! 以上は float64 の有効桁(約 16 桁)を超えるので、 階乗を浮動小数点で割り算すると末尾の桁がずれることがある。 Python なら math.comb(n, r) を使えば内部で約分しながら正確な整数値を返す。 scipy の scipy.special.comb(n, r, exact=True) も同じ目的で利用可能。
Q3. 重複組合せはどう数える?
A. n 種類から重複を許して r 個選ぶ場合は H(n,r) = C(n+r-1, r)。 例えば 47 都道府県からアンケート票を 5 枚配る (同じ県に複数配って良い) なら 47H5 = 51C5 = 2,349,060 通り。
Q4. パスカルの三角形と二項係数の関係は?
A. パスカルの三角形の (n, r) 位置の値はちょうど ₙC_r。 漸化式 C(n,r) = C(n-1, r-1) + C(n-1, r) はパスカルの恒等式と呼ばれ、 動的計画法で組合せを計算するときの土台。
Q5. 47C2 を使った相関分析の組合せ数は?
A. 47 都道府県を「ペア」で総当たり比較する場合 47C2 = 1,081 通り。 SSDSE-B-2026 の人口×出生数(A1101×A4101)の散布図で全ペアを描くなら 1,081 個の点になる。 列数 p の相関行列なら ₚC₂ = p(p-1)/2 のユニークな相関係数を扱う。
Q6. SSDSE-B-2026 以外のデータでも使えますか?
A. はい。 SSDSE-B-2026 は典型的な「47 都道府県 × 多列 × 多年」のパネルデータで、 多くの公的統計が同様の構造を持ちます。 国勢調査、 経済センサス、 RESAS データなどでも同じコードが応用できます。
Q7. 学習のおすすめ順は?
A. ① 直感 → ② 数式 → ③ 実装 → ④ 落とし穴 → ⑤ 関連用語、 の順で本ページを読むのが効率的です。 完璧に理解できなくても OK、 必要になった時に戻ってきてください(ジャストインタイム学習)。
Q8. 組合せ の計算コストは?
A. 47 都道府県・最新年度(n=47)であれば一瞬で終わります。 47 × 100 × 複数年でも数秒〜数十秒。 ただし大規模データや反復計算(クロスバリデーションなど)では時間がかかるため、 必要なら numpy 化・並列化を検討してください。

🔗 隣接手法への橋渡し

「組合せ」は順序を区別しない選び方の数で、 上流の母集団サイズの確認と下流の確率計算 (二項分布・超幾何分布) を組み合わせて初めて「何通り → 何 % か」まで踏み込める。

上流の母集団・標本サイズを整理し、 並列の順列 (順序を区別) と区別して使い分け、 下流の二項分布・超幾何分布に接続すれば、 「47 都道府県から 3 県を抽出する組合せ確率」のような実問題を解ける。

具体的に 1 本つなげると次のようになる。 上流で「47 県・非復元・順序なし」と標本空間を決め(全体は C(47,3) = 16,215 通り)、 並列の順列と比べて「訪問順まで区別するなら 97,290 通り」と確かめ、 下流で高齢化率 30% 以上の 35 県から 3 県とも選ばれる確率を C(35,3)/C(47,3) = 6,545/16,215 ≈ 0.404 と計算する。 その 3 県の平均を他の 3 県と比べる検定を全組について繰り返すなら、 仮説検定の側で多重比較の補正が必要になる。 組合せの数は、 確率の分母にも、 検定の回数にも、 最適化で探す候補の数にも同じ形で現れる。 どの段でも、 564 行のままではなく年度を 1 つに絞り、 数える単位を 47 県にそろえておくことが前提になる。

🌳 手法選択フロー

「組合せ」を実際に使うとき、 何をどう選ぶかを順に判断する。 上から順に答えていくと、 使うべき手法と評価の仕方が決まる。

  1. 選ぶ順序に意味があるか
    順序が結果を変えるなら順列 $_nP_r$、 変えないなら組合せ $_nC_r$。 「1 位・2 位を決める」は順列、 「代表 2 県を選ぶ」は組合せ。
  2. 同じものを 2 回選べるか
    選べるなら重複組合せ $_{n+r-1}C_r$。 選べないなら通常の $_nC_r$。 復元抽出か非復元抽出かと同じ区別。
  3. $n$ はどれくらい大きいか
    $n$ が数十までなら階乗をそのまま計算できる。 大きいときは対数を取るか Stirling 近似 $n! \approx \sqrt{2\pi n}(n/e)^n$ を使い、 桁あふれを避ける。
  4. 確率まで求めたいか
    復元ありの成功回数なら二項分布、 非復元なら超幾何分布。 組合せの数はこれらの確率式の分子・分母に現れる。

47 都道府県から 5 県を選ぶ組合せは $_{47}C_5 = 1{,}533{,}939$ 通り。 総当たりで最良の 5 県を探す設計は、 この規模なら現実的だが、 10 県だと $_{47}C_{10} = 5{,}178{,}066{,}751$ 通り(約 52 億)まで膨らみ、 総当たりは現実的でなくなる。

🔍 解説深化 — 組合せは「データ」ではなく「分析そのもの」も数える

ここまでの節では「n 個のデータから k 個を選ぶ」数え上げを扱いました。 本節では視点を一段上げて、 C(n,k) が「これから実行する分析・検定の回数」を数えるメーターになる、 という実務上もっとも効いてくる読み方を掘り下げます。 これは多重比較・並べ替え検定・ブートストラップという、 コンペのレポートで実際に手が触れる 3 つの場面に直結します。

🎨 直感 — 「比較 1 回」の裏に 1081 回が隠れている

SSDSE-B-2026 の 2023 年データ(47 都道府県)で総人口 A1101 を見ると、 最大は東京都 14,086,000 人、 最小は鳥取県 537,000 人です(実測値)。 「東京と鳥取を比べる」のは自然な発想ですが、 この 2 県ペアは C(47,2) = 1081 通りのペアのうちの 1 つにすぎません。 「一番差が大きいペアを選んでから比較する」という行為は、 暗黙のうちに 1081 回の比較を全部実行してその最大値を報告しているのと同じことです。 組合せの数え上げは、 データを選ぶ場面だけでなく、 自分がこれから何回「見比べる」のかを自覚するためにこそ使えます。

⚠️ 落とし穴(重要)— 数え上げた回数だけ「偶然の有意」が湧く

有意水準 5% の検定を C(47,2) = 1081 ペア全部に行うと、 仮にどのペアにも真の差がなくても、 期待値として 1081 × 0.05 = 約 54 件が偶然「有意」と判定されます。 指標間相関の総当たり C(109,2) = 5886 ペアなら期待値は 5886 × 0.05 = 約 294 件。 つまり「相関行列を眺めて有意なペアを拾う」だけで、 何もない所から数百件の"発見"が製造できてしまう。 これが多重比較問題であり、 その分母を与えるのが組合せ C(n,k) です。

🛡 対処の第一歩:最も素朴な Bonferroni 補正は有意水準を検定回数で割る。 1081 ペアなら 0.05 / 1081 ≈ 4.63 × 10⁻⁵ がペアあたりの基準になります。 補正が厳しすぎる場面では FDR 制御(Benjamini–Hochberg)を検討します。 重要なのは補正手法の選択より先に、 C(n,k) で「自分は何回検定したのか」を数えて明記することです。

🚀 発展 — 並べ替え検定とブートストラップの「空間の大きさ」

組合せは、 リサンプリング法が「なぜ乱数に頼るのか」も説明します。

ここで使った H(n,k) = C(n+k−1, k) は「🎮 触って理解する」節で触れた重複組合せの公式そのものです。 通常の C(n,k)(戻さない選び方)とペアで覚えておくと、 リサンプリング法の議論が一気に読みやすくなります。 なお二項分布・ボンフェローニ補正の専用ページは本用語集には未収録のため、 下記の隣接ページから辿ってください。

順列 多重検定 FDR p 値 有意水準 仮説検定 ブートストラップ サンプリング 相関

※ 本節の数値はすべて SSDSE-B-2026.csv(2023 年・47 都道府県、 A1101=総人口)の実測値、 および math.comb による厳密計算です。