ソースコード:
ドキュメンテーション:
デバッグ用のエントリコードを書く
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from numpy_ml.trees import DecisionTree
X, y = load_iris(True)
dt = DecisionTree()
X_train, X_test, y_train, y_test = train_test_split(X, y)
dt.fit(X_train, y_train)
y_pred = dt.predict(X_test)
score = accuracy_score(y_test, y_pred)
print(score)
キーコードを見る
numpy_ml.trees.dt.DecisionTree#_grow
再帰的に終了します条件1
:
# if all labels are the same, return a leaf
if len(set(Y)) == 1:
if self.classifier:
prob = np.zeros(self.n_classes)
prob[Y[0]] = 1.0
return Leaf(prob) if self.classifier else Leaf(Y[0])
カテゴリの場合、リーフノードはワンホットコードで表されるカテゴリです。
再帰的に終了します条件2
:
# if we have reached max_depth, return a leaf
if cur_depth >= self.max_depth:
v = np.mean(Y, axis=0)
if self.classifier:
v = np.bincount(Y, minlength=self.n_classes) / len(Y)
return Leaf(v)
ノード分割を参照してください
情報獲得
n = len(Y)
n_l, n_r = len(left), len(right)
e_l, e_r = loss(Y[left]), loss(Y[right])
child_loss = (n_l / n) * e_l + (n_r / n) * e_r
# impurity gain is difference in loss before vs. after split
ig = parent_loss - child_loss
二分木であるため、情報獲得率は無意味です(2つのサブノードの固定分割、複数のサブノードの分割が情報獲得の増加につながる状況はありません)
分割点を取得した後、配列パラメーターを直接渡して子ノードを作成します。特別な操作は必要ありません。
# greedily select the best split according to `criterion`
feat, thresh = self._segment(X, Y, feat_idxs)
l = np.argwhere(X[:, feat] <= thresh).flatten()
r = np.argwhere(X[:, feat] > thresh).flatten()
# grow the children that result from the split
left = self._grow(X[l, :], Y[l], cur_depth)
right = self._grow(X[r, :], Y[r], cur_depth)
return Node(left, right, (feat, thresh))
残念ながら、CARTプルーニングのコードは表示されませんでした