冬の10日間
新人が、年の最初の10日間の貸出を数えて言います。「うちは1日に約197台貸します」。店長はうなずきます。
1年全体では、約270台です。数字は正しく、言い方が間違っていました。結果の確かさは、標本、ばらつき、その裏にあるグループの大きさで決まります。
このレッスンのゴール
メモ
標本から出した結果を、どこまで信じてよいか言える。
キーワード
| ことば | いみ |
|---|---|
| 標本 | 大きな表から取り出した、少しの行 |
| 代表的 | 表全体によく似ていること |
| ばらつき | 値どうしがどれくらい離れているか |
| 外れ値 | ほかから大きく離れた値。本物のことも、誤りのこともある |
| 中央値 | 値を並べたときの、真ん中の値 |
| グループの大きさ | 平均や件数の裏にある行の数 |
学生が入力するセルは、このプレビューでは空白です。
標本は、全体に似ていなければならない
すべてを見られないことは、よくあります。そこで標本を取ります。よい標本は代表的です。大事な点で、表全体によく似ています。
表の最初の10行は、代表的であることがまれです。みな同じ場所、同じ時期のものだからです。
日の選び方を3つ比べる
docker exec jupyter python3 -c "import pandas as pd; h=pd.read_csv('hires.csv'); print(\"1年の平均:\", round(h['hires'].mean(),1)); print(\"最初の10日の平均:\", round(h['hires'].head(10).mean(),1)); print(\"36日に1日の平均:\", round(h['hires'].iloc[::36].mean(),1), len(h['hires'].iloc[::36]))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
無作為の標本も、ゆれる
行を無作為に取ると、かたよりを避けられます。ただ、小さな無作為の標本は、取るたびに平均が違います。大きな標本ほど、ゆれは小さくなります。
pandas では、sample(10, random_state=1) が10日を取ります。random_state は種です。同じ数なら、同じ日が出ます。
10日の標本を6つ、100日を6つ
docker exec jupyter python3 -c "import pandas as pd; h=pd.read_csv('hires.csv'); print([round(h['hires'].sample(10, random_state=s).mean(),1) for s in range(1,7)]); print([round(h['hires'].sample(100, random_state=s).mean(),1) for s in range(1,7)])"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
大きな値と、その扱い
外れ値は、ほかから大きく離れた値です。平均をそちらへ引っぱりますが、中央値はほとんど動きません。
大きいからといって、消してはいけません。本当にありうる値かを問います。自転車30台の店で貸出5000台なら誤りなので、除きます。本物の混んだ日は残し、そのことを書きます。
巨大な1日を Python で計算する
# ある店の7日分の貸出と、そこに巨大な1日を足したリストです。
days = [204, 173, 327, 173, 240, 198, 220]
def middle(values):
in_order = sorted(values)
half = len(in_order) // 2
if len(in_order) % 2 == 1:
return in_order[half]
return (in_order[half - 1] + in_order[half]) / 2
print("平均:", round(sum(days) / len(days), 1), "中央値:", middle(days))
days.append(5000)
print("平均:", round(sum(days) / len(days), 1), "中央値:", middle(days))
# 2つの数のうち、大きく動いたのはどちらですか。
最初の日に、作り物の5000を入れる
docker exec jupyter python3 -c "import pandas as pd; h=pd.read_csv('hires.csv'); t=h.copy(); t.loc[t.index[0],'hires']=5000; print(round(h['hires'].mean(),1), h['hires'].median(), round(t['hires'].mean(),1), t['hires'].median())"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
大きい日を上から3つ見る
docker exec jupyter python3 -c "import pandas as pd; h=pd.read_csv('hires.csv'); print(h.nlargest(3,'hires')[['date','weather','hires']].to_string(index=False))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
中央値は、いつも平均よりよい、と思いがちです。外れ値には強いものの、その大きさを隠します。両方を示し、最大の値はいくつで、なぜ残したかを書きましょう。
グループの大きさを見る
8日の平均と200日の平均は、同じ強さの根拠ではありません。平均のそばに、そのグループの行数をいつも添えます。
動詞にも気をつけます。この表では、雨の日は貸出が少ない日と結びついています。雨が貸出を減らした、と示すには、平均だけでは足りません。
雨の日と晴れの日を比べる
docker exec jupyter python3 -c "import pandas as pd; h=pd.read_csv('hires.csv'); r=h[h['weather']=='rainy']['hires']; s=h[h['weather']=='sunny']['hires']; print(len(r),len(s),round(r.mean(),1),round(s.mean(),1)); print(round(r.std(),1), round(s.std(),1))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
例: 数字の読み方
| 見えるもの | 言えること | 言えないこと |
|---|---|---|
| 雨の日120日、平均 227.6 | この表では、雨の日は貸出が少なかった | 雨だけが理由だということ |
| 晴れの日131日、平均 312.2 | この表では、晴れの日は忙しかった | 来年も同じになるということ |
| ばらつき 80.3 と 68.2 | 1日ごとのちがいが大きい | ある日が平均に近いということ |
学生が入力するセルは、このプレビューでは空白です。
さらに: 外れ値の公平な規則
ノートブックで、hires の25パーセンタイルと75パーセンタイルを quantile で求めます。その差を IQR と呼びます。
25パーセンタイル引く1.5 IQR より下、または75パーセンタイル足す1.5 IQR より上の日を数えます。どの日ですか。消しますか。