1. 程式人生 > >決策分類樹演算法之ID3,C4.5算法系列

決策分類樹演算法之ID3,C4.5算法系列

一、引言

在最開始的時候,我本來準備學習的是C4.5演算法,後來發現C4.5演算法的核心還是ID3演算法,所以又輾轉回到學習ID3演算法了,因為C4.5是他的一個改進。至於是什麼改進,在後面的描述中我會提到。

二、ID3演算法

ID3演算法是一種分類決策樹演算法。他通過一系列的規則,將資料最後分類成決策樹的形式。分類的根據是用到了熵這個概念。熵在物理這門學科中就已經出現過,表示是一個物質的穩定度,在這裡就是分類的純度的一個概念。公式為:


在ID3演算法中,是採用Gain資訊增益來作為一個分類的判定標準的。他的定義為:


每次選擇屬性中資訊增益最大作為劃分屬性,在這裡本人實現了一個java版本的ID3演算法,為了模擬資料的可操作性,就把資料寫到一個input.txt檔案中,作為資料來源,格式如下:

Day OutLook Temperature Humidity Wind PlayTennis
1 Sunny Hot High Weak No
2 Sunny Hot High Strong No
3 Overcast Hot High Weak Yes
4 Rainy Mild High Weak Yes
5 Rainy Cool Normal Weak Yes
6 Rainy Cool Normal Strong No
7 Overcast Cool Normal Strong Yes
8 Sunny Mild High Weak No
9 Sunny Cool Normal Weak Yes
10 Rainy Mild Normal Weak Yes
11 Sunny Mild Normal Strong Yes
12 Overcast Mild High Strong Yes
13 Overcast Hot Normal Weak Yes
14 Rainy Mild High Strong No
PalyTennis屬性為結構屬性,是作為類標識用的,中間的OutLool,Temperature,Humidity,Wind才是劃分屬性,通過將源資料與執行程式分類,這樣可以模擬巨大的資料量了。下面是ID3的主程式類,本人將ID3的演算法進行了包裝,對外只開放了一個構建決策樹的方法,在建構函式時候,只需傳入一個數據路徑檔案即可:
package DataMing_ID3;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * ID3演算法實現類
 * 
 * @author lyq
 * 
 */
public class ID3Tool {
	// 類標號的值型別
	private final String YES = "Yes";
	private final String NO = "No";

	// 所有屬性的型別總數,在這裡就是data源資料的列數
	private int attrNum;
	private String filePath;
	// 初始源資料,用一個二維字元陣列存放模仿表格資料
	private String[][] data;
	// 資料的屬性行的名字
	private String[] attrNames;
	// 每個屬性的值所有型別
	private HashMap<String, ArrayList<String>> attrValue;

	public ID3Tool(String filePath) {
		this.filePath = filePath;
		attrValue = new HashMap<>();
	}

	/**
	 * 從檔案中讀取資料
	 */
	private void readDataFile() {
		File file = new File(filePath);
		ArrayList<String[]> dataArray = new ArrayList<String[]>();

		try {
			BufferedReader in = new BufferedReader(new FileReader(file));
			String str;
			String[] tempArray;
			while ((str = in.readLine()) != null) {
				tempArray = str.split(" ");
				dataArray.add(tempArray);
			}
			in.close();
		} catch (IOException e) {
			e.getStackTrace();
		}

		data = new String[dataArray.size()][];
		dataArray.toArray(data);
		attrNum = data[0].length;
		attrNames = data[0];

		/*
		 * for(int i=0; i<data.length;i++){ for(int j=0; j<data[0].length; j++){
		 * System.out.print(" " + data[i][j]); }
		 * 
		 * System.out.print("\n"); }
		 */
	}

