iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >教你用c++从头开始实现决策树
  • 796
分享到

教你用c++从头开始实现决策树

2024-04-02 19:04:59 796人浏览 八月长安
摘要

python已经成为数据科学的语言之王。大多数新的数据科学家和程序员继续学习Python作为他们的第一门语言。这是有充分理由的;Python具有较浅的学习曲线、强大的社区和丰富的数据

python已经成为数据科学的语言之王。大多数新的数据科学家和程序员继续学习Python作为他们的第一门语言。这是有充分理由的;Python具有较浅的学习曲线、强大的社区和丰富的数据科学库生态系统。

我用Python开始了我的数据科学之旅,它仍然是我解决数据科学问题最常用的工具。我很想更好地理解Python从您那里抽象出了什么,以及用性能更高的语言编写更快代码的成本与好处。

为了有代表性地介绍c++,我需要一个代表性的应用程序,c++将是一个合适的选择。从头实现一个分类决策树分类器似乎是一个适当的挑战。这已经被证明是一个测试但有益的学习旅程,我想分享一些我在这个过程中的主要经验。

关键经验:

  • c++很少提供代码提示或保护
  • 尽早做出好的架构决策
  • 从长远来看,编写测试将为您节省时间
  • 语言的在线社区非常有价值
  • 可移植性是一个重要的考虑因素

在Python中,你可以做很多事情。您可以创建一个变量,随心所欲地改变它的类型,然后不必担心如何处理它。这能让你在执行过程中改变想法。非常适合动态迭代原型设计。

在c++中,您必须预先决定您希望您的变量是什么类型。您还必须预先决定希望函数返回的类型。如果您声明错误,例如试图从一个已经声明为返回整数的函数返回一个字符串,那么您的进程将会停止。在这种情况下,编译器将阻止您编译程序,通常带有一个令人费解的错误消息。令人沮丧的是,编译器是您的朋友,它会在这个问题导致后续问题之前预先提醒您。在Python中,只有在太晚的时候才发现问题是很常见的,比如在代码投入生产之后。

在上面的示例中,编译器捕获定义为返回试图返回字符串的整数的函数。

也有编译器不支持您的情况。访问一个被认为存储在特定内存地址的变量时,可能只收到一个垃圾值,因为该变量已经被删除了。在这里,您通常不会在编译时收到错误,而且很容易在代码中留下错误,而您对此却浑然不觉。

在上面的示例中,即使我们试图访问已被删除的变量的内存地址的值,编译也不会给出错误。

尽早做出好的架构决策

在Python中,很容易在尝试解决问题的早期阶段就开始编写解决方案。由于c++的灵活性和较慢的开发速度,这种方法在使用c++时不能很好地工作。

在这个项目中,我最初使用的是我的python方法,即只编写代码,而不绘制端到端解决方案。最后,我坐下来,想出了一个解决这个问题的总体架构。

下面列出了在实现决策树分类器中开发的关键对象。它们包括一个node类和一个Tree类,以及它们相关的属性和方法,并且大部分可以在编写任何代码之前定义:


Node
- Node constructor
- Node destuctor
- Attributes
   - children nodes
   - data
   - best split feature chosen
   - best split cateGory chosen
- Methods
   - giniImpurity() - metric for scoring quality of split
   - bestSplit() - best split feature and category

Tree
- Tree constructor
- Tree destructor
- Attributes
   - root node of tree
- Methods
   - traverse() - traverse nodes of tree
   - fit() - fit tree to dataset
   - predict() - make predictions classes with unseen data
   - CSVReader() - read a csv

决策树项目的核心文件(不包括测试文件)如下所示,以供参考。


. 
├── CMakeLists.txt 
├── CSVReader.cpp 
├── CSVReader.hpp 
├── DecisionTree.cpp 
├── DecisionTree.hpp 
├── Main.cpp 
├── Node.cpp 
├── Node.hpp 
└── README.md

一旦该体系结构就位,解决方案自然就会遵循。对类及其成员函数(类和函数参数以及返回的对象)的接口进行前瞻性设计也可以使事情变得更加容易。

从长远来看,编写测试将为您节省时间

由于c++缺乏安全性,所以测试代码的每个部分是否都成功地完成了预期的功能是至关重要的。用于c++的谷歌Test测试框架很适合这个项目,它使用CMake构建。

以可测试的方式编写代码可以更容易地识别和隔离bug。方法是为实现的类编写静态定义的成员函数。静态定义的成员函数可以在没有父类实例化的情况下独立执行。这使得为完成决策树业务逻辑的一个方面的每一个功能编写特定的、独立的测试用例成为可能。

