机器学习_AdaBoost(机器学习实战)

1、一般流程

1)收集数据:可以使用任意方法
2)准备数据:依赖于所使用 的弱分类器类型,本次使用单层决策树,这种分类器可以处理任何数据类型。当然也可以使用
任意分类器作为弱分类器。作为若分类器,简单分类器的效果更好。
3)分析数据:任何方法
4)训练算法: AdaBoost的大部分时间都用在训练上,分类器将多次在同一数据集上训练弱分类器
5)测试算法:计算分类器的错误率
6)使用算法:同SVM一样,AdaBoost预测两个类别中的一个。如果想把它应用到多个分类,需要修正


2、AdaBoost优缺点

优点:泛化错误率低,易于编码,可以应用在大部分分类器上, 无参数调整
缺点:对离群点敏感
适用数据类型: 数值型和标称型数据


该算法在之前文章中实现过一次,是针对《统计学习方法》的一个例题实现的,更加的贴近数学公式,详见Python__Adaboost简单实现

3、算法实现

算法的核心是: 是基于错误率迭代,增加错误分类的权重,加重优分类器的权重。

算法总共分为三块:
1、弱分类器构建
2、弱分类器分类及错误率计算
3、AdaBoost算法迭代实现分类

出来结果为各个弱分类器,最终分类还需要构建一个整合分类器进行最后分类输出

1、弱分类器构建

import numpy as np
import copy 

def stumpClassify(dataMatrix, dimen, threshVal, threshIneq):
    # 通过阈值对 数据进行比较
    retArray = np.ones((np.shape(dataMatrix)[0], 1))
    if threshIneq == 'lt': #如果小于 little than 
        retArray[dataMatrix[:, dimen] <= threshVal] = -1.0
    else:
        retArray[dataMatrix[:, dimen] > threshVal] = -1.0
    return retArray

2、弱分类器分类及错误率计算


def buildStump(dataArr, classLabels, D):
    # 单层决策树,遍历每个特征找到错误率最小的特征
    data_in = np.mat(dataArr)
    label = np.mat(classLabels).T
    m, n = np.shape(data_in)
    numstep = 10.0
    beststump = {}  
    best_clasest = np.mat(np.zeros((m, 1))) # 变成列
    minErro = np.inf 
    for i in range(n): # 列(特征)遍历 
        col_min, col_max = data_in[:, i].min(), data_in[:, i].max()
        step_size = (col_max - col_min) / numstep
        for j in range(-1, np.int(numstep) + 1): # 阈值区间 
            for compare in ['lt', 'gt']:
                threshVal = (col_min + np.float(j) * step_size) # 阈值
                predictedVals = stumpClassify(data_in, i, threshVal, compare)
                errArr = np.mat(np.ones((m, 1)))
                errArr[predictedVals == label] = 0
                weight_Error = D.T * errArr ## 更新错误的权重 adaboost中
                #print('特征 %d, 阈值 %.2f, 阈值上下: %s, 错误率: %.3f' %(i, threshVal, compare, weight_Error))
                if weight_Error < minErro:
                    minErro = weight_Error
                    best_clasest = copy.deepcopy(predictedVals)
                    beststump['dim'] = i 
                    beststump['thresh'] = threshVal
                    beststump['ineq'] = compare
    return beststump, minErro, best_clasest

3、AdaBoost算法迭代实现分类

def Adaboost_DC(dataArr, classLabels, numIt = 40):
    # 弱分类器集
    week_class_arr = []
    # 初始分布
    m = np.shape(dataArr)[0]
    D = np.mat(np.ones((m, 1)) / m)
    # 初始错误
    aggClassEst = np.mat(np.zeros((m, 1)))
    for i in range(numIt):
        best_stump, error, ClassEst =  buildStump(dataArr, classLabels, D)
        # 分类器权重
        alpha = np.float(0.5 *np.log((1 - error) / max(error, 1e-16) ))
        best_stump['alpha'] = alpha 
        week_class_arr.append(best_stump)
        # 下一次的分布
        ## 增大错误样本权重
        expon = np.multiply(-1 * alpha * np.mat(classLabels).T, ClassEst) # 对应位置相乘
        D = np.multiply(D, np.exp(expon))
        aggClassEst += alpha * ClassEst
        #print('叠加分类结果',aggClassEst.T)
        aggErrors = (np.sign(aggClassEst) != np.mat(classLabels).T )* 1
        errorRate = aggErrors.sum() / m 
        print('总错误率:' , errorRate,'\n')
        if errorRate == 0.0 :
            break
    return week_class_arr, aggClassEst

4、输出分类结果

def Ada_classify(datToClass, classifierArr):
    # 分类函数
    data_in = np.mat(datToClass)
    m = np.shape(data_in)[0]
    aggClassEst = np.mat(np.zeros((m, 1)))
    for i in range(len(classifierArr)):
        classEst = stumpClassify(data_in, classifierArr[i]['dim'], classifierArr[i]['thresh'], classifierArr[i]['ineq'])
        aggClassEst += classifierArr[i]['alpha'] * classEst
        #print(aggClassEst)
    return np.sign(aggClassEst)

4、算法应用

由于算法原因需要指定的数据结构,所以需要函数得到指定的数据结构

import os
import pandas as pd

def get_data(fil):
    data_all = pd.read_csv(fil, sep = '\t', header = None )
    m = data_all.shape[1]
    data_out = np.array(data_all.iloc[:, list(range(0, m - 1))])
    return data_out, list(data_all.iloc[:, -1])

预测与简单评估

fil_root = 'C:/Users/---/Desktop/l/'
file_name = 'horseColicTraining2.txt'
fil = os.path.join(fil_root, file_name) 
file_name1 = 'horseColicTest2.txt'
fil1 = os.path.join(fil_root, file_name1)

if __name__ == '__main__':
    # train
    data, label = get_data(fil)
    classifierArr,aggClassEst = Adaboost_DC(data, label, 100)
    # 测试
    data_t, label_t = get_data(fil1)
    prd  = Ada_classify(data_t, classifierArr)
    print("错误个数:",sum(prd != np.mat(label_t).T),'\n错误率:', sum(prd != np.mat(label_t).T)/len(prd))

5、ROC曲线绘制

import matplotlib.pyplot as plt 
plt.style.use('ggplot')
def plotROC(predStrengths, classLabels):
    cur = (1.0, 1.0)
    y_sum = 0
    pos_sum = sum(np.array(classLabels) == 1)
    y_sp = 1 / pos_sum
    x_sp = 1 / (len(classLabels) - pos_sum)
    sort_index = np.array(predStrengths).flatten().argsort()
    ax = plt.subplot(111)
    for i in sort_index.tolist():
        if classLabels[i] == 1:
            del_x = 0
            del_y = y_sp
        else:
            del_x = x_sp
            del_y = 0
            y_sum += cur[1]
        ax.plot([cur[0], cur[0] - del_x], [cur[1], cur[1] - del_y], c = 'b')
        cur = (cur[0] - del_x, cur[1] - del_y)
    ax.plot([0, 1], [0, 1], 'b--')
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate') 
    plt.title('ROC curve: The AUC is %.2f'%(y_sum * x_sp)) # 积分
    ax.axis([-0.01, 1.01, 0, 1.01])
    plt.show()

plotROC(aggClassEst, label)


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值