クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

決定木の作り方と情報利得

このレッスンのあとで: エントロピーと情報利得を計算して、いちばんよい質問を選べる。

60分のレッスンコマンド1件JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

延滞する貸出を見分ける質問

決定木とは、「はい」か「いいえ」で答える質問をつなげて、答えを決める木の形のモデルです。作るときのいちばん大事な仕事は、どの質問から始めるかを選ぶことです。

大学の図書館は、返却が遅れそうな貸出を、前もって見分けたいと考えています。10件の記録を使い、質問を選ぶ方法を学びます。

このレッスンのゴール

メモ

エントロピーと情報利得を計算して、いちばんよい質問を選べる。

キーワード

ことばいみれい
決定木質問をつなげて答えを決める、木の形のモデル
特徴量質問に使う、記録の項目本の種類
エントロピーグループの答えの混ざり具合を表す数
情報利得質問で分けたあとに、混ざり具合が減った量
葉答えを出す、木の端のグループ

学生が入力するセルは、このプレビューでは空白です。

決定木は質問でデータを分ける

決定木は、質問を1つずつ重ねて、記録を小さなグループに分けます。グループの中が同じ答えだけになれば、そこで止まります。

次の表は、図書館の10件の貸出記録です。「遅れた」が答えで、ほかの3列が質問に使う特徴量です。

例: 10件の貸出記録

本期間時期遅れた
参考書長い試験期間はい
参考書短いふつういいえ
小説長いふつういいえ
参考書短い試験期間はい
小説短い試験期間はい
小説短いふつういいえ
参考書長い試験期間いいえ
参考書短い試験期間はい
小説長い試験期間はい
小説短いふつういいえ

学生が入力するセルは、このプレビューでは空白です。

エントロピーは答えの混ざり具合

グループに「はい」と「いいえ」がどれだけ混ざっているかを、エントロピーで表します。半分ずつなら 1.0 で、いちばん混ざっています。全部同じ答えなら 0 です。

10件は、遅れた5件と遅れなかった5件なので、エントロピーは 1.0 です。

エントロピーを計算する

コード: python
import math

def entropy(yes, no):
    total = yes + no
    result = 0.0
    for count in [yes, no]:
        if count > 0:
            p = count / total
            result = result - p * math.log2(p)
    return round(result, 3)

print(entropy(5, 5))
print(entropy(5, 1))
print(entropy(0, 4))
# entropy(3, 3) と entropy(1, 5) も表示してください。
# 混ざり具合が大きいのはどちらですか。

例: 混ざり具合の目安

グループ混ざり方エントロピー
2件中1件がはい半々1.00
3件中2件がはい少し偏る0.92
6件中5件がはいかなり偏る0.65
5件中5件がはい全部同じ0.00

学生が入力するセルは、このプレビューでは空白です。

ラボの365日の混ざり具合

ラボの hires.csv では、365日のうち131日が busy(300台以上)です。busy と quiet が、どれだけ混ざっているでしょう。

次のコマンドは、p = 131 ÷ 365 から、そのエントロピーを求めます。答えは 0.94 で、かなり混ざっています。

365日のエントロピー

コマンド
docker exec jupyter python3 -c 'import math; p = 131 / 365; print(round(-p * math.log2(p) - (1 - p) * math.log2(1 - p), 2))'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

情報利得が大きい質問を選ぶ

質問で分けると、グループが2つ以上に分かれます。情報利得は、分ける前のエントロピーから、分けたあとの平均を引いた値です。平均には、件数に応じた重みをつけます。

情報利得がいちばん大きい質問が、いちばん答えをそろえる質問です。

例: 3つの質問の情報利得

質問分けたグループ分けたあと情報利得
時期は試験期間か6件(はい5)と4件(はい0)0.390.61
本の種類は参考書か5件(はい3)と5件(はい2)0.970.03
期間は長いか4件(はい2)と6件(はい3)1.000.00

学生が入力するセルは、このプレビューでは空白です。

よくある間違い

注意

木を深くして、学習データを全部当てられるほどよいと考えがちです。実際は、深すぎる木は偶然の細かい違いまで覚えてしまい、新しいデータで外れます。次のレッスンのテストデータで確かめます。

ノートブックに入力: 日の分け方

コード: python
import csv
import math

def entropy(busy, total):
    result = 0.0
    for count in [busy, total - busy]:
        if count > 0:
            result = result - count / total * math.log2(count / total)
    return result

days = []
for row in csv.DictReader(open("hires.csv")):
    days.append([row["weekday"] in ["Sat", "Sun"], row["weather"] == "rainy",
                 float(row["temp_c"]) >= 12, int(row["hires"]) >= 300])

names = ["weekend", "rainy", "warm"]
for n in range(3):
    count = [0, 0]
    busy = [0, 0]
    for day in days:
        side = 0 if day[n] else 1
        count[side] = count[side] + 1
        busy[side] = busy[side] + day[3]
    after = 0.0
    for side in range(2):
        after = after + count[side] / len(days) * entropy(busy[side], count[side])
    print(names[n], round(entropy(busy[0] + busy[1], len(days)) - after, 3))

このラボとソースについて: JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。