元生技データサイエンティストのメモ帳

勉強したことの備忘録とか雑記とか

エントロピーとジニ不純度の比較

こんにちは、sue124です。
昔書いた「Python実践データ分析100本ノック」に関して書いた記事で、「決定木のモデル作成には平均情報量(エントロピーを使っている」と書いたものの、書籍の中で使用している「sklearn.tree.DecisionTreeClassifier」のモジュールではCARTというアルゴリズムジニ不純度を指標にして決定木を構築していることがわかったので、今回はエントロピーとジニ不純度の違いをまとめてみました。

決定木の基本的なことは以前書いた以下の記事を参照願います。

sue124.hatenablog.com


ノード t内でクラス i(全 c個)に属するサンプル数を n_{i}とするとクラス iに属するサンプルの割合を以下のように書くとします。

{ \displaystyle
 p(i|t) = \frac{n_{i}}{n}
}

このとき、エントロピー、ジニ不純度の定義はそれぞれ以下の通りとなります。

エントロピー
{ \displaystyle
 I_{H} = -\sum_{i=1}^{c} p(i|t)\ log\ p(i|t)
}

<ジニ不純度>
{ \displaystyle
 I_{G} = 1 - \sum_{i=1}^{c}p(i|t)^{2}
}


ここで以下の場合を考えてみます。

  • ノード tに単一のクラスしか入っていない場合(最も不純度が低い状態)

エントロピー
{ \displaystyle
 I_{H} = -\sum_{i=1}^{1}\frac{n}{n} \ log\ (\frac{n}{n}) = 0
}

<ジニ不純度>
{ \displaystyle
 I_{G} = 1 - \sum_{i=1}^{1}(\frac{n}{n})^{2} = 0
}

いずれの場合も0になります。

  • ノード tの全てのサンプルが異なるクラスである場合(最も不純度が高い状態)

エントロピー
{ \displaystyle
 I_{H} = -\sum_{i=1}^{c}\frac{1}{c} \ log\ (\frac{1}{c}) = log\ c
}

<ジニ不純度>
{ \displaystyle
 I_{G} = 1 - \sum_{i=1}^{c}(\frac{1}{c})^{2} = 1 - \frac{1}{c}
}

それぞれの上限はクラス数 c次第。


ここで簡単の為にクラスが2個の場合を考え、片方のクラスのデータ数を xとおくと、
エントロピー
{ \displaystyle
 I_{H}(x) = -\frac{x}{n}\ log\ \frac{x}{n} - \frac{n-x}{n}\ log\ \frac{n-x}{n}
}

<ジニ不純度>
{ \displaystyle
 I_{G}(x) = 1 - (\frac{x}{n})^{2} - (\frac{n-x}{n})^{2} = \frac{2nx-2x^{2}}{n^{2}}
}


これらを x微分すると、
エントロピー

{ \displaystyle \frac{d}{dx}I_{H}(x) = -\frac{2}{n}\ log\ \frac{x}{n} + \frac{2}{n}\ log\ \frac{n-x}{n}
}

<ジニ不純度>
{ \displaystyle
 \frac{d}{dx}I_{G}(x) = \frac{2-4x}{n^{2}}
}


これらから、ともに 0\leq x <\frac{1}{2}n で単調増加、 \frac{1}{2} < x \leq nで単調減少となることがわかります。
{ \displaystyle \frac{d}{dx}I_{H}(x)} x=0,nで∞となるので、このエントロピーの方が 0,n周辺での立ち上がりが急になりますね。

以上、エントロピーとジニ不純度の違いを比べてみました。
数式に若干の違いはあれど、表しているものの意味としては大差のない印象でした。

Pythonで作った決定木のモデルを可視化する

こんにちは、sue124です。
前回は以下の書籍の写経を終えた感想を書きましたが、その中で本書の良くない点として挙げた「特に決定木のモデルの可視化が省略されている」ことに関して、自分でやり方を調べたので、書いていきたいと思います。

今回は巷で良く使われているアヤメのデータから品種を特定する決定木のモデルを作って、それを可視化していきます。

import pandas as pd
#対応する名前に変換する関数
def name(num):
    if num == 0:
        return 'Setosa'
    elif num == 1:
        return 'Veriscolour'
    else:
        return 'Virginica'

#アヤメのデータを格納する(説明変数をdataX, 目的変数をdataYとする)
from sklearn import datasets

data = datasets.load_iris()

iris_dataX_df = pd.DataFrame(data=data.data, columns=data.feature_names)

iris_dataY_df = pd.DataFrame(data=data.target)
iris_dataY_df = iris_dataY_df.rename(columns={0: "Species"})
iris_dataY_df["Species"] = iris_dataY_df["Species"].apply(name)

iris_dataX_df, iris_dataY_df の中身はそれぞれこんな感じです。

iris_dataX_df.head()

f:id:sue124:20200419205659p:plain

iris_dataY_df.head()

f:id:sue124:20200419205723p:plain

このデータから決定木のモデルを作ります。

#データを分割する(訓練用:評価用 = 7:3)
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(iris_dataX_df, iris_dataY_df, test_size=0.3)

#決定木モデル作成
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
model.fit(X_train, Y_train)

上記で作ったモデルの可視化するには、以下のようにします。

#決定木モデルの可視化
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
%matplotlib inline

fig = plt.figure(figsize=(20, 10))
plot_tree(model, fontsize=14);

f:id:sue124:20200419210050p:plain

たったこれだけで可視化できます。数行でかけるのだから、書籍の中で省略してほしくなかったなーと思います。
決定木って作ったモデルを可視化してナンボですし。
あと図中には明示されていませんが、左に分岐すると枠内に書いている条件が「True」、右に分岐すると「False」です。


ところで図を良く見ると「gini」の文字が。よくよく確認すると、このモジュールでは決定木のモデル生成に「エントロピー」でなく「ジニ不純度」を使っているそうです。公式ドキュメントを見てても良く「impurity」という単語が出てくるなぁと思ったら、そういうことだったらしいです。

###2020/06/07 追記###
エントロピーとジニ不純度の違いについてまとめてみました。
sue124.hatenablog.com

「Python実践データ分析100本ノック」をやり切った感想

こんにちは、sue124です。
また前回ブログを更新してから1ヶ月、その間に↓の書籍の写経をやり終えたので、今回はその感想(レビュー?)を書いていきたいと思います。


本書の良かった点
本に付いているサンプルデータを使ってとにかく手を動かして、Pythonのモジュールを使ってみる、という構成でした。ノック10本ごとにアウトプットが出るので、達成感があります。
私はこの本をやるまでは「pandasでcsvのデータを少し触れる」程度でしたが、この本の写経で「機械学習や画像分析、最適化問題自然言語分析等、一通りなんとなくはやり方がわかったかな?」ぐらいにはなりました。データ分析をやってみたいけど、取っ掛かりがないという人に本書はとてもおすすめ本書の良くなかった点
機械学習最適化問題の数学的な解説は全カット。(自分で調べてカバーするしかない)
・サンプルデータを使ってのデータ分析はもう少し深堀して欲しかった。特に決定木のモデルの可視化は一番肝心なところなのに省略とは。。
・サンプルコード内の記法が安定しない。特に演算子の前後にスペースがあったりなかったりする。ひどいときは1行のスペース有無が混在している。
・サンプルコードのデバッグで使ったと思われる「#print(変数)」がそのまま本に書かれている。
・ノック87本目から90本目までのサンプルコードがグダグダで、「書きかけのものを本に掲載しちゃったの?」ってぐらいの内容が載っている。サンプルデータと一緒にサンプルコードをダウンロードできるので、そちらから書き写せばなんとかなるが、これは売り物としてちょっと、、というレベル。


色々書いたら良かった点より良くなかった点の方が内容が多くなりましたが、Pythonでのデータ分析初学者が本書で勉強することでデータ分析実践への取っ掛かりができてレベルアップできることは間違いないと思います。
最後に本書を具体的におすすめしたい人を書きたいと思います。

おすすめしたい人
Pythonの基本的な部分をある程度勉強して、次のステップとしてデータ分析をやってみたい人
・画像分析とか機械学習に興味があるけど、Pythonのモジュールを動かしたことがない人

おすすめできない人
・画像分析も機械学習自然言語処理もすでにPythonでやったことのある人
 (物足りないと思います)

決定木でのモデル作成の仕組み

引き続き下記書籍でPythonでのデータ分析についてを勉強しているsue124です。
今回は第5章で使った決定木でのモデル作成についてです。
サンプルコードをそのまま写せばサンプルデータの決定木モデルを作ることができましたが、その仕組みの解説はなかったため自分で調べました。せっかくなので、それをブログに書いていきたいと思います。

まず決定木とはどんなものかというと、、

・教師ありの機械学習
・作成したモデルを下図のように表すことができ、視覚的に理解しやすい
・数値データ、カテゴリーデータが混在していてもOK
・オーバーフィッティングしてしまいやすい(枝分かれの深さを適切に設定する必要がある)

上記のような特徴がある決定木に関して、その仕組みを自分なりに調べた結果が下記です。
もし誤りがあれば、ご指摘いただけると幸いです。


今回は「どういう条件でピクニックに出かけるか?」という問題を例に考えます。
そのためには下図のような「どの程度2つの状態が混ざっているか?」を定量的に評価する必要があります。

f:id:sue124:20200312000654p:plain

扱っているデータが2つのクラスに分離できて、各クラスのデータ数がそれぞれm個、n個である場合、平均情報量(エントロピー)を以下のように表すことができます。

 I(\frac{m}{m+n}, \frac{n}{m+n}) = \frac{m}{m+n}\log_{2}\frac{m+n}{m} +  \frac{n}{m+n}\log_{2}\frac{m+n}{n}

m=1, n=0 のとき  I(0, 0) = 0
m=n のとき     I(\frac{1}{2}, \frac{1}{2}) = 1

エントロピーが下がるほど、分離が進んでいるということができます。
上式の対数の底は何でも良いのですが、クラス数に合わせると上記のように完全に分離できている時に0、全く分離できていない時に1となるので、わかりやすくなります。

なお、クラスが3つ以上(N個)のときは以下のようになります。

 I(P_{1}, P_{2}, ..., P_{N}) = \sum_{i=0}^N P_i \log_{N}\frac{1}{P_i} = -\sum_{i=0}^N P_i \log_{N}P_i
 P_{i} はクラスi のデータの割合。

これによって、最初に挙げた「どういう条件でピクニックに出かけるか?」に関して初期状態が以下のような状態であったとすると、

 全データ数:5個
 Yes:2個
 No:3個

この時のエントロピーは以下のようになります。
 I(\frac{2}{5}, \frac{3}{5}) = \frac{2}{5}\log_{2}\frac{5}{2} +  \frac{3}{5}\log_{2}\frac{5}{3} = 0.972

これを「天気(晴れ、曇り、雨)」で分類して下図のような状態になったとします。

f:id:sue124:20200312083755p:plain

この時のエントロピーは以下のようになります。
全体のエントロピー  = 1 × \frac{2}{5} + 1 × \frac{2}{5} + 0 × \frac{1}{5} = 0.8

天気で分けることによって、エントロピーが下がっているので、分離が進んでいると判断できます。
「晴れ」と「曇り」がまだ Yes と No が混ざっている状態なので、この後さらに別の指標(例えば気温、風速など)で分類していくことになります。


まとめ
決定木では平均情報量(エントロピーで分離度合いを評価し、平均情報量(エントロピー)が下がるように分離を進める。


###2020/06/07 追記###
書籍の中で使用している「sklearn.tree.DecisionTreeClassifier」のモジュールではCARTというアルゴリズムでジニ不純度を指標にして決定木を構築していることがわかったので、エントロピーとジニ不純度の違いをまとめてみました。
sue124.hatenablog.com

ブログ始めました

このブログでは何か面白いことをしたくてプログラミング勉強中の筆者が、勉強したことを書いていきたいと思います。

 

ひとまずは

 

Pythonでのデータ分析

・ラズパイでのカメラを動かす

 

とかをやっていく予定です。

具体的なことは追々書いていこうと思います。