溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用c++從頭開始實(shí)現(xiàn)決策樹

發(fā)布時(shí)間:2021-05-25 13:59:30 來(lái)源:億速云 閱讀:168 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下如何使用c++從頭開始實(shí)現(xiàn)決策樹,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

Python已經(jīng)成為數(shù)據(jù)科學(xué)的語(yǔ)言之王。大多數(shù)新的數(shù)據(jù)科學(xué)家和程序員繼續(xù)學(xué)習(xí)Python作為他們的第一門語(yǔ)言。這是有充分理由的;Python具有較淺的學(xué)習(xí)曲線、強(qiáng)大的社區(qū)和豐富的數(shù)據(jù)科學(xué)庫(kù)生態(tài)系統(tǒng)。

我用Python開始了我的數(shù)據(jù)科學(xué)之旅,它仍然是我解決數(shù)據(jù)科學(xué)問(wèn)題最常用的工具。我很想更好地理解Python從您那里抽象出了什么,以及用性能更高的語(yǔ)言編寫更快代碼的成本與好處。

為了有代表性地介紹c++,我需要一個(gè)代表性的應(yīng)用程序,c++將是一個(gè)合適的選擇。從頭實(shí)現(xiàn)一個(gè)分類決策樹分類器似乎是一個(gè)適當(dāng)?shù)奶魬?zhàn)。這已經(jīng)被證明是一個(gè)測(cè)試但有益的學(xué)習(xí)旅程,我想分享一些我在這個(gè)過(guò)程中的主要經(jīng)驗(yàn)。

關(guān)鍵經(jīng)驗(yàn):

  • c++很少提供代碼提示或保護(hù)

  • 盡早做出好的架構(gòu)決策

  • 從長(zhǎng)遠(yuǎn)來(lái)看,編寫測(cè)試將為您節(jié)省時(shí)間

  • 語(yǔ)言的在線社區(qū)非常有價(jià)值

  • 可移植性是一個(gè)重要的考慮因素

在Python中,你可以做很多事情。您可以創(chuàng)建一個(gè)變量,隨心所欲地改變它的類型,然后不必?fù)?dān)心如何處理它。這能讓你在執(zhí)行過(guò)程中改變想法。非常適合動(dòng)態(tài)迭代原型設(shè)計(jì)。

在c++中,您必須預(yù)先決定您希望您的變量是什么類型。您還必須預(yù)先決定希望函數(shù)返回的類型。如果您聲明錯(cuò)誤,例如試圖從一個(gè)已經(jīng)聲明為返回整數(shù)的函數(shù)返回一個(gè)字符串,那么您的進(jìn)程將會(huì)停止。在這種情況下,編譯器將阻止您編譯程序,通常帶有一個(gè)令人費(fèi)解的錯(cuò)誤消息。令人沮喪的是,編譯器是您的朋友,它會(huì)在這個(gè)問(wèn)題導(dǎo)致后續(xù)問(wèn)題之前預(yù)先提醒您。在Python中,只有在太晚的時(shí)候才發(fā)現(xiàn)問(wèn)題是很常見的,比如在代碼投入生產(chǎn)之后。

如何使用c++從頭開始實(shí)現(xiàn)決策樹

在上面的示例中,編譯器捕獲定義為返回試圖返回字符串的整數(shù)的函數(shù)。

也有編譯器不支持您的情況。訪問(wèn)一個(gè)被認(rèn)為存儲(chǔ)在特定內(nèi)存地址的變量時(shí),可能只收到一個(gè)垃圾值,因?yàn)樵撟兞恳呀?jīng)被刪除了。在這里,您通常不會(huì)在編譯時(shí)收到錯(cuò)誤,而且很容易在代碼中留下錯(cuò)誤,而您對(duì)此卻渾然不覺。

如何使用c++從頭開始實(shí)現(xiàn)決策樹

在上面的示例中,即使我們?cè)噲D訪問(wèn)已被刪除的變量的內(nèi)存地址的值,編譯也不會(huì)給出錯(cuò)誤。

盡早做出好的架構(gòu)決策

在Python中,很容易在嘗試解決問(wèn)題的早期階段就開始編寫解決方案。由于c++的靈活性和較慢的開發(fā)速度,這種方法在使用c++時(shí)不能很好地工作。

在這個(gè)項(xiàng)目中,我最初使用的是我的python方法,即只編寫代碼,而不繪制端到端解決方案。最后,我坐下來(lái),想出了一個(gè)解決這個(gè)問(wèn)題的總體架構(gòu)。

下面列出了在實(shí)現(xiàn)決策樹分類器中開發(fā)的關(guān)鍵對(duì)象。它們包括一個(gè)Node類和一個(gè)Tree類,以及它們相關(guān)的屬性和方法,并且大部分可以在編寫任何代碼之前定義:

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

