もう1人、呼ぶか呼ばないか
店は毎朝、2人目のスタッフを呼ぶかどうかを決めます。必要なのは正確な台数ではありません。「忙しい」か「暇」か、ひと言だけです。
よいやり方は、今日に似た日を探して、その日がどうだったかを見ることです。このレッスンの考え方は、それで全部です。
このレッスンのゴール
メモ
近くの点を使って点を分類し、どれだけ当たるかを測れる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| 分類 | 行にラベルを選ぶこと | |
| ラベル | モデルが予測する答え | busy |
| 特徴量 | モデルが決めるのに使う入力 | temp_c |
| 近傍 | 新しい点にいちばん近い学習データの行 | |
| 正解率 | 予測が当たった割合 | |
| 混同行列 | 本当のラベルと予測を並べた表 |
学生が入力するセルは、このプレビューでは空白です。
近いデータがラベルに投票する
それぞれの日は、特徴量で置かれた1つの点です。ここでは気温と雨です。2日の距離は、2つの点を結ぶまっすぐな線の長さです。
新しい日にラベルをつけるには、いちばん近い k 日の学習データを探します。それぞれが自分のラベルに投票し、多いほうが勝ちます。ラベルが2つなら、k を奇数にすると引き分けになりません。
例: 10度、雨 2 mm の日
| 学習データの日 | ラベル | 距離 | 近い1日に入るか | 近い3日に入るか |
|---|---|---|---|---|
| 9度、4 mm | quiet | 2.24 | はい | はい |
| 13度、0 mm | busy | 3.61 | いいえ | はい |
| 14度、1 mm | busy | 4.12 | いいえ | はい |
| 5度、0 mm | quiet | 5.39 | いいえ | いいえ |
| 7度、8 mm | quiet | 6.71 | いいえ | いいえ |
学生が入力するセルは、このプレビューでは空白です。
距離と投票を手で
# 新しい日: 10度、雨 2 mm です。
new = [10.0, 2.0]
days = [[9.0, 4.0, "quiet"], [13.0, 0.0, "busy"], [14.0, 1.0, "busy"],
[5.0, 0.0, "quiet"], [7.0, 8.0, "quiet"]]
for day in days:
gap = ((day[0] - new[0]) ** 2 + (day[1] - new[1]) ** 2) ** 0.5
print(day[2], round(gap, 2))
# 近い3日が投票します。どのラベルが勝ちますか。
# new を [6.0, 1.0] に変えて、もう一度投票してください。
ノートブックに入力: 新しい日
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
hires = pd.read_csv("hires.csv")
label = hires["hires"].apply(lambda n: "busy" if n >= 300 else "quiet")
X_train, X_test, y_train, y_test = train_test_split(hires[["temp_c", "rain_mm"]], label, test_size=0.25, random_state=1)
knn = KNeighborsClassifier(n_neighbors=5).fit(X_train, y_train)
# 予報から作った、まだ来ていない3日です。
new_days = pd.DataFrame({"temp_c": [18.0, 3.0, 12.0], "rain_mm": [0.0, 8.0, 2.0]})
knn.predict(new_days)
正解率には比べる相手が要る
knn.py は、300台以上の日を busy とします。1年の4分の3で学び、残りの日を k = 5 で予測します。
正解率は、予測が当たった割合です。それだけでは、あまり多くを語りません。そこでスクリプトは、いつも quiet と答える手抜きの決まりの点も表示します。モデルが役に立つのは、それに勝つときだけです。
取っておいた日を分類する
docker exec jupyter python3 steps/knn.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
混同行列はどんな間違いかを見せる
正解率が同じ2つのモデルでも、間違い方は違うことがあります。混同行列は、本当と予測の組み合わせごとに数えます。
knn.py では、行が本当、列が予測で、busy が先です。忙しい日を暇と言えば、1人のスタッフの前に行列ができます。暇な日を忙しいと言えば、待つだけのスタッフに給料を払います。店にとって、どちらの間違いかが大事です。
例: knn.pyの混同行列
| busy と予測 | quiet と予測 | 合計 | |
|---|---|---|---|
| 本当は busy | 23 | 10 | 33 |
| 本当は quiet | 7 | 52 | 59 |
| 合計 | 30 | 62 | 92 |
学生が入力するセルは、このプレビューでは空白です。
よくある間違い
注意
正解率が高ければよい分類器だと考えがちです。片方のラベルが多いと、いつもそれを答えるだけで高い点が出ます。ここでは何の工夫もなく 0.641 です。いつもその手抜きの点と比べ、損の大きい間違いは混同行列で読んでください。
kの選び方
k = 1 だと、モデルはいちばん近い1日を、ノイズまでそのまま写します。学んだ日ではほぼ完ぺきに見え、新しい日では悪くなります。
k を大きくするとノイズはならされます。けれど大きすぎると、どの予測も多いほうのラベルに寄っていきます。knnk.py は6つの k を試し、両方の日で点をつけます。
6つのkを試す
docker exec jupyter python3 steps/knnk.pyここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
さらに挑戦: 週末と尺度
ノートブックのk近傍法に、1と0の週末の特徴量を足してください。knn.py と同じ分け方で点をつけます。次に、すべての特徴量を StandardScaler でそろえてから、もう一度点をつけます。
なぜk近傍法では尺度が大事なのかを説明しましょう。ヒント: 週末は点を1しか動かせませんが、気温は最大26ほど動かします。