第2回 機械が「学習する」とはどういうことか?

  1. 人工知能 (AI) と機械学習 (ML)
  2. Python による決定木の学習
  3. まとめ

1. 人工知能 (AI) と機械学習 (ML)

そもそも「人工知能」とは一体何なのか?

歴史的には、1956年の ダートマス会議ジョン・マッカーシー が初めて "人工知能 (Artificial Intelligence, AI)" なる用語を定義したとされる。 これは人間や動物などがもつ「自然知能 (Natural Intelligence)」に 対して、人工的につくられた (artificial) 知能という意味であった。 しかし、現在では人工知能という用語は一般に 「コンピュータが行う、なにか賢そうな処理」という程度の意味で使われている。 (ちなみに 「人口知能」という誤った漢字を書いている人も多数おり、 人々が単語の意味を本当に理解しているかどうかはあやしい。)

人工知能と機械学習、ニューラルネットワークの関係は 以下のようになっている:

IT技術全般 人工知能 (AI) 機械学習 (ML) ニューラル ネットワーク (NN) ディープ ニューラル ネットワーク (DNN) = ディープ ラーニング (DL)

1.1. 人工知能の原理

通常のコンピュータの処理は、あらかじめ定められた手順に従って 答えを計算する。ところが、このような一般的な処理とは違って、 人工知能の多くの問題は、正しい答えを計算する手順が不明だったり、 そもそも「正しい答え」が厳密に定義されていない (定義できない) ことが多い。 そのため、ほとんどの人工知能の問題は探索問題として定式化される。 つまり、多くの解の可能性の中から「一番よさそうな解」を探し出す、 という処理なのである。 (エキスパートシステムや記号算術など、 探索問題でないものも AI と呼ばれているが、 これらはどちらかといえば例外的である。)

探索問題としての AI の例は:

これをPythonプログラム風に書くと、以下のようになる:

a = [すべての可能性]
best = None  # 現在のベストな回答
for x in a:
    # best と x の「良さそう度」を比較する
    if E(best) < E(x):
        best = x
print(best)

この処理を非常に大規模かつ高速にやると、人間にとっては 「賢そう」に見えるわけである。 人工知能の原理は、人間の脳の原理とはまったく違っていてもかまわない。 (自動車の原理は、人間が走る原理とはまったく違っている。)

問題は「すべての可能性」を現実的にどうやって調べるか? ということである。普通にやると無限に時間がかかってしまうので、 何らかの方法でサバを読む必要がある。 また「良さそう度」を判定する関数 E() をどう書くのか、 という問題もある。 現在のほとんどの人工知能研究は、 このような問題に対する解決策の研究である。

演習2-1. 探索問題をさがせ

次のうち「探索問題」として定義可能なものはどれか、すべて挙げよ。

  1. 行列の積を計算する。
  2. 迷路の解法を発見する。
  3. 売れる小説を書く。
  4. 予定表をカレンダーで管理する。

1.2. 機械学習とは何か?

では次に「機械学習」について説明しよう。 たとえば、以下のような処理を考える。 100×100ピクセルの画像 (Python でいう、リストのリスト) が与えられたとき、 それが「どれくらい人間の顔らしいか」を判定する 関数 faceness() を作りたいとする:

def faceness(image):
    ...
    return x
画像顔らしさ
0.95
0.87
0.02

このような関数は頑張れば人間にも作れるかもしれないが、非常に難しい。 判定に使う変数が極端に多い (100×100個) うえに「何が顔らしいのか」を 論理的に規定するのが難しいからである。そこで、 あらかじめ「顔らしい画像」と「顔らしくない画像」を大量に用意しておき、 コンピュータを使ってこのような関数を自動的に発見させよう、 というアイデアが浮かぶ。 これが機械学習 (Machine Learning, ML) である。 つまり機械学習とは 「プログラムを自動的に作成するプログラム」ということになる。 上で見たように、機械学習は「規則できっちり規定できない処理」に 対して使われることが多い。 規則できっちり規定できる処理 (たとえば確定申告の計算など) は、 計算手順を人間がプログラムしたほうがはるかに確実だからである。

機械学習もまた探索問題として定義されている。 またもPython風に書くと、以下のようになる:

a = [存在しうるすべてのPython関数]
best = None  # 現在のベストな関数
for x in a:
    # best と x の「良さそう度」を比較する
    if E(best) < E(x):
        best = x
print(best)