	/**
	 * 首先初始化每種屬性的值的所有型別,用於後面的子類熵的計算時用
	 */
	private void initAttrValue() {
		ArrayList<String> tempValues;

		// 按照列的方式,從左往右找
		for (int j = 1; j < attrNum; j++) {
			// 從一列中的上往下開始尋找值
			tempValues = new ArrayList<>();
			for (int i = 1; i < data.length; i++) {
				if (!tempValues.contains(data[i][j])) {
					// 如果這個屬性的值沒有新增過,則新增
					tempValues.add(data[i][j]);
				}
			}

			// 一列屬性的值已經遍歷完畢,複製到map屬性表中
			attrValue.put(data[0][j], tempValues);
		}

		/*
		 * for(Map.Entry entry : attrValue.entrySet()){
		 * System.out.println("key:value " + entry.getKey() + ":" +
		 * entry.getValue()); }
		 */
	}

	/**
	 * 計算資料按照不同方式劃分的熵
	 * 
	 * @param remainData
	 *            剩餘的資料
	 * @param attrName
	 *            待劃分的屬性,在算資訊增益的時候會使用到
	 * @param attrValue
	 *            劃分的子屬性值
	 * @param isParent
	 *            是否分子屬性劃分還是原來不變的劃分
	 */
	private double computeEntropy(String[][] remainData, String attrName,
			String value, boolean isParent) {
		// 例項總數
		int total = 0;
		// 正例項數
		int posNum = 0;
		// 負例項數
		int negNum = 0;

		// 還是按列從左往右遍歷屬性
		for (int j = 1; j < attrNames.length; j++) {
			// 找到了指定的屬性
			if (attrName.equals(attrNames[j])) {
				for (int i = 1; i < remainData.length; i++) {
					// 如果是父結點直接計算熵或者是通過子屬性劃分計算熵,這時要進行屬性值的過濾
					if (isParent
							|| (!isParent && remainData[i][j].equals(value))) {
						if (remainData[i][attrNames.length - 1].equals(YES)) {
							// 判斷此行資料是否為正例項
							posNum++;
						} else {
							negNum++;
						}
					}
				}
			}
		}

		total = posNum + negNum;
		double posProbobly = (double) posNum / total;
		double negProbobly = (double) negNum / total;

		if (posProbobly == 1 || posProbobly == 0) {
			// 如果資料全為同種型別,則熵為0,否則帶入下面的公式會報錯
			return 0;
		}

		double entropyValue = -posProbobly * Math.log(posProbobly)
				/ Math.log(2.0) - negProbobly * Math.log(negProbobly)
				/ Math.log(2.0);

		// 返回計算所得熵
		return entropyValue;
	}

	/**
	 * 為某個屬性計算資訊增益
	 * 
	 * @param remainData
	 *            剩餘的資料
	 * @param value
	 *            待劃分的屬性名稱
	 * @return
	 */
	private double computeGain(String[][] remainData, String value) {
		double gainValue = 0;
		// 源熵的大小將會與屬性劃分後進行比較
		double entropyOri = 0;
		// 子劃分熵和
		double childEntropySum = 0;
		// 屬性子型別的個數
		int childValueNum = 0;
		// 屬性值的種數
		ArrayList<String> attrTypes = attrValue.get(value);
		// 子屬性對應的權重比
		HashMap<String, Integer> ratioValues = new HashMap<>();

		for (int i = 0; i < attrTypes.size(); i++) {
			// 首先都統一計數為0
			ratioValues.put(attrTypes.get(i), 0);
		}

		// 還是按照一列,從左往右遍歷
		for (int j = 1; j < attrNames.length; j++) {
			// 判斷是否到了劃分的屬性列
			if (value.equals(attrNames[j])) {
				for (int i = 1; i <= remainData.length - 1; i++) {
					childValueNum = ratioValues.get(remainData[i][j]);
					// 增加個數並且重新存入
					childValueNum++;
					ratioValues.put(remainData[i][j], childValueNum);
				}
			}
		}

		// 計算原熵的大小
		entropyOri = computeEntropy(remainData, value, null, true);
		for (int i = 0; i < attrTypes.size(); i++) {
			double ratio = (double) ratioValues.get(attrTypes.get(i))
					/ (remainData.length - 1);
			childEntropySum += ratio
					* computeEntropy(remainData, value, attrTypes.get(i), false);

			// System.out.println("ratio:value: " + ratio + " " +
			// computeEntropy(remainData, value,
			// attrTypes.get(i), false));
		}

		// 二者熵相減就是資訊增益
		gainValue = entropyOri - childEntropySum;
		return gainValue;
	}

