点検と報告(1):グループごとに確かめる
第9章の点検表に沿って、モデルを使い始める前に確かめます。まず 公平性:端末のグループごとに、間違い方を比べます(テストデータ、しきい値0.5)。
スマホの人は、PC の人と比べて、見逃しの割合がやや高く、無駄な案内の割合は 0.627 と大きく なりました。スマホで学ぶ人は、続いた人でも、6割以上に「やめそう」という案内が届きます。
この差を、どう考えるか
- 影響の大きさ: 案内が届くだけなら、害は小さいかもしれません。しかし、案内の文面が「このままではやめてしまいそうです」のような内容なら、続けている人を不快にさせるおそれがあります。影響は、使い方で変わります
- 原因を考える: 第9章で見たとおり、グループによって特徴量と正解の関係が違うと、全体に合わせたモデルでは、そのグループでずれが大きくなります。このデータでも、スマホの人は、学習時間と「続くか」の関係が違う可能性があります
- 数の少ないグループ: タブレットは84人しかいません。84人のうち、続いた人は35人なので、無駄な案内の割合(0.429)は35人のうちの15人で決まっています。1〜2人違うだけで、値が大きく変わります
対策を試す
レッスン5で試した「スマホ × 学習時間」の特徴量を足すと、スマホの見逃しの割合は0.152から0.143に下がりましたが、無駄な案内の割合は0.627から 0.686に上がりました。ある指標をよくすると別の指標が悪くなることは、よくあります。どちらを優先するかは、使い方(企画シート)で決め、その判断を記録しておきます。
このほかの対策として、案内の文面をすべての人に失礼のない内容にする(予測が外れても害を小さくする)、スマホの人のデータを増やす、グループごとにしきい値を見直す、などがあります。ただし、グループごとにしきい値を変えることには、「グループによって扱いを変えてよいか」という別の問題もあるので、慎重に判断します。
点検と報告(2):説明性・再現性と、モデルの説明書
説明性:モデルは、何を手がかりにしているか
第9章の 並べ替えによる重要度(特徴量をでたらめに並べ替えたときの、F値の下がり方)を測りました(テストデータ、10回の平均)。
モデルは、主に学習時間と連続学習日数を手がかりにしていました。「最初の週によく学習し、続けて学習した人は続きやすい」という、納得しやすい手がかりです。レッスン5で見た「たくさん学習したのに、やめた人」を見逃しやすいのも、この手がかりに頼っているためと考えられます。もし、ID や、使ってはいけない列が上位にあれば、リークや誤りを疑います。
なお、レッスン数・正解数・学習時間は互いに関係が強いので、第9章で見たとおり、重要度が分かれて小さく見えている可能性があります。
再現性:もう一度、同じ結果を出せるか
ランダムフォレストは乱数を使うので、乱数の種を0・1・2と変えると、テストのF値は0.765・0.763・0.762と少し変わりました。結果を再現できるように、次のことを記録します(第9章)。
- データ: どのデータの、どの版か(このデータは、作り方のプログラムと乱数の種で決まる)
- 分け方:
train_test_split(test_size=0.3, random_state=0, stratify=y)
- 前処理とモデル: Pipeline の中身と、ハイパーパラメータ
- 環境: ライブラリの版(この教材は Pyodide 314.0.3、scikit-learn 1.8.0)
モデルの説明書(モデルカード)
モデルを使う人のために、次のことを1枚にまとめます。モデルカード と呼ばれる形式です。
点検と報告のまとめ、よくある誤解と振り返り
from sklearn.metrics import confusion_matrix
from sklearn.inspection import permutation_importance
pred = model.predict(X_test)
for device in ["PC", "スマホ", "タブレット"]:
mask = (X_test["端末"] == device).values # そのグループの人だけ
tn, fp, fn, tp = confusion_matrix(y_test[mask], pred[mask]).ravel()
print(device, "見逃し", fn / (fn + tp), "無駄な案内", fp / (fp + tn))
result = permutation_importance(model, X_test, y_test, scoring="f1", n_repeats=10, random_state=0)
print(dict(zip(X_test.columns, result.importances_mean.round(3))))
confusion_matrix(...).ravel() は、2行2列の混同行列を「tn, fp, fn, tp」の4つの数に並べ直します(tn: 続いた人を続くと予測、fp: 続いた人をやめると予測、fn: やめた人を続くと予測、tp: やめた人をやめると予測)。
よくある誤解
- 「全体の性能がよければ、どのグループでもよい」: スマホの人だけ、無駄な案内の割合が0.627と高くなっていました
- 「公平性の対策をすれば、どの指標もよくなる」: スマホの見逃しを減らす工夫で、無駄な案内が増えました。どちらを優先するかを決めて記録します
- 「報告には、一番よい数字だけを書けばよい」: モデルカードには、限界や、性能の低いグループも書きます。使う人が、使ってよい場面を判断できるようにするためです
振り返り
- 第9章の点検表: 評価の仕方・データリーク・再現性・公平性・説明性を、使い始める前に確かめる
- グループごとに間違い方を比べ、差の影響と原因を考える。数の少ないグループの値はぶれやすい
- 並べ替えによる重要度で、モデルの手がかりが納得できるものかを確かめる
- 目的・データ・性能・グループごとの性能・限界を、モデルカードにまとめる