家谱树java_树家族算法梳理

本文介绍了决策树模型的历史和主要算法,包括ID3、C4.5和CART。ID3作为首个决策树算法,有其局限性,如处理离散特征。C4.5对ID3进行了优化,处理连续值和缺失值,同时进行了剪枝。CART则扩展了树模型的应用,既支持分类也支持回归。集成学习中的随机森林和GBDT在决策树基础上提升了模型效果,XGBoost和LightGBM是针对海量数据优化的GBDT实现。
摘要由CSDN通过智能技术生成

树家族第一篇

树家谱

c19c4d8784a18119af7812ab78743ce4.png

决策树

决策树模型可以看做是if-else指令集合,通过对特征空间的划分来完成分类或者回归任务。

0e77cc3910e2684ba4e7a7dd4f8acc47.png

如上图,是树模型的经典案例。根据天气、温度和风强度决策是否打网球。其过程就像是做了一系列的”if-else"判断。即基于数据,让算法学习这些’if-else‘规则。

树模型家族简史

单棵树

单棵树三大知名算法:ID3、C4.5、CART

1975年,由J.R.Quinlan提出ID3算法,这是首个知名的决策树算法。相对于耗时的人工规则,ID3用极其简单优美的方式从数据中学习出这些【if-else】规则。

虽然ID3很简单,但是还是有很多限制。

1)特征必须是离散,无法处理连续型特征

2)特征选择Gain公式偏向取值多的特征

1993年,Quinlan对其进行优化,并提出C4.5算法。

1984年CART(分类回归)算法提出。与C4.5相比,他有两个重要优点:

1)CART是二叉树(C4.5是多叉树),形式上更加优美简洁,而且不用考虑连续特征离散化问题;

2)CART既能处理分类,又可以处理回归问题。(C4.5只支持分类)。

正因为这些优点GBDT才选择用CART为基础。

总的来说,ID3是决策问题从人工规则到机器学习规则的过度,但是问题较多;C4.5是对ID3的优化;CART扩展了C4.5解决问题的范畴,从分类到回归。

多棵树

树模型和集成学习结合,发展成为‘森林’,极大提升了模型效果。最典型的森林算法分为bagging和boosting两类。

bagging算法簇的RF,和boosting算法簇的GBDT则为佼佼代表。在分类、回归和排序应用中大展前途。

2014年,陈天奇博士团队开源了XGBOOST,惊艳四座。XGBoost是为了让GBDT适应海量数据,从而做出的工程优化实践。

2017年,微软提出LightGBM,微软任务XGB在处理海量数据的工作上做的还不够好,LightGBM更加快速的实现的GBDT。

总的来说,集成学习是在CART基础上让树模型能力的一次飞跃;而GBDT是树模型与集成学习结合的佼佼者;XGBoost和LightGBM则是海量数据背景下对GBDT的优化。

ID3、C4.5和CART

本篇主要内容是ID3、C4.5和CART。再来回顾一下:

为了自动拟合数据,产出决策规则,J.R.Quinlan提出ID3算法,他简单优美,可以很好地达到预期目的。但是也有它的问题:只适用于离散特征,不考虑剪枝有严重的过拟合风险等。

为了让ID3更加强大,针对其弊端J.R.Quinlan做了优化改进,提出了C4.5算法。改进了ID3特征选择方法,增加了处理连续值和缺失值的功能;为了增加泛化能力,C4.5还进行了有效的剪枝策略。C4.5是一个相对成熟通用的算法,至今还有使用。

C4.5只能处理分类任务,导致通用性暴露短板。于是CART算法就来了,CART将树模型扩展为既能进行分类,又能解决回归问题。这使得CART成为后来更多高效模型的基础。

ID3

ID3提出背景

ID3提出之前,对于分类决策需求,一般是人工规则或者简单的概念学习(Find-S算法,候选-消除算法等),其中最大的问题是对于噪声过于敏感,容错性差。而ID3最大的优点就是基于统计信息做出决策,能有效的对抗噪声,提升容错性。

ID3算法

伪代码:

b73f5327098e0d10e2f3dc8b59c9e87a.png

最优特征选择

ID3的缺点

下面是一个简单的家族家谱数据结构的 Java 代码示例: ``` class FamilyTreeNode { String name; List<FamilyTreeNode> children; public FamilyTreeNode(String name) { this.name = name; children = new ArrayList<>(); } public void addChild(FamilyTreeNode child) { children.add(child); } public List<FamilyTreeNode> getChildren() { return children; } public String getName() { return name; } } class FamilyTree { FamilyTreeNode root; public FamilyTree(String name) { root = new FamilyTreeNode(name); } public void addChild(String parentName, String childName) { FamilyTreeNode parent = findNode(root, parentName); parent.addChild(new FamilyTreeNode(childName)); } private FamilyTreeNode findNode(FamilyTreeNode node, String name) { if (node.getName().equals(name)) { return node; } for (FamilyTreeNode child : node.getChildren()) { FamilyTreeNode found = findNode(child, name); if (found != null) { return found; } } return null; } } ``` 在上面的代码中,`FamilyTreeNode` 类表示家族家谱的节点,每个节点包括一个名称和一个子节点列表。`FamilyTree` 类表示整个家族家谱,它包含一个根节点,并提供添加子节点的方法 `addChild`。`findNode` 方法用于在中查找一个节点,根据节点名称递归遍历,直到找到对应的节点。 使用示例: ``` FamilyTree tree = new FamilyTree("Tom"); tree.addChild("Tom", "Jack"); tree.addChild("Tom", "Lucy"); tree.addChild("Jack", "Adam"); tree.addChild("Jack", "Bob"); ``` 上面的代码创建了一个家族家谱,始祖为 Tom,Tom 的子节点是 Jack 和 Lucy,Jack 的子节点是 Adam 和 Bob。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值