決策樹項(xiàng)目的核心文件(不包括測(cè)試文件)如下所示,以供參考。

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

一旦該體系結(jié)構(gòu)就位,解決方案自然就會(huì)遵循。對(duì)類及其成員函數(shù)(類和函數(shù)參數(shù)以及返回的對(duì)象)的接口進(jìn)行前瞻性設(shè)計(jì)也可以使事情變得更加容易。

從長(zhǎng)遠(yuǎn)來(lái)看,編寫測(cè)試將為您節(jié)省時(shí)間

由于c++缺乏安全性,所以測(cè)試代碼的每個(gè)部分是否都成功地完成了預(yù)期的功能是至關(guān)重要的。用于c++的谷歌Test測(cè)試框架很適合這個(gè)項(xiàng)目,它使用CMake構(gòu)建。

以可測(cè)試的方式編寫代碼可以更容易地識(shí)別和隔離bug。方法是為實(shí)現(xiàn)的類編寫靜態(tài)定義的成員函數(shù)。靜態(tài)定義的成員函數(shù)可以在沒有父類實(shí)例化的情況下獨(dú)立執(zhí)行。這使得為完成決策樹業(yè)務(wù)邏輯的一個(gè)方面的每一個(gè)功能編寫特定的、獨(dú)立的測(cè)試用例成為可能。

如何使用c++從頭開始實(shí)現(xiàn)決策樹

上面顯示了在終端中通過(guò)測(cè)試的谷歌Test的輸出。

語(yǔ)言的在線社區(qū)非常有價(jià)值

Python開發(fā)人員有一個(gè)開發(fā)人員社區(qū),使用像Stack Overflow和博客這樣的工具為集體知識(shí)做出貢獻(xiàn)。此資源是Python數(shù)據(jù)科學(xué)的命脈。c++沒有等價(jià)的社區(qū)。在谷歌上搜索開發(fā)c++代碼時(shí)遇到的許多問(wèn)題和錯(cuò)誤消息,往往會(huì)得到?jīng)]有幫助的結(jié)果。一種語(yǔ)言的社區(qū)價(jià)值很大。

如何使用c++從頭開始實(shí)現(xiàn)決策樹

從上面我們可以看到,現(xiàn)在每個(gè)月被回答的與Python相關(guān)的問(wèn)題比c++多4倍。在這里查看這些統(tǒng)計(jì)數(shù)據(jù)的當(dāng)前狀態(tài)。

可移植性是一個(gè)重要的考慮因素

在Python中,你可以確信任何安裝了Python解釋器的系統(tǒng)都能夠執(zhí)行你的Python程序。而在c++中,你就沒有這種特權(quán)了。由于c++是一種編譯語(yǔ)言,在運(yùn)行程序之前必須先編譯程序,而且必須針對(duì)要運(yùn)行程序的宿主的體系結(jié)構(gòu)來(lái)編譯它。

當(dāng)嘗試使用Github Actions遠(yuǎn)程測(cè)試代碼時(shí),這成為一個(gè)重要的問(wèn)題。由于主機(jī)是不同的操作系統(tǒng)和架構(gòu),因此需要在虛擬機(jī)上測(cè)試代碼之前編譯代碼。這是部署代碼時(shí)需要管理的額外開銷。

總結(jié)

學(xué)習(xí)像c++這樣的低級(jí)語(yǔ)言可以讓你接觸到許多快速程序所需的核心概念,如內(nèi)存管理、數(shù)據(jù)結(jié)構(gòu)和編譯語(yǔ)言。它讓人們意識(shí)到Python中預(yù)先實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu),比如Pandas DataFrames,將擁有處理內(nèi)存管理的系統(tǒng),這些系統(tǒng)必須做出一系列假設(shè),因此有局限性。

在實(shí)踐中,不太可能有很多數(shù)據(jù)科學(xué)家會(huì)使用c++來(lái)解決實(shí)驗(yàn)性的數(shù)據(jù)科學(xué)問(wèn)題,但是Python不再是最好的工具,例如編寫快速的數(shù)據(jù)解析器或?qū)崿F(xiàn)昂貴的算法。即使在這種情況下,我也將探索現(xiàn)代低級(jí)語(yǔ)言,如Go-lang和Rust,而不是c++。c++的語(yǔ)法讓人感覺很冗長(zhǎng),而且它缺乏許多可以從這些現(xiàn)代語(yǔ)言中獲得的安全特性。

您可以在這里從頭看到c++決策樹分類器的完整源代碼。您還可以在這里找到一個(gè)示例jupiter notebook,它直接從Python調(diào)用已實(shí)現(xiàn)的決策樹分類器,并在Titanic數(shù)據(jù)集上訓(xùn)練決策樹。https://github.com/hlamotte/decision-tree

以上是“如何使用c++從頭開始實(shí)現(xiàn)決策樹”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI