CART樹的生成算法
輸入:
訓練數據集X,樣本標籤y
輸出:迴歸樹f(x)
步驟
- 若D中所有實例屬於同一類,則T爲單結點樹,並將類作爲該結點的類標記,返回T
- 對每個特徵feature的每個取值value,將y分爲和兩個集合,因爲現在還不是真正的split,只是要計算split後的基尼指數,只需要用到split之後的y
- 計算和的基尼指數之和
- 選擇基尼指數計算結果最小的(feature, value)作爲當前的最優劃分
- 基於最優劃分生成2個子結點,將數據分配到兩個子結點中
- 對子結點遞歸調用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