フリーキーズ | 独学プログラミング

カイ二乗検定入門!アンケート結果の関連性を調べる統計手法を初心者向けに解説

リンドくん

リンドくん

たなべ先生、アンケート結果を分析してるんですけど、「性別と商品の好み」みたいな項目同士に関連があるかどうかって、どうやって調べればいいんですか?

たなべ

たなべ

そういうときに使うのがカイ二乗検定(カイにじょうけんてい)という統計手法なんだ。
アンケートのようなカテゴリーデータの関連性を科学的に調べることができるんだよ。

データ分析を始めると、必ず遭遇するのが「2つの項目に関連性があるか」という問いです。
例えば、「男性と女性で商品の好みに違いがあるのか」「年齢層によって利用サービスに偏りがあるのか」といった疑問は、ビジネスでもよく出てきますよね。

こうした質問に答えるための強力なツールがカイ二乗検定(chi-square test)です。
本記事では、統計学初心者の方でも理解できるよう、カイ二乗検定の基本概念から実際のPythonコードを使った分析まで、段階的に解説していきます。

アンケート結果を「なんとなく」ではなく、科学的根拠を持って分析できるスキルを身につけていきましょう!

オンラインコミュニティ運営しています

HackATAは、IT技術を習得する人のために広く開かれたオンラインコミュニティです。 現在、無料コミュニティとして開放していますので、ご気軽に参加してください。

✓ 再立ち上げ

✓ コミュニティの方向性について意見募集中

HackATA公式Webサイト

カイ二乗検定とは何か

リンドくん

リンドくん

「カイ二乗」って名前からして難しそうなんですけど...

たなべ

たなべ

名前は確かに難しそうだけど、やってることはシンプルなんだよ。
「実際の結果」と「関連がないと仮定した場合の予想結果」を比べるだけなんだ。

カイ二乗検定の基本概念

カイ二乗検定は、カテゴリーデータ(質的データ)の関連性を調べる統計手法です。
カテゴリーデータとは、「男性・女性」「好き・嫌い」「A商品・B商品・C商品」のように、数値ではなく分類で表されるデータのことです。

この検定の核心は以下の考え方にあります。

  • もし2つの項目に関連がないなら、データはある特定のパターンになるはず
  • 実際のデータがそのパターンから大きくずれているなら、関連がある可能性が高い
  • そのずれの大きさを数値化したものがカイ二乗統計量

どんなときに使うのか

カイ二乗検定が活躍する場面は以下のようなケースです。

  • アンケート調査の分析 → 性別と商品の好みに関連があるか
  • マーケティング分析 → 年齢層と購入チャネルに偏りがあるか
  • 医療研究 → 治療法と回復率に関連があるか
  • A/Bテスト → デザインAとBでクリック率に差があるか

これらはすべて「カテゴリー×カテゴリー」の関連性を調べる問題であり、カイ二乗検定が最適な手法となります。

仮説検定の流れ

カイ二乗検定は仮説検定の一種です。基本的な流れは次のようになります。

  1. 帰無仮説の設定 → 「2つの項目に関連はない」と仮定
  2. データの収集 → 実際のアンケート結果などを集める
  3. カイ二乗統計量の計算 → 実際のデータと期待値のずれを数値化
  4. p値の算出 → その統計量が偶然起こる確率を求める
  5. 判定 → p値が小さければ帰無仮説を棄却し、関連があると結論

この一連の流れを理解することで、カイ二乗検定の本質が見えてきます。

カイ二乗検定の計算の仕組み

リンドくん

リンドくん

実際にはどうやって計算するんですか?数式とか出てきますか?

たなべ

たなべ

基本的な考え方を理解しておくと、Pythonで実行するときも何をやってるか分かりやすいよ。
観測度数と期待度数の差を見るんだ。

クロス集計表(分割表)

カイ二乗検定では、まずクロス集計表(分割表)というものを作ります。
例えば、「性別」と「商品の好み」のアンケート結果を整理すると以下のようになります。

A商品が好きB商品が好き合計
男性302050
女性153550
合計4555100

この表の各マスの数字を観測度数と呼びます。

期待度数の計算

次に、もし「性別と商品の好みに関連がない」と仮定した場合の期待度数を計算します。
期待度数は以下の式で求められます。

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

例えば、「男性×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%以上ある場合は、検定結果が信頼できない

期待度数が小さすぎる場合の対処法は以下の通りです。

  1. サンプルサイズを増やす → より多くのデータを集める
  2. カテゴリーを統合する → 細かすぎる分類を大きくまとめる
  3. フィッシャーの正確検定を使う → 特に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を基準に関連性を判断する
  • 注意点 → 期待度数が小さい場合は別の手法を検討する必要がある

データ分析のスキルは、実際に手を動かすことで確実に向上します。
この記事で学んだ知識を活かして、ぜひ実際のデータ分析にチャレンジしてみてください。

この記事をシェア

関連するコンテンツ