機器學習實戰之樹回歸

2021-09-27 02:25:33 字數 3810 閱讀 1121

線性回歸包含一些強大的方法,但是這些方法建立的模型需要擬合所有的樣本點(區域性線性回歸除外)。當資料擁有眾多特徵,且特徵之間關係十分複雜時,構建全域性模型的想法顯得困難。並且,生活中很多問題都是非線性的,不可能使用全域性線性模型來擬合任何模型。

一種可行的方法是將資料集切分成很多份易建模的資料,然後利用線性回歸技術來建模。如果首次切分後仍然難以擬合線性模型就繼續切分。這種切分方式下,數結構回歸法就相當有用。

接下來將介紹乙個新的叫做cart(classification and regression trees)的數建構演算法。該演算法既可用於分類,亦可用於回歸。

樹回歸

優點:可以對複雜和非線性的資料建模;

缺點:結果不易理解;

適用資料型別:數值型和標稱型資料

回顧決策樹:

1)決策樹不斷將資料切分為小資料集,直到所有目標變數完全相同,或者資料不能再切分為止。決策樹是一種貪心演算法,它要在給定時間內做出最佳選擇,但並不關心能否達到全域性最優。

2)使用的數構建演算法是id3。

2.1)id3的做法是每次選取當前最佳的特徵來分隔資料,並按照該特徵的所有取值來切分。

2.2)例:如果乙個特徵有四種取值,那麼資料將被切成4份。一旦按照某特徵切分後,該特徵在之後的演算法執行中將不會起作用,所以有觀點認為該切分方式過於迅速。

2.3)另一種切分方法是二分切分法:每次把資料集切分兩份。如果資料的某特徵值等於切分要求的值,那麼這些資料就進入數的左子樹,反之進入數的右子樹。

3)id3演算法的問題與二分切分法的優勢:

3.1)由於切分過於迅速,不能直接處理連續型特徵。只有事先將連續型特徵轉換成離散型,才能在id3演算法中使用。但是這種轉換過程會破壞連續型變數的內在性質。

3.2)二分切分法易於對樹構建過程進行調整以處理連續型特徵。另外能節省樹的構建時間,但是這點的意義不是特別大,因為樹構建一般是離線完成。

cart使用二元切分來處理連續型變數。決策樹中使用夏農熵來度量集合的無組織程度,如果選用其他方法來代替夏農熵,則可以使用樹構建演算法來完成回歸。

在樹的構建過程中,需要解決多種型別資料的儲存問題。這裡將使用一部字典來儲存樹的資料結構,該字典將包含以下4個元素:

這與決策樹的樹結構有一點不同。

1)決策樹中用一部字典來儲存每個切分,但該字典可以包含兩個或者以上的值。

2)cart演算法只做二元切分,所以這裡固定樹的資料結構。樹包含左鍵和右鍵,可以儲存另一顆子樹或者單個值。字典還包含特徵和特徵值兩個鍵,它們給出切分演算法所有的特徵和特徵值。

當然也可以使用物件導向的程式設計模式來建立這個資料結構,如下:

**程式清單2-1:**建立樹節點

class

treenode()

:def

__init__

(self, feat, val, right, left)

: feature_to_split_on = feat #特徵

value_of_split = val #特徵值

right_branch = right #左鍵

left_branch = left #右鍵

隨後將構建兩種樹:

1)回歸樹(regression tree):每個葉節點包含單個值;

2)模型樹(model tree):每個節點包含乙個線性方程。

建立者兩種樹時,為了使得**復用,以下先給出構建兩種樹的共用**。其偽**如下:

找到最佳的待切分特徵:

如果該節點不能再分:

將該節點存為葉節點

執行二元分類

在右子樹呼叫create_tree()方法

在左子樹呼叫create_tree()方法

建立regtrees.py檔案並新增以下**:

程式清單2-2:cart演算法的實現**

from numpy import

*"""資料載入,但是返回對映後的資料"""

defload_data_set

(file_name)

:with

open

(file_name)

as fd:

fd_data = fd.readlines(

) data_set =

for data in fd_data:

data = data.strip(

).split(

'\t'

) data =

map(

float

, data)

#將每行對映為一組浮點數

return data_set

"""劃分資料集合"""

defbin_split_data_set

(data_set, feature, value)

:#輸入引數:資料集合、待切分特徵、待切分特徵的某個值

mat0 = data_set[nonzero(data_set[

:, feature]

> value)[0

],:]

[0] mat1 = data_set[nonzero(data_set[

:, feature]

<= value)[0

],:]

[0]return mat0, mat1

"""建立葉節點"""

defreg_leaf()

:pass

"""計算總方差"""

defreg_err()

:pass

"""構建樹"""

defcreate_tree

(data_set, leaf_type=reg_leaf, err_type=reg_err, ops=(1

,4))

:#ops包含樹構建所需其他引數的元組

feat, val = choose_best_split(data_set, leaf_type, err_type, ops)

if feat ==

none

:return val

ret_tree =

ret_tree[

'sp_ind'

]= feat

ret_tree[

'sp_val'

]= val

l_tree, r_tree = bin_split_data_set(data_set, feat, val)

ret_tree[

'left'

]= create_tree(l_tree, leaf_type, err_type, ops)

ret_tree[

'right'

]= create_tree(r_tree, leaf_type, err_type, ops)

return ret_tree

defchoose_best_split

(data_set, leaf_type, err_type, ops)

:return0,

0def

test1()

: data_set = load_data_set(

'e:\machine learing\mymachinelearning\data\ex0.txt'

)print

(data_set)

if __name__ ==

'__main__'

: test1(

)

待續…

機器學習實戰 09 樹回歸

機器學習實戰 第9章的樹回歸執行時頻繁出錯,這裡主要有兩點 出錯的 行是 for splitval in set dataset featindex 應改為 for splitval in set dataset featindex t a.tolist 0 具體分析過程檢視 出錯的 行是 def ...

機器學習實戰之線性回歸

之前我們學習的機器學習演算法都是屬於分類演算法,也就是 值是離散值。當 值為連續值時,就需要使用回歸演算法。本文將介紹線性回歸的原理和 實現。如圖所示,這時一組二維的資料,我們先想想如何通過一條直線較好的擬合這些散點了?直白的說 盡量讓擬合的直線穿過這些散點 這些點離擬合直線很近 目標函式 要使這些...

機器學習實戰之線性回歸

線性回歸原理與推導 如圖所示,這時一組二維的資料,我們先想想如何通過一條直線較好的擬合這些散點了?直白的說 盡量讓擬合的直線穿過這些散點 這些點離擬合直線很近 目標函式 要使這些點離擬合直線很近,我們需要用數學公式來表示。首先,我們要求的直線公式為 y xtw。我們這裡要求的就是這個w向量 類似於l...