本文へスキップ
ひもとくAI

評価と改善:混同行列・しきい値・誤りの分析

レッスン 5/6

評価と改善(1):混同行列と、しきい値

混同行列で、間違い方を見る

ロジスティック回帰の、テストデータ(900人)での混同行列です(第5章・第9章)。

「続く」と予測「やめる」と予測
本当は続いた(348人)169179(無駄な案内)
本当はやめた(552人)73(見逃し)479
  • 見逃し: やめた552人のうち73人(13.2%)には、案内が届かない
  • 無駄な案内: 続いた348人のうち179人(51.4%)に、必要のない案内が届く

続いた人の半分に案内が届くのは多すぎる、と感じるかもしれません。この題材では、案内が届いても害は小さいので、見逃しを減らす方を重く見ています。しかし、案内の数に限りがある(例えば、運営の人が1人ずつ電話をかける)なら、話は変わります。

しきい値を動かす

ロジスティック回帰は、「やめる確率」を出します。ふつうは確率0.5以上を「やめる」としますが、このしきい値は、使い方に合わせて変えられます(第9章)。

しきい値案内を送る人数再現率適合率F値
0.38010.9620.6630.785
0.47450.9180.6810.782
0.56580.8680.7280.792
0.65340.7450.7700.757
0.73760.5510.8090.655
  • メールで一斉に送る(1人あたりの手間が小さい)なら、しきい値を0.3〜0.4に下げて、見逃しを減らす
  • 電話をかける(1人あたりの手間が大きい)なら、しきい値を0.6〜0.7に上げて、本当にやめそうな人に絞る

同じモデルでも、しきい値は、使い方(企画シート)で決める ものです。F値が一番大きい0.5が、いつも一番よいとは限りません。

評価と改善(2):誤りを調べ、改善を試す

見逃した人は、どんな人か

正解率やF値だけでなく、間違えたデータを実際に見る と、改善の手がかりが見つかります。見逃した73人(本当はやめたのに「続く」と予測した人)と、見つけられた479人を比べました。

人数最初の週の学習時間(中央値)
見つけられた、やめた人47969分
見逃した、やめた人73189.5分

見逃した人は、最初の週にたくさん学習していたのに、やめてしまった人たちでした。モデルは「学習時間が長い人は続く」と判断しているので、こうした人を見逃します。見逃した73人の端末は、スマホが37人、PCが29人、タブレットが7人でした。

改善のアイデアを、交差検証で確かめる

誤りの分析から、次の2つの特徴量を足してみました。

  • 1レッスンあたりの正解数(正解数 ÷(レッスン数 + 1)): 時間は長くても、つまずいている人を見分けられるかもしれない
  • スマホ × 学習時間(スマホの人だけ学習時間、ほかは0): スマホの人は、学習時間と「続くか」の関係が違うかもしれない
特徴量交差検証のF値テストのF値
もとのまま0.7790.792
1レッスンあたりの正解数を足す0.7770.794
スマホ × 学習時間を足す0.7770.788

どちらも、交差検証のF値は上がりませんでした(テストで0.794に上がったものもありますが、テストの結果でモデルを選んではいけません)。思いついた改善が効かないことは、よくあります。効かなかった特徴量は採用せず、「試したが効かなかった」ことを記録しておきます。後で同じことを試す手間を省けます。

改善には、ほかにも次のような方法があります。

  • データを増やす・質を上げる: 見逃した人を見分けられそうな情報を、予測する時点(最初の1週間の終わり)までに手に入る範囲で、新しく集める(例えば、申し込みのときに「学ぶ目的」を聞く)。2週目の様子のように、予測する時点より後の情報は使えない(レッスン1)
  • ハイパーパラメータを調整する: 第8章のグリッドサーチ(正則化の強さ C など)
  • 使い方を変える: しきい値を変える、案内の内容を変える

モデルを複雑にするより、「データを増やす・質を上げる」方が効果の大きいことがよくあります。

評価と改善のまとめ、よくある誤解と振り返り

proba = model.predict_proba(X_test)[:, 1]        # 「やめる(1)」の確率
pred = (proba >= 0.4).astype(int)                # しきい値0.4で「やめる」と予測
from sklearn.metrics import confusion_matrix, recall_score, precision_score
print(confusion_matrix(y_test, pred))            # 行が本当の正解、列が予測
print(recall_score(y_test, pred), precision_score(y_test, pred), pred.sum())   # 再現率・適合率・送る人数

missed = (y_test == 1) & (pred == 0)             # 見逃した人
print(X_test[missed]["最初の週の学習時間"].median())

predict_proba の結果は、クラス0とクラス1の確率が並んだ表なので、[:, 1] で「やめる」の確率だけを取り出します。(y_test == 1) & (pred == 0) のように、& で条件を組み合わせると、見逃した人だけを選べます。

よくある誤解

  • 「しきい値は、いつも0.5」: しきい値は使い方で決めます。一斉のメールなら低く、1人ずつの電話なら高く、のように変えます
  • 「正解率やF値を見れば、評価は終わり」: 混同行列で間違い方を見て、間違えたデータを実際に調べると、改善の手がかりが見つかります
  • 「思いついた改善は、試せば効く」: 足した2つの特徴量は、どちらも交差検証のF値を上げませんでした。効くかどうかは、交差検証で確かめます

振り返り

  • 混同行列で、見逃しと無駄な案内の数を確かめる
  • しきい値を動かすと、送る人数・再現率・適合率が変わる。使い方に合わせて選ぶ
  • 間違えたデータを調べ、改善のアイデアを作る。効くかどうかは交差検証で確かめ、効かなければ採用しない

演習

演習を読み込んでいます…