【机器学习】作业8

标签(空格分隔): 机器学习


AdaBoost简介及原理

Adaboost是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。
Adaboost的结构:最后的分类器YM是由数个弱分类器(weak classifier)组合而成的,相当于最后m个弱分类器来投票决定分类结果,而且每个弱分类器的“话语权”因子α大小不一样。

11

可以看到,U(1)是初始的权重向量,所有弱分类器的权重为1N,其中N是分类器总数;yn代表各个弱分类器;而T对应样例数目,共迭代训练T次;

数据集介绍

手写数字识别

1

读入txt文件,为一个手写数字处理成的矩阵,文件名为x_y.txt期中x为数字,y为编号

0~9每个数字大约有200个数据,取前150个为训练数据,后面为测试数据

读取数据

上次作业偷了个懒,取了去年的测试结果

今年看了看以前的代码,修改load_Data()函数

虽然依然不是很优雅,不过很easy的划分出了训练数据和测试数据

def load_Data():
    hwLabels = []
    goldLabels = []
    trainingFileList = listdir('data/HandWritingDigit/')
    m = len(trainingFileList)
    trainingMat = zeros((1500, 1024))
    testMat = zeros((m - 1500, 1024))
    i = 0; j = 0
    for fileNameStr in trainingFileList:
        fileStr = fileNameStr.split('.')[0]
        classNumStr = int(fileStr.split('_')[0])
        classNumid = int(fileStr.split('_')[1])
        if classNumid < 150:
            hwLabels.append(classNumStr)
            trainingMat[i, :] = img2vect('data/HandWritingDigit/%s' % fileNameStr)
            i += 1
        else:
            goldLabels.append(classNumStr)
            testMat[j, :] = img2vect('data/HandWritingDigit/%s' % fileNameStr)
            j += 1
    return trainingMat, hwLabels, testMat, goldLabels

Adaboost in SKlearn

上一次作业中,使用随机森林最终达到的效果是

error: 13/434, acc = 97.00%

不过这次,还没有调参,决策树的各种参数,需要调,adaboost也需要调

def handwritingClassTest(dep):
    trainingMat, hwLabels, testMat, goldLabels = load_Data()
    mTest = len(testMat)

    #clf = RandomForestClassifier(n_estimators=100, max_depth=None, min_samples_split=2, random_state=0, max_features=21)
    clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth=dep, min_samples_split=10, min_samples_leaf=50),
                         algorithm="SAMME",
                         n_estimators=200, learning_rate=0.8)
    clf.fit(trainingMat, hwLabels)
    classifierResult = clf.predict(testMat)

    err_cnt = 0.0
    for i in range(mTest):
        if (classifierResult[i]) != goldLabels[i]:
            err_cnt += 1.0

    acc = 1 - (err_cnt/float(mTest))
    st = 'error: %d/%d, acc = %2.2f%%' % (err_cnt,mTest,acc*100)
    print(st)

关于决策树深度:

    for dep in range(15):
        print('dep = ' + str(dep+1))
        handwritingClassTest(dep+1)

运行结果

dep = 1 error: 56/434, acc = 87.10%
dep = 2 error: 32/434, acc = 92.63%
dep = 3 error: 24/434, acc = 94.47%
dep = 4 error: 18/434, acc = 95.85%
dep = 5 error: 15/434, acc = 96.54%
dep = 6 error: 10/434, acc = 97.70%
dep = 7 error: 12/434, acc = 97.24%
dep = 8 error: 13/434, acc = 97.00%
dep = 9 error: 13/434, acc = 97.00%
dep = 10 error: 15/434, acc = 96.54%
dep = 11 error: 15/434, acc = 96.54%

掐断了程序,我们大概已经得到想要的结果了,dep=6

其他参数同理,使用for循环来枚举

error: 10/434, acc = 97.70%

相对于随机森林97.00%,略微进步了一点

参考文献

  1. Adaboost 算法的原理与推导
  2. python机器学习库scikit-learn简明教程之:AdaBoost算法
  3. 3.
原文地址:https://www.cnblogs.com/cww97/p/12349325.html