[機器學習]回歸--Decision Tree Regression


CART決策樹又稱分類回歸樹,當數據集的因變量為連續性數值時,該樹算法就是一個回歸樹,可以用葉節點觀察的均值作為預測值;當數據集的因變量為離散型數值時,該樹算法就是一個分類樹,可以很好的解決分類問題。但需要注意的是,該算法是一個二叉樹,即每一個非葉節點只能引伸出兩個分支,所以當某個非葉節點是多水平(2個以上)的離散變量時,該變量就有可能被多次使用。

在sklearn中我們可以用來提高決策樹泛化能力的超參數主要有
- max_depth:樹的最大深度,也就是說當樹的深度到達max_depth的時候無論還有多少可以分支的特征,決策樹都會停止運算.
- min_samples_split: 分裂所需的最小數量的節點數.當葉節點的樣本數量小於該參數后,則不再生成分支.該分支的標簽分類以該分支下標簽最多的類別為准
- min_samples_leaf; 一個分支所需要的最少樣本數,如果在分支之后,某一個新增葉節點的特征樣本數小於該超參數,則退回,不再進行剪枝.退回后的葉節點的標簽以該葉節點中最多的標簽你為准
- min_weight_fraction_leaf: 最小的權重系數
- max_leaf_nodes:最大葉節點數,None時無限制,取整數時,忽略max_depth









我們這次用的數據是公司內部不同的promotion level所對應的薪資


下面我們來看一下在Python中是如何實現的

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

dataset = pd.read_csv('Position_Salaries.csv')
X = dataset.iloc[:, 1:2].values
# 這里注意:1:2其實只有第一列,與1 的區別是這表示的是一個matrix矩陣,而非單一向量。
y = dataset.iloc[:, 2].values
下來,進入正題,開始Decision Tree Regression回歸:
from sklearn.tree import DecisionTreeRegressor
regressor = DecisionTreeRegressor(random_state = 0)
regressor.fit(X, y)

y_pred = regressor.predict(6.5)

# 圖像中顯示
X_grid = np.arange(min(X), max(X), 0.01)
X_grid = X_grid.reshape((len(X_grid), 1))
plt.scatter(X, y, color = 'red')
plt.plot(X_grid, regressor.predict(X_grid), color = 'blue')
plt.title('Truth or Bluff (Decision Tree Regression)')
plt.xlabel('Position level')
plt.ylabel('Salary')
plt.show()



下面的代碼主要是對決策樹最大深度與過擬合之間關系的探討,可以看出對於最大深度對擬合關系影響.

與分類決策樹一樣的地方在於,最大深度的增加雖然可以增加對訓練集擬合能力的增強,但這也就可能意味着其泛化能力的下降


import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt

# Create a random dataset
rng = np.random.RandomState(1)
X = np.sort(10 * rng.rand(160, 1), axis=0)
y = np.sin(X).ravel()
y[::5] += 2 * (0.5 - rng.rand(32)) # 每五個點增加一次噪音

# Fit regression model
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=4)
regr_3 = DecisionTreeRegressor(max_depth=8)
regr_1.fit(X, y)
regr_2.fit(X, y)
regr_3.fit(X, y)

# Predict
X_test = np.arange(0.0, 10.0, 0.01)[:, np.newaxis]
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
y_3 = regr_3.predict(X_test)

# Plot the results
plt.figure()
plt.scatter(X, y, s=20, edgecolor="black",
            c="darkorange", label="data")
plt.plot(X_test, y_1, color="cornflowerblue",
         label="max_depth=2", linewidth=2)
plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=4", linewidth=2)
plt.plot(X_test, y_3, color="r", label="max_depth=8", linewidth=2)
plt.xlabel("data")
plt.ylabel("target")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()


從上面的測試可以看出隨着決策樹最大深度的增加,決策樹的擬合能力不斷上升.
在這個例子中一共有160個樣本,當最大深度為8(大於lg(200))時,我們的決策樹已經不僅僅擬合了我們的正確樣本,同時也擬合了我們添加的噪音,這導致了其泛化能力的下降.

最大深度與訓練誤差測試誤差的關系

下面我們進行對於不同的最大深度決策樹的訓練誤差與測試誤差進行繪制.
當然你也可以通過改變其他可以控制決策樹生成的超參數進行相關測試.


from sklearn import model_selection
def creat_data(n):
    np.random.seed(0)
    X = 5 * np.random.rand(n, 1)
    y = np.sin(X).ravel()
    noise_num=(int)(n/5)
    y[::5] += 3 * (0.5 - np.random.rand(noise_num)) # 每第5個樣本,就在該樣本的值上添加噪音
    return model_selection.train_test_split(X, y,test_size=0.25,random_state=1)
def test_DecisionTreeRegressor_depth(*data,maxdepth):
    X_train,X_test,y_train,y_test=data
    depths=np.arange(1,maxdepth)
    training_scores=[]
    testing_scores=[]
    for depth in depths:
        regr = DecisionTreeRegressor(max_depth=depth)
        regr.fit(X_train, y_train)
        training_scores.append(regr.score(X_train,y_train))
        testing_scores.append(regr.score(X_test,y_test))

    ## 繪圖
    fig=plt.figure()
    ax=fig.add_subplot(1,1,1)
    ax.plot(depths,training_scores,label="traing score")
    ax.plot(depths,testing_scores,label="testing score")
    ax.set_xlabel("maxdepth")
    ax.set_ylabel("score")
    ax.set_title("Decision Tree Regression")
    ax.legend(framealpha=0.5)
    plt.show()

X_train,X_test,y_train,y_test=creat_data(200)    
test_DecisionTreeRegressor_depth(X_train,X_test,y_train,y_test,maxdepth=12)


由上圖我們可以看出,當我們使用train_test進行數據集的分割的時候,最大深度2即為我們需要的最佳超參數.

同樣的你也可以對其他超參數進行測試,或者換用cv進行測試,再或者使用hyperopt or auto-sklearn等神器



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM