STEP 19:カイ二乗検定の実践

📊 STEP 19: カイ二乗検定の実践

カテゴリデータの関連性を検証しよう

📋 このステップで学ぶこと

  • カイ二乗検定とは何か
  • カテゴリカルデータの分析方法
  • クロス集計表の作り方
  • 独立性の検定
  • 実務例(性別と購買の関係、地域と好みの関係)

学習時間の目安:3時間

🔍 1. カイ二乗検定とは

カテゴリカルデータとは

📌 カテゴリカルデータ

数値ではなく、カテゴリ(分類)で表されるデータ

例:
・性別:男性 / 女性
・購入:する / しない
・満足度:満足 / 普通 / 不満
・地域:東京 / 大阪 / 名古屋
・商品:A / B / C

t検定との違い:
・t検定:数値データの平均を比較
・カイ二乗検定:カテゴリデータの関連性を検証

カイ二乗検定の目的

💡 カイ二乗検定でわかること

2つのカテゴリ変数に関連性があるかを検定

仮説:
・H₀:2つの変数は独立(関連性なし)
・H₁:2つの変数に関連性がある

ビジネス例:
・性別と購入の有無に、関連性はあるか?
・地域と商品の好みに、関連性はあるか?
・年代と満足度に、関連性はあるか?
・広告の種類とクリック率に、関連性はあるか?

わかること:
「性別によって購入率が異なる」などの関連性を統計的に証明!

検定 データの種類
t検定 数値データ 男性 vs 女性の購入金額(円)
カイ二乗検定 カテゴリデータ 男性 vs 女性の購入有無(する/しない)

📋 2. クロス集計表

クロス集計表とは

📌 クロス集計表(分割表)

2つのカテゴリ変数の組み合わせごとに、度数を集計した表

例:性別 × 購入の有無

購入した 購入しない 合計
男性 30 70 100
女性 50 50 100
合計 80 120 200
📊 観察

・男性の購入率:30%(30/100)
・女性の購入率:50%(50/100)
→ 女性の方が購入率が高そう…でも偶然?

期待度数の計算

💡 期待度数とは

「2つの変数が独立(関連性なし)だった場合に、期待される度数」

計算式:
期待度数 = (行の合計 × 列の合計)/ 全体の合計

例:男性かつ購入した、の期待度数
= (100 × 80)/ 200
= 8000 / 200
= 40人

カイ二乗検定:
実際の度数と期待度数のずれが、偶然では説明できないほど大きいか?

購入した 購入しない
男性 実際:30 / 期待:40 実際:70 / 期待:60
女性 実際:50 / 期待:40 実際:50 / 期待:60

🔢 3. カイ二乗統計量の計算

計算式

📌 カイ二乗統計量(χ²)

計算式:
χ² = Σ(実際の度数 – 期待度数)² / 期待度数

意味:
・χ²が大きい → 実際と期待のずれが大きい → 関連性あり
・χ²が小さい → 実際と期待のずれが小さい → 関連性なし

【カイ二乗統計量の計算例】 男性・購入: (30 – 40)² / 40 = 100 / 40 = 2.50 男性・非購入:(70 – 60)² / 60 = 100 / 60 = 1.67 女性・購入: (50 – 40)² / 40 = 100 / 40 = 2.50 女性・非購入:(50 – 60)² / 60 = 100 / 60 = 1.67 χ² = 2.50 + 1.67 + 2.50 + 1.67 = 8.34

自由度とp値

💡 自由度とp値

χ²統計量から、p値を求めるには自由度が必要

自由度の計算:
自由度 = (行数 – 1)×(列数 – 1)

例:
2行 × 2列の表
自由度 = (2 – 1)×(2 – 1)= 1

p値:
χ² = 8.34、自由度 = 1 の場合
→ p値 ≈ 0.004

判定:
p値(0.004)< α(0.05)→ 帰無仮説を棄却
→ 性別と購入に関連性あり

💻 4. Pythonでの実装

