adaboost代码实现

11 篇文章 0 订阅
9 篇文章 1 订阅

文章目录

from numpy import *

def loadSimpData():
    datMat = matrix([[1., 2.1],
                     [2., 1.1],
                     [1.3, 1.],
                     [1., 1.],
                     [2., 1.]])
    classLabels = [1.0, 1.0, -1.0, -1.0, 1.0]
    return datMat, classLabels



datMat, classLabels = loadSimpData()

#通过阈值比较对数据进行分类,参数分别为(数据集,dimen为第几列,threshVal为阈值,threshIneq为阈值变量(lt或gt,大于或者小于的一个符号))
def stumpClassify(dataMatrix, dimen, threshVal, threshIneq):
    retArray = ones((shape(dataMatrix)[0], 1))                      #返回类别,shape函数是numpy.core.fromnumeric中的函数,它的功能是查看矩阵或者数组的维数。
    # print(retArray)
    # [[1.]
    #  [1.]
    #  [1.]
    #  [1.]
    #  [1.]]
    #注:ones([5,1])是等价于ones((5,1))的,ones((shape(dataMatrix)[0], 1)) 等价于ones((5,1))
    # print(shape(dataMatrix))                                        #(5, 2)
    # print(shape(dataMatrix)[0])                                     #5

    if threshIneq == 'lt':
        retArray[dataMatrix[:, dimen] <= threshVal] = -1.0
        #这里是把matrix里面的第一列即:[1,2,1.3,1,2]中的每个元素与[1.2,1.2,1.2,1.2,12]里面的对应的每个元素比较大小(这里假设threshVal值为1.2),如果前者小于等于后者,则将[[1.],[1.],[1.],[1.],[1.]]中的对应的那个1改成-1
    else:
        retArray[dataMatrix[:, dimen] > threshVal] = -1.0
    return retArray
# #[[-1.]
#  [-1.]
#  [-1.]
#  [-1.]
#  [-1.]]retArray是类似于左边这样的
#dataMatrix[:,j]的用法
# d = np.array([[1, 2, 3, 4], [2, 3, 4, 5], [5, 6, 7, 8]])
# # print(d)
# # [[1 2 3 4]
# #  [2 3 4 5]
# #  [5 6 7 8]]
# d0 = d[:, 0]
# print(d0)
# # [1 2 5]  ;这是第0列
# e = d[:, 1]
# print(e)
# # [2 3 6]  ;这是第1列
#
# print("--------下面是f--------")
# f = d[:, 2]
# print(f)
# # [3 4 7]   ;这是第2列
# print("-------------")
# g = d[:, 3]
# print(g)
# [4 5 8]   ;这是第3列
# 总结:d[:,j],j是列的索引



#创建最佳决策树 参数分别为(数据集,类别,权值),这里的dataArr,classLabels分别就是上面加载数据函数返回的datMat,classLabels
#这个函数的作用是利用足够多的阈值不断的去测试,最后获取足够小的错误率,以及此时最小错误率所对应的原始数据的那一列,以及此时的阈值,还有预测值(它本质上就是一个分类器)
#
def buildStump(dataArr, classLabels, D):
    dataMatrix = mat(dataArr)                                                   #感觉没啥变化,dataArr本来就是矩阵
    labelMat = mat(classLabels).T
    m, n = shape(dataMatrix)  # 5,2
    numSteps = 10.0                                                               #步数
    bestStump = {}                                                                #最优决策树(弱分类器)
    bestClasEst = mat(zeros((m, 1)))                                              #这里m等于5,这里初始值是0([[0],[0],[0],[0],[0]]),最终是要变为[[-1],[1],[-1],[-1],[1]]
    minError = inf
    for i in range(n):                                                            #这里的n等于2,其实这里是遍历每一列;  这里是决策树取列
        rangeMin = dataMatrix[:, i].min()                                         #i为0时,取的是第一列的最小值;i为1时,取的是第二列的最小值;特征最小的值
        rangeMax = dataMatrix[:, i].max()                                         #i为0时,取的是第一列的最大值;i为1时,取的是第二列的最大值;特征最大的值
        stepSize = (rangeMax - rangeMin) / numSteps                               #这里求的是步长,每一列的最大值减去最小值除以步数
        for j in range(-1, int(numSteps) ):                                        #j一开始取-1,这里给了一个范围,通过范围来设定阈值,通过不同的阈值来获取不同的错误率,
                                                                                  #>>> range(1, 11)【这里默认步长为1】     # 从 1 开始到 11;[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
            for inequal in ['lt', 'gt']:
                threshVal = (rangeMin + float(j) * stepSize)                      #这里是利用一个简单的算法来确定阈值
                # print(threshVal)
                predictedVals = stumpClassify(dataMatrix, i, threshVal, inequal)  #这里的dataMatrix是数据集,i表示是第几列,threshVal表示的阈值,inequal表示的是符号
                                                                                  #predictedVals表示的是获取到预测的类别,这里得到的是多个预测值,下面就可以计算错误率了
                errArr = mat(ones((m, 1)))                                        #这里m等于5,这里是初始化错误率,下面判断哪个错误率是最小的
                # print(errArr)
                errArr[predictedVals == labelMat] = 0                             #当这里的预测值predictedVals等于真实值labelMat的时候,将errAr里面的对应值设为0(即判断对了的设置为0);这实际上是两个列表里面对应值的比较
                weightedError = D.T * errArr                                      #这个D.T是权值,这里其实计算的是错误率,
                # D.T * errArr = [[0.2] [0.2] [0.2] [0.2][0.2]] * [[0.] [0.] [1.][1.][0.]]
                # print(weightedError)
                if weightedError < minError:
                    minError = weightedError
                    bestClasEst = predictedVals.copy()
                    # print(bestClasEst)
                    # print("-------")
                    bestStump['dim'] = i                                           #这里是决策树了,得出最优的那个列的索引
                    bestStump['thresh'] = threshVal                                #得到最优的那个阈值
                    bestStump['ineq'] = inequal                                    #得到最优的那个符号,stumpClassify函数的最后一个参数,这里符号有两个,一个是Lt,一个是gt
    return bestStump, minError, bestClasEst                                        #这里返回的是最优的决策树,最优的误差(误差值最小),最优的预测值(分类器)【其本质上就是说分成这种分类的时候,其误差是最小的】
