本文将构建两种树,一种回归树(regression tree),其每个节点包含单个值;第二种是模型树(model tree),其每个叶节点包含一个线性方程。 createTree()伪代码: 找到最佳的待切分特征: 如果该节点不能再分,将该节点存为叶节点 执行二元切分 在右子树调用createTree()方法 在左子树调用createTree()方法 from numpy import *
def loadDataSet(fileName): dataMat = [] fr = open(fileName) for line in fr.readlines(): curLine = line.strip().split('\t') fltLine = map(float,curLine) #将每行映射成浮点数 dataMat.append(fltLine) return dataMat
def binSplitDataSet(dataSet, feature, value): #dataSet是数据集合,feature是待切分的特征,value是该特征的某个值 mat0 = dataSet[nonzero(dataSet[:,feature] > value)[0],:][0] mat1 = dataSet[nonzero(dataSet[:,feature] <= value),:][0] return mat0,mat1
def regLeaf(dataSet):#returns the value used for each leaf return mean(dataSet[:,-1])
def regErr(dataSet): return var(dataSet[:,-1]) * shape(dataSet)[0]
def createTree(dataSet, leafType=regLeaf, errType=regErr, ops=(1,4)):#assume dataSet is NumPy Mat so we can array filtering feat, val = chooseBestSplit(dataSet, leafType, errType, ops)#choose the best split if feat == None: return val #if the splitting hit a stop condition return val retTree = {} retTree['spInd'] = feat retTree['spVal'] = val lSet, rSet = binSplitDataSet(dataSet, feat, val) retTree['left'] = createTree(lSet, leafType, errType, ops) retTree['right'] = createTree(rSet, leafType, errType, ops) return retTree 对上述代码构造假数据进行测试: import regTrees from numpy import* testMat = mat(eye(4)) #构造4行4列单位阵 print(testMat) print(testMat[:,1])#testMat矩阵中的第2列 mat0,mat1 = regTrees.binSplitDataSet(testMat,1,0.5) #调用binSplitDataSet函数切分该矩阵。把第二列数据中大于0.5的分为一类,小于等于0.5的分为第二类。 print(mat0) print(mat1) [[ 1. 0. 0. 0.] [ 0. 1. 0. 0.] [ 0. 0. 1. 0.] [ 0. 0. 0. 1.]] ****** [[ 0.] [ 1.] [ 0.] [ 0.]] ****** [[ 0. 1. 0. 0.]] ****** [[ 1. 0. 0. 0.] [ 0. 0. 1. 0.] [ 0. 0. 0. 1.]] 将CART算法用于回归: 回归树假设叶节点是常数值,这种策略认为数据中的复杂关系可以用树结构来概括。 chooseBestSplit(): 功能:给定某个误差计算方法,该函数会找到数据集熵最佳的二元切分方式。此外该函数还要确定什么时候停止切分,一旦停止切分会生成一个叶节点。所以该函数需要完成两个方面: 1.用最佳方式切分数据集 2.生成相应的叶节 |