クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

仮説検定とp値の考え方

このレッスンのあとで: 見つけた差が偶然かどうかを、並べ替え検定で確かめることができる。

60分のレッスンコマンド2件JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

その差は偶然か

仮説検定は、見つけた差が、偶然でも起こる程度のものかどうかを確かめる方法です。使えば、「この差は本物か」という問いに、勘ではなく確率で答えられます。

貸し自転車の店では、土日は平日より貸出が多く見えます。この差が本物なのか、たまたまなのかを確かめます。

このレッスンのゴール

メモ

見つけた差が偶然かどうかを、並べ替え検定で確かめることができる。

キーワード

ことばいみれい
帰無仮説「差は偶然だけで生まれた」という出発点の仮定
検定統計量差を1つの数にしたもの平均の差
並べ替え検定ラベルを入れ替えて、偶然に出る差を調べる方法
p値差がないとき、実際の差以上が偶然に出る確率
有意水準p値がこれより小さければ、偶然とは考えにくいとする境目0.05
有意p値が有意水準より小さいこと

学生が入力するセルは、このプレビューでは空白です。

「差はない」と仮定して始める

検定は、まず「本当は差がない」と仮定します。これを帰無仮説と言います。差を1つの数にしたものが検定統計量です。

ここでは、土日と平日の平均の差が検定統計量です。差がなくても、日の割り振りしだいで、小さな差は偶然に出ます。

土日と平日の平均の差

コマンド
docker exec jupyter python3 -c "import csv; rows = list(csv.DictReader(open('hires.csv'))); we = [int(r['hires']) for r in rows if r['weekday'] in ('Sat', 'Sun')]; wd = [int(r['hires']) for r in rows if r['weekday'] not in ('Sat', 'Sun')]; print(len(we), len(wd), round(sum(we) / len(we), 1), round(sum(wd) / len(wd), 1), round(sum(we) / len(we) - sum(wd) / len(wd), 1))"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

ラベルを入れ替えて偶然を作る

差が偶然なら、「晴れ」と「雨」のラベルを入れ替えても、同じくらいの差が出るはずです。ラベルの付け方を全部試すのが、並べ替え検定です。

試した付け方のうち、実際の差以上になった割合が、p値です。次の表は、8日を4日ずつに分ける70通りを数えたものです。

例: 8日を4日ずつに分ける

比べる2組実際の差差が同じか大きいp値
晴れ 260 280 300 320 と雨 200 220 240 25062.570通りのうち11 ÷ 70 = 0.014
晴れ 240 260 300 320 と雨 220 250 270 29022.570通りのうち1515 ÷ 70 = 0.214

学生が入力するセルは、このプレビューでは空白です。

全部の分け方を試す

コード: python
# 8日を4日ずつに分ける、全部の分け方を試します。
a = [260, 280, 300, 320]
b = [200, 220, 240, 250]
pool = a + b
n = len(pool)
seen = sum(a) / 4 - sum(b) / 4
ways = 0
extreme = 0
for mask in range(2 ** n):
    group = []
    rest = []
    for i in range(n):
        if (mask // 2 ** i) % 2 == 1:
            group.append(pool[i])
        else:
            rest.append(pool[i])
    if len(group) == 4:
        ways = ways + 1
        if sum(group) / 4 - sum(rest) / 4 >= seen - 0.000001:
            extreme = extreme + 1
print("分け方:", ways, "差が同じか大きい:", extreme)
print("p値:", round(extreme / ways, 4))
# a の 260 を 230 に変えて、p値がどう動くか確かめてください。

p値の読み方

p値が小さいほど、「差は偶然だけ」とは考えにくくなります。多くは、0.05より小さいときに「有意」と言います。この境目が有意水準です。

p値は、差の大きさも、差の大切さも表しません。p値が大きいだけでは、差がない証拠にもなりません。

よくある間違い

注意

多くの人は、p値が0.03なら「差が偶然である確率は3%」と読みます。正しくは、差がないと仮定したとき、この差以上が偶然に出る確率が3%です。差が本物である確率を、p値は教えてくれません。

何度も調べると当たりが出る

20個の違いを調べると、本当は差がなくても、約1つは0.05より小さく出ます。1つも当たらない確率は 0.95 を20回かけた約0.36で、少なくとも1つ当たる確率は約0.64です。

調べた数は、結果と一緒に伝えます。

20回調べて、1つは当たる確率

コマンド
docker exec jupyter python3 -c "print(round(1 - 0.95 ** 20, 3))"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

さらに挑戦: 土日の差を検定する

ノートブックで、365日の貸出台数を2000回シャッフルし、104日と261日に分けてください。そのたびに、平均の差を求めます。

実際の差55.2以上が出た回数を数えましょう。0回なら、p値は 1 ÷ 2000 より小さいと書きます。

このラボとソースについて: JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。