最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實現(xiàn)的決策樹算法完整實例

 更新時間:2017年11月23日 11:00:08   作者:Jerry_u013058160  
這篇文章主要介紹了Java實現(xiàn)的決策樹算法,簡單描述了決策樹的概念、原理,并結(jié)合完整實例形式分析了java實現(xiàn)決策樹算法的相關(guān)操作技巧,代碼中備有較為詳盡的注釋便于理解,需要的朋友可以參考下

本文實例講述了Java實現(xiàn)的決策樹算法。分享給大家供大家參考,具體如下:

決策樹算法是一種逼近離散函數(shù)值的方法。它是一種典型的分類方法,首先對數(shù)據(jù)進行處理,利用歸納算法生成可讀的規(guī)則和決策樹,然后使用決策對新數(shù)據(jù)進行分析。本質(zhì)上決策樹是通過一系列規(guī)則對數(shù)據(jù)進行分類的過程。

決策樹構(gòu)造可以分兩步進行。第一步,決策樹的生成:由訓(xùn)練樣本集生成決策樹的過程。一般情況下,訓(xùn)練樣本數(shù)據(jù)集是根據(jù)實際需要有歷史的、有一定綜合程度的,用于數(shù)據(jù)分析處理的數(shù)據(jù)集。第二步,決策樹的剪枝:決策樹的剪枝是對上一階段生成的決策樹進行檢驗、校正和修下的過程,主要是用新的樣本數(shù)據(jù)集(稱為測試數(shù)據(jù)集)中的數(shù)據(jù)校驗決策樹生成過程中產(chǎn)生的初步規(guī)則,將那些影響預(yù)衡準確性的分枝剪除。

java實現(xiàn)代碼如下:

