决策树——CART和模型树
CART樹
理解: ???? 如果CART樹處理離散型數據,叫做分類決策樹,那么,引入基尼指數作為尋找最好的數據劃分的依據,基尼指數越小,說明數據的“純度越高”,隨機森林的代碼里邊就運用到了基尼指數。如果CART樹處理連續(xù)型數據時,叫做回歸決策樹,那么,引入了平方誤差,首先,它使用二元切分來處理數據,得到兩個子集,計算誤差,找到最小誤差,確定最佳切分的特征編號和特征值,然后進行建樹。
構建回歸樹,需要給定某個誤差計算方法,該函數會找到數據集上最佳的二元切分方式。另外,該函數還要確定什么時候停止劃分,一旦停止劃分會生成一個葉節(jié)點。這里引入reLeaf(),regErr()分別得到葉節(jié)點和總方差。葉節(jié)點的模型是目標變量的 均值,var()是均方差,所以需要乘以數據集的樣本個數。
劃分數據集時,如果找不到一個‘好’的二元切分,該函數返回None值并產生葉節(jié)點,葉節(jié)點的值也為None。
通過降低決策樹的復雜度來避免過擬合的過程叫剪枝,預剪枝和后剪枝的單個效果可能是不好的,一般來說,我們可以同時采用這兩種剪枝方法。
模型樹:
理解:模型樹和回歸樹的區(qū)別就是回歸樹的葉節(jié)點是一個常數值,而模型樹的葉節(jié)點是分段線性函數,分段線性模型就是我們對數據集的一部分數據以某個線性模型建模,而另一份數據以另一個線性模型建模。
#模型樹 # 主要功能:將數據格式化成目標變量Y和自變量X。X、Y用于執(zhí)行簡單的線性規(guī)劃。 def linearSolve(dataSet) :m,n = shape(dataSet) X = mat(ones((m,n))); Y = mat(ones((m,1)))X[:, 1:n] = dataSet[:, 0:n-1]; Y = dataSet[:, -1]xTx = X.T*X# 矩陣的逆不存在時會造成程序異常if linalg.det(xTx) == 0.0 :raise NameError('This matrix is singular, cannot do inverse, \n try increasing the second value of ops')ws = xTx.I * (X.T * Y)return ws, X, Y# 與regLeaf()類似,當數據不需要切分時,它負責生成葉節(jié)點的模型。 def modelLeaf(dataSet) :ws, X, Y = linearSolve(dataSet)return ws# 在給定的數據集上計算誤差。與regErr()類似,會被chooseBestSplit()調用來找到最佳切分。 def modelErr(dataSet) :ws, X, Y = linearSolve(dataSet)yHat = X * wsreturn sum(power(Y-yHat, 2))# 為了和modeTreeEval()保持一致,保留兩個輸入參數 def regTreeEval(model, inDat) :return float(model)# 對輸入數據進行格式化處理,在原數據矩陣上增加第0列,元素的值都是1 def modelTreeEval(model, inDat) :n = shape(inDat)[1]X = mat(ones((1, n+1)))X[:, 1:n+1] = inDatreturn float(X*model)def isTree(obj): return (type(obj).__name__=='dict') # 在給定樹結構的情況下,對于單個數據點,該函數會給出一個預測值。 # modeEval是對葉節(jié)點進行預測的函數引用,指定樹的類型,以便在葉節(jié)點上調用合適的模型。 # 此函數自頂向下遍歷整棵樹,直到命中葉節(jié)點為止,一旦到達葉節(jié)點,它就會在輸入數據上 # 調用modelEval()函數,該函數的默認值為regTreeEval() def treeForeCast(tree, inData, modelEval=regTreeEval) :if not isTree(tree) : return modelEval(tree, inData)if inData[tree['spInd']] > tree['spVal'] :if isTree(tree['left']) :return treeForeCast(tree['left'], inData, modelEval)else : return modelEval(tree['left'], inData)else :if isTree(tree['right']) :return treeForeCast(tree['right'], inData, modelEval)else :return modelEval(tree['right'], inData)# 多次調用treeForeCast()函數,以向量形式返回預測值,在整個測試集進行預測非常有用 def createForeCast(tree, testData, modelEval=regTreeEval) :m = len(testData)yHat = mat(zeros((m,1)))for i in range(m) :yHat[i,0] = treeForeCast(tree, mat(testData[i]), modelEval)return yHat使用Tkinter工具構建圖形用戶界面:
from numpy import * from tkinter import * import regTrees as regTreesimport matplotlib matplotlib.use('TkAgg') #設置后端TkAgg #將TkAgg和matplotlib鏈接起來 from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure# def reDraw(tolS, tolN) :reDraw.f.clf() #清空之前的圖像reDraw.a = reDraw.f.add_subplot(111) #重新添加新圖if chkBtnVar.get() : #檢查選框model tree是否被選中if tolN < 2 : tolN = 2myTree = regTrees.createTree(reDraw.rawDat, regTrees.modelLeaf, regTrees.modelErr, (tolS, tolN))yHat = regTrees.createForeCast(myTree, reDraw.testDat, regTrees.modelTreeEval)else :myTree = regTrees.createTree(reDraw.rawDat, ops=(tolS, tolN))yHat = regTrees.createForeCast(myTree, reDraw.testDat)# reDraw.rawDat[:,0].A,需要將矩陣轉換成數組reDraw.a.scatter(reDraw.rawDat[:,0].A, reDraw.rawDat[:,1].A, s=5) # 繪制真實值reDraw.a.plot(reDraw.testDat, yHat, linewidth=2.0) # 繪制預測值reDraw.canvas.show()# def getInputs() :#獲取輸入try : tolN = int(tolNentry.get()) #期望輸入是整數except : #清楚錯誤用默認值替換tolN = 10print ("enter Integer for tolN")tolNentry.delete(0, END)tolNentry.insert(0, '10')try : tolS = float(tolSentry.get())except : #期望輸入是浮點數tolS = 1.0print ("enter Float for tolS")tolSentry.delete(0, END)tolSentry.insert(0, '1.0')return tolN, tolS# def drawNewTree() :# 取得輸入框的值tolN, tolS = getInputs() # 從輸入文本框中獲取參數# 利用tolN,tolS,調用reDraw生成漂亮的圖reDraw(tolS, tolN) #繪制圖#布局GUI root = Tk() # 創(chuàng)建畫布 Label(root, text='Plot Place Holder').grid(row=0, columnspan=3)Label(root, text='tolN').grid(row=1, column=0) tolNentry = Entry(root) tolNentry.grid(row=1, column=1) tolNentry.insert(0, '10') Label(root, text='tolS').grid(row=2, column=0) tolSentry = Entry(root) tolSentry.grid(row=2, column=1) tolSentry.insert(0, '1.0') # 點擊“ReDraw”按鈕后,調用drawNewTree()函數 Button(root, text='ReDraw', command=drawNewTree).grid(row=1, column=2, rowspan=3)chkBtnVar = IntVar() chkBtn = Checkbutton(root, text='Model Tree', variable=chkBtnVar) chkBtn.grid(row=3, column=0, columnspan=2)reDraw.f = Figure(figsize=(5,4), dpi=100) reDraw.canvas = FigureCanvasTkAgg(reDraw.f, master=root) reDraw.canvas.show() reDraw.canvas.get_tk_widget().grid(row=0, columnspan=3)reDraw.rawDat = mat(regTrees.loadDataSet('ex00.txt')) reDraw.testDat = arange(min(reDraw.rawDat[:, 0]), max(reDraw.rawDat[:, 0]), 0.01)reDraw(1.0, 10)root.mainloop()總結
以上是生活随笔為你收集整理的决策树——CART和模型树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cad道路里程桩号标注_CAD道路桩号自
- 下一篇: STM32F103按键操作的另一种实现—