上面显示了在终端中通过测试的谷歌Test的输出。

语言的在线社区非常有价值

python开发人员有一个开发人员社区,使用像Stack Overflow和博客这样的工具为集体知识做出贡献。此资源是Python数据科学的命脉。c++没有等价的社区。在谷歌上搜索开发c++代码时遇到的许多问题和错误消息,往往会得到没有帮助的结果。一种语言的社区价值很大。

从上面我们可以看到,现在每个月被回答的与Python相关的问题比c++多4倍。在这里查看这些统计数据的当前状态。

可移植性是一个重要的考虑因素

在Python中,你可以确信任何安装了Python解释器的系统都能够执行你的Python程序。而在c++中,你就没有这种特权了。由于c++是一种编译语言,在运行程序之前必须先编译程序,而且必须针对要运行程序的宿主的体系结构来编译它。

当尝试使用GitHub Actions远程测试代码时,这成为一个重要的问题。由于主机是不同的操作系统和架构,因此需要在虚拟机上测试代码之前编译代码。这是部署代码时需要管理的额外开销。

总结

学习像c++这样的低级语言可以让你接触到许多快速程序所需的核心概念,如内存管理、数据结构和编译语言。它让人们意识到Python中预先实现的数据结构,比如pandas DataFrames,将拥有处理内存管理的系统,这些系统必须做出一系列假设,因此有局限性。

在实践中,不太可能有很多数据科学家会使用c++来解决实验性的数据科学问题,但是Python不再是最好的工具,例如编写快速的数据解析器或实现昂贵的算法。即使在这种情况下,我也将探索现代低级语言,如Go-lang和Rust,而不是c++。c++的语法让人感觉很冗长,而且它缺乏许多可以从这些现代语言中获得的安全特性。

您可以在这里从头看到c++决策树分类器的完整源代码。您还可以在这里找到一个示例jupiter notebook,它直接从Python调用已实现的决策树分类器,并在Titanic数据集上训练决策树。https://github.com/hlamotte/decision-tree

到此这篇关于教你用c++从头开始实现决策树的文章就介绍到这了,更多相关c++实现决策树内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 教你用c++从头开始实现决策树

本文链接: https://www.lsjlt.com/news/126754.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • c语言怎么计算字符串长度
    在C语言中,可以使用内置的strlen()函数来计算字符串的长度。该函数位于string.h头文件中。以下是一个示例代码: #inc...
    99+
    2024-05-15
    c语言
  • c语言怎么判断三个数的大小
    可以通过比较三个数之间的大小关系来判断它们的大小。以下是一个示例代码: #include <stdio.h> int ...
    99+
    2024-05-15
    c语言
  • c++排序函数sort怎么使用
    在C++中,使用sort函数对容器中的元素进行排序,可以按照默认的升序排列,也可以自定义排序规则。 下面是一个简单的例子,对一个ve...
    99+
    2024-05-15
    c++
  • c++中string的compare函数怎么使用
    在C++中,可以使用string的compare函数来比较两个string对象的大小。该函数的原型如下: int compare(c...
    99+
    2024-05-15
    c++
  • c++中string的compare函数有什么用
    c++中string的compare函数用于比较两个字符串的大小关系。该函数返回一个整数值,表示两个字符串的比较结果。 具体来说,如...
    99+
    2024-05-15
    c++
  • c++中print函数的功能有哪些
    在C++中,通常使用std::cout来进行输出操作,而不是使用print函数。std::cout是C++标准库中的一个输出流对象,...
    99+
    2024-05-15
    c++
  • c语言数据结构怎么使用
    在C语言中,数据结构可以通过定义结构体来实现。以下是一些常见的数据结构的使用方法示例: 链表: #include <std...
    99+
    2024-05-15
    c语言
  • c++中print函数的用法是什么
    在C++中没有内置的print函数,但可以使用cout来输出内容到控制台。cout是C++标准库中的一个输出流对象,可以使用<...
    99+
    2024-05-15
    c++
  • c++中concept的用法是什么
    在C++20中,Concept是一种新的语言特性,用于定义类型要求和约束。Concept可以被用来约束函数模板、类模板和普通函数的参...
    99+
    2024-05-15
    c++
  • c++中concept的作用是什么
    在C++中,concept的作用是定义一种通用的约束,用于限制模板参数的类型范围。通过使用concept,可以在编译时对模板参数进行...
    99+
    2024-05-15
    c++
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作