	/**
	 * 計算資訊增益比
	 * 
	 * @param remainData
	 *            剩餘資料
	 * @param value
	 *            待劃分屬性
	 * @return
	 */
	private double computeGainRatio(String[][] remainData, String value) {
		double gain = 0;
		double spiltInfo = 0;
		int childValueNum = 0;
		// 屬性值的種數
		ArrayList<String> attrTypes = attrValue.get(value);
		// 子屬性對應的權重比
		HashMap<String, Integer> ratioValues = new HashMap<>();

		for (int i = 0; i < attrTypes.size(); i++) {
			// 首先都統一計數為0
			ratioValues.put(attrTypes.get(i), 0);
		}

		// 還是按照一列,從左往右遍歷
		for (int j = 1; j < attrNames.length; j++) {
			// 判斷是否到了劃分的屬性列
			if (value.equals(attrNames[j])) {
				for (int i = 1; i <= remainData.length - 1; i++) {
					childValueNum = ratioValues.get(remainData[i][j]);
					// 增加個數並且重新存入
					childValueNum++;
					ratioValues.put(remainData[i][j], childValueNum);
				}
			}
		}

		// 計算資訊增益
		gain = computeGain(remainData, value);
		// 計算分裂資訊,分裂資訊度量被定義為(分裂資訊用來衡量屬性分裂資料的廣度和均勻):
		for (int i = 0; i < attrTypes.size(); i++) {
			double ratio = (double) ratioValues.get(attrTypes.get(i))
					/ (remainData.length - 1);
			spiltInfo += -ratio * Math.log(ratio) / Math.log(2.0);
		}

		// 計算機資訊增益率
		return gain / spiltInfo;
	}

	/**
	 * 利用源資料構造決策樹
	 */
	private void buildDecisionTree(AttrNode node, String parentAttrValue,
			String[][] remainData, ArrayList<String> remainAttr, boolean isID3) {
		node.setParentAttrValue(parentAttrValue);

		String attrName = "";
		double gainValue = 0;
		double tempValue = 0;

		// 如果只有1個屬性則直接返回
		if (remainAttr.size() == 1) {
			System.out.println("attr null");
			return;
		}

		// 選擇剩餘屬性中資訊增益最大的作為下一個分類的屬性
		for (int i = 0; i < remainAttr.size(); i++) {
			// 判斷是否用ID3演算法還是C4.5演算法
			if (isID3) {
				// ID3演算法採用的是按照資訊增益的值來比
				tempValue = computeGain(remainData, remainAttr.get(i));
			} else {
				// C4.5演算法進行了改進,用的是資訊增益率來比,克服了用資訊增益選擇屬性時偏向選擇取值多的屬性的不足
				tempValue = computeGainRatio(remainData, remainAttr.get(i));
			}

			if (tempValue > gainValue) {
				gainValue = tempValue;
				attrName = remainAttr.get(i);
			}
		}

		node.setAttrName(attrName);
		ArrayList<String> valueTypes = attrValue.get(attrName);
		remainAttr.remove(attrName);

		AttrNode[] childNode = new AttrNode[valueTypes.size()];
		String[][] rData;
		for (int i = 0; i < valueTypes.size(); i++) {
			// 移除非此值型別的資料
			rData = removeData(remainData, attrName, valueTypes.get(i));

			childNode[i] = new AttrNode();
			boolean sameClass = true;
			ArrayList<String> indexArray = new ArrayList<>();
			for (int k = 1; k < rData.length; k++) {
				indexArray.add(rData[k][0]);
				// 判斷是否為同一類的
				if (!rData[k][attrNames.length - 1]
						.equals(rData[1][attrNames.length - 1])) {
					// 只要有1個不相等,就不是同類型的
					sameClass = false;
					break;
				}
			}

			if (!sameClass) {
				// 建立新的物件屬性,物件的同個引用會出錯
				ArrayList<String> rAttr = new ArrayList<>();
				for (String str : remainAttr) {
					rAttr.add(str);
				}

				buildDecisionTree(childNode[i], valueTypes.get(i), rData,
						rAttr, isID3);
			} else {
				// 如果是同種型別,則直接為資料節點
				childNode[i].setParentAttrValue(valueTypes.get(i));
				childNode[i].setChildDataIndex(indexArray);
			}

		}
		node.setChildAttrNode(childNode);
	}

