5-6 CART樹的生成

CART樹的生成算法

輸入:
訓練數據集X,樣本標籤y
輸出:迴歸樹f(x)

步驟

  1. 若D中所有實例屬於同一類CkC_k,則T爲單結點樹,並將類CkC_k作爲該結點的類標記,返回T
  2. 對每個特徵feature的每個取值value,將y分爲R1R_1R2R_2兩個集合,因爲現在還不是真正的split,只是要計算split後的基尼指數,只需要用到split之後的y
    y1(feature,value)={yixi(feature)value}y2(feature,value)={yiyi(feature)>value} y_1(feature, value) = \{y_i | x_i^{(feature)} \le value\} \\ y_2(feature, value) = \{y_i | y_i^{(feature)} \gt value\}
  3. 計算y1y_1y2y_2的基尼指數之和

Gini(p)=Kpk(1pk)=1Kpk2 Gini(p) = \sum^K p_k(1-p_k) = 1 - \sum^Kp_k^2

  1. 選擇基尼指數計算結果最小的(feature, value)作爲當前的最優劃分
  2. 基於最優劃分生成2個子結點,將數據分配到兩個子結點中
  3. 對子結點遞歸調用CART算法

代碼

def gini(y):
    ySet = set(y)
    ret, n = 1, y.shape[0]
    for yi in ySet:
        ret -= (y[y==yi].shape[0]/n)**2
    return ret

def CART(X, y):
    # 若D中所有實例屬於同一類$$C_k$$
    if len(set(y))==1:
        # 將類$$C_k$$作爲該結點的類標記
        return y[0]
    bestGini = np.inf
    # 對每個特徵feature的每個取值value
    for feature in range(X.shape[1]):
        for value in set(X[:,feature]):
            # 將X分爲$$R_1$$和$$R_2$$兩個集合
            y1 = y[X[:,feature]<= value]
            y2 = y[X[:,feature]> value]
            # 計算$$R_1$$和$$R_2$$的基尼指數之和
            sumGini = gini(y1) + gini(y2)
            # 選擇基尼指數計算結果最小的(feature, value)作爲當前的最優劃分
            if sumGini < bestGini:
                bestFeature, bestValue, bestGini = feature, value, sumGini
    # 基於最優劃分生成2個子結點,將數據分配到兩個子結點中
    node = {'feature':bestFeature,
            'value':bestValue,
            'left':CART(X[X[:,bestFeature]<= bestValue], y[X[:,bestFeature]<= bestValue]),
           'right':CART(X[X[:,bestFeature]> bestValue], y[X[:,bestFeature]> bestValue])}
    return node
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章