從軟體工程的角度寫機器學習4——-C4.5決策樹的工程實現

來源:互聯網
上載者:User

標籤:

C4.5決策樹的工程實現

這篇文章開始,將講述一系列機器學習演算法的工程實現方案。出於常用且簡單的考慮,選擇了C4.5決策樹作為第一個演算法。

工程架構

鑒於本篇是第一個演算法實現,應此需要把整個工程架構介紹一下。
出於最優效能考慮,本架構是為C/C++語言設計的。不過即使用其他語言,也可以按這個架構實現,模組還可以再精簡。

本工程定位:
1、無腦版機器學習演算法庫,使用者基本不需要瞭解任何演算法細節,也不需要瞭解配置的演算法參數含義。
2、可分離的演算法庫,演算法庫輸出的模型檔案可以方便地被其他工程解析使用。
3、高效能的演算法庫,理論上能達到極限效能。

總體設計如:

資料層

這一層解決資料如何定義,如何產生,如何使用,如何銷毀的問題。
定義兩種資料類型:
Matrix:待用資料,矩陣形式儲存,預設使用浮點,精度可全域性地作配置。
Chain:動態資料,也即時間序列類型資料。

理想情況是,資料層盡量提供統一介面供運算層和演算法層使用,無論是在CPU上申請的矩陣記憶體,還是在GPU顯存中申請出來的記憶體,無論是普通矩陣,還是疏鬆陣列,對外透明。不過,有些演算法還是必須要根據矩陣的具體情況作區分的(比如QR變換算矩陣特徵向量的演算法就希望基於疏鬆陣列加速),因此,除了統一介面外,也支援類型識別,讓運算層能夠“因地制宜”。

離散資料和連續資料的區分也是作抽象的一個痛點,這裡的設計是預設資料是連續的,但在Matrix和Chain類型中引入meta資訊,用中繼資料去確定那些列是離散的,有哪些離散值可選。

運算層特性

一方面,機器學習演算法大部分都是矩陣運算,封裝在一層便於複用,另一方面,為了後續效能最佳化便利,需要專門一個運算層。此層作為最佳化重點,需要接一個最佳化模組。

提供如下功能:
1、基本矩陣運算:矩陣相乘、矩陣求逆、求特徵根等等。
2、基於矩陣的複雜運算:梯度下降、卷積、核函數映射等等。
3、資料轉換相關:時間序列展開為矩陣資料(AR模型、相空間重構等)、疏鬆陣列與稠密矩陣互轉、資料隨機抽樣等等。

最佳化

最佳化手段主要包括兩方面,可根據實際應用的需要,去專門最佳化某些演算法。
1、GPGPU:OpenCL/CUDA
2、SIMD:neon/SSE

有句“名言”:過早最佳化是萬惡之源。但踩過一系列代碼最佳化的坑後,深刻覺得,不考慮最佳化才是萬惡之源,對一個寫得很糟糕的程式作最佳化改造的代價,遠超過一開始就高效率編寫的時間成本。講究代碼效率,也並不是說一開始就要把效能最佳化到極致,而是要按一個有利於後續效能最佳化的架構去設計,這樣後面在有效能要求時不需要作大重構。

演算法層

這一層實現基礎的機器學習演算法。如SVM、C45決策樹、樸素貝葉斯、羅吉斯迴歸等。
我們很希望全部運算在矩陣運算層中做掉,這樣可以統一最佳化。不過理想很美好,現實很殘酷。考慮有些操作不容易封裝矩陣運算層,這一層也允許直接與資料層互動,操作實際資料。
以下是演算法層的介面定義:

/*預測模型*/class IPredictor{public:    virtual Matrix* vPredict(Matrix* X) const = 0;    /*以下兩個介面用於分類*/    //輸出各個類型的機率    virtual Matrix* vPredictProb(Matrix* X) const = 0;    //獲得各個類型的值    virtual Matrix* vGetValues() const = 0;    virtual Node* vDump() const = 0;};/*監督學習演算法*/class ILearner{public:    virtual IPredictor* vLearn(Matrix* X, Matrix* Y) const = 0;};/*非監督學習演算法*/class IFreeLearner{public:    virtual IPredictor* vLearn(Matrix* X) const = 0;};/*時間序列預測模型*/class IChainPredictor{public:    virtual Chain* vPredict(Chain* X) const = 0;    virtual Node* vDump() const = 0;};/*時間序列訓練演算法*/class IChainLearner{public:    virtual IChainPredictor* vLearn(Matrix* X) const = 0;};

注意到,對於分類模型,我們給出了提供機率預測的需求,這對於一些應用情境是很重要的,比如基於Face Service的一系列影像處理演算法。事實上,所有分類演算法,都是可以計算這個機率的。

出於更廣泛的工程應用考慮,我們需要能將預測演算法(也即訓練所得模型)序列化。推薦的方式是dump成一棵文法樹(上面的Node為樹結點),然後選一個json或xml庫去序列化。還原序列化時,先解出文法樹,再根據文法樹還原模型。

演算法抽象層

這一層的目的是實現複合演算法,比如基於決策樹實現隨機森林、adaboost、gbdt,基於二分類SVM實現多分類SVM,以及對訓練演算法作評分(交叉驗證)等等。 這一層允許調用演算法層的介面和運算層的資料轉換介面(比如抽樣等)。

C45決策樹演算法實現

關於決策樹的演算法原理可參考這篇文章:
http://www.cnblogs.com/bourneli/archive/2013/03/15/2961568.html

演算法描述與參數

引自上面那篇文章,該演算法步驟如下:

1. 開始,所有記錄看作一個節點2. 遍曆每個變數的每一種分割方式,找到最好的分割點3. 分割成兩個節點N1和N24. 對N1和N2分別繼續執行2-3步,直到每個節點足夠“純”為止

詳細的實現是這樣的:
訓練演算法:

1、接受輸入自變數矩陣X,因變數矩陣Y2、基於矩陣Y計算純度,滿足如下任一條件則終止,轉步驟5產生節點:(1)達到最大樹深限制(2)純度達到targetPrune(3)Y的數量小於minNumber3、基於自變數矩陣X的統計列出所有分劃點,遍曆每一個點,計算純度增益,選取收益最大的一個分劃點:(1)基於該點分隔對應的Y為Y1和Y2。(2)按一定公式計算Y1的純度和Y2的純度。(3)計算純度增益。4、產生分劃點,並基於最優分劃點,將Y分成Y1和Y2,將X分為X1和X2,從1步執行。5、產生結果點:(1)得出Y中所有類型,記為數值矩陣。(2)計算Y中所有類型的佔比,記為機率矩陣。(3)以機率最高的類型作為該點的預設預測值。

這裡涉及到這些參數:
1、最大樹深限制maxDepth
2、提前終止的純度要求targetPrune
3、每個有效節點至少要覆蓋到的資料量minNumber
這三個參數需要按一定規則,將其映射到[0,1)區間,以便使用者無差別調參。

樹結構分劃點

1、分劃資訊:第幾列,值為多少
2、左右兩節點的指標/引用

結果點

結果點包括
1、機率矩陣
2、數值矩陣
3、預設值

預測時,按分劃資訊一層層往下找到結果點,取結果點的機率矩陣和數值矩陣即可。

類、模組位置

無論是ID3、C45還是C50演算法,決策樹的預測模型都是一種相同的樹型結構,而C45決策樹是一種構造決策樹的演算法。因此,命名方面,預測模型是不帶C45的首碼的。

該演算法涉及到的類分布如下:

從軟體工程的角度寫機器學習4——-C4.5決策樹的工程實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.