package demo;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class DicisionTree {
  public static void main(String[] args) throws Exception {
    System.out.print("腳本之家測試結(jié)果:");
    String[] attrNames = new String[] { "AGE", "INCOME", "STUDENT",
        "CREDIT_RATING" };
    // 讀取樣本集
    Map<Object, List<Sample>> samples = readSamples(attrNames);
    // 生成決策樹
    Object decisionTree = generateDecisionTree(samples, attrNames);
    // 輸出決策樹
    outputDecisionTree(decisionTree, 0, null);
  }
  /**
   * 讀取已分類的樣本集,返回Map:分類 -> 屬于該分類的樣本的列表
   */
  static Map<Object, List<Sample>> readSamples(String[] attrNames) {
    // 樣本屬性及其所屬分類(數(shù)組中的最后一個元素為樣本所屬分類)
    Object[][] rawData = new Object[][] {
        { "<30 ", "High ", "No ", "Fair   ", "0" },
        { "<30 ", "High ", "No ", "Excellent", "0" },
        { "30-40", "High ", "No ", "Fair   ", "1" },
        { ">40 ", "Medium", "No ", "Fair   ", "1" },
        { ">40 ", "Low  ", "Yes", "Fair   ", "1" },
        { ">40 ", "Low  ", "Yes", "Excellent", "0" },
        { "30-40", "Low  ", "Yes", "Excellent", "1" },
        { "<30 ", "Medium", "No ", "Fair   ", "0" },
        { "<30 ", "Low  ", "Yes", "Fair   ", "1" },
        { ">40 ", "Medium", "Yes", "Fair   ", "1" },
        { "<30 ", "Medium", "Yes", "Excellent", "1" },
        { "30-40", "Medium", "No ", "Excellent", "1" },
        { "30-40", "High ", "Yes", "Fair   ", "1" },
        { ">40 ", "Medium", "No ", "Excellent", "0" } };
    // 讀取樣本屬性及其所屬分類,構(gòu)造表示樣本的Sample對象,并按分類劃分樣本集
    Map<Object, List<Sample>> ret = new HashMap<Object, List<Sample>>();
    for (Object[] row : rawData) {
      Sample sample = new Sample();
      int i = 0;
      for (int n = row.length - 1; i < n; i++)
        sample.setAttribute(attrNames[i], row[i]);
      sample.setCategory(row[i]);
      List<Sample> samples = ret.get(row[i]);
      if (samples == null) {
        samples = new LinkedList<Sample>();
        ret.put(row[i], samples);
      }
      samples.add(sample);
    }
    return ret;
  }
  /**
   * 構(gòu)造決策樹
   */
  static Object generateDecisionTree(
      Map<Object, List<Sample>> categoryToSamples, String[] attrNames) {
    // 如果只有一個樣本,將該樣本所屬分類作為新樣本的分類
    if (categoryToSamples.size() == 1)
      return categoryToSamples.keySet().iterator().next();
    // 如果沒有供決策的屬性,則將樣本集中具有最多樣本的分類作為新樣本的分類,即投票選舉出分類
    if (attrNames.length == 0) {
      int max = 0;
      Object maxCategory = null;
      for (Entry<Object, List<Sample>> entry : categoryToSamples
          .entrySet()) {
        int cur = entry.getValue().size();
        if (cur > max) {
          max = cur;
          maxCategory = entry.getKey();
        }
      }
      return maxCategory;
    }
    // 選取測試屬性
    Object[] rst = chooseBestTestAttribute(categoryToSamples, attrNames);
    // 決策樹根結(jié)點,分支屬性為選取的測試屬性
    Tree tree = new Tree(attrNames[(Integer) rst[0]]);
    // 已用過的測試屬性不應(yīng)再次被選為測試屬性
    String[] subA = new String[attrNames.length - 1];
    for (int i = 0, j = 0; i < attrNames.length; i++)
      if (i != (Integer) rst[0])
        subA[j++] = attrNames[i];
    // 根據(jù)分支屬性生成分支
    @SuppressWarnings("unchecked")
    Map<Object, Map<Object, List<Sample>>> splits =
    /* NEW LINE */(Map<Object, Map<Object, List<Sample>>>) rst[2];
    for (Entry<Object, Map<Object, List<Sample>>> entry : splits.entrySet()) {
      Object attrValue = entry.getKey();
      Map<Object, List<Sample>> split = entry.getValue();
      Object child = generateDecisionTree(split, subA);
      tree.setChild(attrValue, child);
    }
    return tree;
  }
  /**
   * 選取最優(yōu)測試屬性。最優(yōu)是指如果根據(jù)選取的測試屬性分支,則從各分支確定新樣本
   * 的分類需要的信息量之和最小,這等價于確定新樣本的測試屬性獲得的信息增益最大
   * 返回數(shù)組:選取的屬性下標(biāo)、信息量之和、Map(屬性值->(分類->樣本列表))
   */
  static Object[] chooseBestTestAttribute(
      Map<Object, List<Sample>> categoryToSamples, String[] attrNames) {
    int minIndex = -1; // 最優(yōu)屬性下標(biāo)
    double minValue = Double.MAX_VALUE; // 最小信息量
    Map<Object, Map<Object, List<Sample>>> minSplits = null; // 最優(yōu)分支方案
    // 對每一個屬性,計算將其作為測試屬性的情況下在各分支確定新樣本的分類需要的信息量之和,選取最小為最優(yōu)
    for (int attrIndex = 0; attrIndex < attrNames.length; attrIndex++) {
      int allCount = 0; // 統(tǒng)計樣本總數(shù)的計數(shù)器
      // 按當(dāng)前屬性構(gòu)建Map:屬性值->(分類->樣本列表)
      Map<Object, Map<Object, List<Sample>>> curSplits =
      /* NEW LINE */new HashMap<Object, Map<Object, List<Sample>>>();
      for (Entry<Object, List<Sample>> entry : categoryToSamples
          .entrySet()) {
        Object category = entry.getKey();
        List<Sample> samples = entry.getValue();
        for (Sample sample : samples) {
          Object attrValue = sample
              .getAttribute(attrNames[attrIndex]);
          Map<Object, List<Sample>> split = curSplits.get(attrValue);
          if (split == null) {
            split = new HashMap<Object, List<Sample>>();
            curSplits.put(attrValue, split);
          }
          List<Sample> splitSamples = split.get(category);
          if (splitSamples == null) {
            splitSamples = new LinkedList<Sample>();
            split.put(category, splitSamples);
          }
          splitSamples.add(sample);
        }
        allCount += samples.size();
      }
      // 計算將當(dāng)前屬性作為測試屬性的情況下在各分支確定新樣本的分類需要的信息量之和
      double curValue = 0.0; // 計數(shù)器:累加各分支
      for (Map<Object, List<Sample>> splits : curSplits.values()) {
        double perSplitCount = 0;
        for (List<Sample> list : splits.values())
          perSplitCount += list.size(); // 累計當(dāng)前分支樣本數(shù)
        double perSplitValue = 0.0; // 計數(shù)器:當(dāng)前分支
        for (List<Sample> list : splits.values()) {
          double p = list.size() / perSplitCount;
          perSplitValue -= p * (Math.log(p) / Math.log(2));
        }
        curValue += (perSplitCount / allCount) * perSplitValue;
      }
      // 選取最小為最優(yōu)
      if (minValue > curValue) {
        minIndex = attrIndex;
        minValue = curValue;
        minSplits = curSplits;
      }
    }
    return new Object[] { minIndex, minValue, minSplits };
  }
  /**
   * 將決策樹輸出到標(biāo)準輸出
   */
  static void outputDecisionTree(Object obj, int level, Object from) {
    for (int i = 0; i < level; i++)
      System.out.print("|-----");
    if (from != null)
      System.out.printf("(%s):", from);
    if (obj instanceof Tree) {
      Tree tree = (Tree) obj;
      String attrName = tree.getAttribute();
      System.out.printf("[%s = ?]\n", attrName);
      for (Object attrValue : tree.getAttributeValues()) {
        Object child = tree.getChild(attrValue);
        outputDecisionTree(child, level + 1, attrName + " = "
            + attrValue);
      }
    } else {
      System.out.printf("[CATEGORY = %s]\n", obj);
    }
  }
  /**
   * 樣本,包含多個屬性和一個指明樣本所屬分類的分類值
   */
  static class Sample {
    private Map<String, Object> attributes = new HashMap<String, Object>();
    private Object category;
    public Object getAttribute(String name) {
      return attributes.get(name);
    }
    public void setAttribute(String name, Object value) {
      attributes.put(name, value);
    }
    public Object getCategory() {
      return category;
    }
    public void setCategory(Object category) {
      this.category = category;
    }
    public String toString() {
      return attributes.toString();
    }
  }
  /**
   * 決策樹(非葉結(jié)點),決策樹中的每個非葉結(jié)點都引導(dǎo)了一棵決策樹
   * 每個非葉結(jié)點包含一個分支屬性和多個分支,分支屬性的每個值對應(yīng)一個分支,該分支引導(dǎo)了一棵子決策樹
   */
  static class Tree {
    private String attribute;
    private Map<Object, Object> children = new HashMap<Object, Object>();
    public Tree(String attribute) {
      this.attribute = attribute;
    }
    public String getAttribute() {
      return attribute;
    }
    public Object getChild(Object attrValue) {
      return children.get(attrValue);
    }
    public void setChild(Object attrValue, Object child) {
      children.put(attrValue, child);
    }
    public Set<Object> getAttributeValues() {
      return children.keySet();
    }
  }
}