# ({'dim': 0, 'thresh': 1.3, 'ineq': 'lt'}, matrix([[0.2]]), array([[-1.],
#        [ 1.],
#        [-1.],
#        [-1.],
#        [ 1.]]))



D = mat(ones((5,1))/5)
# print(D)
# [[0.2]
#  [0.2]
#  [0.2]
#  [0.2]
#  [0.2]]
bestStump, minError, bestClasEst = buildStump(datMat, classLabels, D)
# print(buildStump(datMat,classLabels,D))


##adaboost决策树训练(迭代次数40)
def adaBoostTrainDS(dataArr, classLabels, numIt=40):
    weakClassArr = []                                       #这里面可以放多个分类器
    m = shape(dataArr)[0]
    # print(m)                                              #m 是 5
    # print("-----上面这是m-----")
    D = mat(ones((m, 1)) / m)                               #这里是在初始化权值
    aggClassEst = mat(zeros((m, 1)))                        #这里是话语权和分类器的乘积(这里是初始化为0了!),最终的分类器等于每个话语权与每个分类器的乘积之和
    for i in range(numIt):                                  #这里numIt等于40
        #获取分类器(最优决策树),错误率,预测类别
        bestStump, error, classEst = buildStump(dataArr, classLabels, D)
        alpha = float(0.5 * log((1.0 - error) / max(error, 1e-16)))                     #计算话语权,alpha = 1/2 *log)((1-error)/max(error,1e-16)),这里分母为max(error,1e-16)这么写的目的是不希望分母为0

        bestStump['alpha'] = alpha                                                      #把话语权添加到词典里面
        weakClassArr.append(bestStump)                                                  #词典添加到列表里面
        expon = multiply(-1 * alpha * mat(classLabels).T, classEst)                     #这里计算的是指数:expon=exp(-alpha_m * y_i * G_m(x_i));classLabels对应于公式里面的y_i(_符号表示i为下标)
                                                                                        #classEst表示的是分类的结果,是通过buildStump函数来或得的,对应于G_m(x_i)
        D = multiply(D, exp(expon))                                                     #这里是更新权值,W_m+1_i = W_mi/Z_m * exp(expon);W_m+1_i对应于左边的D;W_mi/Z_m对应于右边的D
        D = D / D.sum()                                                                 #这里是归一化操作;到这里更新完
        aggClassEst += alpha * classEst                                                 #更新完之后需要做的是构建分类器的线性组合,即f(x) = alpha_m * G_m(x)(注意:m取值为从1到)
        aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T, ones((m, 1)))     #print(multiply(False,2))            #0
                                                                                        #print(multiply(True,2))             #2
                                                                                        #这里sign(aggClassEst) != mat(classLabels).T这个条件成立的话,就为1,否则为0,其实这里是判断预测错误(正确)的个数
        errorRate = aggErrors.sum() / m                                                 #错误的个数/总数 就会得到错误率,这里循环到第三次的时候errorRate等于0了
        if errorRate == 0.0: break
    return weakClassArr                                                                 #最终的分类器
    #[{'dim': 0, 'thresh': 1.3, 'ineq': 'lt', 'alpha': 0.6931471805599453}, {'dim': 1, 'thresh': 1.0, 'ineq': 'lt', 'alpha': 0.9729550745276565}, {'dim': 0, 'thresh': 0.9, 'ineq': 'lt', 'alpha': 0.8958797346140273}]


weakClassArr = adaBoostTrainDS(datMat, classLabels, numIt=40)
# print(weakClassArr)



#测试分类器
def adaClassify(datToClass, classifierArr):                                                 #datToClass是测试集,classifierArr是分类器的集合
    dataMatrix = mat(datToClass)
    m = shape(dataMatrix)[0]                                                                #得到对应的形状
    aggClassEst = mat(zeros((m, 1)))                                                        #初始化话语权和分类器的乘积
    for i in range(len(classifierArr)):
        classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'],
                                 classifierArr[i]['ineq'])                                  #这里得到的是第i个分类器
        aggClassEst += classifierArr[i]['alpha'] * classEst                                 #这里是第i个分类器所对应的alpha乘以所对应的分类器,而后相乘得到最终的分类器
    return sign(aggClassEst)

print(adaClassify([1., 2.1], weakClassArr))         #1
print(adaClassify([1.3, 1.], weakClassArr))         #-1



# print(datMat,classLabels)
# stumpClassify(datMat, 0, 1.2, 'lt')
# [[1.]
#  [1.]
#  [1.]
#  [1.]
#  # [1.]]
### 回答1: 我不是很熟悉matlab,但我可以提供一些相关资源,可以帮助你找到adaboost代码实现方法:Mathworks网站上有一系列关于AdaBoost算法实现的教程,也可以在StackOverflow上搜索相关问题。 ### 回答2: AdaboostAdaBoost)是一种著名的集成学习算法,(Adaptive Boosting)即“自适应增强算法”。它能够将多个弱分类器组合起来,形成一个强分类器,从而提高分类的准确性。下面是一个用MATLAB实现Adaboost的简单示例代码。 ``` % 假设有m个样本,每个样本有n个特征 m = 1000; n = 10; % 生成随机样本数据 X = rand(m, n); Y = randi([0, 1], m, 1); % 初始化权重 w = ones(m, 1) / m; % 定义弱分类器的数量 T = 10; % 存储每个弱分类器的权重和阈值 alpha = zeros(T, 1); threshold = zeros(T, 1); weakClassifiers = cell(T, 1); for t = 1:T % 训练一个弱分类器 weakClassifier = trainWeakClassifier(X, Y, w); weakClassifiers{t} = weakClassifier; % 使用当前弱分类器进行预测 predictions = predictWeakClassifier(weakClassifier, X); % 计算分类误差率 errorRate = sum(w .* (predictions ~= Y)); % 计算当前弱分类器的权重 alpha(t) = 0.5 * log((1 - errorRate) / errorRate); % 更新样本权重 w = w .* exp(-alpha(t) .* Y .* predictions); w = w / sum(w); % 存储当前弱分类器的阈值 threshold(t) = weakClassifier.threshold; end % 定义一个新的样本用于测试 xTest = rand(1, n); % 预测新样本的类别 class = predict(xTest, weakClassifiers, alpha, threshold); function weakClassifier = trainWeakClassifier(X, Y, w) % 这里使用一个简单的弱分类器,比如决策树桩(decision stump) options = statset('UseParallel', true); % 并行计算加速运算 weakClassifier = fitctree(X, Y, 'Weights', w, 'SplitCriterion', 'deviance', 'MaxNumSplits', 1, 'Options', options); end function predictions = predictWeakClassifier(weakClassifier, X) predictions = predict(weakClassifier, X); end function class = predict(x, weakClassifiers, alpha, threshold) class = 0; for t = 1:length(weakClassifiers) if x(weakClassifiers{t}.PredictorNames) <= threshold(t) class = class + alpha(t); else class = class - alpha(t); end end class = sign(class); end ``` 这是一个简单的Adaboost实现示例,具体可以根据实际需求进行调整和改进。 ### 回答3: AdaBoost是一种可以用于二分类或多分类的机器学习算法,常用于人脸识别、图像识别等领域。 下面是使用MATLAB实现AdaBoost算法的简单示例代码: ```matlab % 加载数据集 load('data.mat'); % 初始化权重 N = size(X, 1); w = ones(N, 1) / N; % 初始化弱分类器和弱分类器权重 weakClassifiers = {}; alpha = []; for t = 1:10 % 选择最佳弱分类器 weakClassifier = selectBestWeakClassifier(X, y, w); % 计算误分类错误率 error = sum(w .* (weakClassifier(X) ~= y)); % 计算弱分类器权重 weakClassifierWeight = log((1 - error) / error) / 2; % 更新样本权重 w = w .* exp(-weakClassifierWeight * y .* weakClassifier(X)); w = w / sum(w); % 保存弱分类器和弱分类器权重 weakClassifiers{t} = weakClassifier; alpha(t) = weakClassifierWeight; end % 预测分类结果 predictions = sign(sum(cell2mat(cellfun(@(h, a) a * h(X), weakClassifiers, num2cell(alpha), 'UniformOutput', false)), 2)); % 计算准确率 accuracy = sum(predictions == y) / N; disp(['准确率:', num2str(accuracy)]); ``` 该代码中,数据集被加载,权重被初始化为相等的值,然后循环中每次迭代都选择一个最佳的弱分类器,计算误分类错误率和弱分类器权重,并更新样本权重。在循环中保存了所有的弱分类器和权重。最后,预测结果被计算出来,并且准确率被打印出来。 请注意,其中会用到自定义的`selectBestWeakClassifier`和弱分类器函数。这些函数需要根据具体问题进行实现。 这只是一个简单示例,实际应用中可能需要根据具体问题对AdaBoost算法进行调优和改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值