2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

カイ二乗分布を分布として理解する:有意水準と自由度を可視化する

Last updated at Posted at 2025-12-29

はじめに

カイ二乗分布(χ² 分布)は、統計検定やデータ解析で最もよく使われる分布の一つです。

実務では、

モデルでフィットして χ² が自由度くらいなら、まあ良い

といった経験則で判断することも多いと思います。

ただ、

  • それは どれくらい起こりやすい値なのか
  • 「良い」「悪い」は どこから決まるのか
  • reduced χ²が なぜ便利なのか

を、分布として意識する機会は案外多くありません。

この記事では、

  • カイ二乗分布そのものの形
  • 有意水準(右側・左側)
  • 自由度による振る舞いの違い
  • reduced χ²(縮約カイ二乗)の分布

可視化しながら 整理してみます。

本記事の実装コードは Google Colab こちら から実行できます。

カイ二乗分布とは

カイ二乗分布は、標準正規分布に従う独立な確率変数 $z_i$ を用いて、

\chi^2 = \sum_{i=1}^{\nu} z_i^2

と定義されます。
ここで $z_i$ は平均 0・分散 1 の標準正規分布、$\nu$ は自由度です。

直感的には、

正規分布に従うズレを標準化して二乗し、それを $\nu$ 個足し合わせた量

だと考えれば十分です。

この定義から、次の性質が従います。

  • $\chi^2 \ge 0$(二乗和なので負にならない)
  • 分布は右に裾を引く非対称な形
  • 平均:$\langle \chi^2 \rangle = \nu$
  • 分散:$\mathrm{Var}(\chi^2) = 2\nu$

つまり、

$\chi^2 \approx \nu$

という状態は、「モデルが正しければ最も起こりやすい値」 を意味しています。

reduced χ²とは

reduced χ² (補正カイ二乗)は、χ² を自由度で割った量として

\chi^2_{\rm red} = \frac{\chi^2}{\nu}

と定義されます。

χ² の性質から、

  • 平均:$\langle \chi^2_{\rm red} \rangle = 1$
  • 分散:$\mathrm{Var}(\chi^2_{\rm red}) = \frac{2}{\nu}$

となり、期待値が常に 1 に揃うのが特徴です。

この性質によって、
自由度の異なるフィット結果を 同じ尺度で比較できるようになります。

有意水準を考える

なぜ右側だけを見るのか

多くの場合、カイ二乗検定では

χ² が 大きすぎる

かどうかを問題にします。

誤差の見積もりが妥当で、モデルが正しければ、
χ² は平均 $\nu$ の周りに分布するはずだからです。

右側の裾(たとえば 95% 点)を超える場合、

「こんな大きな χ² は、偶然では起きにくい」

と判断します。

左側も実は意味がある

一方で、

  • χ² が 小さすぎる

場合も、実務的には無視できません。

例えば、

  • 誤差を過大評価している
  • データ点やモデルが独立でない

といった可能性が考えられます。

つまり、

右側だけでなく、左側も含めて分布全体を見る

ことが、モデル診断として重要になります。

χ² と reduced χ² の分布をまず見てみる

ここまでの話を踏まえて、まずは 分布そのものの形を見てみます。

  • 曲線:自由度 $\nu = 3, 13, 23, \dots, 193$
  • 左:χ² の分布
  • 右:reduced χ² の分布
χ² reduced χ²
χ² χ²_red
χ² コードはこちら
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import chi2
from matplotlib import colors, colormaps

# ============================================================
# Chi-square PDF (raw chi-square)
# ============================================================

# Chi-square axis
x = np.linspace(0, 250, 2000)

# Degrees of freedom to display
nu_list = np.arange(3, 201, 10)

fig, ax = plt.subplots(figsize=(6, 4))

# Colormap setup
norm = colors.Normalize(vmin=nu_list.min(), vmax=nu_list.max())
cmap = colormaps["turbo"]

for nu in nu_list:
    pdf = chi2.pdf(x, nu)
    ax.plot(
        x, pdf,
        color=cmap(norm(nu)),
        lw=1,
        alpha=0.9
    )

ax.set_xlabel(r"$\chi^2$")
ax.set_ylabel("PDF")

# Colorbar
sm = plt.cm.ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])
cbar = fig.colorbar(sm, ax=ax)
cbar.set_label(r"degrees of freedom $\nu$")

fig.tight_layout()
plt.show()
reduced χ² コードはこちら
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import chi2
from matplotlib import colors, colormaps