基本的な例

# ============================================ # カイ二乗検定の実装 # ============================================ # カイ二乗検定とは? # → 2つのカテゴリ変数に「関連性があるか」を検定 # → 例:性別と購入、年代と商品選択、地域と嗜好 # # t検定との違い: # → t検定: 数値データの平均を比較 # → カイ二乗検定: カテゴリデータの分布を比較 import numpy as np import pandas as pd from scipy.stats import chi2_contingency # ============================================ # クロス集計表(分割表)を作成 # ============================================ # クロス集計表とは? # → 2つのカテゴリ変数の組み合わせごとに人数を集計した表 # → 行: 性別(男性/女性) # → 列: 購入(した/しない) data = pd.DataFrame({ ‘購入した’: [30, 50], # 男性30人、女性50人が購入 ‘購入しない’: [70, 50] # 男性70人、女性50人が非購入 }, index=[‘男性’, ‘女性’]) print(“【クロス集計表】”) print(data) print(f”\n全体: {data.sum().sum()}人”) # 購入率の計算(参考情報) print(“\n【購入率】”) for gender in data.index: 購入率 = data.loc[gender, ‘購入した’] / data.loc[gender].sum() print(f”{gender}: {購入率:.1%}”) # 仮説の設定 print(“\n【仮説の設定】”) print(“H₀(帰無仮説): 性別と購入は独立(関連性なし)”) print(“H₁(対立仮説): 性別と購入に関連性あり”) # ============================================ # chi2_contingency(): カイ二乗検定を実行 # ============================================ # 戻り値: # chi2: カイ二乗統計量(ずれの大きさを数値化) # p_value: p値(この差が偶然である確率) # dof: 自由度 = (行数-1) × (列数-1) # expected: 期待度数(独立な場合の理論値) chi2, p_value, dof, expected = chi2_contingency(data) # ============================================ # 期待度数とは? # ============================================ # 「関連性がない」と仮定した場合の理論的な人数 # 実際の度数と期待度数の差が大きい → 関連性あり print(“\n【期待度数】(独立な場合の理論値)”) expected_df = pd.DataFrame(expected, index=data.index, columns=data.columns) print(expected_df) print(“\n【検定結果】”) print(f”カイ二乗統計量(χ²): {chi2:.4f}”) print(f”p値: {p_value:.4f}”) print(f”自由度: {dof}”) # 判定 alpha = 0.05 print(f”\n【判定】(有意水準α={alpha})”) if p_value < alpha: print(f"p値({p_value:.4f}) < α({alpha})") print("→ 帰無仮説を棄却") print("→ 性別と購入に関連性あり!") print("→ 性別によってマーケティング施策を変えるべき") else: print(f"p値({p_value:.4f}) ≥ α({alpha})") print("→ 帰無仮説を棄却できない") print("→ 性別と購入に関連があるとは言えない")
# 出力例 【クロス集計表】 購入した 購入しない 男性 30 70 女性 50 50 全体: 200人 【購入率】 男性: 30.0% 女性: 50.0% 【仮説の設定】 H₀: 性別と購入は独立(関連性なし) H₁: 性別と購入に関連性あり 【期待度数】 購入した 購入しない 男性 40.0 60.0 女性 40.0 60.0 【検定結果】 カイ二乗統計量: 8.3333 p値: 0.0039 自由度: 1 【判定】(α=0.05) p値(0.0039) < α(0.05) → 帰無仮説を棄却 → 性別と購入に関連性あり!

生データからクロス集計表を作成

