2011年11月17日木曜日

phpでCARTアルゴリズムを使った決定木を作成する。

PHPで,CARTアルゴリズムを使った決定木の作成をやってみた。
CARTアルゴリズムは、こんなかんじ

とりあえず、
①ある変数で2つに分類したノードそれぞれで、目的変数に対するジニ係数を計算する。
②ルートノードのジニ係数と、分類したノードのジニ係数の差を計算する。
③すべての変数に対して、その差を計算し、差が最大のものを分岐条件とする。
④これを繰り返していく。
こんな感じで。


1、渡すデータ
必要なデータを入れた配列を、さらに配列に入れた形。
// 渡すデータ構造
    $data = array();
    $data[0]  = array("生死"=>"生還","年齢"=>"35","性別"=>"男","等級"=>"1等");
    $data[1]  = array("生死"=>"生還","年齢"=>"12","性別"=>"女","等級"=>"1等");
    $data[2]  = array("生死"=>"生還","年齢"=>"35","性別"=>"女","等級"=>"2等");
    $data[3]  = array("生死"=>"死亡","年齢"=>"34","性別"=>"女","等級"=>"2等");
    $data[4]  = array("生死"=>"生還","年齢"=>"23","性別"=>"男","等級"=>"3等");
    $data[5]  = array("生死"=>"死亡","年齢"=>"31","性別"=>"男","等級"=>"3等");
    $data[6]  = array("生死"=>"死亡","年齢"=>"32","性別"=>"男","等級"=>"3等");
    $data[7]  = array("生死"=>"死亡","年齢"=>"23","性別"=>"男","等級"=>"乗組員");
    $data[8]  = array("生死"=>"死亡","年齢"=>"25","性別"=>"男","等級"=>"乗組員");
    $data[9]  = array("生死"=>"死亡","年齢"=>"29","性別"=>"女","等級"=>"乗組員");
    $data[10] = array("生死"=>"死亡","年齢"=>"40","性別"=>"女","等級"=>"乗組員");
データ : 船が難破したときの乗客の生還死亡リスト
目的変数 : 生死
カテゴリ変数 : 年齢、性別、等級



2、多値変数、連続変数をすべて、二値変数に変換する
決定木は二分木なので、
持っている変数の中で値が3種類以上あるもの(多値変数:等級)、
値が連続であるもの(連続変数:年齢)を、
二値変数に置きなおす必要がある。

① 多値変数を二値変数に変換する
多値変数の取りうる値を2つのグループに分け、
二値変数とする。
この時も、CARTアルゴリズムを使い、
どの分け方が、もっとも目的変数の影響を反映するかを
確定する。

多値変数「等級」が、以下の感じの二値変数となる。
グループ1 : 1等
グループ2 : 2等3等乗務員


② 連続変数を二値変数に変換する
連続変数の値が昇順になるよう並び替え、
どこで区切るともっとも目的変数の影響を反映するかを、
またCARTアルゴリズムを使って確定する。

連続変数「年齢」が、以下の感じの二値変数となる。
グループ1 : 30 以下
グループ2 : 30 より大きい



3、木の生成

① 分岐
CART使って分岐条件になる変数を決め、データを分ける。
そのデータでさらに分岐条件を決め、またデータを分ける。
これを繰り返して、木構造を作成する。


② 分岐の終了、枝刈り
なんかいろいろ方法あるみたいだけど、
とりあえず、最後までやればいいや。



4、木の利用
入力したデータから目的変数を除いた形式で配列を渡すと、
想定される目的変数の値を返すようにした。

// 渡すデータ構造
    $target = array("年齢"=>"40","性別"=>"女","等級"=>"乗組員");



なんとなくできたが、
なんちゃってデータマイニングになっている感は
否めない。

拙いコードだけどさらしてみる。

https://github.com/kokukuma/php-decision-tree

0 件のコメント:

コメントを投稿