機械学習では、関数の「良さそう度」は比較的簡単に定義できる。 たとえば上の顔認識の例では、すでに「顔らしい画像」と「顔らしくない画像」が 与えられていると仮定しよう。すると、ある関数 f が「顔らしい画像」を顔と判定し、 「顔らしくない画像」を顔でないと判定すれば、 その関数は「よい」ということになる:

# 顔判定プログラム p の「良さそう度」を計算
face = [すべての顔らしい画像]
noface = [すべての顔らしくない画像]
def E(f):
    score = 0
    # 顔を顔として判定したら得点。
    for image in face:
        if f(image) == 顔:
            score = score + 1
    # 顔でないものを顔でないととして判定したら得点。
    for image in noface:
        if f(image) != 顔:
            score = score + 1
    return score

ここでの問題は、「すべての関数」がこれまた無限に存在することである。 したがって、機械学習で生成する (探索する) プログラムは 通常の Python の関数などではなく、非常に限定された形の 「プログラムもどき」であることが多い。 機械学習の分野では、これは「分類器 (classifier)」や 「モデル (model)」などと呼ばれている。 分類器やモデルの形式を研究することが、 現在の機械学習のおもな研究内容である。

注意: 機械学習における「学習」は、通常の日本語の「学習」とは若干意味が異なっている。 たとえば日本語では「私は海水が塩辛いということを学習した」などというが、 機械学習における学習とは「ひとつの事実」を学ぶことではなく、 「方法」を学ぶことなのである。

注意: 機械学習における「プログラムの生成」自体は探索処理であるが、 実際に (探索の結果) 得られたプログラム自体は、ほとんどの場合、探索処理ではない。 つまり、機械学習を使って得られた画像認識プログラムはほぼ一瞬で実行できるものが多い。 これは、人間がひとたび顔を学習してしまえば、一瞬で顔を認識できるのと似ている。

なお、上に示した顔認識の例は 機械学習の中で「教師つき学習」と呼ばれる形式である。 機械学習には、大きく分けて 3種類の形式が存在する:

  1. 教師つき学習 (supervised learning): あらかじめ人が集めた正解データと不正解データをもとに学習する。
  2. 教師なし学習 (unsupervised learning): 正解・不正解がわからない生のデータのみから学習する。
  3. 強化学習 (reinforcement learning): データがほとんどない状態から開始し、データを集めながら学習する。
演習2-2. 必要なデータを考える

教師つき学習で以下のタスク (問題) を扱うとする。 何が学習用のデータとして必要か?

  1. 画像にネコが写っているかどうか判定するタスク。
  2. ある地点の24時間後の天気・気温を、過去の気象記録のみから推測するタスク。
  3. ある人の年齢・性別・出身学校から、年収を予想するタスク。

ニューラルネットワークとは何か?

ニューラルネットワーク (Neural Network, NN) は 教師つき学習の方式のひとつで、以下のような人間の神経回路を模した ニューロン (neuron) という架空の装置を「プログラムもどき」として 使ったものである。さらに ディープニューラルネットワーク (Deep Neural Network, DNN) とは、 この装置を多段階 (数十〜数百) に接続したものである。

ニューロン (ノード) 入力1 入力2 入力3 入力4 出力1 出力2

ニューラルネットワークや DNN でなぜ学習ができるのかという 説明は後にまわすとして、まず機械学習の概念をよりよく理解するために、 もっと簡単な (ニューラルネットワークではない) 教師つき学習方式である 決定木を見てみよう。

1.3. 決定木とは

決定木 (decision tree) とは、以下のような if〜elif〜else文だけからなるプログラムである。 要するに「このときはこれ」という規則の集合にすぎない。 (正確には、ここで紹介しているものは決定木の簡易版である decision stump と言われるもので、本物の決定木はif文が何重にも ネストしたものである。)

def f(変数1, 変数2, ...):
    if 変数 == 値1:
        return 答えA
    elif 変数 == 値2:
        return 答えB
    elif
        ...

たとえば「ある年のある月が全部で何日間あるか?」を推定する決定木を考えてみる。 もちろん、人間は完全な規則を知っているが、 ここでは以下の16件の「与えられた観測結果だけ」をもとに推測させることを考える:

訓練データ
年 (y)月 (m)日数 (n)
2016 131
2016 229
2016 430
2016 731
2016 831
2017 228
2017 430
2017 630
2017 930
20171130
2018 131
2018 228
2018 331
20181031
2020 531
20201231

ここで、まず重要な仮定を置かねばならない。それは

