決策樹CART的python實現

2022-06-26 16:51:12 字數 3955 閱讀 4917

cart演算法只做二元切分,因此每個樹節點包含待切分的特徵,待切分的特徵值,左子樹,右子樹。

import

numpy as np

class

treenode(object):

def__init__

(self, feat, val, right, left):

featuretospliton =feat

valueofsplit =val

rightbranch =right

leftbranch = left

給定特徵和特徵值的資料切分函式

1

defbinsplitdataset(dataset, feature, value):

2 mat0 = dataset[np.nonzero(dataset[:, feature] >value)[0], :]

3 mat1 = dataset[np.nonzero(dataset[:, feature] <=value)[0], :]

4return mat0, mat1

樹構建函式,包含4個引數,資料集和其他3個可選引數。這些可選引數決定了樹的型別:leaftype給出建立葉節點的函式;errtype代表誤差計算函式;ops是乙個包含樹構建所需其他引數的元組。

createtree是乙個遞迴函式。該函式首先嘗試將資料集分成兩個部分,切分由函式choosebestsplit()完成。如果滿足停止條件,choosebestsplit將返回none和某類模型的值。如果構建的是回歸樹,該模型是乙個常數。如果是模型樹,模型是乙個線性方程。如果不滿足停止條件,choosebestsplit將建立乙個新的python字典並將資料集分成兩份,在這兩份資料集上將分別繼續遞迴呼叫createtree函式。

1

def createtree(dataset, leaftype=regleaf, errtype=regerr, ops=(1, 4)):

2 feat, val =choosebestsplit(dataset, leaftype, errtype, ops)

3if feat ==none:

4return

val5 rettree ={}

6 rettree["

spind

"] =feat

7 rettree["

spval

"] =val

8 lset, rset =binsplitdataset(dataset, feat, val)

9 rettree["

left

"] =createtree(lset, leaftype, errtype, ops)

10 rettree["

right

"] =createtree(rset, leaftype, errtype, ops)

11return rettree

1.回歸樹

choosebestsplit只需完成兩件事:用最佳方式切分資料集和生成相應地葉節點。其包含:dataset、leaftype、errtype和ops。leaftype是對建立葉節點的函式的引用,errtype是計算總方差函式的引用。choosebestsplit函式的目標是找到資料集切分的最佳位置。它遍歷所有特徵及其所有特徵值來找到使誤差最小化的切分閾值。

1

defregleaf(dataset):

2return np.mean(dataset[:, -1]) # 資料最後一列為**值34

defregerr(dataset):

5return np.var(dataset[:, -1]) *np.shape(dataset)[0]67

def choosebestsplit(dataset, leaftype=regleaf, errtype=regerr, ops=(1, 4)):

8 tols =ops[0]

9 toln = ops[1]

10if len(set(dataset[:, -1].tolist())) == 1:

11return

none, leaftype(dataset)

12 m, n =np.shape(dataset)

13 s =errtype(dataset)

14 bests =np.inf

15 bestindex =0

16 bestvalue =0

17for featindex in range(n-1):

18for splitval in

set(dataset[:, featindex]):

19 mat0, mat1 =binsplitdataset(dataset, featindex, splitval)

20if (np.shape(mat0)[0] < toln) or (np.shape(mat1)[0] 21continue

22 news = errtype(mat0) +errtype(mat1)

23if news 24 bestindex =featindex

25 bestvalue =splitval

26 bests =news

27if (s - bests) 28return

none, leaftype(dataset)

29 mat0, mat1 =binsplitdataset(dataset, bestindex, bestvalue)

30if (np.shape(mat0)[0] < toln) or (np.shape(mat1)[0] 31return

none, leaftype(dataset)

32return bestindex, bestvalue

2.模型樹

用樹來對資料建模,除了把葉節點簡單的設定為常數值之外,還有一種方法是把葉節點設定為分段線性函式,這裡所謂的分段線性是指模型由多個線性片段組成。

為了找到最佳切分應該怎樣計算誤差呢?對於給定的資料集,應該先用線性的模型對它進行擬合,然後計算真實的目標值與模型**值間的差值。最後將這些差值的平方求和就得到了所需的誤差。

1

deflinearsolve(dataset):

2 m, n =np.shape(dataset)

3 x =np.mat(np.ones((m, n)))

4 y = np.mat(np.ones((m, 1)))

5 x[:, 1:n] = dataset[:, 0:n-1]

6 y = dataset[:, -1]

7 xtx = x.t *x

8if np.linalg.det(xtx) ==0:

9raise nameerror('

this matrix is singular, cannot do inverse, try increasing the second value of ops')

10 ws = xtx.i * (x.t *y)

11return

ws, x, y

1213

defmodelleaf(dataset):

14 ws, x, y =linearsolve(dataset)

15return

ws16

17def

modelerr(dataset):

18 ws, x, y =linearsolve(dataset)

19 yhat = x *ws

20return np.sum(np.power(y - yhat, 2))

決策樹和CART決策樹

首先簡單介紹下決策樹 說到決策樹肯定離不開資訊熵 什麼是資訊熵 不要被這名字唬住,其實很簡單 乙個不太可能的時間居然發生了,要比乙個非常可能的時間發生提供更多的資訊。訊息說 今天早上太陽公升起 資訊量是很少的,以至於沒有必要傳送。但另一條訊息說 今天早上日食 資訊量就很豐富。概率越大資訊量就越少,與...

CART決策樹python實現

from sklearn import tree import pydotplus defcart skl test df pd.read csv dataset liquefaction data mle.csv x df csr vs y df target clf tree.decisiont...

決策樹之CART

本系列分享由三篇部落格組成,建議從前往後閱讀學習。決策樹之id3 決策樹之c4.5 決策樹之cart 前面我們講到了決策樹演算法id3,和c4.5。c4.5是在id3的基礎上發展而來的,c4.5還存在的缺陷有 1 c4.5不能解決回歸的問題。2 c4.5需要進行多個對數計算,效率比較低。3 對於離散...