Scikit-Learnを使ったPythonの決定木

決定木は,回帰と分類の両方を行うことができる教師付き機械学習アルゴリズムとして,最も頻繁に広く使われているものの一つである.決定木アルゴリズムの背後にある直観は単純であるが、非常に強力でもある。

データセットの各属性に対して、決定木アルゴリズムはノードを形成し、最も重要な属性はルートノードに配置される。評価のためには、ルートノードから始めて、条件または「決定」に合致する対応するノードを辿ってツリーを下っていく。このプロセスは、決定木の予測または結果を含む葉ノードに到達するまで続けられる。

このように、意思決定ツリーというのは少し複雑に聞こえるかもしれませんが、実は皆さんも知らず知らずのうちに意思決定のために使っているのです。例えば、ある人から車を1日貸してほしいと頼まれ、車を貸すかどうか決断しなければならない場面を考えてみましょう。決断の材料となる要素はいくつかありますが、そのいくつかを以下に列挙します。

    1. その人は親しい友人か、それとも単なる知り合いか?1.親しい友人なのか、それとも単なる知り合いなのか?
  1. 2.その人は初めて車を貸してくれるのか?そうであれば車を貸し、そうでなければ次のステップに進む。
    1. 前回車を返したとき、その車は壊れていたか?はい」なら断り、「いいえ」なら貸し出す。

上記のシナリオのデシジョンツリーは次のようになる。

決定木の利点

予測分析に決定木を使用することには、いくつかの利点がある。

    1. 決定木は連続値と離散値の両方の予測に使用できる。すなわち、回帰と分類の両方のタスクでうまく機能する。
    1. アルゴリズムの訓練に必要な労力が比較的少なくて済む。
    1. 非線形分離可能なデータの分類に使用することができる。
    1. KNNや他の分類アルゴリズムと比較して、非常に高速かつ効率的である。

Python Scikit Learnによる決定木の実装

このセクションでは、PythonのScikit-Learnライブラリを使って決定木アルゴリズムを実装します。以下の例では、決定木を使用して、分類と回帰の両方の問題を解決します。

注:分類と回帰の両方のタスクは、Jupyter iPython Notebookで実行されました。

1. 分類のための決定木

このセクションでは、紙幣の画像の4つの異なる属性によって、紙幣が本物か偽物かを予測します。属性とは、ウェーブレット変換された画像の分散、画像の曲率、エントロピー、画像の歪度のことである。

データセット

このタスクのデータセットは、以下のリンクからダウンロードできる。

https://drive.google.com/open?id=13nw-uRXPY8XIZQxKRNZ3yYlho-CYm_Qt

このデータセットに関するより詳細な情報は、このデータセットのUCI MLレポをチェックしてください。

Scikit-Learnでこのアルゴリズムを実装する残りのステップは、典型的な機械学習問題と同じです。ライブラリとデータセットをインポートし、いくつかのデータ分析を行い、データをトレーニングセットとテストセットに分け、アルゴリズムをトレーニングして予測を行い、最後にデータセットでアルゴリズムの性能を評価します。

ライブラリをインポートする

以下のスクリプトは、必要なライブラリをインポートします。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline


データセットのインポート

今回のファイルはCSV形式なので、パンダの read_csv メソッドを使ってCSVデータファイルを読み込むことにします。以下のスクリプトを実行してください。

dataset = pd.read_csv("D:/Datasets/bill_authentication.csv")


ここでは、「D」ドライブの「Datasets」フォルダに「bill_authentication.csv」というファイルが格納されています。お客様の環境にあわせて変更してください。

データ解析

次のコマンドを実行すると、データセットの行と列の数が表示されます。

dataset.shape


出力は「(1372,5)」となり、データセットには1372レコードと5つの属性があることが分かる。

データセットの最初の5つのレコードを調べるには、次のコマンドを実行する。

dataset.head()


出力はこのようになります。

| 分散|歪度|カートーシズ|エントロピー|クラス
| — | — | — | — | — | — |
| 0 | 3.62160 | 8.6661 | -2.8073 | -0.44699 | 0 |
| 1 | 4.54590 | 8.1674 | -2.4586 | -1.46210 | 0 |
| 2 | 3.86600 | -2.6383 | 1.9242 | 0.10645 | 0 |
| 3 | 3.45660 | 9.5228 | -4.0112 | -3.59440 | 0 |
| 4 | 0.32924 | -4.4552 | 4.5718 | -0.98880 | 0 |

データの準備

このセクションでは、データを属性とラベルに分割し、その結果得られたデータをトレーニングセットとテストセットの両方に分割します。こうすることで、あるデータセットでアルゴリズムを学習させ、その後、アルゴリズムがまだ見ていない全く別のデータセットでテストすることができる。これにより、学習したアルゴリズムが実際にどのように動作するかを、より正確に把握することができる。

データを属性とラベルに分けるには、以下のコードを実行します。

X = dataset.drop('Class', axis=1)
y = dataset['Class']