「日数 n は、与えられた変数 ym だけから推測可能である」
ということである。この仮定が成り立たなければ、そもそも学習は不可能である。

このように、推測のヒントとなる ym のような変数を 特徴量 または 素性 (feature) とよぶ。 統計学の世界では、これらは 説明変数 (explanatory variable) とも呼ばれる。 これらの特徴量を使って、たとえば以下の2通りの決定木を作ることができる:

演習2-3. 決定木の性能を測定する

上記の 16件のデータに対して、決定木 A と 決定木 B の精度を測定したい。 以下の空欄に、決定木 A、B それぞれを使った答えを埋め、正答数を求めよ。

年 (y)月 (m) 決定木A決定木B日数 (n)
2016 131
2016 229
2016 430
2016 731
2016 831
2017 228
2017 430
2017 630
2017 930
20171130
2018 131
2018 228
2018 331
20181031
2020 531
20201231

決定木 A を使った場合は 12件が正しく (正答率 75%) 、 決定木 B を使った場合は 15件が正しい答えを推測する (正答率 94%)。 どちらの決定木も完璧には正しくないが、これは分類器を単純な規則のみに限定したためで、 決定木を使った機械学習の限界である。

訓練フェーズと推論フェーズ

さて、上で求めた決定木 A と B のどちらがよりよいのか? これは、上の結果を見ただけでは判断できない。 なぜなら機械学習の性能は、すでに結果がわかっている データをどれくらい覚えられるかではなく 「未知のデータをどれくらい正確に推測できるか (汎化, generalization)」にかかっているからである。 (記憶と学習は違う - 過去問をすべて暗記したからといって、本番で満点がとれるとは限らない。)

決定木を含む、すべての教師つき機械学習では 訓練 (training) と 推論 (inference) の2つの段階が存在する。

(なお、本講座では「訓練」と「学習」はほぼ同じ意味で使っている。)

演習2-4. 決定木の性能を測定する (本番)

では「本番の試験」として、決定木 A および 決定木 B を推論フェーズで使うことを考える。 以下の新しい 8件のデータを使ったときの正答数を答えよ。

テストデータ
年 (y)月 (m)決定木A決定木B日数 (n)
2016 5 31
2016 9 30
2017 1 31
201712 31
2018 4 30
2018 6 30
2020 2 29
202010 31

上記の 8件の新たなデータに対して、 決定木 A を使った場合は 2件が正しく (正答率 25%)、 決定木 B を使った場合は 7件が正しい推測結果を返す (正答率 88%)。 したがって、この場合は「決定木 B のほうがよい」といえる。

このように、教師つき機械学習では、学習用に必ず2種類の異なるデータを使用する。 最初に決定木 A, B を作成 (探索) するときに使ったデータを 訓練データ (training data) とよび、 決定木の実際の性能を測定するときに使ったデータを テストデータ (test data) とよぶ。 ようするに訓練データとは「過去問」であり、 テストデータが「本番の試験」である。 教師つき学習では、訓練時にはテストデータは絶対に見てはいけない。 なぜならそうすると客観的な性能を測定できないからである。

実際には、上の訓練データはわざと決定木 A に有利にできており、 テストデータは決定木 B に有利にできているように見えるかもしれない。 この例からわかるように、機械学習の「賢さ」は与えるデータによって決まる。 偏ったデータを与えれば、機械学習は偏った規則を学習してしまう。 また、実際のグレゴリオ暦の規則 (4で割り切れる年はうるう年だが、100で割り切れる場合はうるう年ではなく、 ただし400で割り切れる場合はやはりうるう年である) のようなものを 決定木で学習するためには、400年分以上のデータが必要である。 精度を上げるには、なるべく偏りの少ない多くの訓練データを用意したほうがよい。

2. Python による決定木の学習

さて、すべての可能な分類器 (決定木) を Python で実際にしらみつぶしに探索するには どうすればよいだろうか? ここでは、ひとつの決定木を Python の辞書として 表すことを考える。たとえば、上の決定木 A は以下のような規則として表せる:

# 決定木A
rule = { "2016":"31", "2017":"30", "2018":"31", "2020":"31" }

もっとも単純な決定木では一度に 1つの特徴量しか見ないので、 ここではあらかじめ調べる特徴量 (ここでは変数 y) を決めておき、 「特徴量の値 → その回答」をそれぞれ辞書のキー・バリューとしている。 また、ここでは各特徴量の値は「等しいかどうか」を調べるだけで 大小関係を考慮しないので、すべての値を文字列型として扱っている。 (こうしておくとあとで便利。)

次に訓練データ、テストデータをそれぞれリストのリストとして定義する。 (ここでは便宜上、順番を変えて、各行の最初の要素を回答にしている。)

# 訓練データ
train = [
    #  n   特徴量y  特徴量m
    ["31", "2016",  "1"],
... ["29", "2016", "2"], ["30", "2016", "4"], ["31", "2016", "7"], ["31", "2016", "8"], ["28", "2017", "2"], ["30", "2017", "4"], ["30", "2017", "6"], ["30", "2017", "9"], ["30", "2017", "11"], ["31", "2018", "1"], ["28", "2018", "2"], ["31", "2018", "3"], ["31", "2018", "10"], ["31", "2020", "5"],
["31", "2020", "12"], ] # テストデータ test = [ # n 特徴量y 特徴量m ["31", "2016", "5"],
... ["30", "2016", "9"], ["31", "2017", "1"], ["31", "2017", "12"], ["30", "2018", "4"], ["30", "2018", "6"], ["29", "2020", "2"],
["31", "2020", "10"], ]

上の学習用データ traintest から 決定木を訓練 (学習) するには、以下のようにする。

  1. まず、使用する特徴量を決める。ここでは特徴量 y としよう。 訓練データ train中で、それぞれの y の値に対して現れる回答を集計する:
    # 1番目の特徴量yを使った決定木を作成。
    feats = {}
    for row in train:
        answer = row[0]  # 回答
        f = row[1]       # 特徴量y
        if not (f in feats):
            # キーが存在しないとき、空のリストから始める。
            feats[f] = []
        feats[f].append(answer)
    

    これを実行すると、最終的に以下のような辞書ができる。 特徴量 y の値に対して、複数の回答がリストとして格納されている:

    feats = {
        "2016": ["31", "29", "30", "31", "31"],
        "2017": ["28", "30", "30", "30", "30"],
        "2018": ["31", "28", "31", "31"],
        "2020": ["31", "31"],
    }
    
  2. それぞれの特徴量 (辞書 feats のキー) に対応づけられた複数の回答のうち、 一番よく出てきたものを多数決で「正式な回答」として選ぶようにする:
    rule = {}
    for f in feats.keys():
        # ある特徴量に対して、もっとも頻出した答えを正式な回答とする。
        rule[f] = findbest(feats[f])
    
    ここで、関数 findbest() は 「与えられたリストの中で、もっとも多く現れた要素を返す」関数である。
    def findbest(a):
        # 同一の要素の数を数える。
        c = {}
        for x in a:
            if x in c:
                c[x] += 1
            else:
                c[x] = 1
        # 最大値を決定する。
        best = a[0]
        for x in c.keys():
            if c[best] < c[x]:
               best = x
        return best
    
    # findbest(['a','a','b','c','c','c','d']) == 'c'
    
    すると、以下のような規則ができあがる:
    rule = {
        "2016": "31",
        "2017": "30",
        "2018": "31",
        "2020": "31",
    }
    

    この辞書 rule が機械学習によって得られた「決定木」である。 これを使うには、単に特徴量 y の値をキーとして rule を検索すればよい。

    print(rule["2017"])  # y=2017 であれば "30"
    
  3. 最後に、できた規則を決定木として使い、 どれくらい正しい結果を返すのかを測定する。 これにはテストデータ test を使う:
    # できた決定木の正しさを測定する。
    score = 0
    for row in test:
        answer = row[0]  # 回答
        f = row[1]       # 特徴量yの値
        if (f in rule) and (rule[f] == answer):
            # 規則を使った結果、正しい回答を出せれば得点。
            score = score + 1
    print(score)
    
  4. 以上 1. 〜 4. を、すべての特徴量 (この場合は ym) に対してくりかえす。 もっとも得点が高かった決定木を学習結果とすればよい。
演習2-5. 決定木を学習する

上で説明した学習アルゴリズムを実際に実行してみよう。 解説したコードを 2回分つなげればよいが、 2回目だけは別の特徴量を使うように一部変更する必要がある。

learn.py
# 訓練データ
(上記訓練データの部分)
# テストデータ
(上記テストデータの部分)

# 1番目の特徴量yを使った決定木を作成。
(上記 1, 2 のコード)
# できた決定木の正しさを測定する。
(上記 3 のコード)

