リンドくんたなべ先生、アンケート結果を分析してるんですけど、「性別と商品の好み」みたいな項目同士に関連があるかどうかって、どうやって調べればいいんですか?
たなべそういうときに使うのがカイ二乗検定(カイにじょうけんてい)という統計手法なんだ。
アンケートのようなカテゴリーデータの関連性を科学的に調べることができるんだよ。
データ分析を始めると、必ず遭遇するのが「2つの項目に関連性があるか」という問いです。
例えば、「男性と女性で商品の好みに違いがあるのか」「年齢層によって利用サービスに偏りがあるのか」といった疑問は、ビジネスでもよく出てきますよね。
こうした質問に答えるための強力なツールがカイ二乗検定(chi-square test)です。
本記事では、統計学初心者の方でも理解できるよう、カイ二乗検定の基本概念から実際のPythonコードを使った分析まで、段階的に解説していきます。
アンケート結果を「なんとなく」ではなく、科学的根拠を持って分析できるスキルを身につけていきましょう!
カイ二乗検定とは何か
リンドくん「カイ二乗」って名前からして難しそうなんですけど...
たなべ名前は確かに難しそうだけど、やってることはシンプルなんだよ。
「実際の結果」と「関連がないと仮定した場合の予想結果」を比べるだけなんだ。
カイ二乗検定の基本概念
カイ二乗検定は、カテゴリーデータ(質的データ)の関連性を調べる統計手法です。
カテゴリーデータとは、「男性・女性」「好き・嫌い」「A商品・B商品・C商品」のように、数値ではなく分類で表されるデータのことです。
この検定の核心は以下の考え方にあります。
- もし2つの項目に関連がないなら、データはある特定のパターンになるはず
- 実際のデータがそのパターンから大きくずれているなら、関連がある可能性が高い
- そのずれの大きさを数値化したものがカイ二乗統計量
どんなときに使うのか
カイ二乗検定が活躍する場面は以下のようなケースです。
- アンケート調査の分析 → 性別と商品の好みに関連があるか
- マーケティング分析 → 年齢層と購入チャネルに偏りがあるか
- 医療研究 → 治療法と回復率に関連があるか
- A/Bテスト → デザインAとBでクリック率に差があるか
これらはすべて「カテゴリー×カテゴリー」の関連性を調べる問題であり、カイ二乗検定が最適な手法となります。
仮説検定の流れ
カイ二乗検定は仮説検定の一種です。基本的な流れは次のようになります。
- 帰無仮説の設定 → 「2つの項目に関連はない」と仮定
- データの収集 → 実際のアンケート結果などを集める
- カイ二乗統計量の計算 → 実際のデータと期待値のずれを数値化
- p値の算出 → その統計量が偶然起こる確率を求める
- 判定 → p値が小さければ帰無仮説を棄却し、関連があると結論
この一連の流れを理解することで、カイ二乗検定の本質が見えてきます。
カイ二乗検定の計算の仕組み
リンドくん実際にはどうやって計算するんですか?数式とか出てきますか?
たなべ基本的な考え方を理解しておくと、Pythonで実行するときも何をやってるか分かりやすいよ。
観測度数と期待度数の差を見るんだ。
クロス集計表(分割表)
カイ二乗検定では、まずクロス集計表(分割表)というものを作ります。
例えば、「性別」と「商品の好み」のアンケート結果を整理すると以下のようになります。
| A商品が好き | B商品が好き | 合計 | |
|---|---|---|---|
| 男性 | 30 | 20 | 50 |
| 女性 | 15 | 35 | 50 |
| 合計 | 45 | 55 | 100 |
この表の各マスの数字を観測度数と呼びます。
期待度数の計算
次に、もし「性別と商品の好みに関連がない」と仮定した場合の期待度数を計算します。
期待度数は以下の式で求められます。
期待度数 = (その行の合計 × その列の合計) ÷ 全体の合計
例えば、「男性×A商品」の期待度数は次のようになります。
期待度数 = (50 × 45) ÷ 100 = 22.5
カイ二乗統計量の計算
各マスについて、観測度数と期待度数の差を計算し、それを標準化したものの合計がカイ二乗統計量です。
カイ二乗統計量 = Σ [(観測度数 - 期待度数)² ÷ 期待度数]
この値が大きいほど、実際のデータが「関連なし」という仮定から大きくずれていることを意味します。
p値による判定
カイ二乗統計量が計算できたら、それが偶然起こる確率(p値)を求めます。
一般的にはp値が0.05未満なら「関連がある」と判定します。
このp値の計算には自由度が必要で、クロス集計表の場合は以下のように求めます。
自由度 = (行数 - 1) × (列数 - 1)
Pythonでカイ二乗検定を実行してみよう
リンドくんPythonでやってみたいです!
たなべじゃあ、実際のコードを見ていこう。Pythonのscipyライブラリを使えば、すごく簡単にできるんだよ。
基本的なサンプルコード
まずは、先ほどの「性別と商品の好み」の例をPythonで分析してみましょう。
import numpy as np
from scipy.stats import chi2_contingency
# クロス集計表のデータ
observed = np.array([
[30, 20], # 男性:A商品、B商品
[15, 35] # 女性:A商品、B商品
])
# カイ二乗検定の実行
chi2, p_value, dof, expected = chi2_contingency(observed)
# 結果の表示
print(f"カイ二乗統計量: {chi2:.4f}")
print(f"p値: {p_value:.4f}")
print(f"自由度: {dof}")
print("\n期待度数:")
print(expected)
# 判定
alpha = 0.05
if p_value < alpha:
print(f"\np値({p_value:.4f}) < {alpha} のため、関連性がある可能性が高い")
else:
print(f"\np値({p_value:.4f}) >= {alpha} のため、関連性があるとは言えない")このコードを実行すると、以下のような結果が得られます。
カイ二乗統計量: 9.0909
p値: 0.0026
自由度: 1
期待度数:
[[22.5 27.5]
[22.5 27.5]]
p値(0.0026) < 0.05 のため、関連性がある可能性が高い
コードの解説
このコードのポイントを解説します。
chi2_contingency()関数 → カイ二乗検定を一発で実行してくれる便利な関数- 戻り値 → カイ二乗統計量、p値、自由度、期待度数の4つが返される
- 判定基準 → 一般的にはp値0.05を基準に使う
pandasを使った例
実際のデータ分析では、pandasのDataFrameを使うことが多いです。
以下はアンケートデータからクロス集計表を作成し、カイ二乗検定を行う例です。
import pandas as pd
import numpy as np
from scipy.stats import chi2_contingency
# アンケートデータの作成(実際はCSVファイルなどから読み込む)
data = {
'性別': ['男性']*50 + ['女性']*50,
'好きな商品': ['A']*30 + ['B']*20 + ['A']*15 + ['B']*35
}
df = pd.DataFrame(data)
# クロス集計表の作成
cross_table = pd.crosstab(df['性別'], df['好きな商品'])
print("クロス集計表:")
print(cross_table)
print()
# カイ二乗検定の実行
chi2, p_value, dof, expected = chi2_contingency(cross_table)
# 結果の表示
print(f"カイ二乗統計量: {chi2:.4f}")
print(f"p値: {p_value:.4f}")
print(f"自由度: {dof}")
# わかりやすい判定メッセージ
if p_value < 0.05:
print(f"\n結論: 性別と商品の好みには関連性があります(p={p_value:.4f})")
else:
print(f"\n結論: 性別と商品の好みに関連性があるとは言えません(p={p_value:.4f})")3×3以上の表にも対応
カイ二乗検定は、2×2の表だけでなく、より大きな表にも使えます。
例えば、年齢層と利用サービスの関連を調べる場合は次のようになります。
# 年齢層(3カテゴリー)× サービス(3カテゴリー)の例
observed = np.array([
[20, 30, 10], # 20代:サービスA、B、C
[25, 25, 20], # 30代:サービスA、B、C
[15, 20, 35] # 40代:サービスA、B、C
])
chi2, p_value, dof, expected = chi2_contingency(observed)
print(f"カイ二乗統計量: {chi2:.4f}")
print(f"p値: {p_value:.4f}")
print(f"自由度: {dof}")
if p_value < 0.05:
print("\n年齢層と利用サービスには関連性があります")
else:
print("\n年齢層と利用サービスに関連性があるとは言えません")このように、chi2_contingency()関数は表のサイズに関わらず使用できます。
カイ二乗検定の注意点と制約
リンドくんどんな場合でもカイ二乗検定を使っていいんですか?
たなべ実は、いくつか注意すべき点があるんだ。特にサンプルサイズが小さい場合は気をつける必要があるよ。
期待度数の制約
カイ二乗検定を正しく適用するには、以下の条件を満たす必要があります。
- すべてのセルの期待度数が5以上であること
- もし期待度数が5未満のセルが20%以上ある場合は、検定結果が信頼できない
期待度数が小さすぎる場合の対処法は以下の通りです。
- サンプルサイズを増やす → より多くのデータを集める
- カテゴリーを統合する → 細かすぎる分類を大きくまとめる
- フィッシャーの正確検定を使う → 特に2×2表で期待度数が小さい場合
フィッシャーの正確検定の使用例
期待度数が小さい2×2表の場合は、フィッシャーの正確検定を使います。
from scipy.stats import fisher_exact
# 期待度数が小さい2×2表の例
observed = np.array([
[8, 2], # グループA
[1, 5] # グループB
])
# フィッシャーの正確検定
odds_ratio, p_value = fisher_exact(observed)
print(f"オッズ比: {odds_ratio:.4f}")
print(f"p値: {p_value:.4f}")
if p_value < 0.05:
print("\n関連性があります")
else:
print("\n関連性があるとは言えません")独立性の仮定
カイ二乗検定では、各観測が独立しているという前提があります。
例えば、同じ人が複数回回答している場合などは、この前提が崩れるため注意が必要です。
因果関係ではない
重要な点として、カイ二乗検定で関連性が認められても、それは因果関係を意味しないことに注意してください。
例えば、「アイスクリームの売上」と「溺死者数」に統計的な関連が見られても、アイスクリームが溺死を引き起こすわけではありません。
両方とも「夏」という共通の要因が影響しているだけです。
まとめ
リンドくんカイ二乗検定、思ったより使いやすいですね!アンケート分析がもっと楽しくなりそうです。
たなべそう言ってもらえると嬉しいね!
統計の力を使えば、データから客観的な答えを導き出せるんだ。ぜひいろんな場面で活用してみてね。
カイ二乗検定は、カテゴリーデータの関連性を調べるための強力な統計手法です。
この記事で学んだ内容を振り返ってみましょう。
重要なポイントは以下です。
- カイ二乗検定の目的 → カテゴリー変数同士の関連性を統計的に検証する
- 基本的な考え方 → 観測度数と期待度数のずれを数値化して評価する
- Pythonでの実装 →
scipy.stats.chi2_contingency()で簡単に実行できる - 判定基準 → 一般的にはp値0.05を基準に関連性を判断する
- 注意点 → 期待度数が小さい場合は別の手法を検討する必要がある
データ分析のスキルは、実際に手を動かすことで確実に向上します。
この記事で学んだ知識を活かして、ぜひ実際のデータ分析にチャレンジしてみてください。





