当前位置: 首页 >  技术分享 >  聊聊基于Alink库的决策树模型算法实现

聊聊基于Alink库的决策树模型算法实现

导读:示例代码及相关内容来源于《Alink权威指南(Java版)》.概述.决策树模型再现了人们做决策的过程,该过程由一系列的判断构成,后面的判断基于前面的判断结果,不断缩小范围,最终推出结果。.如下,基于决策树模型预测天气,是最常见的示例。天气的整个预测过程,就是不断地判断推测的过程。

示例代码及相关内容来源于《Alink权威指南(Java版)》

概述

决策树模型再现了人们做决策的过程,该过程由一系列的判断构成,后面的判断基于前面的判断结果,不断缩小范围,最终推出结果。
如下,基于决策树模型预测天气,是最常见的示例。天气的整个预测过程,就是不断地判断推测的过程。

特征分类

特征(Feature)是对事物某种特性的描述,是建立在原始数据之上的特定表示,它是一个可识别的属性。日常生活中的很多事物我们都可以用二维表格来表示(这就是为什么Excel这么通用的原因),我们收集到的数据同样也可以用二维表格表示,那么通常特征就对应这种表示中的某一列。对于一个通用的二维数据集,每个观测值由一行表示,每个特征由一列表示,对于每一个观测具有一个特定的值。下面就是用户基本属性表,其中每一列就是一个特征,其中年龄、身高、体重是数值的,是数值特征,数值特征也叫做连续特征,而性别是用文本描述的,并且只有男女两种取值,是离散特征。

连续特征

以用户属性数据为例,比如身高、年龄、体重等特征数据,可以看作是连续特征数据,因为其分布一般是连续且不均匀的数值数据。

离散数据

以用户属性数据为例,比如性别数据,只有两种取值,是分布均匀,分组清晰的文本数据。

决策树模型处理这两种数据的区别其实也就是需要考虑数据是否分组聚集,以及是否划分数据,如何划分数据。导致其数学形式的表述有差异。

决策树分类与算法

常见决策树算法

目前常用的决策树模型有三种,分别是

  • ID3
  • C4.5
  • CART

虽然这三种算法的区别以及实现初衷不尽相同,但其实可以都是基于三种不同类型的决策树模型来实现的。而这三种类型分别是:

  • GINI:基尼值,CART算法模型
  • INFOGAIN:信息增益,ID3算法模型
  • INFOGAINRATIO:信息增益率,C4.5算法模型

如上所示,不同的决策树算法对应着不同类型的决策树模型。

决策树分类

决策树分为两大类:回归树与分类树,其分别对应解决机器学习领域中的分类和回归问题。分类树预测分类标签值,回归树用于预测数值。
分类树在每次分枝时,会针对当前枝节点的样本,找出最优的分裂特征和分裂方式,从而得到若干新节点;继续分枝,直到所有样本都被分入类别唯一的叶节点。
回归树的建模也差不多,但分裂指标不同,回归树一般以均方差为分裂指标。

Alink实现决策树算法模型

实现概览

在Alink库中,已经封装好了决策树算法的相关细节,使得业务开发及其简单——简单的API调用即可。
实现Demo如下:

/**
 * 基于C45决策树算法进行模型训练,并输出模型
 * 1. 设置C45决策树模型参数
 * 1.1 设置特征列
 * 1.2 设置离散特征列
 * 1.3 设置标签列
 * 1.4 打印输出模型
 * */
