Java 机器学习库Smile实战AdaBoost

Posted JeemyJohn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 机器学习库Smile实战AdaBoost相关的知识,希望对你有一定的参考价值。

1. AdaBoost算法简介

      Boost 算法系列的起源来自于PAC Learnability(PAC 可学习性)。这套理论主要研究的是什么时候一个问题是可被学习的,当然也会探讨针对可学习的问题的具体的学习算法。这套理论是由Valiant提出来的,也因此(还有其他贡献哈)他获得了2010年的图灵奖。下面是他的照片:



PAC 定义了学习算法的强弱:

       弱学习算法—识别错误率小于1/2(即准确率仅比随机猜测略高的学习算法)

       强学习算法—识别准确率很高并能在多项式时间内完成的学习算法

       同时 ,Valiant和 Kearns首次提出了 PAC学习模型中弱学习算法和强学习算法的等价性问题,即任意给定仅比随机猜测略好的弱学习算法 ,是否可以将其提升为强学习算法 ? 如果二者等价 ,那么只需找到一个比随机猜测略好的弱学习算法就可以将其提升为强学习算法 ,而不必寻找很难获得的强学习算法。 也就是这种猜测,让无数牛人去设计算法来验证PAC理论的正确性。

      不过很长一段时间都没有一个切实可行的办法来实现这个理想。细节决定成败,再好的理论也需要有效的算法来执行。终于功夫不负有心人, Schapire在1996年提出一个有效的算法真正实现了这个夙愿,它的名字叫AdaBoost。AdaBoost把多个不同的决策树用一种非随机的方式组合起来,表现出惊人的性能!第一,把决策树的准确率大大提高,可以与SVM媲美。第二,速度快,且基本不用调参数。第三,几乎不Overfitting。我估计当时Breiman和Friedman肯定高兴坏了,因为眼看着他们提出的CART正在被SVM比下去的时候,AdaBoost让决策树起死回生!Breiman情不自禁地在他的论文里赞扬AdaBoost是最好的现货方法(off-the-shelf,即“拿下了就可以用”的意思)。



下面是Adaboost 算法的实现思想:



接下来是Smile库中的AdaBoost算法的用法实战程序:

package Test;

import smile.classification.AdaBoost;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by zhanghuayan on 2017/1/17.
 */
public class AdaBoostTest 

    public static void main(String[] args) throws Exception 

        List<List<Double>> datas = new ArrayList<List<Double>>();
        List<Double> data = new ArrayList<Double>();
        List<Integer> labels = new ArrayList<Integer>();

        String line;
        List<String> lines;
        File file = new File("iris.txt");
        BufferedReader reader = new BufferedReader(new FileReader(file));
        while ((line = reader.readLine()) != null) 
            lines = Arrays.asList(line.trim().split("\\t"));
            for (int i = 0; i < lines.size() - 1; i++) 
                data.add(Double.parseDouble(lines.get(i)));
            
            labels.add(Integer.parseInt(lines.get(lines.size() - 1)));

            datas.add(data);
            data = new ArrayList<Double>();

        

        //转换label
        int[] label = new int[labels.size()];
        for (int i = 0; i < label.length; i++) 
            label[i] = labels.get(i);
        

        //转换属性
        int rows = datas.size();
        int cols = datas.get(0).size();
        double[][] srcData = new double[rows][cols];
        for (int i = 0; i < rows; i++) 
            for (int j = 0; j < cols; j++) 
                srcData[i][j] = datas.get(i).get(j);
            
        


        AdaBoost adaBoost = new AdaBoost(srcData, label, 4, 8);
        double right = 0;
        for (int i = 0; i < srcData.length; i++) 
            int tag = adaBoost.predict(srcData[i]);
            if (i % 50 == 0) System.out.println();
            System.out.print(tag + " ");
            if (tag == label[i]) 
                right += 1;
            
        
        right = right / srcData.length;
        System.out.println("Accrurate: " + right * 100 + "%");
    



数据集与Java 机器学习库Smile实战(一)SVM 中的iris数据集格式一致。下面是程序输出的结果:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 

Accrurate: 100.0%

当然这里的训练数据和测试数据使用的是同一数据,所以可能出现过拟合现象。因此现实训练的时候应采取例如交叉验证等技术手段调整参数。


2. 参数解释

              AdaBoost adaBoost = new AdaBoost(srcData, label, 4, 8);

第3个参数是子树的个数,第4个参数是每个子树最大叶子节点数。

训练好了之后就可以如下调用predict()方法:

                       int tag = adaBoost.predict(srcData[i]);



对机器学习,人工智能感兴趣的小伙伴,请关注我的公众号:

以上是关于Java 机器学习库Smile实战AdaBoost的主要内容,如果未能解决你的问题,请参考以下文章

机器学习day12 机器学习实战adaboost集成方法与重新进行疝马病的预测

《机器学习实战第7章:利用AdaBoost元算法提高分类性能》

机器学习实战之 第七章 集成方法(随机森林和 AdaBoost)

机器学习实战笔记-利用AdaBoost元算法提高分类性能

机器学习实战第7章——利用AdaBoost元算法提高分类性能

集成学习实战——Boosting(GBDT,Adaboost,XGBoost)