ここで、変数 X にはデータセットからラベルである “Class” カラムを除いた全てのカラムが格納されています。y変数には、"Class" カラムの値が格納される。X 変数は属性セットで、y 変数は対応するラベルを格納します。

最後の前処理は、データをトレーニングセットとテストセットに分割することです。Scikit-Learn の model_selection ライブラリには train_test_split メソッドが含まれており、これを使ってデータをランダムにトレーニングセットとテストセットに分割します。以下のコードを実行してください。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20)


上記のコードでは、test_size パラメータでテストセットの比率を指定しています。これは、データの20%をテストセット、80%をトレーニングセットに分割するために使用します。

学習と予測

データがトレーニングセットとテストセットに分割されたら、最後のステップはこのデータに対して決定木アルゴリズムを学習させ、予測を行うことである。Scikit-Learnにはtreeライブラリがあり、様々な決定木アルゴリズム用のクラスやメソッドが組み込まれています。ここでは分類タスクを実行するので、この例では DecisionTreeClassifier クラスを使用します。このクラスの fit メソッドは、学習データに対してアルゴリズムを学習するために呼び出されます。このデータは fit メソッドのパラメータとして渡されます。以下のスクリプトを実行して、アルゴリズムを学習してください。

from sklearn.tree import DecisionTreeClassifier
classifier = DecisionTreeClassifier()
classifier.fit(X_train, y_train)


さて、分類器の学習が終わったら、テストデータに対して予測を行ってみましょう。予測を行うには、DecisionTreeClassifier クラスの predict メソッドを用います。使い方は以下の通りです。

y_pred = classifier.predict(X_test)


アルゴリズムの評価

この時点で、我々はアルゴリズムを学習し、いくつかの予測を行った。ここで、我々のアルゴリズムがどの程度正確であるかを見てみましょう。分類タスクでよく使われるメトリクスは、混同行列、精度、再現率、F1スコアです。幸運なことに、Scikit=Learnの metrics ライブラリには classification_reportconfusion_matrix メソッドが含まれており、これらのメトリクスを計算するのに利用することが可能です。

from sklearn.metrics import classification_report, confusion_matrix
print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred))


これは以下のような評価になります。

[[142    2]
    2  129]]
              precision   recall   f1-score   support


0       0.99     0.99       0.99       144
           1       0.98     0.98       0.98       131


avg / total       0.99     0.99       0.99       275


混同行列から、275個のテストインスタンスのうち、我々のアルゴリズムが誤分類したのは4個だけであることがわかります。 これは98.5%の精度です。悪くないですね。

2. 回帰のための決定木

Scikit Learnを用いた決定木による回帰問題の解法は、分類の場合と非常によく似ています。しかし、回帰では木ライブラリの DecisionTreeRegressor クラスを使用します。また、回帰の評価指標は分類の評価指標とは異なります。それ以外のプロセスはほとんど同じです。

データセット

このセクションで使用するデータセットは、線形回帰の記事で使用したものと同じです。このデータセットを使って、ガソリン税(セント)、一人当たり収入(ドル)、舗装された高速道路(マイル)、運転免許を持つ人口の割合に基づいて、米国の48州におけるガソリン消費量(百万ガロン)を予測しようとするものである。

このデータセットは、以下のリンクから入手可能です。

https://drive.google.com/open?id=1mVmGNx6cbfvRHC_DvF12ZL3wGLSHD9f_

このデータセットの詳細は、原文で確認できる。

上記のデータセットの最初の2列は有用な情報を提供しないので、データセットファイルから削除された。

では、このデータに決定木アルゴリズムを適用して、このデータからガス消費量を予測してみよう。

ライブラリをインポートする
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline


データセットのインポート
dataset = pd.read_csv('D:Datasetspetrol_consumption.csv')


データ解析

今回もdataframeのhead関数を使って、実際にデータがどのようなものかを見ていきます。

dataset.head()


出力はこのようになります。

| | Petrol_tax | Average_income | Paved_Highways | Population_Driver_license(%) | Petrol_Consumption

| 0 | 9.0 | 3571 | 1976 | 0.525 | 541 |
| 1 | 9.0 | 4092 | 1250 | 0.572 | 524 |
| 2 | 9.0 | 3865 | 1586 | 0.580 | 561 |
| 3 | 7.5 | 4870 | 2351 | 0.529 | 414 |
| 4 | 8.0 | 4399 | 431 | 0.544 | 410 |

データセットの統計的な詳細を見るには、次のコマンドを実行します。

dataset.describe()


Petrol_tax Average_income Paved_Highways Population_Driver_license(%) Petrol_Consumption
カウント|48.000000|48.000000|48.000000|48.000000|48.000000|48.000000|48.000000
平均値|7.668333|4241.83333|5565.41667|0.570333|576.770833||。
std|0.950770|573.623768|3491.507166|0.055470|111.885816|です。
最小値|5.000000|3063.000000|431.000000|0.451000|344.000000||||。
25% 7.000000 3739.000000 3110.250000 0.529750 509.500000
50% 7.500000 4298.000000 4735.500000 0.564500 568.500000
75% 8.125000 4578.750000 7156.000000 0.595250 632.750000
最大|10.00000|5342.000000|17782.000000|0.724000|986.000000|||||||。
データの準備

