Pythonで決定木を実装する方法:scikit-learnによる分類モデルの構築手順を解説
決定木(Decision Tree)は、主にデータ分類のシナリオで活用されるアルゴリズムです。木構造で表現され、各ノードは特徴量を、各エッジ(枝)はそこで行われた判断を表します。ルートノードから出発して特徴量を順番に評価しながら、どのエッジをたどるかを決めていきます。新しいデータポイントが入力されるたびにこの同じ手法が繰り返し適用され、分類に必要なすべての特徴量が評価された時点で最終的な結論が導き出されます。つまり、決定木アルゴリズムとは、一連の訓練用変数をもとに従属変数を予測するために使用される教師あり学習モデルなのです。
例:薬剤データセットの読み込み
ここでは、Kaggleで公開されている薬剤テストデータを使用します。まず最初のステップとして、pandasを使ってCSVファイルからデータを読み込み、その内容と構造を確認しましょう。
import pandas as pd
datainput = pd.read_csv("drug.csv", delimiter=",") #https://www.kaggle.com/gangliu/drugsets
print(datainput)上記のコードを実行すると、次のような結果が得られます。
Age Sex BP Cholesterol Na_to_K Drug 0 23 F HIGH HIGH 25.355 drugY 1 47 M LOW HIGH 13.093 drugC 2 47 M LOW HIGH 10.114 drugC 3 28 F NORMAL HIGH 7.798 drugX 4 61 F LOW HIGH 18.043 drugY .. ... .. ... ... ... ... 195 56 F LOW HIGH 11.567 drugC 196 16 M LOW HIGH 12.006 drugC 197 52 M NORMAL HIGH 9.894 drugX [200 rows x 6 columns]
データの前処理
次に、データ内のさまざまなテキスト値を数値へ変換する前処理を行います。これにより、年齢・性別・血圧などの値に基づいて「どの薬剤を使用すべきか」を判定するモデルの訓練とテストが可能になります。カテゴリカルな文字列データは、scikit-learnのLabelEncoderを使って数値ラベルに変換します。
例
import numpy as np
import pandas as pd
from sklearn.metrics import confusion_matrix
datainput = pd.read_csv("drug.csv", delimiter=",")
X = datainput[['Age', 'Sex', 'BP', 'Cholesterol', 'Na_to_K']].values
from sklearn import preprocessing
label_gender = preprocessing.LabelEncoder()
label_gender.fit(['F','M'])
X[:,1] = label_gender.transform(X[:,1])
label_BP = preprocessing.LabelEncoder()
label_BP.fit([ 'LOW', 'NORMAL', 'HIGH'])
X[:,2] = label_BP.transform(X[:,2])
label_Chol = preprocessing.LabelEncoder()
label_Chol.fit([ 'NORMAL', 'HIGH'])
X[:,3] = label_Chol.transform(X[:,3])
# 最初の6件を表示
print(X[0:6])上記のコードを実行すると、次のような結果が得られます。
[[23 0 0 0 25.355] [47 1 1 0 13.093] [47 1 1 0 10.113999999999999] [28 0 2 0 7.797999999999999] [61 0 1 0 18.043] [22 0 2 0 8.607000000000001]]
従属変数の数値変換
続いて、目的変数となる「Drug」列も同様に扱えるよう準備します。これにより、訓練データセットと評価用データセットの両方で一貫した形式でデータを利用できるようになります。
例
import pandas as pd
datainput = pd.read_csv("drug.csv", delimiter=",")
X = datainput[['Age', 'Sex', 'BP', 'Cholesterol', 'Na_to_K']].values
y = datainput["Drug"]
print(y[0:6])出力結果
上記のコードを実行すると、次のような結果が得られます。
0 drugY 1 drugC 2 drugC 3 drugX 4 drugY 5 drugX Name: Drug, dtype: object
データセットの分割(訓練データとテストデータ)
次に、用意したデータ全体のうち70%を訓練データセットとして使い、残りの30%をテストデータとして分類モデルの評価に使用します。train_test_splitを利用することで、簡単にデータを分割できます。
例
import pandas as pd
from sklearn.model_selection import train_test_split
datainput = pd.read_csv("drug.csv", delimiter=",")
X = datainput[['Age', 'Sex', 'BP', 'Cholesterol', 'Na_to_K']].values
y = datainput["Drug"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=3)
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)出力結果
上記のコードを実行すると、次のような結果が得られます。
(140, 5) (60, 5) (140,) (60,)
訓練済みモデルによる予測と精度評価
最後に、訓練データセットに対して決定木を適用し、結果を確認します。ここでは、入力データをもとに「エントロピー」と呼ばれる不純度の基準を使用して木を構築します。エントロピーを基準にすることで、情報利得が最大になるようにノードが分割され、効率的な分類が実現されます。そして最後に、テストデータに対する決定木の予測精度を計算します。
例
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn import metrics
datainput = pd.read_csv("drug.csv", delimiter=",")
X = datainput[['Age', 'Sex', 'BP', 'Cholesterol', 'Na_to_K']].values
# データの前処理
from sklearn import preprocessing
label_gender = preprocessing.LabelEncoder()
label_gender.fit(['F', 'M'])
X[:, 1] = label_gender.transform(X[:, 1])
label_BP = preprocessing.LabelEncoder()
label_BP.fit(['LOW', 'NORMAL', 'HIGH'])
X[:, 2] = label_BP.transform(X[:, 2])
label_Chol = preprocessing.LabelEncoder()
label_Chol.fit(['NORMAL', 'HIGH'])
X[:, 3] = label_Chol.transform(X[:, 3])
y = datainput["Drug"]
# データの分割
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=3)
drugTree = DecisionTreeClassifier(criterion="entropy", max_depth=4)
drugTree.fit(X_train, y_train)
predicted = drugTree.predict(X_test)
print(predicted)
print("\nDecisionTrees's Accuracy: ", metrics.accuracy_score(y_test, predicted))出力結果
上記のコードを実行すると、次のような結果が得られます。
['drugY' 'drugX' 'drugX' 'drugX' 'drugX' 'drugC' 'drugY' 'drugA' 'drugB' 'drugA' 'drugY' 'drugA' 'drugY' 'drugY' 'drugX' 'drugY' 'drugX' 'drugX' 'drugB' 'drugX' 'drugX' 'drugY' 'drugY' 'drugY' 'drugX' 'drugB' 'drugY' 'drugY' 'drugA' 'drugX' 'drugB' 'drugC' 'drugC' 'drugX' 'drugX' 'drugC' 'drugY' 'drugX' 'drugX' 'drugX' 'drugA' 'drugY' 'drugC' 'drugY' 'drugA' 'drugY' 'drugY' 'drugY' 'drugY' 'drugY' 'drugB' 'drugX' 'drugY' 'drugX' 'drugY' 'drugY' 'drugA' 'drugX' 'drugY' 'drugX'] DecisionTrees's Accuracy: 0.9833333333333333
このように、構築した決定木モデルは約98.3%という高い精度で薬剤の分類を予測できました。カテゴリカルデータのエンコーディング、適切なデータ分割、そしてエントロピー基準による木の構築という一連の流れを押さえておくことで、実際の分類問題にも応用できるでしょう。
-
Pythonのbase64モジュールを使ったデータエンコード・デコード入門
PythonにおけるBase64エンコーディングとはPython標準ライブラリのbase64モジュールは、バイナリデータをプレーンテキスト(ASCII)プロトコルで安全に送信できる形式へ変換するための機能を提供します。メール送信、URLへの埋め込み、HTTP POSTリクエストなど、テキストベースの通信経路でバイナリデータを扱いたい場面で活躍するモジュールです。このモジュールが実装しているのは、RFC 3548で定義されたBase16、Base32、Base64の各アルゴリズム、および事実上の標準となっているAscii85とBase85のエンコーディングです。RFC 3548準拠のエンコーディ
-
PythonでのCX_Freezeの使い方:スクリプトを実行ファイル(EXE)に変換する方法
はじめに 何か面白いものを作りたいという欲求は人間の本能であり、完成したものは誰かに共有したくなるものです。Pythonでもその願いを叶えられます。ただし、作成したPythonスクリプトをそのまま共有するには、相手のマシンにも同じバージョンのPythonと、プログラムで使用しているすべてのモジュールがインストールされている必要があります。 そこで役立つのがCX_Freezeです。このツールを使えば、Pythonがインストールされていない環境でも動作するスタンドアロンの実行ファイル(.exe)を作成できます。 CX_Freezeのインストール まず、コマンドプロンプトで以下のコマンドを実行し、c