	/**
	 * 屬性劃分完畢,進行資料的移除
	 * 
	 * @param srcData
	 *            源資料
	 * @param attrName
	 *            劃分的屬性名稱
	 * @param valueType
	 *            屬性的值型別
	 */
	private String[][] removeData(String[][] srcData, String attrName,
			String valueType) {
		String[][] desDataArray;
		ArrayList<String[]> desData = new ArrayList<>();
		// 待刪除資料
		ArrayList<String[]> selectData = new ArrayList<>();
		selectData.add(attrNames);

		// 陣列資料轉化到列表中,方便移除
		for (int i = 0; i < srcData.length; i++) {
			desData.add(srcData[i]);
		}

		// 還是從左往右一列列的查詢
		for (int j = 1; j < attrNames.length; j++) {
			if (attrNames[j].equals(attrName)) {
				for (int i = 1; i < desData.size(); i++) {
					if (desData.get(i)[j].equals(valueType)) {
						// 如果匹配這個資料,則移除其他的資料
						selectData.add(desData.get(i));
					}
				}
			}
		}

		desDataArray = new String[selectData.size()][];
		selectData.toArray(desDataArray);

		return desDataArray;
	}

	/**
	 * 開始構建決策樹
	 * 
	 * @param isID3
	 *            是否採用ID3演算法構架決策樹
	 */
	public void startBuildingTree(boolean isID3) {
		readDataFile();
		initAttrValue();

		ArrayList<String> remainAttr = new ArrayList<>();
		// 新增屬性,除了最後一個類標號屬性
		for (int i = 1; i < attrNames.length - 1; i++) {
			remainAttr.add(attrNames[i]);
		}

		AttrNode rootNode = new AttrNode();
		buildDecisionTree(rootNode, "", data, remainAttr, isID3);
		showDecisionTree(rootNode, 1);
	}

	/**
	 * 顯示決策樹
	 * 
	 * @param node
	 *            待顯示的節點
	 * @param blankNum
	 *            行空格符,用於顯示樹型結構
	 */
	private void showDecisionTree(AttrNode node, int blankNum) {
		System.out.println();
		for (int i = 0; i < blankNum; i++) {
			System.out.print("\t");
		}
		System.out.print("--");
		// 顯示分類的屬性值
		if (node.getParentAttrValue() != null
				&& node.getParentAttrValue().length() > 0) {
			System.out.print(node.getParentAttrValue());
		} else {
			System.out.print("--");
		}
		System.out.print("--");

		if (node.getChildDataIndex() != null
				&& node.getChildDataIndex().size() > 0) {
			String i = node.getChildDataIndex().get(0);
			System.out.print("類別:"
					+ data[Integer.parseInt(i)][attrNames.length - 1]);
			System.out.print("[");
			for (String index : node.getChildDataIndex()) {
				System.out.print(index + ", ");
			}
			System.out.print("]");
		} else {
			// 遞迴顯示子節點
			System.out.print("【" + node.getAttrName() + "】");
			for (AttrNode childNode : node.getChildAttrNode()) {
				showDecisionTree(childNode, 2 * blankNum);
			}
		}

	}

}
他的場景呼叫實現的方式為:
/**
 * ID3決策樹分類演算法測試場景類
 * @author lyq
 *
 */