# 生データからクロス集計表を作成 import pandas as pd from scipy.stats import chi2_contingency # 生データ(各行が1人の顧客) データ = pd.DataFrame({ ‘性別’: [‘男性’, ‘女性’, ‘男性’, ‘女性’, ‘男性’, ‘女性’, ‘男性’, ‘女性’, ‘男性’, ‘女性’, ‘男性’, ‘女性’, ‘男性’, ‘女性’, ‘男性’, ‘女性’], ‘購入’: [‘しない’, ‘した’, ‘しない’, ‘した’, ‘しない’, ‘した’, ‘しない’, ‘した’, ‘しない’, ‘しない’, ‘した’, ‘した’, ‘しない’, ‘した’, ‘しない’, ‘しない’] }) print(“【生データ(最初の5行)】”) print(データ.head()) # クロス集計表を作成 クロス表 = pd.crosstab(データ[‘性別’], データ[‘購入’]) print(“\n【クロス集計表】”) print(クロス表) # カイ二乗検定 chi2, p_value, dof, expected = chi2_contingency(クロス表) print(f”\n【検定結果】”) print(f”χ² = {chi2:.4f}”) print(f”p値 = {p_value:.4f}”) if p_value < 0.05: print("→ 関連性あり!") else: print("→ 関連性があるとは言えない")

📊 5. Excelでの実装

Excelでカイ二乗検定

【Excel関数:CHISQ.TEST】 =CHISQ.TEST(実際の範囲, 期待度数の範囲) 【手順】 1. クロス集計表を作成(実際の度数) 2. 期待度数を計算 期待度数 = (行の合計 × 列の合計) / 全体の合計 3. CHISQ.TEST関数でp値を計算 【データの配置例】 A B C D 1 購入 非購入 合計 2 男性 30 70 100 3 女性 50 50 100 4 合計 80 120 200 【期待度数の計算(F2セル)】 =($D2*B$4)/$D$4 → これをF2:G3にコピー F G 2 40 60 3 40 60 【p値の計算】 =CHISQ.TEST(B2:C3, F2:G3) → p値が返される(例:0.0039) → p < 0.05 なら、関連性あり!
💡 Excelでの期待度数の計算

例:男性・購入の期待度数

計算式:
=($D2*B$4)/$D$4

説明:
・$D2:男性の合計(100人)
・B$4:購入の合計(80人)
・$D$4:全体の合計(200人)
・$(ドルマーク):絶対参照(コピーしても固定)

この式を全セルにコピーして、期待度数の表を完成させます。

📈 6. 実務での活用例

例1:地域別の商品選好

# 地域別の商品選好の分析 import pandas as pd from scipy.stats import chi2_contingency # クロス集計表 data = pd.DataFrame({ ‘商品A’: [40, 30, 20], ‘商品B’: [30, 40, 30], ‘商品C’: [20, 30, 50] }, index=[‘東京’, ‘大阪’, ‘名古屋’]) print(“【クロス集計表】”) print(data) # 各地域の選好率 print(“\n【地域別の選好率】”) for region in data.index: total = data.loc[region].sum() print(f”\n{region}:”) for product in data.columns: rate = data.loc[region, product] / total print(f” {product}: {rate:.1%}”) # カイ二乗検定 chi2, p_value, dof, expected = chi2_contingency(data) print(“\n【検定結果】”) print(f”χ² = {chi2:.4f}”) print(f”p値 = {p_value:.4f}”) if p_value < 0.05: print("→ 地域と商品選好に関連性あり!") print("→ 地域別のマーケティング戦略が有効") else: print("→ 地域と商品選好に関連性なし") print("→ 全国統一の戦略でOK")
# 出力例 【クロス集計表】 商品A 商品B 商品C 東京 40 30 20 大阪 30 40 30 名古屋 20 30 50 【地域別の選好率】 東京: 商品A: 44.4% 商品B: 33.3% 商品C: 22.2% 大阪: 商品A: 30.0% 商品B: 40.0% 商品C: 30.0% 名古屋: 商品A: 20.0% 商品B: 30.0% 商品C: 50.0% 【検定結果】 χ² = 16.6667 p値 = 0.0023 → 地域と商品選好に関連性あり! → 地域別のマーケティング戦略が有効

例2:広告の種類とクリック率

# 広告の種類とクリック率の分析 import pandas as pd from scipy.stats import chi2_contingency # クロス集計表 data = pd.DataFrame({ ‘クリック’: [25, 40, 35], ‘非クリック’: [75, 60, 65] }, index=[‘テキスト広告’, ‘画像広告’, ‘動画広告’]) print(“【クロス集計表】”) print(data) # クリック率 print(“\n【クリック率】”) for ad in data.index: total = data.loc.sum() ctr = data.loc / total print(f”{ad}: {ctr:.1%}”) # カイ二乗検定 chi2, p_value, dof, expected = chi2_contingency(data) print(“\n【検定結果】”) print(f”χ² = {chi2:.4f}”) print(f”p値 = {p_value:.4f}”) if p_value < 0.05: print("→ 広告タイプによってクリック率が異なる!") else: print("→ 広告タイプによるクリック率の差は有意でない")

⚠️ 7. カイ二乗検定の注意点

使用条件

⚠️ カイ二乗検定の前提条件

期待度数が小さいと、検定が正確でなくなる

条件:
・すべてのセルの期待度数が5以上
・80%以上のセルで、期待度数が5以上

期待度数が小さい場合:
Fisherの正確確率検定を使う(2×2表の場合)
・カテゴリを統合して、期待度数を増やす
・サンプルサイズを増やす

Python:
from scipy.stats import fisher_exact
oddsratio, p_value = fisher_exact(table)

解釈の注意

💡 カイ二乗検定でわかること・わからないこと

わかること:

  • 2つの変数に関連性があるか
  • 独立ではないことを示せる

わからないこと:

  • どちらが原因で、どちらが結果か(因果関係)
  • 関連の強さ(p値は強さを示さない)
    → クラメールのVやφ係数を使う
  • どのセルが特に関連しているか
    → 残差分析が必要

関連の強さを測る

# 関連の強さを測る指標 import numpy as np import pandas as pd from scipy.stats import chi2_contingency # クロス集計表 data = pd.DataFrame({ ‘購入した’: [30, 50], ‘購入しない’: [70, 50] }, index=[‘男性’, ‘女性’]) # カイ二乗検定 chi2, p_value, dof, expected = chi2_contingency(data) # クラメールのVを計算 n = data.sum().sum() # 全体のサンプルサイズ min_dim = min(len(data.index) – 1, len(data.columns) – 1) cramers_v = np.sqrt(chi2 / (n * min_dim)) print(“【関連の強さ】”) print(f”クラメールのV: {cramers_v:.4f}”) print(“\n【解釈の目安】”) print(“V < 0.1: ほとんど関連なし") print("0.1 ≤ V < 0.3: 弱い関連") print("0.3 ≤ V < 0.5: 中程度の関連") print("V ≥ 0.5: 強い関連")
# 出力例 【関連の強さ】 クラメールのV: 0.2041 【解釈の目安】 V < 0.1: ほとんど関連なし 0.1 ≤ V < 0.3: 弱い関連 0.3 ≤ V < 0.5: 中程度の関連 V ≥ 0.5: 強い関連

📝 STEP 19 のまとめ

✅ このステップで学んだこと

1. カイ二乗検定の基本

  • カテゴリデータの関連性を検証
  • H₀:2つの変数は独立(関連性なし)
  • H₁:2つの変数に関連性がある

2. クロス集計表と期待度数

  • 期待度数 = (行の合計 × 列の合計)/ 全体
  • χ² = Σ(実際 – 期待)² / 期待

3. 注意点

  • 期待度数が5以上であること
  • 関連性 ≠ 因果関係
  • p値は関連の強さを示さない
💡 最も大切なポイント

カイ二乗検定は、カテゴリデータの分析に欠かせません!

使用シーン:
・性別、年代、地域などのカテゴリ変数
・購入する/しない、満足/不満などの2値変数

判定の流れ:
1. クロス集計表を作成
2. 期待度数を計算
3. χ²統計量とp値を計算
4. p < 0.05 なら、関連性あり

