暖かい日には何台出すか
明日の予報は20度です。店は今夜のうちに、倉庫から何台の自転車を出すかを決めなければなりません。
1年分の記録から、暖かい日ほど忙しいことはわかります。記録の中に1本の直線を引くと、「忙しい」が計画に使える数になります。どこまで信じてよいかも、わかります。
このレッスンのゴール
メモ
データに直線を当てはめ、その直線がどれだけよいかを言える。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 線形回帰 | ある値から別の値を出す、直線の決まり | |
| 傾き | 入力が1増えたときの、答えの変わる量 | |
| 切片 | 入力が0のときの答え | |
| 残差 | 本当の値から予測を引いたもの | |
| 最小二乗法 | 残差の2乗の合計がいちばん小さい直線を選ぶ方法 | |
| 決定係数 | 変化のうち直線が説明する割合で、0から1 | R squared |
| テストデータ | モデルを確かめるために、取っておく行 |
学生が入力するセルは、このプレビューでは空白です。
直線は傾きと切片でできている
直線は hires = 切片 + 傾き * 気温 と書けます。傾きは、1度上がるごとに何台増えるかを表します。切片は、0度のときの直線の予測です。
scikit-learn の LinearRegression は、データから両方を求めます。line.py は、365日すべてを使い、気温だけで台数の直線を引きます。
気温で台数の直線を引く
docker exec jupyter python3 steps/line.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
最小二乗法が直線を選ぶ
どの日も、直線の少し上か下にあります。その差が残差です。残差を2乗すると、下の差も上の差と同じように数えられます。それを合計します。
最小二乗法は、この合計がいちばん小さくなる直線です。2つの短い計算で求まります。xとyが一緒に動く量から傾きを出し、平均から切片を出します。
例: 3日分とその残差
| 気温 | 台数 | 直線 130 + 13.75 x | 残差 | 2乗 |
|---|---|---|---|---|
| 4 | 190 | 185 | 5 | 25 |
| 8 | 230 | 240 | -10 | 100 |
| 12 | 300 | 295 | 5 | 25 |
| 合計 | 0 | 150 |
学生が入力するセルは、このプレビューでは空白です。
2つの計算を手でする
# 3日分で、最小二乗法を手で計算します。
temps = [4, 8, 12]
hires = [190, 230, 300]
mean_x = sum(temps) / len(temps)
mean_y = sum(hires) / len(hires)
top = 0
bottom = 0
for n in range(len(temps)):
top = top + (temps[n] - mean_x) * (hires[n] - mean_y)
bottom = bottom + (temps[n] - mean_x) ** 2
slope = top / bottom
intercept = mean_y - slope * mean_x
print("傾き:", slope, "切片:", intercept)
# 300 を 270 に変えて、もう一度実行してください。
# 傾きは上がりますか、下がりますか。
ノートブックに入力: 残差
from sklearn.linear_model import LinearRegression
import pandas as pd
hires = pd.read_csv("hires.csv")
model = LinearRegression().fit(hires[["temp_c"]], hires["hires"])
hires["residual"] = hires["hires"] - model.predict(hires[["temp_c"]])
# 残差の平均と、予測からいちばん外れた日です。
print(round(hires["residual"].mean(), 1))
hires.loc[hires["residual"].abs().idxmax(), ["date", "weekday", "weather", "temp_c", "hires"]]
見ていない日で直線を判断する
直線は、学んだ日にはいつもそれなりに合います。本当に知りたいのは、新しい日にどうかです。
そこでデータを分けます。約4分の3の学習データで直線を引き、残りをテストデータとして取っておきます。決定係数と平均誤差は、テストデータだけで測ります。
学ぶ日と確かめる日に分ける
docker exec jupyter python3 steps/split.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
学んだデータで決定係数が高ければ、予測もうまくいくと考えがちです。モデルは、見たことのあるデータではいつもよく見えます。見たことのないテストデータで判断し、その数字を伝えてください。
入力を増やすと説明が増える
気温だけでは、日々の変化の約60%しか説明できません。雨も効いています。
model.py は、気温と雨の2つを入力にした直線を1本引きます。入力ごとに自分の傾きを持ちます。傾きがマイナスなら、その入力は答えを下げます。
気温と雨で直線を引く
docker exec jupyter python3 steps/model.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
さらに挑戦: 週末を入力に足す
ノートブックで、直線に3つ目の入力を足してください。hires["weekday"].isin(["Sat", "Sun"]).astype(int) で作る、1と0の週末の列です。
split.py と同じように、学習データで直線を引き、テストデータで点をつけます。テストの決定係数は上がりましたか。週末の傾きが店にとって何を意味するかを、一文で書きましょう。