public class Client {
	public static void main(String[] args){
		String filePath = "C:\\Users\\lyq\\Desktop\\icon\\input.txt";
		
		ID3Tool tool = new ID3Tool(filePath);
		tool.startBuildingTree(true);
	}
}
最終的結果為:
	------【OutLook】
		--Sunny--【Humidity】
				--High--類別:No[1, 2, 8, ]
				--Normal--類別:Yes[9, 11, ]
		--Overcast--類別:Yes[3, 7, 12, 13, ]
		--Rainy--【Wind】
				--Weak--類別:Yes[4, 5, 10, ]
				--Strong--類別:No[6, 14, ]

請從左往右觀察這棵決策樹,【】裡面的是分類屬性,---XXX----,XXX為屬性的值,在葉子節點處為類標記。

對應的分類結果圖:


這裡的構造決策樹和顯示決策樹採用的DFS的方法,所以可能會比較難懂,希望讀者能細細體會,可以除錯一下程式碼,一步步的跟蹤會更加容易理解的。

三、C4.5演算法

如果你已經理解了上面ID3演算法的實現,那麼理解C4.5也很容易了,C4.5與ID3在核心的演算法是一樣的,但是有一點所採用的辦法是不同的,C4.5採用了資訊增益率作為劃分的根據,克服了ID3演算法中採用資訊增益劃分導致屬性選擇偏向取值多的屬性。資訊增益率的公式為:


分母的位置是分裂因子,他的計算公式為:


和熵的計算公式比較像,具體的資訊增益率的演算法也在上面的程式碼中了,請關注著2個方法:

		// 選擇剩餘屬性中資訊增益最大的作為下一個分類的屬性
		for (int i = 0; i < remainAttr.size(); i++) {
			// 判斷是否用ID3演算法還是C4.5演算法
			if (isID3) {
				// ID3演算法採用的是按照資訊增益的值來比
				tempValue = computeGain(remainData, remainAttr.get(i));
			} else {
				// C4.5演算法進行了改進,用的是資訊增益率來比,克服了用資訊增益選擇屬性時偏向選擇取值多的屬性的不足
				tempValue = computeGainRatio(remainData, remainAttr.get(i));
			}

			if (tempValue > gainValue) {
				gainValue = tempValue;
				attrName = remainAttr.get(i);
			}
		}
在補充一下C4.5在其他方面對ID3的補充和改進:

1、在構造決策樹的過程中能對樹進行剪枝。

2、能對連續性的值進行離散化的操作。

四、編碼時遇到的一些問題

為了實現ID3演算法,從理解閱讀他的原理就已經用掉了比較多的時間,然後再嘗試閱讀別人寫的C++版本的程式碼,又是看了幾天,好不容易實現了2個演算法,最後在構造樹的過程中遇到了最大了麻煩,因為用到了遞迴構造樹,對於其中節點的設計就顯得至關重要了,也許我自己目前的設計也不是最優秀的。下面盤點一下我的程式的遇到的一些問題和存在的潛在的問題:

1、在構建決策樹的時候,出現了remainAttr值缺少的情況,就是遞迴的時候remainAttr的屬性劃分移除掉之後,對於上次的遞迴操作的屬性時受到影響了,後來發現是因為我remainAttr採用的是ArrayList,他是一個引用物件,通過引用傳入的方式,物件用的還是同一個,所以果斷重新建了一個ArrayList物件,問題就OK了。

				// 建立新的物件屬性,物件的同個引用會出錯
				ArrayList<String> rAttr = new ArrayList<>();
				for (String str : remainAttr) {
					rAttr.add(str);
				}

				buildDecisionTree(childNode[i], valueTypes.get(i), rData,
						rAttr, isID3);