運行結(jié)果:

更多關(guān)于java算法相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設(shè)計有所幫助。

相關(guān)文章

  • springboot+springmvc+mybatis項目整合

    springboot+springmvc+mybatis項目整合

    這篇文章主要為大家詳細介紹了springboot+springmvc+mybatis項目的整合,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Java時區(qū)轉(zhuǎn)換及Date類實現(xiàn)原理解析

    Java時區(qū)轉(zhuǎn)換及Date類實現(xiàn)原理解析

    這篇文章主要介紹了Java時區(qū)轉(zhuǎn)換及Date類實現(xiàn)原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • ActiveMQ持久化機制代碼實例

    ActiveMQ持久化機制代碼實例

    這篇文章主要介紹了ActiveMQ持久化機制代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java虛擬機GC日志分析

    Java虛擬機GC日志分析

    這篇文章主要介紹了Java虛擬機GC日志分析,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • 詳解Java并發(fā)包基石AQS

    詳解Java并發(fā)包基石AQS

    Java并發(fā)包(JUC)中提供了很多并發(fā)工具,這其中,很多我們耳熟能詳?shù)牟l(fā)工具,譬如ReentrangLock、Semaphore,它們的實現(xiàn)都用到了一個共同的基類--AbstractQueuedSynchronizer,簡稱AQS。本文將從幾個方面來詳細介紹:基本實現(xiàn)原理、自定義同步器、源碼分析
    2021-06-06
  • JavaWeb如何實現(xiàn)本地文件上傳功能

    JavaWeb如何實現(xiàn)本地文件上傳功能

    這篇文章主要介紹了JavaWeb如何實現(xiàn)本地文件上傳功能,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java基礎(chǔ)學(xué)習(xí)之集合底層原理

    Java基礎(chǔ)學(xué)習(xí)之集合底層原理

    今天帶大家回顧Java基礎(chǔ)的相關(guān)知識,文中對集合底層原理作了非常詳細的圖文介紹,對Java初學(xué)者有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • java集合框架線程同步代碼詳解

    java集合框架線程同步代碼詳解

    這篇文章主要介紹了java集合框架線程同步代碼詳解,具有一定借鑒價值,需要的朋友可以參考下。
    2017-12-12
  • springboot全局配置文件與多環(huán)境配置的全過程

    springboot全局配置文件與多環(huán)境配置的全過程

    SpringBoot項目在多環(huán)境配置上表現(xiàn)的非常優(yōu)秀,只需要非常簡單的操作就可以完成配置,下面這篇文章主要給大家介紹了關(guān)于springboot全局配置文件與多環(huán)境配置的相關(guān)資料,需要的朋友可以參考下
    2021-12-12
  • java中l(wèi)ist使用時需避免的場景總結(jié)

    java中l(wèi)ist使用時需避免的場景總結(jié)

    眾所周知,Java為開發(fā)者提供了多種集合類的實現(xiàn),其中幾乎所有業(yè)務(wù)代碼都需要用到List,但List的錯誤使用也會導(dǎo)致諸多問題,所以本文我們就來看一看幾個錯誤使用List的場景吧
    2023-10-10

最新評論

普安县| 涞水县| 五莲县| 景德镇市| 合江县| 长葛市| 当涂县| 娱乐| 达州市| 本溪| 吴川市| 建昌县| 庆元县| 远安县| 民勤县| 分宜县| 宜春市| 修水县| 益阳市| 仁寿县| 德钦县| 襄樊市| 彭泽县| 哈尔滨市| 铁岭市| 鄂温| 玉门市| 大足县| 平武县| 耒阳市| 五华县| 桐乡市| 株洲县| 鄂伦春自治旗| 阿拉尔市| 湘潭市| 博客| 绥滨县| 汕尾市| 育儿| 浑源县|