次のSTEP 20では、A/Bテストの設計を学びます!

🎯 次のステップの予告

STEP 20では、「A/Bテストの設計」を学びます。Webサイトやアプリの改善効果を科学的に検証する方法を習得しましょう!

📝 練習問題

問題 1 基礎

以下のクロス集計表で、期待度数を計算してください。

A商品B商品合計
東京6040100
大阪3070100
合計90110200
東京・A商品の期待度数は?

【解答】

期待度数の計算式:

期待度数 = (行の合計 × 列の合計)/ 全体の合計

東京・A商品の期待度数
= (100 × 90)/ 200
= 9000 / 200
= 45人

解釈:
もし地域と商品が独立(関連性なし)なら、東京でA商品を選ぶ人は45人になるはず。

実際は60人 → 期待より15人多い
→ 東京ではA商品が好まれている可能性

問題 2 基礎

カイ二乗検定とt検定の使い分けについて説明してください。
どのような場合にカイ二乗検定を使いますか?

【解答】

カイ二乗検定を使う場合:

両方の変数がカテゴリデータのとき
例:性別(男/女)× 購入(する/しない)
例:地域(東京/大阪/名古屋)× 商品(A/B/C)

t検定を使う場合:

目的変数が数値データのとき
例:性別(男/女)× 購入金額(円)
例:導入前/後 × 売上(万円)

判断基準:
目的変数が何か?
・カテゴリ → カイ二乗検定
・数値 → t検定

問題 3 応用

以下のクロス集計表で、カイ二乗検定を実行してください。

クリック非クリック
広告A2575
広告B4060
(1) 各広告のクリック率を計算してください
(2) 有意水準α=0.05で、広告の種類とクリック率に関連性はありますか?

【解答】

(1) クリック率

広告A:25 /(25 + 75)= 25 / 100 = 25%
広告B:40 /(40 + 60)= 40 / 100 = 40%

(2) Pythonでカイ二乗検定

import pandas as pd from scipy.stats import chi2_contingency data = pd.DataFrame({ ‘クリック’: [25, 40], ‘非クリック’: [75, 60] }, index=[‘広告A’, ‘広告B’]) chi2, p, dof, expected = chi2_contingency(data) print(f”χ² = {chi2:.4f}, p値 = {p:.4f}”)

結果:
・χ² = 4.8077
・p値 = 0.0283

判定:
p値(0.0283)< α(0.05)→ 帰無仮説を棄却
→ 広告の種類とクリック率に関連性あり
→ 広告Bの方がクリック率が高い

問題 4 応用

カイ二乗検定の結果、p値 = 0.001 でした。
これは「関連が非常に強い」ということですか?
関連の強さを測るには、どうすれば良いですか?

【解答】

p値は関連の強さを示すものではありません!

p値が示すもの:
・「偶然でこうなる確率」(統計的な確実性)
・関連性の有無を判定

関連の強さを示すもの:
クラメールのV(どんなサイズの表でも使える)
φ係数(2×2表の場合)

クラメールのVの解釈:
・V < 0.1:ほとんど関連なし
・0.1 ≤ V < 0.3:弱い関連
・0.3 ≤ V < 0.5:中程度の関連
・V ≥ 0.5:強い関連

注意:サンプルが大きいと、弱い関連でもp値は小さくなる!

問題 5 実践

以下のクロス集計表で、期待度数が5未満のセルがあります。
この場合、どう対処すべきですか?

購入非購入
10代218
20代1535
30代2030

【解答】

問題の確認:

10代・購入の期待度数を計算:
= (20 × 37)/ 120 = 740 / 120 = 6.17人

→ 期待度数は5以上だが、実際の度数が2人と非常に小さい

対処法:

方法1:カテゴリを統合(推奨)
10代と20代を「20代以下」にまとめる

購入非購入
20代以下1753
30代2030

方法2:Fisherの正確確率検定
2×2表の場合、期待度数が小さくても使える