# ============================================================
# Chi-square PDF (reduced chi-square)
# ============================================================

# Reduced chi-square axis
x = np.linspace(0, 3, 1000)

# Degrees of freedom to display
nu_list = np.arange(3, 201, 10)

fig, ax = plt.subplots(figsize=(6, 4))

# Colormap setup
norm = colors.Normalize(vmin=nu_list.min(), vmax=nu_list.max())
cmap = colormaps["turbo"]

for nu in nu_list:
    pdf = chi2.pdf(x * nu, nu) * nu
    ax.plot(
        x, pdf,
        color=cmap(norm(nu)),
        lw=1,
        alpha=0.9
    )

# Mean (reduced)
ax.axvline(
    1,
    color="k", ls="--", lw=1.5,
    label=r"$\langle \chi^2_{\rm red} \rangle = 1$"
)

ax.set_xlabel(r"$\chi^2_{\rm red}$")
ax.set_ylabel("PDF")

# Colorbar
sm = plt.cm.ScalarMappable(norm=norm, cmap=cmap)
sm.set_array([])
cbar = fig.colorbar(sm, ax=ax)
cbar.set_label(r"degrees of freedom $\nu$")

ax.legend()
fig.tight_layout()
plt.show()

χ² のまま見ると、自由度が増えるにつれて分布は右へ広がっていきます。
一方で、自由度で正規化した reduced χ² では、分布が 1 に向かってどんどん尖っていく 様子がわかります。

自由度ごとの信頼区間を可視化する

次に、自由度ごとに χ² と reduced χ² の信頼区間を並べて可視化します。

  • 横軸:自由度 $\nu$
  • 縦軸:左が $\chi^2$、右が reduced $\chi^2$
  • 曲線:5%, 10%, 90%, 95% 分位点
χ² reduced χ²
quantile chi2red
χ² コードはこちら
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import chi2

# ============================================================
# Chi-square quantiles (raw chi-square)
# ============================================================

# Degrees of freedom
nu = np.arange(3, 201)

fig, ax = plt.subplots(figsize=(6, 6))

# --- Lower tail ---
ax.plot(
    nu, chi2.ppf(0.05, nu),
    color="tab:blue", ls="--", label="5 %"
)
ax.plot(
    nu, chi2.ppf(0.10, nu),
    color="tab:blue", ls="-", label="10 %"
)

# --- Upper tail ---
ax.plot(
    nu, chi2.ppf(0.90, nu),
    color="tab:orange", ls="-", label="90 %"
)
ax.plot(
    nu, chi2.ppf(0.95, nu),
    color="tab:orange", ls="--", label="95 %"
)

# Mean
ax.plot(
    nu, nu,
    color="k", ls="--",
    label=r"$\langle \chi^2 \rangle = \nu$"
)

ax.set_xlabel("degrees of freedom")
ax.set_ylabel(r"$\chi^2$")
ax.set_aspect("equal", adjustable="box")
ax.legend()

fig.tight_layout()
plt.show()
reduced χ² コードはこちら
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import chi2

# ============================================================
# Chi-square quantiles (reduced chi-square)
# ============================================================

# Degrees of freedom
nu = np.arange(3, 201)

fig, ax = plt.subplots(figsize=(6, 6))

# --- Lower tail ---
ax.plot(
    nu, chi2.ppf(0.05, nu) / nu,
    color="tab:blue", ls="--", label="5 %"
)
ax.plot(
    nu, chi2.ppf(0.10, nu) / nu,
    color="tab:blue", ls="-", label="10 %"
)

# --- Upper tail ---
ax.plot(
    nu, chi2.ppf(0.90, nu) / nu,
    color="tab:orange", ls="-", label="90 %"
)
ax.plot(
    nu, chi2.ppf(0.95, nu) / nu,
    color="tab:orange", ls="--", label="95 %"
)

# Mean (reduced)
ax.axhline(
    1,
    color="k", ls="--",
    label=r"$\langle \chi^2_{\rm red} \rangle = 1$"
)

ax.set_xlabel("degrees of freedom")
ax.set_ylabel(r"$\chi^2_{\rm red}$")
ax.legend()

fig.tight_layout()
plt.show()

左図では、$\chi^2$ の揺れ幅が自由度とともに大きくなる様子がわかります。
一方、右図では reduced χ² が 1 を中心に収束していく様子がはっきり確認できます。

補足:自由度ごとの目安表について

下の表では、解析結果を ざっと確認するための目安 として、自由度 $\nu = 2$ から $10,000$ までを並べています。
(低自由度では細かく、高自由度では見やすさを保つために間引いて掲載しています。)

