わかりやすい機械学習-Pythonは単純な決定木を手動で実装します

この記事は、金の創造への道を始めるための「新人創造セレモニー」イベントに参加しました。

前書き

決定木は機械学習の一般的なアルゴリズムモデルです。この記事では、単純な離散間隔分類問題からの決定木の確立プロセスを分析し、Pythonを使用して単純な決定木を手動で実装します。

バックグラウンド

この例では、面接を背景として、985であるかどうか、教育、およびそれが認められるかどうかを判断するためのプログラミング言語の3つの指標を選択します。

デシジョンツリー構築プロセス

1)すべてのインジケーターをインジケーターリストに追加します

2)インデックスリスト内の各インデックスのエントロピーを計算し、エントロピーが最小のインデックスに従って除算します

3)正常に分割できる場合は、結果を直接取得します。それ以外の場合は、インジケーターリストからインジケーターを削除し、手順2)を実行して、結果をデシジョンツリーに追加します。

注:この記事では、辞書を使用してツリー(マルチフォークツリー)の構造を表します。

依存関係パッケージ

import numpy as np
from collections import Counter
from math import log2
复制代码

損失を計算する

情報エントロピー

def entropy(y_label):
    counter = Counter(y_label)
    ent = 0.0
    for num in counter.values():
        p = num / len(y_label)
        ent += -p * log2(p)
    return ent
复制代码

ここで情報エントロピーを使用することに加えて、代わりにジニ係数を使用することもできます

ジニ係数

def geni(y_label):
    counter = Counter(y_label)
    g = 1
    for num in counter.values():
        p = num / len(y_label)
        g -= p * p
    return g
复制代码

デシジョンツリーを定義する

class DecisionTree:
    def __init__(self):
        self.tree = {}
    #训练决策树
    def fit(self,X,y):
        cols = list(range(X.shape[1]))
        #对X得每一列数据,计算分割后得信息熵
        self.tree = self._genTree(cols, X, y)
    #递归生成决策树

    def _genTree(self, cols, X, y):
        # 计算最小信息熵得特征
        imin = cols[0] # 最下熵得列
        emin = 100 # 最小熵值
        for i in cols:
            coli = X[:,i]#拿到第i个特征数据
            enti = sum([entropy(y[coli==d]) for d in set(coli)]) # (也可以使用基尼系数计算,下同)
            if enti < emin:
                imin = i
                emin = enti
        #根据最小熵特征有几个值,就生成几个新的子树分支   
        newtree={}
        mincol = X[:,imin]
        cols.remove(imin)
        #针对这个特征得每个值,进一步划分树
        for d in set(mincol):
            entd = entropy(y[mincol==d])  # 计算信息熵
            if entd <1e-10:#已经完全分开
                newtree[d] = y[mincol==d][0]
            else:#还需要进一步细分
                newtree[d] = self._genTree(cols.copy(), X[mincol==d, :], y[mincol==d])
        return {imin: newtree}#将列号作为索引,返回新生成的树

    #预测新样本
    def predict(self, X):
        X = X.tolist()
        y = [None for i in range(len(X))]
        for i in range(len(X)):
            predictDict = self.tree
            while predictDict != 'Yes' and predictDict != 'No':
                col = list(predictDict.keys())[0]
                predictDict = predictDict[col]
                predictDict = predictDict[X[i][col]]
            else:
                y[i] = predictDict
        return y
复制代码

テスト

X=np.array([['Yes985','本科','C++'],
            ['Yes985','本科','Java'],
            ['No985' ,'硕士','Java'],
            ['No985' ,'硕士','C++'],
            ['Yes985','本科','Java'],
            ['No985' ,'硕士','C++'],
            ['Yes985','硕士','Java'],
            ['Yes985','博士','C++'],
            ['No985' ,'博士','Java'],
            ['No985' ,'本科','Java']])
y=np.array(['No','Yes','Yes','No','Yes','No','Yes','Yes','Yes','No'])

dt = DecisionTree()
dt.fit(X, y)
print(dt.tree)
print(dt.predict(X))
复制代码

試験結果トレーニングデータのテスト結果は非常に良好であることがわかります。自分でテストするためのデータを作成できます。

コードの説明

エントロピー関数:情報エントロピーの計算に使用されます。ここで、Counterはさまざまなカテゴリの数をカウントするために使用され、各カテゴリの数を総数で割って確率を取得し、情報エントロピーを確率で計算します。DecisonTree.fit:モデルをトレーニングするために、ツリーのルートノードがこの関数で確立されます。DecisonTree._genTree:ツリーを構築します。構築プロセスは上記のとおりです。DecisonTree.predict:予測を行います。決定木では、最後の予測結果のみがリーフノードになります。予測プロセス:1)インジケーターを選択します2)選択したインジケーターに従って、インジケーターのサブノードとデータに対応する値に従って新しいサブノードを確立して選択します3)サブノードがインジケーター、インジケーターを使用してプロセスを繰り返します2)、サブノードがインジケーターの場合、インジケーターを使用してプロセスを繰り返します2)ノードが予測結果の場合、予測は終了します

おすすめ

転載: juejin.im/post/7077352935834779685