# 2番目の特徴量mを使った決定木を作成。
(上記 1, 2 のコードを一部変更)
# できた決定木の正しさを測定する。
(上記 3 のコード)

2.1. 実際のデータを使った機械学習

上の例では特徴量が 2つしかなかったので決定木も 2種類しかできなかった。 次にもうすこし本格的なケースを扱う。

UCI Machine Learning Repository は 機械学習の実験に使うさまざまなデータを集めたサイトである。 この中にある キノコのデータベース から毒キノコを見分ける規則を学習したい。

これは 8124件のデータが入った CSVファイルである。 各行には 23個の値が入っており、最初の値は正解 (毒ならば p、食用ならば e) が書かれている。 あとの 22個はキノコを見分けるためのさまざまな特徴である。 ここでの目的は、あるキノコが食用かどうかを 22個の特徴量のうちどれかを使って判定することである。

注意: このデータが本当に正しい保証はない。 これを使って、実際に生育しているキノコを判定しないこと。
キノコの特徴量一覧
番号説明
0正解 (e:食用, p:毒)
1かさの形状 (b:ベル状, c:円錐, x:凸型, f:平面, k:こぶ状, s:凹型)
2かさの表面 (f:繊維質, g:みぞ状, y:うろこ状, s:つるつる)
3かさの色 (n:茶色, b:黄褐色, c:肉桂色, g:灰色, r:緑色, p:ピンク, u:紫色, e:赤色, w:白色, y:黄色)
4傷の有無 (t:あり, f:なし)
5におい (a:アーモンド, l:アニス, c:クレソート, y:生臭い, f:腐敗臭, m:カビ臭い, n:無臭, p:刺激臭, s:スパイシー)
6ひだの付き方 (a:密着, d:下がっている, f:フリー, n:刻み目)
7ひだの間隔 (c:近い, w:密集, d:離れている)
8ひだの大きさ (b:広い, n:狭い)
9ひだの色 (k:黒色, n:茶色, b:黄褐色, h:チョコレート色, g:灰色, r:緑色, o:オレンジ, p:ピンク, u:紫色, e:赤色, w:白色, y:黄色)
10柄の形状 (e:広がっている, t:狭まっている)
11柄の先端 (b:球状, c:棒状, u:カップ, e:等幅, z:枝状, r:根っこ状, ?:欠けている)
12柄の表面(リングの上) (f:繊維質, y:うろこ状, k:すべすべ, s:つるつる)
13柄の表面(リングの下) (f:繊維質, y:うろこ状, k:すべすべ, s:つるつる)
14柄の色(リングの上) (n:茶色, b:黄褐色, c:肉桂色, g:灰色, o:オレンジ, p:ピンク, e:赤色, w:白色, y:黄色)
15柄の色(リングの下) (n:茶色, b:黄褐色, c:肉桂色, g:灰色, o:オレンジ, p:ピンク, e:赤色, w:白色, y:黄色)
16覆いの形状 (p:部分, u:全体)
17覆いの色 (n:茶色, o:オレンジ, w:白色, y:黄色)
18リングの数 (n:なし, o:ひとつ, t:ふたつ)
19リングの形状 (c:網状, e:減衰, f:派手, l:大型, n:なし, p:垂下, s:ぴったり, z:帯状)
20胞子の色 (k:黒色, n:茶色, b:黄褐色, h:チョコレート色, r:緑色, o:オレンジ, u:紫色, w:白色, y:黄色)
21個体数 (a:豊富, c:群生, n:おびただしい, s:ところどころに, v:数本, y:孤立)
22生育地 (g:芝生, l:葉っぱ, m:牧草地, p:道端, u:都市, w:汚物, d:樹木)

2.2. ひとつの特徴量を使った決定木の学習

この例では特徴量が 22個あるが、やることは 演習2-5 の例とほとんど同じである。

まず、訓練データとテストデータを CSV ファイルから読み込む。 ここでは 8124件のデータうち、最初の 7000件を訓練データとして、 残りをテストデータとして使うことにする:

mushroom.py
# CSVファイルを読み込む。
import csv
with open("agaricus-lepiota.data") as fp:
    table = list(csv.reader(fp))

# 最初の7000件を訓練データとして使う。
train = table[:7000]
# 残りをテストデータとして使う。
test = table[7000:]

次に for文を使って、22個の特徴量それぞれに対し 決定木を作成しては、その精度を測定する。 これは演習2-5 のコードを変更して、 1番目ではなく i+1番目の特徴量を使うようにすればよい:

mushroom.py (つづき)
for i in range(22):
    # (i+1)番目の特徴量を使った決定木を作成。
    feats = {}
    for row in train:
        answer = row[0]  # 回答
        f = row[i+1]  # (i+1)番目の特徴量
        ...
    # できた決定木の正しさを測定する。
    score = 0
    for row in test:
        ...
    # 使った特徴量と規則、スコアを表示する。
    print(f"使った特徴量:{i+1}")
    print(f"規則:{rule}")
    print(f"スコア:{score}")

もっとも高いスコアを表示した決定木がここでの最終的な学習結果ということになる。

学習に使うデータをシャッフルする

じつは agaricus-lepiota.data に一覧されているキノコの順序は 大幅に偏っている。そこで、7000件以降のデータを テストデータとして使うと、偏った結果を学習してしまう。これを避けるために、 random.shuffle() 関数を使って、 リストtable をまずシャッフルしてから使うことにする。

演習2-6. キノコの特徴量を使った決定木の学習
  1. 上のプログラム mushroom.py を完成させ、実際に実行せよ。
  2. mushroom.py の適当な位置に random.shuffle(table) を加え、結果がどう変わるか確認せよ。

2.3. ふたつの特徴量を使った決定木の学習

さて、ひとつの特徴量だけを使った決定木では正確さに限界があった。 ここではさらに拡張して、ふたつの特徴量を使った決定木を作成してみる。 これは以下のように、やや複雑な if文からなる規則を作成する。

def f(変数1, 変数2):
    if 変数1 == 値1 and 変数2 == 値2:
        return 答えA
    elif 変数1 == 値3 and 変数2 == 値4:
        return 答えB
    elif
        ...

特徴量を文字列として + で連結すれば、 2つの特徴量が等しいかを同時に判断できる。 したがって、やり方は特徴量が 1つのときとかなり似ている:

def f(変数1, 変数2):
    if (変数1+","+変数2) == (値1+","+値2):
        return 答えA
    elif (変数1+","+変数2) == (値3+","+値4):
        return 答えB
    elif
        ...

実際のプログラムは以下のようになる。 for文を2重にして (i, j) の 組み合せをすべて試している。

mushroom2.py
...
# 2種類の特徴量の組み合わせをすべて試す。
for i in range(22):
    for j in range(22):
        # (i,j) と (j,i) を2度やらないように、i < j のケースだけ考える。
        if i < j:
            # (i+1)番目と(j+1)番目の特徴量を使った決定木を作成。
            feats = {}
            for row in train:
                answer = row[0]  # 回答
                f1 = row[i+1]  # (i+1)番目の特徴量
                f2 = row[j+1]  # (j+1)番目の特徴量
                f = f1+","+f2  # 連結した特徴量
                ...
            # できた決定木の正しさを測定する。
            score = 0
            ...
            # 使った特徴量と規則、スコアを表示する。
            print(f"使った特徴量:{i+1},{j+1}")
            print(f"規則:{rule}")
            print(f"スコア:{score}")
演習2-7. ふたつの特徴量を使った決定木の学習
  1. 上のプログラム mushroom2.py を実際に完成させ、実行せよ。
  2. このプログラムは 22×21 = 462通りの特徴量の組み合せを全部試す。 そのため、決定木も 462種類できる。これだけ多いと目で見て比較するのが大変なため、 各決定木のスコアを自動的に比較し、もっとも性能のよい学習結果だけを 表示するような処理を追加せよ。

以上のように、決定木は単純に実装できる機械学習アルゴリズムのひとつである。 実際には、ここで紹介したものをさらに改良した ID3C4.5 といった アルゴリズムが使われているが、基本的な原理は同じである。 決定木は以下のような長所をもつ:

  1. 単純な if-then 文の羅列なので、一度木を学習してしまえば、 実行は非常に高速である。
  2. 学習した結果を人間が読んで理解することができる。

とくに b. の利点は重要で、このため決定木はデータマイニング等の分野で データの規則を抽出するためによく利用されている。 大きな声では言えないが、多くのデータ分析ではニューラルネットワークなどよりも、 決定木のほうがずっと便利ということがありうる。 ニューラルネットワークが適しているのは、決定木ではどうしても扱えない 生データ (画像など) を扱うときであり、たいていのケースでは 決定木や、(ここでは紹介していない) ベイズ推定 などを使うほうが簡単である。

3. まとめ


クリエイティブ・コモンズ・ライセンス
この作品は、クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。
Yusuke Shinyama