单层决策树python_基于单决策树的AdaBoost算法的python实现

importnumpy as npimportmatplotlib.pyplot as pltdefloadDataSet(fileName):"""读取数据集

:param fileName: 文件名称

:return: 以列表的形式返回数据集和数据标签"""

#获取特征数

numFeat = len(open(fileName).readline().split('\t'))#定义空列表用于保存特征

dataMat =[]#定义空列表用于保存标签

labelMat =[]#读取文件

fr =open(fileName)#按行读取

for line infr.readlines():#定义空列表用于保存每行的数据

lineArr =[]#将每行数据转为str,并按\t分割

curLine = line.strip().split('\t')#添加每行的数据

for i in range(numFeat-1):

lineArr.append(float(curLine[i]))#将每行的数据保存到lineArr

dataMat.append(lineArr)#将每行的数据存到dataMat

#添加标签

labelMat.append(float(curLine[-1]))returndataMat,labelMatdefstumpClassify(dataMatrix,dimen,threshVal,threshIneq):"""定义一个单决策树分类器

:param dataMatrix: 数据矩阵(数组格式)

:param dimen:dataMatrix的某一列

:param threshVal:阈值

:param threshIneq:切换不等式的控制参数

:return:"""

#定义一个(样本数,1)的1数组

retArray = np.ones((dataMatrix.shape[0],1))if threshIneq == 'lt':#当参数为'lt'时,阈值分类方式如下

retArray[dataMatrix[:,dimen] <= threshVal] = -1.0

else:

retArray[dataMatrix[:,dimen]> threshVal] = -1.0

returnretArraydefbuildStump(dataArr,classLabels,D):"""找到数据集上最佳的单决策树

:param dataArr: 数据集(列表)

:param classLabels: 分类标签

:param D: 参数D

:return:最优单决策树参数、最小识别错误率、最好的预测值"""

#将列表数据转化成数组格式

dataMatrix =np.mat(dataArr)#将标签数据转化成数据格式

labelMat =np.mat(classLabels).T#m为样本数,n为特征数

m,n =dataMatrix.shape# numSteps = 10.0

#构建一个空字典,用于存放给定权重向量D时

#所得到的最佳单层决策树参数

bestStump ={}#定义一个数组,用于存放预测结果

bestClasEst = np.mat(np.zeros((m,1)))#定义最小的错误为无穷大

minError =np.inf#对每个特征数进行遍历

for i inrange(n):#计算步长

rangeMin =dataMatrix[:,i].min()

rangeMax=dataMatrix[:,i].max()

stepSize= (rangeMax-rangeMin)/numSteps#根据步长计算阈值:切换阈值

for j in range(-1,int(numSteps)+1):#切换不等式

for inequal in ['lt', 'gt']:#计算阈值

threshVal = rangeMin + float(j) *stepSize#预测值

predictedVals =stumpClassify(dataMatrix,i,threshVal,inequal)#计算错误率

errArr = np.mat(np.ones((m,1)))

errArr[predictedVals== labelMat] =0

weightedError= D.T*errArr#找出最佳的决策树,即分类结果错误率最小的,

if weightedError

minError=weightedError

bestClasEst=predictedVals.copy()

bestStump['dim'] =i

bestStump['thresh'] =threshVal

bestStump['ineq'] =inequal#返回最优的单决策树参数

returnbestStump,minError,bestClasEstdef adaBoostTrainDS(dataArr,classLabels,numIt=40):""":param dataArr: 数据集

:param classLabels: 类别标签

:param numIt: 弱分类器数,默认定义40个

:return:"""

#定义列表用于保存弱分类器的参数

weakClassArr =[]#获取样本数

dataArr=np.mat(dataArr)

m=dataArr.shape[0]#初始化权重D

D = np.mat(np.ones((m,1))/m)#用于保存更新的权重值

aggClassEst = np.mat(np.zeros((m,1)))#训练每个弱分类器的参数

for i inrange(numIt):#获得第i弱分类器的参数、错误率

bestStump,error,classEst =buildStump(dataArr,classLabels,D)#计算第i个弱分类器的alpha值

alpha = float(0.5*np.log((1.0-error)/max(error,1e-16)))#保存alpha值

bestStump['alpha'] =alpha#保存第i弱分类器参数

weakClassArr.append(bestStump)#更新D

expon = np.multiply(-1*alpha*np.mat(classLabels).T,classEst)

D=np.multiply(D,np.exp(expon))

D= D/D.sum()#打印该分类器分类结果

print("Number"+str(i) +"of Errorrate :"+str(error))#alpha作为分类结果的权重,进行求和

aggClassEst += alpha*classEst#计算错误率

aggErrors = np.multiply(np.sign(aggClassEst) != np.mat(classLabels).T,np.ones((m,1)))

errorRate= aggErrors.sum()/m#打印错误率

print("total error:",errorRate)if errorRate == 0.0:break

returnweakClassArr,aggClassEstdefadaClassify(datToClass,classifierArr):"""AdaBoost分类器

:param datToClass: 数据集

:param classifierArr: 分类器参数

:return:"""

#输入数据

dataMatrix =np.mat(datToClass)#获取样本数

m =dataMatrix.shape[0]

aggClassEst= np.mat(np.zeros((m,1)))for i inrange(len(classifierArr)):#预测结果

classEst = stumpClassify(dataMatrix,classifierArr[i]['dim'],

classifierArr[i]['thresh'],

classifierArr[i]['ineq'])## alpha作为分类结果的权重,进行求和

aggClassEst += classifierArr[i]['alpha']*classEstreturnnp.sign(aggClassEst)if __name__=="__main__":#获取训练数据

dataMat, labelMat=loadDataSet('horseColicTraining2.txt')#训练弱分类器

weakClassArr,_=adaBoostTrainDS(dataMat,labelMat,numIt=50)#获取测试数据集

testMat,testlabel=loadDataSet('horseColicTest2.txt')#获取测试结果

predicted=adaClassify(testMat,weakClassArr)#计算测试结果正确率

errArr=np.mat(np.ones(predicted.shape))

RightRate=1-errArr[predicted!=np.mat(testlabel).T].sum()/predicted.shape[0]#打印结果

print("正确率:",1-errArr[predicted!=np.mat(testlabel).T].sum()/predicted.shape[0])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值