static void c_2_5() throws Exception {
    MemSourceBatchOp source = new MemSourceBatchOp(
        new Row[] {
            Row.of("sunny", 85.0, 85.0, false, "no"),
            Row.of("sunny", 80.0, 90.0, true, "no"),
            Row.of("overcast", 83.0, 78.0, false, "yes"),
            Row.of("rainy", 70.0, 96.0, false, "yes"),
            Row.of("rainy", 68.0, 80.0, false, "yes"),
            Row.of("rainy", 65.0, 70.0, true, "no"),
            Row.of("overcast", 64.0, 65.0, true, "yes"),
            Row.of("sunny", 72.0, 95.0, false, "no"),
            Row.of("sunny", 69.0, 70.0, false, "yes"),
            Row.of("rainy", 75.0, 80.0, false, "yes"),
            Row.of("sunny", 75.0, 70.0, true, "yes"),
            Row.of("overcast", 72.0, 90.0, true, "yes"),
            Row.of("overcast", 81.0, 75.0, false, "yes"),
            Row.of("rainy", 71.0, 80.0, true, "no")
        },
        new String[] {"Outlook", "Temperature", "Humidity", "Windy", "Play"}
    );

    source.lazyPrint(-1);

    source
        .link(
            new C45TrainBatchOp()
                .setFeatureCols("Outlook", "Temperature", "Humidity", "Windy") // 设置特征列
                .setCategoricalCols("Outlook", "Windy")	// 设置离散特征
                .setLabelCol("Play")	// 设置标签列
                .lazyPrintModelInfo()
                .lazyCollectModelInfo(new Consumer <DecisionTreeModelInfo>() {
                    @Override
                    public void accept(DecisionTreeModelInfo decisionTreeModelInfo) {
                        try {
                            decisionTreeModelInfo.saveTreeAsImage(
                                DATA_DIR + "weather_tree_model.png", true);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                })
        );

    BatchOperator.execute();
}

最终生成一个决策树图

算子函数

C45TrainBatchOp

API说明
简单看看其构造函数

@NameCn("C45决策树分类训练")
@NameEn("C45 Decision Tree Training")
@EstimatorTrainerAnnotation(
    estimatorName = "com.alibaba.alink.pipeline.classification.C45"
)
public class C45TrainBatchOp extends BaseRandomForestTrainBatchOp<C45TrainBatchOp> implements C45TrainParams<C45TrainBatchOp>, WithModelInfoBatchOp<DecisionTreeModelInfo, C45TrainBatchOp, C45ModelInfoBatchOp> {
    private static final long serialVersionUID = -1894634246411633664L;

    public C45TrainBatchOp() {
        this((Params)null);
    }

    /**
    * 主要是这里,构造了决策树模型的类别为INFOGAINRATIO
    */
    public C45TrainBatchOp(Params parameter) {
        super(parameter);
        this.getParams().set(TreeUtil.TREE_TYPE, TreeType.INFOGAINRATIO);
        this.getParams().set(HasNumTreesDefaltAs10.NUM_TREES, 1);
        this.getParams().set(HasFeatureSubsamplingRatio.FEATURE_SUBSAMPLING_RATIO, 1.0D);
        this.getParams().set(HasSubsamplingRatio.SUBSAMPLING_RATIO, 1.0D);
    }

    public C45ModelInfoBatchOp getModelInfoBatchOp() {
        return (C45ModelInfoBatchOp)(new C45ModelInfoBatchOp(this.getParams())).linkFrom(new BatchOperator[]{this});
    }
}
内容
  • 《领域驱动设计》:从领域视角深入仓储(Repository)的设计和实现
    《领域驱动设计》:从领域视角深入
    2023-12-04
    一、前言 “.DDD设计的目标是关注领域模型而并非技术来创建更好的软件,假设开发人员构建了一个SQL,并将它传递给基础设
  • JVM调优篇:探索Java性能优化的必备种子面试题
    JVM调优篇:探索Java性能优
    2023-12-04
    JVM内存模型.首先面试官会询问你在进行JVM调优之前,是否了解JVM内存模型的基础知识。这是一个重要的入门问题。JVM
  • 游戏中模型动画的几种实现方式
    游戏中模型动画的几种实现方式
    2023-12-02
    游戏内动画的实现方式一般有这几种:.骨骼动画.顶点动画.材质动画.CPU蒙皮动画.骨骼动画.骨骼动画是一种基于骨骼系统的
  • ***性能优化和调整服务
    ***性能优化和调整服务
    2023-12-31
    ***性能优化和调整服务.***性能优化和调整服务是指针对服务器的硬件和软件进行调整和优化,以提高其运行效率和稳定性的服
  • 科技创新孵化器服务
    科技创新孵化器服务
    2023-12-16
    科技创新孵化器服务.科技创新孵化器是指为初创科技企业提供办公、技术、**和资金服务的机构,而科技创新孵化器服务则是指这些
  • ***迁移与升级解决方案
    ***迁移与升级解决方案
    2024-01-05
    ***迁移与升级解决方案.随着业务的不断扩大和发展,很多企业逐渐意识到原有的***已经不能满足日益增长的需求,因此需要进
  • 虚拟现实技术开发
    虚拟现实技术开发
    2024-01-15
    虚拟现实技术开发.虚拟现实技术已经成为了当今科技行业的热门话题,它的发展日益迅猛,给人们的生活和工作带来了巨大的变革。在
  • 全球电子元件市场趋势分析
    全球电子元件市场趋势分析
    2023-12-31
    全球电子元件市场趋势分析.近年来,全球电子元件市场呈现出不断增长的趋势。随着科技的不断发展和智能设备的普及,电子元件市场
  • 电子元件质量检测与认证服务
    电子元件质量检测与认证服务
    2024-01-05
    电子元件质量检测与认证服务.为什么需要电子元件质量检测与认证服务?.随着电子产业的不断发展,电子元件在各个生产领域都起着
  • ***虚拟化技术咨询服务
    ***虚拟化技术咨询服务
    2023-12-21
    ***虚拟化技术咨询服务.在当今数字化时代,***虚拟化技术越来越受到企业和个人用户的青睐。虚拟化技术通过将物理***划
  • 高性能电子元件**
    高性能电子元件**
    2024-01-10
    高性能电子元件**.随着科技的不断进步,电子行业的发展日新月异。高性能电子元件作为电子产品的关键组成部分,对于产品的性能
  • 定制化电子元件解决方案
    定制化电子元件解决方案
    2024-01-15
    定制化电子元件解决方案.在现代科技发展迅速的时代,电子元件的需求日益增加,同时对于定制化的需求也在不断提升。定制化电子元
  • ***安全加固与防护方案
    ***安全加固与防护方案
    2024-01-10
    ***安全加固与防护方案.随着互联网的快速发展,***安全问题日益凸显。一旦***遭受攻击,可能导致数据泄露、服务中断甚