目安表はこちら
nu chi2red_5% chi2red_10% chi2red_90% chi2red_95%
2 0.051 0.105 2.303 2.996
4 0.178 0.266 1.945 2.372
6 0.273 0.367 1.774 2.099
8 0.342 0.436 1.670 1.938
10 0.394 0.487 1.599 1.831
12 0.436 0.525 1.546 1.752
14 0.469 0.556 1.505 1.692
16 0.498 0.582 1.471 1.644
18 0.522 0.604 1.444 1.604
20 0.543 0.622 1.421 1.571
22 0.561 0.638 1.401 1.542
24 0.577 0.652 1.383 1.517
26 0.592 0.665 1.368 1.496
28 0.605 0.676 1.354 1.476
30 0.616 0.687 1.342 1.459
32 0.627 0.696 1.331 1.444
34 0.637 0.704 1.321 1.429
36 0.646 0.712 1.311 1.417
38 0.655 0.720 1.303 1.405
40 0.663 0.726 1.295 1.394
42 0.670 0.733 1.288 1.384
44 0.677 0.738 1.281 1.375
46 0.683 0.744 1.275 1.366
48 0.690 0.749 1.269 1.358
50 0.695 0.754 1.263 1.350
52 0.701 0.758 1.258 1.343
54 0.706 0.763 1.253 1.336
56 0.711 0.767 1.249 1.330
58 0.715 0.771 1.244 1.324
60 0.720 0.774 1.240 1.318
62 0.724 0.778 1.236 1.313
64 0.728 0.781 1.232 1.307
66 0.732 0.784 1.229 1.302
68 0.736 0.787 1.225 1.298
70 0.739 0.790 1.222 1.293
72 0.743 0.793 1.219 1.289
74 0.746 0.796 1.216 1.285
76 0.749 0.799 1.213 1.281
78 0.752 0.801 1.210 1.277
80 0.755 0.803 1.207 1.273
82 0.758 0.806 1.205 1.270
84 0.760 0.808 1.202 1.267
86 0.763 0.810 1.200 1.263
88 0.766 0.812 1.197 1.260
90 0.768 0.814 1.195 1.257
92 0.770 0.816 1.193 1.254
94 0.773 0.818 1.191 1.251
96 0.775 0.820 1.189 1.249
98 0.777 0.822 1.187 1.246
100 0.779 0.824 1.185 1.243
102 0.781 0.825 1.183 1.241
104 0.783 0.827 1.181 1.238
106 0.785 0.828 1.180 1.236
108 0.787 0.830 1.178 1.234
110 0.789 0.832 1.176 1.232
112 0.791 0.833 1.175 1.229
114 0.793 0.834 1.173 1.227
116 0.794 0.836 1.172 1.225
118 0.796 0.837 1.170 1.223
120 0.798 0.839 1.169 1.221
122 0.799 0.840 1.167 1.220
124 0.801 0.841 1.166 1.218
126 0.802 0.842 1.164 1.216
128 0.804 0.844 1.163 1.214
130 0.805 0.845 1.162 1.212
132 0.807 0.846 1.161 1.211
134 0.808 0.847 1.159 1.209
136 0.809 0.848 1.158 1.207
138 0.811 0.849 1.157 1.206
140 0.812 0.850 1.156 1.204
142 0.813 0.851 1.155 1.203
144 0.814 0.852 1.154 1.201
146 0.816 0.853 1.153 1.200
148 0.817 0.854 1.152 1.199
150 0.818 0.855 1.151 1.197
152 0.819 0.856 1.150 1.196
154 0.820 0.857 1.149 1.195
156 0.821 0.858 1.148 1.193
158 0.822 0.859 1.147 1.192
160 0.823 0.860 1.146 1.191
162 0.825 0.861 1.145 1.190
164 0.826 0.861 1.144 1.188
166 0.827 0.862 1.143 1.187
168 0.828 0.863 1.142 1.186
170 0.829 0.864 1.141 1.185
172 0.829 0.865 1.140 1.184
174 0.830 0.865 1.140 1.183
176 0.831 0.866 1.139 1.182
178 0.832 0.867 1.138 1.181
180 0.833 0.868 1.137 1.179
182 0.834 0.868 1.136 1.178
184 0.835 0.869 1.136 1.177
186 0.836 0.870 1.135 1.176
188 0.837 0.870 1.134 1.175
190 0.837 0.871 1.134 1.175
192 0.838 0.872 1.133 1.174
194 0.839 0.872 1.132 1.173
196 0.840 0.873 1.131 1.172
198 0.841 0.874 1.131 1.171
200 0.841 0.874 1.130 1.170
250 0.858 0.887 1.116 1.152
300 0.870 0.897 1.106 1.138
350 0.879 0.904 1.098 1.128
400 0.887 0.911 1.092 1.119
450 0.893 0.916 1.086 1.112
500 0.898 0.920 1.082 1.106
550 0.903 0.924 1.078 1.101
600 0.907 0.927 1.075 1.097
650 0.911 0.930 1.072 1.093
700 0.914 0.932 1.069 1.090
750 0.917 0.934 1.067 1.086
800 0.919 0.936 1.065 1.084
850 0.922 0.938 1.063 1.081
900 0.924 0.940 1.061 1.079
950 0.926 0.942 1.059 1.077
1000 0.928 0.943 1.058 1.075
1050 0.929 0.944 1.056 1.073
1100 0.931 0.946 1.055 1.071
1150 0.932 0.947 1.054 1.070
1200 0.934 0.948 1.053 1.068
1250 0.935 0.949 1.052 1.067
1300 0.936 0.950 1.051 1.065
1350 0.938 0.951 1.050 1.064
1400 0.939 0.952 1.049 1.063
1450 0.940 0.953 1.048 1.062
1500 0.941 0.953 1.047 1.061
1550 0.942 0.954 1.046 1.060
1600 0.943 0.955 1.046 1.059
1650 0.943 0.956 1.045 1.058
1700 0.944 0.956 1.044 1.057
1750 0.945 0.957 1.044 1.056
1800 0.946 0.958 1.043 1.055
1850 0.947 0.958 1.042 1.055
1900 0.947 0.959 1.042 1.054
1950 0.948 0.959 1.041 1.053
2000 0.949 0.960 1.041 1.053
3000 0.958 0.967 1.033 1.043
3500 0.961 0.969 1.031 1.040
4000 0.964 0.971 1.029 1.037
4500 0.966 0.973 1.027 1.035
5000 0.967 0.974 1.026 1.033
5500 0.969 0.976 1.025 1.032
6000 0.970 0.977 1.023 1.030
6500 0.971 0.978 1.023 1.029
7000 0.972 0.978 1.022 1.028
7500 0.973 0.979 1.021 1.027
8000 0.974 0.980 1.020 1.026
8500 0.975 0.980 1.020 1.025
9000 0.976 0.981 1.019 1.025
9500 0.976 0.981 1.019 1.024
10000 0.977 0.982 1.018 1.023