2、第二個問題是當程式劃分到最後一個屬性時,如果出現了資料的類標識並不是同一個類的時候,我的處理操作時直接不處理,直接返回,會造成節點沒有資料屬性,也沒有資料索引。
	private void buildDecisionTree(AttrNode node, String parentAttrValue,
			String[][] remainData, ArrayList<String> remainAttr, boolean isID3) {
		node.setParentAttrValue(parentAttrValue);

		String attrName = "";
		double gainValue = 0;
		double tempValue = 0;

		// 如果只有1個屬性則直接返回
		if (remainAttr.size() == 1) {
			System.out.println("attr null");
			return;
		}
		.....
在這種情況下的處理不是很恰當個人覺得是這樣。

相關推薦

決策分類演算法ID3C4.5系列

一、引言 在最開始的時候,我本來準備學習的是C4.5演算法,後來發現C4.5演算法的核心還是ID3演算法,所以又輾轉回到學習ID3演算法了,因為C4.5是他的一個改進。至於是什麼改進,在後面的描述中我會提到。 二、ID3演算法 ID3演算法是一種分類決策樹演算法。他通過一系

決策演算法ID3C4.5CART)

ID3,C4.5,CART是是決策樹的核心演算法。它們都由特徵選擇,樹的生成,剪枝組成。但ID3和C4.5用於分類,CART可用於分類與迴歸。 1.ID3演算法 ID3演算法遞迴地構建決策樹,從根節點開始,對所有特徵計算資訊增益,選擇資訊增益最大的特徵作為節點的特徵,由該特徵的不同取值建

機器學習回顧篇(7):決策演算法ID3C4.5

  注:本系列所有部落格將持續更新併發布在github上,您可以通過github下載本系列所有文章筆記檔案。   1 演算法概述¶

影象演算法二:特徵提取系列Harris

Harris運算元介紹: 該運算元是C.Harris和M.J.Stephens在1988年提出的一種點特徵提取運算元。這種運算元受訊號處理中自相關函式的啟發,可以給出影象中某一畫素點的自相關矩陣肘,其特徵值是自相關函式的一階曲率,如果X,Y兩個方向上的曲率值都

機器學習總結(八)決策ID3C4.5演算法CART演算法

本文主要總結決策樹中的ID3,C4.5和CART演算法,各種演算法的特點,並對比了各種演算法的不同點。 決策樹:是一種基本的分類和迴歸方法。在分類問題中,是基於特徵對例項進行分類。既可以認為是if-then規則的集合,也可以認為是定義在特徵空間和類空間上的條件概率分佈。 決策樹模型:決策樹由結點和有向邊組

離散型與連續型資料決策構建及列印實現 R語言ID3C4.5演算法

本人的第一篇文章,趁著我們的資料探勘課設的時間,把實現的決策樹程式碼,拿出來分享下。有很多漏洞和缺陷,還有很多駭客思想的成分,但是總之,能實現,看網上的程式碼,能用的其實也沒幾個。廢話不多說,直接看程式碼 特別鳴謝博主skyonefly的程式碼 附上鍊接:R

決策演算法ID3C4.5 CART

決策樹是機器學習中非常經典的一類學習演算法,它通過樹的結構,利用樹的分支來表示對樣本特徵的判斷規則,從樹的葉子節點所包含的訓練樣本中得到預測值。決策樹如何生成決定了所能處理的資料型別和預測效能。主要的決策樹演算法包括ID3,C4.5, CART等。 1,ID3 ID3是由 

機器學習演算法 --- 決策ID3C4.5

一、決策樹基本概念及演算法優缺點 1.什麼是決策樹 分類決策樹模型是一種描述對例項進行分類的樹形結構。決策樹由結點和有向邊組成。結點有兩種型別:內部結點和葉結點。內部結點表示一個特徵或屬性,葉結點表示一個類。 決策樹(Decision Tree),又稱判定

【面試考】【入門】決策演算法ID3C4.5和CART

關於決策樹的purity的計算方法可以參考: [決策樹purity/基尼係數/資訊增益 Decision Trees](https://www.cnblogs.com/PythonLearner/p/12940067.html) 如果有不懂得可以私信我,我給你講。 ## ID3 用下面的例子來理解這個演算法:

演算法-基於ID3C4.5決策演算法

目錄   摘要 構建過程 ID3演算法 注意點: C4.5 參考文獻: 摘要 決策樹演算法是相對比較清晰簡單的有監督分類演算法,所謂有監督就是需要給出標準的已知分類的樣本資料集,根據資料集訓練或者說構建出一個模型,然後根據模型對新的資料進行預測分類。

決策ID3C4.5、C5.0

2011年獲得了資料探勘領域最高榮譽獎KDD創新獎,昆蘭發明了著名的決策樹學習演算法ID3、C4.5,其個人主頁公佈了C4.5的C程式碼。—————————————————————————————————————————————————————————————————————

【機器學習】決策(三)——生成演算法ID3C4.5與CRAT)

