別名・略称:正規性の仮定
正規性(Normality):データが正規分布に従う性質。 多くの検定の前提となる。
| 手法 | 特徴 |
|---|---|
| ヒストグラム | 視覚的、 ざっくり判断 |
| Q-Q プロット | 直線に乗れば正規、 ズレ方で歪み判定 |
| Shapiro-Wilk | 小〜中サンプル(n < 5000)。 p > 0.05 で正規性棄却せず |
| Kolmogorov-Smirnov | 大サンプル向け。 但し感度が高い |
| 歪度・尖度 | 数値で形を確認。 |skew| < 2 なら許容範囲 |
SSDSE データで「消費支出」の正規性を確認:
| 指標 | 値 | 判定 |
|---|---|---|
| 歪度 | 0.18 | ほぼ対称 |
| 尖度 | -0.3 | やや平ら |
| Shapiro-Wilk p | 0.62 | p > 0.05 → 正規性棄却できない |
→ 消費支出は近似的に正規分布と見なしてOK。 t 検定や線形回帰の前提を満たす。
SSDSE-B-2026(47 都道府県・2023 年データ)を題材にした最小コード:
1 2 3 4 5 6 7 8 9 10 11 12 13 | from scipy import stats import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1) x = df['消費支出'].dropna() # 歪度・尖度 print('Skew:', x.skew(), 'Kurt:', x.kurt()) # Shapiro-Wilk 検定 stat, p = stats.shapiro(x) print(f'Shapiro-Wilk: W={stat:.3f}, p={p:.3f}') # p > 0.05 なら正規性を仮定可 |
本ページでは 正規性(Normality) を、 SSDSE-B-2026 の都道府県データ(n=47)を題材に、 視覚診断+形式検定+数値的指標の3層で評価します。
都道府県の 総人口(A1101) は、 東京・大阪のような大都市が右に長く伸びる典型的な右に歪んだ分布です。
| 対象列 | Shapiro W | p値 | 歪度 | 結論 |
|---|---|---|---|---|
| 総人口 | 0.59 | < 0.001 | +2.9 | 非正規(右歪) |
| log(総人口) | 0.96 | 0.12 | +0.3 | 概ね正規 |
| 高齢化率 | 0.97 | 0.21 | −0.1 | 概ね正規 |
1 2 3 4 5 6 7 8 9 10 | import pandas as pd
from scipy import stats
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
x = df['A1101'].dropna() # 総人口
# Shapiro-Wilk 検定
w, p = stats.shapiro(x)
print(f'W = {w:.4f}, p = {p:.4g}')
print('帰無仮説(正規性)を' + ('棄却' if p < 0.05 else '棄却せず')) |
1 2 3 4 5 6 7 8 | # Q-Q プロット
import matplotlib.pyplot as plt
from scipy import stats
fig, ax = plt.subplots(figsize=(6,6))
stats.probplot(x, dist='norm', plot=ax)
ax.set_title('Q-Q Plot : 総人口')
plt.tight_layout(); plt.savefig('qq.png', dpi=150) |
1 2 3 4 5 | # 対数変換で正規性が改善するか確認
import numpy as np
log_x = np.log(x)
w2, p2 = stats.shapiro(log_x)
print(f'log変換後 W = {w2:.4f}, p = {p2:.4g}') |
1 2 3 4 5 | # 歪度・尖度
skew = stats.skew(x)
kurt = stats.kurtosis(x)
print(f'歪度 = {skew:.3f} (正規分布は 0)')
print(f'尖度 = {kurt:.3f} (正規分布は 0; Fisher 流)') |
| 対象列(SSDSE-B) | 歪度 | 尖度 | Shapiro p | 判定 |
|---|---|---|---|---|
| A1101 総人口 | 2.93 | 8.45 | < 0.001 | 非正規(右歪) |
| log(A1101) | 0.27 | -0.42 | 0.12 | 概ね正規 |
| A1301 老年人口 | 2.31 | 5.86 | < 0.001 | 非正規(右歪) |
| 高齢化率 | -0.05 | -0.62 | 0.21 | 概ね正規 |
| 出生率 | 0.45 | -0.18 | 0.18 | 概ね正規 |
1 2 3 4 5 | from statsmodels.stats.diagnostic import lilliefors
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
stat, p = lilliefors(df['A1101'])
print(f'Lilliefors stat={stat:.4f} p={p:.4g}') |
1 2 3 4 5 6 | from scipy import stats
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
res = stats.anderson(df['A1101'], dist='norm')
print('A^2:', res.statistic)
print('臨界値:', res.critical_values) |
1 2 3 4 5 6 | from scipy import stats
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
x = df['A1101'].dropna()
y, lam = stats.boxcox(x)
print(f'最適 λ = {lam:.3f}') |
Carl Friedrich Gauss が誤差解析で導入したのが起源(1809 年)。 「Gaussian distribution」の名はこれに由来。
Shapiro と Wilk が 1965 年に開発した Shapiro-Wilk 検定は、 小サンプルでの検出力が高く、 n ≤ 50 で広く用いられます。 R や Python の標準関数として実装されており、 統計入門で最初に学ぶ正規性検定の一つです。
現代では機械学習の前処理として、 また残差診断の場面で頻繁に登場します。 ただし「正規性が必要」と「正規性が望ましい」の混同が初学者で多く、 不要な変換が解釈を歪める事例も多発しています。
A1101 → 総人口(千人)。 分析の分母になる基本量です。A1301 → 65 歳以上人口。 高齢化率を産む分子。A1201 → 15 〜 64 歳人口(生産年齢人口)。 経済活動の主体。μ → 全国平均。 比較基準として用います。α → 有意水準。 第一種の誤り許容率(正規性 に関する判断で重要)。p → p 値。 H₀ の下でデータがどれだけ稀かを示す。基本量の関係を、 記号 → 意味で整理します。 任意の比率は
$$\text{比率} = \frac{\text{分子}}{\text{分母}} \times 100\quad\text{単位: }\%$$
記号 → 意味:
平均と分散は
$$\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_i,\quad s^2 = \frac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar{x})^2$$
t 統計量・効果量は
$$t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{s_1^2/n_1 + s_2^2/n_2}},\quad d = \frac{\bar{x}_1 - \bar{x}_2}{s_{\text{pooled}}}$$
SSDSE-B-2026 の都道府県データから 正規性 の文脈で代表値を読み取ります。 各列の記号 → 意味を確認し、 平均・中央値・四分位を併記する習慣を身につけましょう。
| 都道府県 | 総人口(千) | 65歳以上人口(千) | 高齢化率(%) | 記号 → 意味 |
|---|---|---|---|---|
| 秋田県 | 945 | 370 | 39.1 | A1101 → 総人口 / A1301 → 高齢者 / 比率 → 高齢化率 |
| 東京都 | 14,047 | 3,193 | 22.7 | 巨大分母 → 平均を引き上げる外れ値の典型 |
| 沖縄県 | 1,467 | 323 | 22.0 | 若い人口構造 → 全国最低の高齢化率 |
| 大阪府 | 8,838 | 2,420 | 27.4 | 大都市圏の中位 → 比較基準として有用 |
| 島根県 | 658 | 231 | 35.1 | 人口減少地域 → 分母縮小型の高齢化 |
import pandas as pd
from scipy import stats
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
df['aging'] = df['A1301']/df['A1101']*100
W, p = stats.shapiro(df['aging'])
print(f'Shapiro W={W:.4f}, p={p:.4f}')
# p>0.05 なら正規性を棄却できないdata/raw/SSDSE-B-2026.csv(47 都道府県 × 主要統計列)。 出力例は数値・p 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。from scipy import stats
import numpy as np
z = (df['aging'] - df['aging'].mean()) / df['aging'].std()
D, p = stats.kstest(z, 'norm')
print(f'KS D={D:.4f}, p={p:.4f}')data/raw/SSDSE-B-2026.csv(47 都道府県 × 主要統計列)。 出力例は数値・p 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。import matplotlib.pyplot as plt
import scipy.stats as stats
stats.probplot(df['aging'], dist='norm', plot=plt)
plt.title('Q-Q plot of 高齢化率')
plt.tight_layout(); plt.savefig('qq.png', dpi=150)data/raw/SSDSE-B-2026.csv(47 都道府県 × 主要統計列)。 出力例は数値・p 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。from scipy.stats import boxcox
y, lam = boxcox(df['aging'])
print(f'lambda={lam:.3f}')
W2, p2 = stats.shapiro(y)
print(f'変換後 Shapiro W={W2:.4f}, p={p2:.4f}')data/raw/SSDSE-B-2026.csv(47 都道府県 × 主要統計列)。 出力例は数値・p 値・統計量で、 解釈には「実値で計算してみる → 仮説検定 → 効果量 → 結論」の流れを推奨します。正規性 を中心に、 前提概念・並列分野・発展手法へリンクします。
グループ教材から 正規性 の文脈に直結する論文・ハンズオンを辿れます。
正規性 は古典統計と社会データの交差点で発達してきました。 19 世紀末から 20 世紀初頭にかけて Pearson, Fisher, Neyman などが基礎を整え、 戦後の公的統計整備により実務応用が広がりました。
2010 年代以降は、 「再現性危機」「ビッグデータ」「AI 倫理」の三つの波が 正規性 に新しい意味を与えました。 単に p<0.05 を出すのではなく、 効果量・信頼区間・事前登録・データシートが必須となっています。
日本では総務省統計局・国立社会保障人口問題研究所・経済産業省 RESAS などが公的統計を整備し、 教育用に SSDSE が無償公開されました。 本ページもこの枠組みで 正規性 を扱います。
https://www.e-stat.go.jp/https://www.nstac.go.jp/use/literacy/ssdse/https://docs.scipy.org/doc/scipy/reference/stats.htmlhttps://www.statsmodels.org/同じカテゴリの手法、 上位概念、 派生分野へのリンクを補強します。
正規性 を SSDSE-B-2026 の 47 都道府県データで多角的に検証します。 ここでは(1)地域グルーピング、 (2)時系列推移の近似、 (3)リスク評価指標の三つを順に扱います。
SSDSE-B-2026 の都道府県を北海道・東北・関東・中部・近畿・中国・四国・九州・沖縄の 9 ブロックに集約して比較します。 ブロック内分散とブロック間分散の比から 正規性 の構造を観察できます。
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
df['aging'] = df['A1301'] / df['A1101'] * 100
block_map = {
'北海道': '北海道', '青森県':'東北','岩手県':'東北','宮城県':'東北','秋田県':'東北','山形県':'東北','福島県':'東北',
'茨城県':'関東','栃木県':'関東','群馬県':'関東','埼玉県':'関東','千葉県':'関東','東京都':'関東','神奈川県':'関東',
'新潟県':'中部','富山県':'中部','石川県':'中部','福井県':'中部','山梨県':'中部','長野県':'中部','岐阜県':'中部','静岡県':'中部','愛知県':'中部',
'三重県':'近畿','滋賀県':'近畿','京都府':'近畿','大阪府':'近畿','兵庫県':'近畿','奈良県':'近畿','和歌山県':'近畿',
'鳥取県':'中国','島根県':'中国','岡山県':'中国','広島県':'中国','山口県':'中国',
'徳島県':'四国','香川県':'四国','愛媛県':'四国','高知県':'四国',
'福岡県':'九州','佐賀県':'九州','長崎県':'九州','熊本県':'九州','大分県':'九州','宮崎県':'九州','鹿児島県':'九州',
'沖縄県':'沖縄'
}
df['block'] = df['Prefecture'].map(block_map)
print(df.groupby('block')['aging'].agg(['mean','std','min','max']))
過去 50 年の高齢化率推移は近似的に直線(やや上に凸)です。 線形外挿で 2030 / 2040 / 2050 年の値を推定し、 正規性 の将来像を可視化します。
import numpy as np
years = [1970, 1980, 1990, 2000, 2010, 2020]
rate = [7.1, 9.1, 12.1, 17.4, 23.0, 28.6] # 厚労省・統計局公表値
coef = np.polyfit(years, rate, 2)
for y in [2030, 2040, 2050]:
print(f'{y} 年予測: {np.polyval(coef, y):.1f}%')
複数指標を z 標準化し、 単純合成スコアで都道府県をランキングします。 重み付けの工夫により 正規性 の優先度を可変にできます。
import pandas as pd
cols = ['A1101','A1301']
z = (df[cols] - df[cols].mean()) / df[cols].std()
df['risk_score'] = z['A1301'] - 0.5 * z['A1101']
print(df[['Prefecture','aging','risk_score']].sort_values('risk_score', ascending=False).head(10))
同じカテゴリの隣接概念、 派生分野、 上位概念へのリンクを補強します。
95% 信頼区間と検出力の式を併記します。
$$\text{CI}_{95\%} = \bar{x} \pm 1.96 \frac{s}{\sqrt{n}}$$
記号 → 意味:
正規性 を「カメラの絞り」に例えると、 絞りを開けすぎると(α を大きくすると)光(偽陽性)が入りすぎ、 絞りすぎると(α を小さくすると)暗くなって何も写らない(偽陰性増加)。 適度な絞り=適度な α を、 撮影条件=研究設計に応じて決める作業が統計的判断です。
import pandas as pd
from scipy import stats
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
df['aging'] = df['A1301'] / df['A1101'] * 100
# 全国平均との一群比較
t, p = stats.ttest_1samp(df['aging'], 29.0)
print(f't={t:.3f} / p={p:.4f}')
# 効果量
d = (df['aging'].mean() - 29.0) / df['aging'].std()
print(f"Cohen's d = {d:.3f}")
# 95% 信頼区間
import numpy as np
m, s, n = df['aging'].mean(), df['aging'].std(), len(df)
ci = (m - 1.96*s/np.sqrt(n), m + 1.96*s/np.sqrt(n))
print(f'95% CI = {ci}')
正規性 を扱うときに頻繁に登場する基本数式を一括掲載します。 KaTeX レンダリングは自動で行われます。
$$\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_i$$
$$s^2 = \frac{1}{n-1}\sum_{i=1}^{n} (x_i - \bar{x})^2$$
$$z = \frac{x - \mu}{\sigma}$$
$$\text{CI}_{1-\alpha} = \bar{x} \pm z_{\alpha/2} \cdot \frac{s}{\sqrt{n}}$$
$$t = \frac{\bar{x}_1 - \bar{x}_2}{\sqrt{\frac{s_1^2}{n_1} + \frac{s_2^2}{n_2}}}$$
$$F = \frac{MS_{between}}{MS_{within}}$$
$$\chi^2 = \sum \frac{(O - E)^2}{E}$$
$$r = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum (x_i - \bar{x})^2}\sqrt{\sum (y_i - \bar{y})^2}}$$
| 記号 | 意味 | SSDSE-B-2026 での対応 |
|---|---|---|
| \(x_i\) | i 番目の観測値 | 各都道府県の値 |
| \(n\) | 標本サイズ | 47 都道府県なら n=47 |
| \(\bar{x}\) | 標本平均 | df['列名'].mean() |
| \(\mu\) | 母平均 | 理論値 / 比較基準 |
| \(s\) | 標本標準偏差(不偏) | df['列名'].std(ddof=1) |
| \(\sigma\) | 母標準偏差 | 通常未知 → s で代用 |
| \(\alpha\) | 有意水準 = 第一種の誤り許容率 | 慣例: 0.05 |
| \(p\) | p 値(H₀ 下での観測の稀さ) | scipy で計算 |
| \(d\) | Cohen's d(効果量) | 差を s で割る |
| \(r\) | Pearson 相関係数 | df.corr() |
SSDSE-B-2026 を読み込み、 正規性 に直接関連する集計を 5 種類実行します。
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='utf-8', skiprows=1)
df['aging'] = df['A1301'] / df['A1101'] * 100
# 1) 基本統計
print(df['aging'].describe())
# 2) 上位下位 5 県
print('上位:', df.nlargest(5, 'aging')[['Prefecture','aging']])
print('下位:', df.nsmallest(5, 'aging')[['Prefecture','aging']])
# 3) 全国平均との差
print('差の絶対値合計:', (df['aging'] - df['aging'].mean()).abs().sum())
# 4) z-score 化
df['z'] = (df['aging'] - df['aging'].mean()) / df['aging'].std()
print('z>2 の県:', df[df['z']>2]['Prefecture'].tolist())
# 5) 5 分位(quintile)
df['quint'] = pd.qcut(df['aging'], 5, labels=['Q1','Q2','Q3','Q4','Q5'])
print(df['quint'].value_counts().sort_index())
import matplotlib.pyplot as plt
df['aging'].plot.hist(bins=15, edgecolor='black', figsize=(8,4.5))
plt.axvline(df['aging'].mean(), color='red', linestyle='--', label='平均')
plt.axvline(df['aging'].median(), color='blue', linestyle=':', label='中央値')
plt.legend(); plt.xlabel('高齢化率(%)'); plt.tight_layout()
plt.savefig('hist.png', dpi=150)
plt.figure(figsize=(6,5))
plt.boxplot(df['aging'], vert=True, patch_artist=True,
boxprops=dict(facecolor='#E0F2F1'))
plt.ylabel('高齢化率(%)')
plt.title('SSDSE-B-2026 47 都道府県')
plt.tight_layout(); plt.savefig('box.png', dpi=150)
plt.figure(figsize=(8,5))
plt.scatter(df['A1101']/1e6, df['aging'])
plt.xlabel('総人口(百万人)'); plt.ylabel('高齢化率(%)')
plt.xscale('log')
plt.title('総人口(対数)と高齢化率の関係')
plt.tight_layout(); plt.savefig('scat.png', dpi=150)
sorted_df = df.sort_values('aging')
plt.figure(figsize=(7,11))
plt.barh(sorted_df['Prefecture'], sorted_df['aging'], color='#00897B')
plt.xlabel('高齢化率(%)'); plt.tight_layout()
plt.savefig('rank.png', dpi=150)
import seaborn as sns
df['region'] = df['Prefecture'].apply(lambda p: '東' if p in ['東京都','神奈川県','千葉県','埼玉県','茨城県','栃木県','群馬県'] else ('西' if p in ['大阪府','京都府','兵庫県','奈良県','和歌山県'] else 'その他'))
sns.violinplot(data=df, x='region', y='aging')
plt.tight_layout(); plt.savefig('violin.png', dpi=150)
正規性 は以下の用語と密接に関係しています。 ノードを辿りながら知識ネットワークを広げましょう。
正規性 は 「望遠鏡の解像度と倍率」 に例えられます。 倍率を上げると(標本サイズを増やすと)細部が見える反面、 視野は狭くなる。 解像度(精度=効果量)と倍率(規模=サンプル)のバランスが鍵です。
もう一つの比喩は 「魚群探知機」 。 強い反射(大きな効果)は小さな船(小標本)でも見えるが、 弱い反射(小さな効果)は大型船(大標本)でなければ検出できない。 ここに 正規性 の本質があります。