cart演算法只做二元切分,因此每個樹節點包含待切分的特徵,待切分的特徵值,左子樹,右子樹。
importnumpy as np
class
treenode(object):
def__init__
(self, feat, val, right, left):
featuretospliton =feat
valueofsplit =val
rightbranch =right
leftbranch = left
給定特徵和特徵值的資料切分函式
1defbinsplitdataset(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函式。
1def 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函式的目標是找到資料集切分的最佳位置。它遍歷所有特徵及其所有特徵值來找到使誤差最小化的切分閾值。
1defregleaf(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.模型樹
用樹來對資料建模,除了把葉節點簡單的設定為常數值之外,還有一種方法是把葉節點設定為分段線性函式,這裡所謂的分段線性是指模型由多個線性片段組成。
為了找到最佳切分應該怎樣計算誤差呢?對於給定的資料集,應該先用線性的模型對它進行擬合,然後計算真實的目標值與模型**值間的差值。最後將這些差值的平方求和就得到了所需的誤差。
1deflinearsolve(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 對於離散...