決定株分類器

はじめに

世の中には決定木(Decision Tree)やランダムフォレストなど有名なものがありますが、 まずは原初に戻ってみます。

ざっくり説明

アルゴリズム

決定株分類器は、ある訓練標本が与えられた時にd次元の入力データ群のどれか1次元を選択し、 その次元の値がある閾値以上かどうかで分類する手法です。

f:id:hades-netherworld-service:20160501150310p:plain

ざっくりしていますが、これで終わりです。 シンプルですね。

サンプルコード

決定境界を描画するプログラムが以下です。

#coding:utf-8
# 決定株分類器サンプルコード

import numpy as np
import matplotlib.pyplot as plt

N = 100  # データ数
LOOP = 5000 # ルール数
W_N = 0.8 # 弱分類器計算用の訓練データ数(割合)

if __name__ == "__main__":
    # 訓練データを作成
    cls1 = []
    cls2 = []

    mean1 = [-1, 2]
    mean2 = [1, -1]
    cov = [[1.2, 0.5], [0.5, 1.2]]

    cls1.extend(np.random.multivariate_normal(mean1, cov, int(N/2)))
    cls2.extend(np.random.multivariate_normal(mean2, cov, int(N/2)))

    # データ行列Xを作成
    X = np.vstack((cls1, cls2))

    # cost計算
    diff = [[-1, N], [-1, N]]
    for n in range(2):
        for d in X:
            t_diff = 0
            # 閾値を超えた場合1と仮定して計算し、
            # 反転したものと比較して小さい方を正確な誤差とする
            for cd in cls1:
                if cd[n] < d[n]:
                    t_diff += 1
            for cd in cls2:
                if cd[n] >= d[n]:
                    t_diff += 1
            t_diff = min(t_diff, N - t_diff)
            if (diff[n][1] > t_diff):
                diff[n] = [d[n], t_diff]

    # 決定境界を描画
    index = np.argmin(np.array(diff)[:,1])
    if (index == 0):
        x = diff[index][0]
        y = 0*x + np.linspace(-5, 5, 1000)
    elif (index == 1):
        x = np.linspace(-5, 5, 1000)
        y = 0*x + diff[index][0]
    plt.plot(x, y, "k")

    # 訓練データを描画
    x1, x2 = np.array(cls1).transpose()
    plt.plot(x1, x2, 'rx')

    x1, x2 = np.array(cls2).transpose()
    plt.plot(x1, x2, 'bx')

    plt.xlim(-5, 5)
    plt.ylim(-5, 5)
    plt.show()

実行結果

上を実行した結果はこんな感じになります。

f:id:hades-netherworld-service:20160501150350j:plain

大したことはやっていませんが、何かしら境界を引けていそうです。

木、そして森へ

アルゴリズムから分かるように、決定株分類器は、計算コストは小さいですが、 入力データの持っているデータ(次元)の殆どを捨て去るため、精度は望めません。 そこで決定木(Decision Tree)やランダムフォレストなどの、決定株を進化させたものがあります。 これらに関しては後日書きたいと思いますmm