回顧 前面我們介紹了決策樹的特徵選擇,以及根據資訊增益構建決策樹。 那麼決策樹的生成又有哪些經典演算法呢?本篇將主要介紹ID3的生成演算法,然後介紹C4.5中的生成演算法。最後簡單介紹CRAT演算法。 ID3演算法 前面我們提到,一般而言,資訊增

決策ID3C4.5、CART演算法:資訊熵區別剪枝理論總結

決策樹演算法中的ID3、c4.5、CART演算法,記錄如下:     決策樹演算法:顧名思義,以二分類問題為例,即利用自變數構造一顆二叉樹,將目標變數區分出來,所有決策樹演算法的關鍵點如下:     1.分裂屬性的選擇。即選擇哪個自變數作為樹叉,也就是在n個自變數中,優先選

決策的構建演算法 -- ID3C4.5 演算法

1. 概述 上一篇日誌中,我們介紹了最簡單的分類迴歸演算法 – K 近鄰演算法。 k 近鄰演算法 本篇日誌我們來介紹構建專家系統和資料探勘最常用的演算法 – 決策樹。 2. 決策樹 在系統流程圖中,我們常

R語言學習系列(資料探勘決策演算法實現--ID3程式碼篇)

轉載自:http://blog.csdn.net/hawksoft/article/details/7760868 1、輔助類,用於計算過程和結果儲存 [csharp] view plaincopyprint? /// &

決策分類器(ID3C4.5 Java實現)

分類 什麼是分類?舉個例子,銀行貸款員需要分析資料,以便搞清楚哪些是貸款申請者是值得信賴的。通訊公司也希望能分清楚哪些客戶容易接受某一套餐,從而定向營銷。資料分類一般又包括學習階段(構建分類器)和分類階段(使用模型預測給定資料的類標號)。 決策樹分類器

ID3C4.5決策演算法總結

1.決策樹的演算法流程 決策樹的演算法流程主要是: 1.如果當前樣本集全部為同一類別,則返回這一類標籤 2.如果當前屬性集為空集或者D中樣本在屬性集中的取值全部相同,那麼採用多數表決法,返回樣本數最多的類標籤 3.如果不滿足上面三個條件,說明當前結點還可

Python3實現機器學習經典演算法(四)C4.5決策

一、C4.5決策樹概述   C4.5決策樹是ID3決策樹的改進演算法,它解決了ID3決策樹無法處理連續型資料的問題以及ID3決策樹在使用資訊增益劃分資料集的時候傾向於選擇屬性分支更多的屬性的問題。它的大部分流程和ID3決策樹是相同的或者相似的,可以參考我的上一篇部落格:https://www.cnblogs.

決策ID3C4.5、CART、隨機森林的原理與例子

(寫在前面:作者是一名剛入學的模式識別專業的碩士生,第一次寫部落格,有錯誤的地方還請大家多多指教評論,一起交流呀~) 決策樹的基本流程 ①劃分特徵的選擇(常見的選擇方法有:資訊增益、增益率、基尼指數,下文會詳細介紹) ②劃分停止準則:停止準則表示該節點不再劃分

決策的進化(ID3C4.5、CART、GBDT、RF、DART、lambdaMART、XGBoost、lightGBM)

pipeline 在資料探勘領域中,決策樹是對資料進行建模的一種很有效的手段。當資料集被清洗好後,資料集就是樣本的集合,每一個樣本都是有一樣多的屬性,但屬性值可能不同(也有可能不存在即屬性值缺失)。每一個樣本,分為屬性(也可稱為特徵)和label兩部分,我們運用決策樹處理資