點一下關注吧!!!非常感謝!!持續更新!!!
大模型篇章已經開始!
- 目前已經更新到了第 22 篇:大語言模型 22 - MCP 自動操作 Figma+Cursor 自動設計原型
Java篇開始了!
- MyBatis 更新完畢
- 目前開始更新 Spring,一起深入淺出!
目前已經更新到了:
- Hadoop(已更完)
- HDFS(已更完)
- MapReduce(已更完)
- Hive(已更完)
- Flume(已更完)
- Sqoop(已更完)
- Zookeeper(已更完)
- HBase(已更完)
- Redis (已更完)
- Kafka(已更完)
- Spark(已更完)
- Flink(已更完)
- ClickHouse(已更完)
- Kudu(已更完)
- Druid(已更完)
- Kylin(已更完)
- Elasticsearch(已更完)
- DataX(已更完)
- Tez(已更完)
- 數據挖掘(已更完)
- Prometheus(已更完)
- Grafana(已更完)
- 離線數倉(已更完)
- 實時數倉(正在更新…)
- Spark MLib (正在更新…)
預剪枝和后剪枝
決策樹對訓練集有很好的分類能力,但是對于未知的測試集未必能有很好的分類能力,導致模型的泛化能力差,可能發生過擬合的情況,為了防止過擬合的情況出現,可以對決策樹進行剪枝,剪枝分為預剪枝和后剪枝。
預剪枝
預剪枝就是在構建決策樹的時候提前停止,比如指定樹的深度最大為3,那么訓練出來的決策樹的高度就是3,預剪枝主要是建立某些規則限制決策樹的生長,降低了過擬合的風險,降低了建樹的時間,但是有可能帶來欠擬合的問題。
后剪枝
后剪枝是一種全局的優化方法,在決策樹構建好之后,然后才開始進行剪枝。后剪枝的過程就是刪除一些子樹,這個葉子節點的標識類別通過大多數原則來確定,即屬于這個葉子節點下大多數樣本所屬的類別就是該葉子節點的標識。
選擇減掉哪些子樹時,可以計算沒有減掉子樹之前的誤差和減掉子樹之后的誤差,如果相差不大,可以將子樹減掉。
一般使用后剪枝得到的結果比較好。
算法總結
- 分裂標準(Split Criterion):選擇劃分屬性與劃分點
- 樹生成(Growing):遞歸地對子集繼續分裂
- 剪枝(Pruning):降低過擬合:預剪枝 / 事后剪枝
- 葉節點預測:分類樹:投票 / 概率;回歸樹:均值 / 中位數
ID3、C4.5、CART 的區別主要體現在 分裂標準、支持的屬性類型、樹結構與剪枝方法。
ID3
存在的缺點:
● ID3 算法在選擇根節點和各內部節點中的分支屬性時,采用信息增益作為評價標準。信息增益的缺點是傾向于選擇取值較多的屬性,在有些情況下這類屬性可能不會提供太多有價值的信息
● ID3 算法只能對描述屬性為離散型屬性的數據集構造決策樹
核心思想
信息增益 (Information Gain):選擇能最大化熵下降(信息增益)的屬性來分裂,僅支持 離散屬性;連續屬性需先離散化。
算法流程
- 計算當前數據集 D 的熵 H(D)
- 對每個屬性 a 計算 Gain(D,a)
- 選 Gain 最大者分裂,對子集遞歸生成子樹
- 當屬性耗盡或樣本純度足夠時停止
C4.5
那為什么 C4.5 好呢?
● 用信息增益率來選擇屬性
● 可以處理連續數值型屬性
● 采用了一種后剪枝的方法
● 對于缺失值的處理
優點:
● 產生的分類規則易于理解,準確率較高
缺點:
● 在構造數的過程中,需要對數據集進行多次的順序掃描和排序,因而導致算法的低效
● 只適合與能夠駐留在內存的數據集,當訓練集大得無法再內存中時則程序無法運行
CART
CART算法相比C4.5算法的分類方法,采用了簡化的二叉樹模型,同時特征選擇采用了近似的基尼系數來簡化計算。
流程要點
- 對每個特征枚舉所有切分點 → 計算基尼下降量 / 均方誤差下降量
- 選最大下降量的「特征 + 切分點」做二分
- 直到葉節點樣本少于閾值或純度滿足停止準則
- 代價復雜度剪枝得到最終子樹
決策樹案例
package icu.wzk.logicimport org.apache.spark.mllib.tree.DecisionTree
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.{SparkConf, SparkContext}object LogicTest2 {def main(args: Array[String]): Unit = {val conf = new SparkConf().setMaster("local").setAppName("dt")val sc = new SparkContext(conf)sc.setLogLevel("warn")//讀取數據集val labeledPointData = MLUtils.loadLibSVMFile(sc, "./data/dt.data")val trainTestData = labeledPointData.randomSplit(Array(0.8, 0.2), seed = 1)val trainData = trainTestData(0)val testData = trainTestData(1)//訓練模型val categoriFeatureMap = Map[Int, Int](0 -> 4, 1 -> 4, 2 -> 3, 3 -> 3)val model = DecisionTree.trainClassifier(trainData, 2,categoriFeatureMap, "entropy", 3, 32)//預測val testRes = testData.map(data => {(model.predict(data.features), data.label)})testRes.take(10).foreach(println(_))//評價val errorRate = testRes.filter(x => x._1 != x._2).count().toDouble /testData.count()println("錯誤率:" + errorRate)//if-else展示println(model.toDebugString)sc.stop()}
}