方法3:サンプルサイズを増やす
追加でデータを収集

推奨:方法1のカテゴリ統合が最も実用的!
ただし、ビジネス的に意味のある統合かを確認すること。

❓ よくある質問

Q1: カイ二乗検定とt検定、どちらを使うべきですか?
データのタイプで決まります。

カイ二乗検定を使う:
・両方の変数がカテゴリデータ
・例:性別(男/女)× 購入(する/しない)
・例:地域(東京/大阪/名古屋)× 商品(A/B/C)

t検定を使う:
・目的変数が数値データ
・説明変数がカテゴリデータ(2グループ)
・例:性別(男/女)× 購入金額(円)
・例:導入前/後 × 売上(万円)

判断基準:
目的変数が何か?
・カテゴリ → カイ二乗検定
・数値 → t検定
Q2: p値が小さいほど、関連が強いということですか?
いいえ、違います!

p値が示すもの:
・「偶然でこうなる確率」(統計的な確実性)
・関連性の有無を判定

関連の強さを示すもの:
・クラメールのV
・φ係数(2×2表の場合)

例:
ケースA:サンプル = 100人、p = 0.03、V = 0.2(弱い関連)
ケースB:サンプル = 10000人、p = 0.001、V = 0.05(非常に弱い関連)

→ ケースBの方がp値は小さいが、関連は弱い!

重要:
サンプルが大きいと、弱い関連でもp値は小さくなる
Q3: 3×3以上の表でも、カイ二乗検定は使えますか?
はい、使えます!

カイ二乗検定の適用範囲:
・2×2表
・2×3表、3×2表
・3×3表、4×4表など
→ どんなサイズでもOK

ただし:
・期待度数が5以上の条件は同じ
・表が大きいほど、セル数が増える
・期待度数が小さいセルが出やすい

有意になった場合:
・「どこかに関連がある」とわかる
・でも「どのセルが特に関連しているか」は不明
残差分析で詳しく調べる
Q4: カイ二乗検定で「関連性あり」となったら、因果関係があるということですか?
いいえ、関連性 ≠ 因果関係です!

カイ二乗検定でわかること:
・2つの変数に関連性がある
・独立ではない

わからないこと:
・どちらが原因で、どちらが結果か
・第3の変数が影響していないか

例:アイスクリームの売上と溺死者数
・カイ二乗検定 → 関連性あり
・でも因果関係はない!
・第3の変数「気温」が両方に影響

因果関係を示すには:
・ランダム化比較試験(RCT)
・A/Bテスト
・時系列分析
・理論的な裏付け
Q5: Excelで自動的にカイ二乗検定できませんか?
CHISQ.TEST関数で簡単にできます!

手順:
1. クロス集計表を作成(実際の度数)
2. 期待度数を計算(各セル)
3. CHISQ.TEST関数でp値を取得

例:
=CHISQ.TEST(A1:B2, D1:E2)

期待度数の計算式(E2セル):
=($C2*B$4)/$C$4

注意:
・期待度数は手動で計算が必要
・χ²統計量は直接出ない(p値のみ)

χ²統計量も知りたい場合:
=CHISQ.INV.RT(p値, 自由度)
自由度 = (行数-1)×(列数-1)
Q6: カイ二乗検定の結果をレポートするには、どう書けば良いですか?
統計結果を正しく報告するフォーマットがあります。

標準的な報告フォーマット:
「χ²(自由度) = χ²値, p = p値」

例1:有意な場合
「性別と購入行動に有意な関連が見られた(χ²(1) = 8.33, p = .004)。女性の購入率(50%)は男性(30%)より高かった。」

例2:有意でない場合
「地域と商品選好に有意な関連は見られなかった(χ²(4) = 3.21, p = .523)。」

含めるべき情報:
・χ²値と自由度
・p値
・各カテゴリの割合
・関連の強さ(クラメールのV)があるとなお良い
📝

学習メモ

ビジネスデータ分析・意思決定 - Step 19

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE