实际生活中很多问题都是非线性的,不可能使用全局线性模型来拟合任何数据
一种可行的方法是将数据集切分成很多份易建模的数据,然后利用线性回归技术来建模.如果首次切分后仍然难以拟合线性模型就继续切分.在这种切分方式下,树结构和回归法就相当有用.
ID3的做法是每次选取当前最佳的特征来分割数据,并按照该特征的所有可能取值来切分,一旦按某特征切分后,该特征在之后的算法执行过程中将不会在起作用,所以有观点认为这种方式过于迅速,而且ID3算法还存在另一个问题,它不能直接处理连续型特征,只能事先将连续型特征转换成离散型,才能在ID3算法中使用,但这种转换过程会破坏连续型变量的内在性质. 而使用二元切分法则易于对树构建过程进行调整以处理连续型特征.
CART是十分著名且广泛记载的树构建算法,它使用二元切分来处理连续型变量.对CART稍作修改就可以处理回归问题.ID3使用香农嫡来度量集合的无组织程度.如果选用其他方法来代替香农嫡,就可以使用树构建算法来完成回归.
回归树与分类树的思路类似,但叶节点的数据类型不是离散型,而是连续型.
一,连续和离散型特征的树的构建
from numpy import *
def loadDataSet(filename):
dataMat = []
fr = open(filename)
for line in fr.readlines():
curLine = line.strip().split('\t')
fltLine = map(float,curLine) #map all elements to float()
dataMat.append(fltLine)
return dataMat
def binSplitDataSet(dataSet, feature, value):
mat0 = dataSet[nonzero(dataSet[:,feature]>value)[0],:][0]
mat1 = dataSet[nonzero(dataSet[:,feature]<=value)[0],:][0]
return mat0, mat1
def createTree(dataSet, leafType=regLeaf, errType=regErr, ops=(1,4)):
feat, val = chooseBestSplit(dataSet, leafType, errType, ops) #choose the best split
if feat==None: 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