決定木とその発展アルゴリズムを図で理解する

AIの中で何が一番人間の思考に近いという話についてはディープラーニングや昨今の生成AIがそれなんだろうと自分では思っていますが個人的には統計分析だけに限れば決定木系アルゴリズムが人間の思考に近いんじゃないかと思ってちょっと一番使いがちなんですけど、そこで決定木のアルゴリズムを図で理解するという試みをしてみようと思います。
使うデータはアヤメのデータです。
# 決定木
回帰になると説明が難しいので分類で考えてみると統計データの変数ごとにif文で大小比較してそれを全部分類できるまでしていくというものだったと思います。
## 図示関数
```Python3
from sklearn.tree import export_graphviz as EG
from pydotplus import graph_from_dot_data as GFDD
def cart_analysis_DT(x, y, model, filename="CART"):
    y_data = list(set(y.values))
    for i in range(len(y_data)):
        y_data[i] = str(y_data[i])
    dotdata = EG(model, filled=True, rounded=True, class_names=y_data, feature_names=x.columns, out_file=None)
    graph = GFDD(dotdata)
    graph.write_png(filename+".png")
```

## プログラム
```Python3
from sklearn.tree import DecisionTreeClassifier as DTC
import pandas as pd

df = pd.read_csv("iris.csv")
y = df["category"]
x = df.drop("category", axis=1)

dtc = DTC()
dtc.fit(x, y)
cart_analysis_DT(x, y, dtc, filename="DTC")
```
## 図
![DTC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/8fea3ecf-bb15-41cc-9340-562daa9881fb.png)
このように変数ごとに基準値を設けてそれぞれ分岐して分類していることが分かります。

# ランダムフォレスト
ランダムフォレストは自分の知識が正しければデータをランダムで作成する決定木の数だけ分割して分割されたデータから決定木を作り最後に予測結果を出すときに最頻値を使います。
## 図示関数
```Python3
from sklearn.tree import export_graphviz as EG
from pydotplus import graph_from_dot_data as GFDD
def cart_analysis_RF(x, y, model, filename="CART"):
    y_data = list(set(y.values))
    for i in range(len(y_data)):
        y_data[i] = str(y_data[i])
    for i in range(len(model.estimators_)):
        dotdata = EG(model.estimators_[i], filled=True, rounded=True, class_names=y_data, feature_names=x.columns, out_file=None)
        graph = GFDD(dotdata)
        graph.write_png(filename+str(i)+".png")
```
## プログラム
初期値だと決定木の数が多いので3つだけ作ります。
```Python3
from sklearn.ensemble import RandomForestClassifier as RFC
import pandas as pd

df = pd.read_csv("iris.csv")
y = df["category"]
x = df.drop("category", axis=1)

rfc = RFC(n_estimators=3)
rfc.fit(x, y)
cart_analysis_RF(x, y, rfc, filename="RFC")
```
## 図
![RFC0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/5f692bcc-5f2d-ae29-6b27-048a0abe9930.png)
![RFC1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/48e72184-cfa6-75a5-5acd-ae5a29970411.png)
![RFC2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/c00dcad7-6785-a29a-3b31-ae51076b1af2.png)

最初のサンプル数が異なる事が分かります。それに合わせて決定木が作られていますが基本的に決定木の作り方自体は同じです。最後にこれで最頻値を取ります。

# 勾配ブースティング決定木
これはちょっと自分が理解あまりできていないのですが、簡単に言えばクラスごとの決定木(陰性と陽性)を最適に学習していき最後にニューラルネットワークのようにsoftmax関数を使って確率的に分類していきます。
## 図示関数
```Python3
from sklearn.tree import export_graphviz as EG
from pydotplus import graph_from_dot_data as GFDD
def cart_analysis_GBDT(x, y, model, filename="CART"):
    y_data = list(set(y.values))
    for i in range(len(y_data)):
        y_data[i] = str(y_data[i])
    for i in range(len(model.estimators_[len(model.estimators_)-1])):
        dotdata = EG(model.estimators_[len(model.estimators_)-1, i], filled=True, rounded=True, class_names=y_data, feature_names=x.columns, out_file=None)
        graph = GFDD(dotdata)
        graph.write_png(filename+str(i)+".png")
```
## プログラム
過学習前提でフルに決定木を作ってほしいので決定木の深さを最大20にしました。
```Python3
from sklearn.ensemble import GradientBoostingClassifier as GBC
import pandas as pd

df = pd.read_csv("iris.csv")
y = df["category"]
x = df.drop("category", axis=1)

gbc = GBC(max_depth=20)
gbc.fit(x, y)
cart_analysis_GBDT(x, y, gbc, filename="GBC")
```
## 図
![GBC0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/2755cb2e-e0f2-777c-61cf-5609e33d3186.png)
![GBC1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/f7dd2523-8530-13c8-bc19-1885ab69d03e.png)
![GBC2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/f245f833-9917-f4a2-e469-14424f38fb32.png)
今度はクラスが出て来なく代わりに「friedman_mse」というものが出力されます。これで誤差を計算しています。

# まとめ
俺は決定木が一番人間の思考回路に似ていると思うんだけどなあ・・・