分類タスクと同様に、このセクションでは、データを属性とラベルに分割し、その結果、トレーニングセットとテストセットに分割します。

以下のコマンドを実行し、データをラベルと属性に分割します。

X = dataset.drop('Petrol_Consumption', axis=1)
y = dataset['Petrol_Consumption']


ここで、変数 X には、ラベルである ‘Petrol_Consumption’ カラムを除く、データセットからの全てのカラムが格納されています。y変数には 'Petrol_Consumption' カラムの値が入ります。つまり、X変数には属性セット、y` 変数には対応するラベルが入ることになります。

以下のコードを実行し、データをトレーニングセットとテストセットに分割する。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)


学習と予測

先に述べたように、回帰タスクでは、分類タスクとは異なる sklearn クラスを使用します。ここで使うクラスは、先ほどの DecisionTreeClassifier とは異なり、DecisionTreeRegressor クラスです。

ツリーを学習するために、 DecisionTreeRegressor クラスをインスタンス化し、 fit メソッドを呼び出します。

from sklearn.tree import DecisionTreeRegressor
regressor = DecisionTreeRegressor()
regressor.fit(X_train, y_train)


テストセットに対して予測を行うには、 predict メソッドを用います。

y_pred = regressor.predict(X_test)


それでは、予測値と実際の値を比較して、どの程度の精度であったかを見てみましょう。

df=pd.DataFrame({'Actual':y_test, 'Predicted':y_pred})
df


出力はこのようになります。

| | 実績値 | 予測値

| 41 | 699 | 631.0 |
| 2 | 561 | 524.0 |

| 35 | 644 | 631.0 |

あなたの場合、トレーニングとテストの分割によって、比較されるレコードが異なる可能性があることを忘れないでください。train_test_split` メソッドはランダムにデータを分割するので、おそらく同じトレーニングセットとテストセットを持つことはないでしょう。

アルゴリズムの評価

回帰アルゴリズムのパフォーマンスを評価するために、一般的に使用されるメトリクスは、平均絶対誤差、平均二乗誤差、および二乗平均平方根誤差です。Scikit-Learnライブラリには、これらの値を計算するのに役立つ関数が含まれています。これを行うには、metricsパッケージの以下のコードを使用します。

from sklearn import metrics
print('Mean Absolute Error:', metrics.mean_absolute_error(y_test, y_pred))
print('Mean Squared Error:', metrics.mean_squared_error(y_test, y_pred))
print('Root Mean Squared Error:', np.sqrt(metrics.mean_squared_error(y_test, y_pred)))


出力はこのようになります。

Mean Absolute Error: 54.7
Mean Squared Error: 4228.9
Root Mean Squared Error: 65.0299930801


このアルゴリズムの平均絶対誤差は54.7で、「Petrol_Consumption」列のすべての値の平均の10%未満です。これは、我々のアルゴリズムがうまく予測できたことを意味します。

さらに上を目指す – 手作りのEnd to Endプロジェクト

好奇心旺盛なあなたは、もっと先を目指したいと思っていませんか?そんなあなたには、ガイド付きプロジェクトがおすすめです。「ハンズオン住宅価格予測 – Pythonによる機械学習” をご覧ください。

をご覧ください。
このプロジェクトでは、Scikit-LearnとKerasのモデルから住宅価格を予測するために、従来の機械学習モデルや深層学習モデル、Ensemble Learning、メタラーを利用した強力な構築方法を学ぶことができます。
>
>
>

Tensorflowの上に構築された深層学習APIであるKerasを使って、アーキテクチャを試し、積み重ねたモデルのアンサンブルを構築し、メタラーナーのニューラルネットワーク(レベル1モデル)を訓練して、家の価格を割り出すことにします。

ディープラーニングは素晴らしいものですが、それに頼る前に、浅い学習アルゴリズムのような、より単純な技術で問題を解決することも試みることをお勧めします。ベースラインの性能は、ランダムフォレスト回帰アルゴリズムに基づくものです。さらに、Scikit-Learnを使用して、バギングや投票などの手法により、モデルのアンサンブルを作成することも検討します。

これはエンドツーエンドのプロジェクトであり、他の機械学習プロジェクトと同様に、探索的データ分析から始まり、データ前処理を経て、最後に浅い学習と深い学習のモデルを構築して、以前に探索とクリーニングを行ったデータに適合させます。

結論

この記事では、Pythonの人気ライブラリScikit-Learnを使って、分類と回帰の両方のタスクに決定木を使用する方法を紹介しました。決定木はそれ自体かなり単純なアルゴリズムですが、Scikit-Learnを使った実装はさらに簡単です。

タイトルとURLをコピーしました