单层决策树(decision stump)是一种简单的决策树,它仅仅是基于单个特征来做决策,由于这棵树只有一次分裂过程,因此它实际上仅仅是一个树桩。例如对下面一幅图进行分类:
这里的数据分别是(1,2.1),(2,1.1),(1.3,1),(1,1),(2,1)这里要将圈和框分开:
1、按照横坐标or纵坐标来划分,这里将横坐标视为特征一,纵坐标视为特征二(单决策树只能根据一个特征来做决策);
1.1 基于第一步,因此外层循环即为数据集特征的循环;
1.1.1 如果是按照第一个特征来划分类别,那么第一个特征点中存在节点,即树的左右分支,这个时候怎样判断是左还是右呢?
1.1.2 首先根据数据大小跟定一个阈值T,这里我们T=minx+INT*stup,即最小特征值(第一个坐标的最小值或者。。。。。)+(1,2,3,4,5.....)*步长,这个阈值随着整数值INT的改变而循环改变;大于阈值T的则为“rt”,反之则为“lt”;
1.1.3判断错误率,初始化一个5*1的列向量e,全部为1,如果预测结果和标签相同,则将初始化对应的值修改为0,最后再用一个权重向量D.T*e,这个值即为最后的错误率,如果这个错误率小于一定的阈值,即为最有的决策树。
1.1.4 这里要比较每个阈值T的结果是"rt"和"lt"的错误率,同时你还要判断大循环中第一个特征的错误率,或者第二个特征的错误率;
2、python代码如下:
def <span style="color:#3333ff;">stumpClassify</span>(dataMatrix,dimen,threshVal,threshIneq):#just classify the data retArray = ones((shape(dataMatrix)[0],1)) if threshIneq == 'lt': retArray[dataMatrix[:,dimen] <= threshVal] = -1.0 else: retArray[dataMatrix[:,dimen] > threshVal] = -1.0 return retArray这是子循环中判断一个特征值应该是"lt"还是"rt";
def buildStump(dataArr,classLabels,D):
#首先转化为矩阵形式,便于矩阵的计算 dataMatrix = mat(dataArr); labelMat = mat(classLabels).T m,n = shape(dataMatrix) numSteps = 10.0; bestStump = {}; bestClasEst = mat(zeros((m,1)))
minError = inf #初始值设为正无穷大 <span style="color:#3333ff;">for i in range(n):#特征的循环,第一个还是第二个特征,只能为单特征</span> rangeMin = dataMatrix[:,i].min(); rangeMax = dataMatrix[:,i].max(); stepSize = (rangeMax-rangeMin)/numSteps <span style="color:#6633ff;">for j in range(-1,int(numSteps)+1)</span>:#loop over all range in current dimension for inequal in ['lt', 'gt']: #go over less than and greater than <span style="color:#3333ff;">threshVal = (rangeMin + float(j) * stepSize)</span> <span style="color:#3333ff;">predictedVals = stumpClassify(dataMatrix,i,threshVal,inequal)</span>#call stump classify with i, j, lessThan errArr = mat(ones((m,1))) errArr[predictedVals == labelMat] = 0 weightedError = D.T*errArr #calc total error multiplied by D #print "split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError) if<span style="color:#3333ff;"> weightedError < minError:</span> minError = weightedError bestClasEst = predictedVals.copy() bestStump['dim'] = i bestStump['thresh'] = threshVal bestStump['ineq'] = inequal return bestStump,minError,bestClasEst3、输出结果:
即最好的决策树为按照第一个特征来划分全部为左分支,错误率为0.2,可以看到将一个分错了,正确的应该为(1,1,-1,-1,1)