淘宝上做微请帖的在哪个网站,wordpress 插件手机,建筑网页设计详情,wordpress如何安装主题CART树
理解#xff1a; 如果CART树处理离散型数据#xff0c;叫做分类决策树#xff0c;那么#xff0c;引入基尼指数作为寻找最好的数据划分的依据#xff0c;基尼指数越小#xff0c;说明数据的“纯度越高”#xff0c;随机森林的代码里边就运用到了基尼指数。如…CART树
理解 如果CART树处理离散型数据叫做分类决策树那么引入基尼指数作为寻找最好的数据划分的依据基尼指数越小说明数据的“纯度越高”随机森林的代码里边就运用到了基尼指数。如果CART树处理连续型数据时叫做回归决策树那么引入了平方误差首先它使用二元切分来处理数据得到两个子集计算误差找到最小误差确定最佳切分的特征编号和特征值然后进行建树。
构建回归树需要给定某个误差计算方法该函数会找到数据集上最佳的二元切分方式。另外该函数还要确定什么时候停止划分一旦停止划分会生成一个叶节点。这里引入reLeaf(),regErr()分别得到叶节点和总方差。叶节点的模型是目标变量的 均值var是均方差所以需要乘以数据集的样本个数。
划分数据集时如果找不到一个‘好’的二元切分该函数返回None值并产生叶节点叶节点的值也为None。
from numpy import *
#载入数据
def loadDataSet(fileName) : dataMat []fr open(fileName)for line in fr.readlines() :curLine line.strip().split(\t)fltLine list(map(float, curLine))#将后面的数据集映射为浮点型dataMat.append(fltLine)return dataMat#切分数据集为两个子集
# dataSet: 数据集合
# feature: 待切分的特征
# value: 该特征的某个值
#nonzero():得到数组非零元素的位置数组索引
def binSplitDataSet(dataSet, feature, value) :mat0 dataSet[nonzero(dataSet[:,feature] value)[0],:]mat1 dataSet[nonzero(dataSet[:,feature] value)[0],:]return mat0, mat1# 负责生成叶节点当chooseBestSplit()函数确定不再对数据进行切分时
# 将调用该regLeaf()函数来得到叶节点的模型在回归树中该模型其实就是目标变量的均值
def regLeaf(dataSet) :return mean(dataSet[:, -1])# 误差估计函数该函数在给定的数据上计算目标变量的平方误差这里直接调用均方差函数var
# 因为这里需要返回的是总方差所以要用均方差乘以数据集中样本的个数
def regErr(dataSet) :return var(dataSet[:, -1]) * shape(dataSet)[0]# dataSet: 数据集合
# leafType: 给出建立叶节点的函数
# errType: 误差计算函数
# ops: 包含树构建所需其他参数的元组
def createTree(dataSet, leafTyperegLeaf, errTyperegErr, ops(1,4)) :# 将数据集分成两个部分若满足停止条件chooseBestSplit将返回None和某类模型的值# 若构建的是回归树该模型是个常数。若是模型树其模型是一个线性方程。# 若不满足停止条件chooseBestSplit()将创建一个新的Python字典并将数据集分成两份# 在这两份数据集上将分别继续递归调用createTree()函数feat, val chooseBestSplit(dataSet, leafType, errType, ops)if feat None : return valretTree {}retTree[spInd] featretTree[spVal] vallSet, rSet binSplitDataSet(dataSet, feat, val)retTree[left] createTree(lSet, leafType, errType, ops)retTree[right] createTree(rSet, leafType, errType, ops)return retTree# 回归树的切分函数构建回归树的核心函数。目的找出数据的最佳二元切分方式。如果找不到
# 一个“好”的二元切分该函数返回None并同时调用createTree()方法来产生叶节点叶节点的
# 值也将返回None。
# 如果找到一个“好”的切分方式则返回特征编号和切分特征值。
# 最佳切分就是使得切分后能达到最低误差的切分。
def chooseBestSplit(dataSet, leafTyperegLeaf, errTyperegErr, ops(1,4)) :# tolS是容许的误差下降值# tolN是切分的最小样本数tolS ops[0]; tolN ops[1]# 如果剩余特征值的数目为1那么就不再切分而返回if len(set(dataSet[:, -1].T.tolist()[0])) 1 :return None, leafType(dataSet)# 当前数据集的大小m,n shape(dataSet)# 当前数据集的误差S errType(dataSet)bestS inf; bestIndex 0; bestValue 0for featIndex in range(n-1) :
# for splitVal in set(dataSet[:, featIndex]) :for splitVal in set(dataSet[:,featIndex].T.tolist()[0]):mat0, mat1 binSplitDataSet(dataSet, featIndex, splitVal)if (shape(mat0)[0] tolN) or (shape(mat1)[0] tolN) : continuenewS errType(mat0) errType(mat1)if newS bestS :bestIndex featIndexbestValue splitValbestS newS# 如果切分数据集后效果提升不够大那么就不应该进行切分操作而直接创建叶节点if (S - bestS) tolS :return None, leafType(dataSet)mat0, mat1 binSplitDataSet(dataSet, bestIndex, bestValue)# 检查切分后的子集大小如果某个子集的大小小于用户定义的参数tolN那么也不应切分。if (shape(mat0)[0] tolN) or (shape(mat1)[0] tolN) :return None, leafType(dataSet)# 如果前面的这些终止条件都不满足那么就返回切分特征和特征值。return bestIndex, bestValue
通过降低决策树的复杂度来避免过拟合的过程叫剪枝预剪枝和后剪枝的单个效果可能是不好的一般来说我们可以同时采用这两种剪枝方法。
模型树
理解模型树和回归树的区别就是回归树的叶节点是一个常数值而模型树的叶节点是分段线性函数分段线性模型就是我们对数据集的一部分数据以某个线性模型建模而另一份数据以另一个线性模型建模。
#模型树
# 主要功能将数据格式化成目标变量Y和自变量X。X、Y用于执行简单的线性规划。
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()类似当数据不需要切分时它负责生成叶节点的模型。
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, n1)))X[:, 1:n1] inDatreturn float(X*model)def isTree(obj): return (type(obj).__name__dict)
# 在给定树结构的情况下对于单个数据点该函数会给出一个预测值。
# modeEval是对叶节点进行预测的函数引用指定树的类型以便在叶节点上调用合适的模型。
# 此函数自顶向下遍历整棵树直到命中叶节点为止一旦到达叶节点它就会在输入数据上
# 调用modelEval()函数该函数的默认值为regTreeEval()
def treeForeCast(tree, inData, modelEvalregTreeEval) :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, modelEvalregTreeEval) :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, s5) # 绘制真实值reDraw.a.plot(reDraw.testDat, yHat, linewidth2.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()
# 创建画布
Label(root, textPlot Place Holder).grid(row0, columnspan3)Label(root, texttolN).grid(row1, column0)
tolNentry Entry(root)
tolNentry.grid(row1, column1)
tolNentry.insert(0, 10)
Label(root, texttolS).grid(row2, column0)
tolSentry Entry(root)
tolSentry.grid(row2, column1)
tolSentry.insert(0, 1.0)
# 点击“ReDraw”按钮后调用drawNewTree()函数
Button(root, textReDraw, commanddrawNewTree).grid(row1, column2, rowspan3)chkBtnVar IntVar()
chkBtn Checkbutton(root, textModel Tree, variablechkBtnVar)
chkBtn.grid(row3, column0, columnspan2)reDraw.f Figure(figsize(5,4), dpi100)
reDraw.canvas FigureCanvasTkAgg(reDraw.f, masterroot)
reDraw.canvas.show()
reDraw.canvas.get_tk_widget().grid(row0, columnspan3)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()