より大きな自由度が必要な場合は、コード内の自由度の刻みを適宜調整してください。

目安表作成コードはこちら
import numpy as np
import pandas as pd
from scipy.stats import chi2

# -----------------------------
# 自由度の定義
# -----------------------------
nu_fine   = np.arange(2, 201, 2)        # 2〜200 : 2刻み
nu_mid    = np.arange(250, 2001, 50)    # 250〜2000 : 50刻み
nu_coarse = np.arange(3000, 10001, 500) # 3000〜10000 : 500刻み

nus = np.concatenate([nu_fine, nu_mid, nu_coarse])

# -----------------------------
# 有意水準
# -----------------------------
levels = [0.05, 0.10, 0.90, 0.95]

# -----------------------------
# テーブル作成(reduced χ² のみ)
# -----------------------------
data = {"nu": nus}

for cl in levels:
    data[f"chi2red_{int(cl*100)}%"] = chi2.ppf(cl, nus) / nus

df = pd.DataFrame(data)
df["nu"] = df["nu"].astype(int)

# -----------------------------
# Markdown 出力
# -----------------------------
floatfmt = [".0f"] + [".3f"] * (len(df.columns) - 1)
print(df.to_markdown(index=False, floatfmt=floatfmt))

おわりに

χ² や reduced χ²(縮約カイ二乗)は、「良さそう」「悪さそう」 を直感的に判断するための便利な指標として使われがちです。

しかしその裏には、

  • 分布の形
  • 自由度による揺れ
  • 有意水準の意味

といった、明確な確率的背景があります。

この記事で見たように、一度 分布として眺めておく ことで、

なぜ「$\chi^2 \approx \nu$」や「reduced χ² $\approx 1$」といった目安が使われているのか

について、少しイメージしやすくなるかもしれません。

本記事が、その理解のきっかけになれば幸いです。

関連記事

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?