機器學習演算法的R語言實現(二):決策樹演算法

來源:互聯網
上載者:User

標籤:des   style   class   blog   http   ext   

1、介紹

    ?決策樹(decision tree)是一種有監督的機器學習演算法,是一個分類演算法。在給定訓練集的條件下,產生一個自頂而下的決策樹,樹的根為起點,樹的葉子為樣本的分類,從根到葉子的路徑就是一個樣本進行分類的過程。
    ?為一個決策樹的例子,見http://zh.wikipedia.org/wiki/%E5%86%B3%E7%AD%96%E6%A0%91                                 ?    可見,決策樹上的判斷節點是對某一個屬性進行判斷,產生的路徑數量為該屬性可能的取值,最終到葉子節點時,就完成一個分類(或預測)。決策樹具有直觀、易於解釋的特性。  2、決策樹產生演算法    ?本文主要討論如何由一個給定的訓練集產生一個決策樹。如果都一個資料集合$D$,其特徵集合為$A$,那麼以何種順序對A中的特徵進行判斷就成為決策樹產生過程中的關鍵。首先給出一個決策樹產生演算法-ID3演算法(參考《統計學習方法》李航著)--------------------我是演算法開始分割線-------------------------------------------     ID3演算法:    輸入:訓練資料集D,特徵集A,閾值e    輸出:決策樹T    (1)若D中所有樣本屬於同一類Ck,則T為單節點樹,並將類Ck作為該節點的類標記,返回T;    (2)A為空白集,T為單節點樹,將D中執行個體數最大的類Ck作為該節點的類標記,返回T;    (3)否則,計算A中各特徵對D的資訊增益,選擇資訊增益最大的特徵值Ag;    (4)如果Ag<e,則置T為單節點樹,將D中執行個體數最大的類Ck作為該節點的類標記,返回T;    (5)否則,對Ag的每一個可能的取值ai,依Ag=ai將D分割為若干非空子集Di,將Di中執行個體數最大的類作為標記,構建子節點,由節點及其子節點構成樹T,返回T;    (6)對第i個子節點,以Di為訓練集,以 A-{Ag}為特徵集,遞迴調用(1)~(5)步,得到子樹Ti,返回Ti。--------------------我是演算法結束分割線-------------------------------------------     演算法第(3)步中,資訊增益是評估每一個特徵值對D的劃分效果,劃分的原則為將無序的資料變得盡量有序。評價隨機變數不確定性一個概念是熵,熵越大,不確定性越大。如果確定一個特徵Ag,在確定該特徵前後,D的熵的變化值就是特徵Ag的資訊增益。  3、熵及資訊增益     熵:    設X是一個取有限個值(n)的離散隨機變數,其機率分布為\[P(X=x_{i})=P_{i}, i=1,2,...,n\]則隨機變數X的熵定義為\[H(x) =  - \sum\limits_{i = 1}^n {{P_i}\log {P_i}} \]     資訊增益:    訓練集為\(D\),\(|D|\)為樣本容量,設有k個類\({C_k}\),k=1,...k, \({|C_k|}\)為類\({C_k}\)的樣本個數,且有\(\sum\limits_{i = 1}^k {|{C_k}|}  = |D|\)    設特徵A有n個不同取值\(\{ {a_{1,}}{a_2}, \cdots ,{a_n}\} \)  ,根據A的值,將D劃分為n個子集\({D_1},{D_2}, \cdots ,{D_n}\), \({|D_i|}\)為\({D_i}\) 的樣本數,\(\sum\limits_{i = 1}^n {|{D_i}|}  = |D|\)。    記子集\({D_i}\)中屬於類\({C_k}\)的樣本集合為\({D_{ik}}\),即\({D_{ik}} = {D_i} \cap {C_k}\)。    \({|D_{ik}|}\)為\({D_{ik}}\)的樣本個數。    (1)資料集D的經驗熵H(D)\[H(D) =  - \sum\limits_{k = 1}^K {\frac{{|{C_k}|}}{{|D|}}{{\log }_2}} \frac{{|{C_k}|}}{{|D|}}\]    (2)特徵A對資料集D的經驗條件熵H(D|A)\[H(D|A) = \sum\limits_{i = 1}^n {\frac{{|{D_i}|}}{{|D|}}H({D_i}) =  - } \sum\limits_{i = 1}^n {\frac{{|{D_i}|}}{{|D|}}\sum\limits_{k = 1}^K {\frac{{|{D_{ik}}|}}{{|{D_i}|}}} } {\log _2}\frac{{|{D_{ik}}|}}{{|{D_i}|}}\]    (3)計算資訊增益\[g(D,A) = H(D) - H(D|A)\]資訊增益越大,表示A對D趨於有序的貢獻越大。 -------------------------------分割線------------------------------------------------ 決策樹的R語言實現如下: library(plyr) # 測試資料集 http://archive.ics.uci.edu/ml/datasets/Car+Evaluation ##計算訓練集合D的熵H(D)##輸入:trainData 訓練集,類型為資料框##      nClass 指明訓練集中第nClass列為分類結果##輸出:訓練集的熵cal_HD <- function(trainData, nClass){  if ( !(is.data.frame(trainData) & is.numeric(nClass)) )    "input error"  if (length(trainData) < nClass)    "nClass is larger than the length of trainData"    rownum <- nrow(trainData)  #對第nClass列的值統計頻數  calss.freq <- count(trainData,nClass)     #計算每個取值的  機率*log2(機率)  calss.freq <- mutate(calss.freq, freq2 = (freq / rownum)*log2(freq / rownum))    -sum(calss.freq[,"freq2"])    #使用arrange代替order,方便的按照多列對資料框進行排序   #mtcars.new2 <- arrange(mtcars, cyl, vs, gear) } #cal_HD(mtcars,11) ##計算訓練集合D對特徵值A的條件熵H(D|A)##輸入:trainData 訓練集,類型為資料框##      nClass 指明訓練集中第nClass列為分類結果##      nA 指明trainData中條件A的列號##輸出:訓練集trainData對特徵A的條件熵cal_HDA <- function(trainData, nClass, nA){  rownum <- nrow(trainData)    #對第nA列的特徵A計算頻數  nA.freq <- count(trainData,nA)  i <- 1  sub.hd <- c()  for (nA.value in nA.freq[,1]){    #取特徵值A取值為na.value的子集    sub.trainData <- trainData[which(trainData[,nA] == nA.value),]        sub.hd[i] <- cal_HD(sub.trainData,nClass)    i <- i+1  }    nA.freq <- mutate(nA.freq, freq2 = (freq / rownum)*sub.hd)  sum(nA.freq[,"freq2"])} ##計算訓練集合D對特徵值A的資訊增益g(D,A)##輸入:trainData 訓練集,類型為資料框##      nClass 指明訓練集中第nClass列為分類結果##      nA 指明trainData中特徵A的列號##輸出:訓練集trainData對特徵A的資訊增益g_DA <- function(trainData, nClass, nA){  cal_HD(trainData, nClass) - cal_HDA(trainData, nClass, nA)} ##根據訓練集合產生決策樹##輸入:trainData 訓練集,類型為資料框##      strRoot 指明根節點的屬性名稱##      strRootAttri 指明根節點的屬性取值##      nClass 指明訓練集中第nClass列為分類結果##      cAttri 向量,表示當前可用的特徵集合,用列號表示##      e 如果特徵的最大資訊增益小於e,則剩餘作為一個分類,類頻數最高的最為分類結果##輸出:決策樹Tgen_decision_tree <- function(trainData, strRoot, strRootAttri, nClass, cAttri, e){  # 樹的描述,(上級節點名稱、上級節點屬性值、自己節點名稱,自己節點的取值)  decision_tree <- data.frame()    nClass.freq <- count(trainData,nClass)   ##類別出現的頻數  nClass.freq <- arrange(nClass.freq, desc(freq))  ##按頻數從低到高排列  col.name <- names(trainData) ##trainData的列名    ##1、如果D中所有屬於同一類Ck,則T為單節點樹    if nrow(nClass.freq) == 1{    rbind(decision_tree, c(strRoot, strRootAttri, nClass.freq[1,1], ‘‘))    return decision_tree  }    ##2、如果屬性cAttri為空白,將D中頻數最高的類別返回  if length(cAttri) == 0{    rbind(decision_tree, c(strRoot, strRootAttri, nClass.freq[1,1], ‘‘))    return decision_tree  }    ##3、計算cAttri中各特徵值對D的資訊增益,選擇資訊增益最大的特徵值Ag及其資訊增益  maxDA <- 0    #記錄最大的資訊增益  maxAttriName <- ‘‘   #記錄最大資訊增益對應的屬性名稱  maxAttriIndex <- ‘‘   #記錄最大資訊增益對應的屬性列號    for(i in cAttri){    curDA <- g_DA(trainData,nClass,i)    if (maxDA <= curDA){      maxDA <- curDA      maxAttriName <- col.name[i]    }  }    ##4、如果最大資訊增益小於閾值e,將D中頻數最高的類別返回  if (maxDA < e){    rbind(decision_tree, c(strRoot, strRootAttri, nClass.freq[1,1], ‘‘))    return decision_tree  }    ##5、否則,對Ag的每一可能值ai,依Ag=ai將D分割為若干非空子集Di  ##   將Di中執行個體數最大的類作為標記,構建子節點  ##   由節點及其子節點構成樹T,返回T  for (oneValue in unique(trainData[,maxAttriName])){    sub.train <- trainData[which(trainData[,maxAttriName] == oneValue),]  #Di    #sub.trian.freq <- count(sub.train,nClass)   ##類別出現的頻數    #sub.trian.freq <- arrange(sub.trian.freq, desc(freq))  ##按頻數從低到高排列        rbind(decision_tree, c(strRoot, strRootAttri, maxAttriName , oneValue))        ##6、遞迴構建下一步    # 剔除已經使用的屬性    next.cAttri <- cAttri[which(cAttri !=maxAttriIndex)]    # 遞迴調用    next.dt <-gen_decision_tree(sub.train, maxAttriName,                                oneValue, nClass, next.cAttri, e)    rbind(decision_tree, next.dt)  }    names(decision_tree) <- c(‘preName‘,‘preValue‘,‘curName‘,‘curValue‘)  decision_tree}  ---------------決策樹總結-------------------1、R中有實現決策樹演算法的包rpart,和畫出決策樹的包rpart.plot,本例自己實現決策樹演算法是為了更好的理解。2、由於決策樹只能處理離散屬性,因此連續屬性應首先進行離散化。3、決策樹易於理解,對業務的解釋性較強。4、ID3演算法容易引起過擬合,需考慮樹的剪枝。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.