上一期【人工智能-17】機器學習:KNN算法、模型選擇和調優、樸素貝葉斯分類
文章目錄
- 一、決策樹
- 1.使用理由
- 2.技術
- 二、隨機森林
- 1.使用理由
- 2.原理核心:Bagging + 隨機特征子集
- 3.優點和缺點
一、決策樹
決策樹是一種監督學習算法,主要用于分類(預測離散標簽,如“是/否”、“貓/狗/鳥”)和回歸(預測連續值,如房價、溫度)任務。
它的模型結構像一棵倒置的樹:
-
根節點 (Root Node): 包含整個數據集,代表最開始要判斷的特征。
-
內部節點 (Internal Node / Decision Node): 代表一個特征或屬性上的測試。基于測試結果,數據被分割到不同的子節點。
-
分支 (Branches): 代表一個特征測試的可能結果(例如,特征“年齡”的分支可能是“年齡<30”和“年齡>=30”)。
-
葉節點 (Leaf Node / Terminal Node): 代表最終的決策結果(分類標簽或回歸值)。數據到達葉節點后不再分割。
構建決策樹的過程就是通過一系列“如果…那么…”的規則,將復雜的數據集逐步分割成更小、更“純凈”的子集,直到達到停止條件(如子集足夠純凈、達到最大深度、包含樣本數太少等)。
1.使用理由
高度可解釋性: 這是決策樹最核心的優勢!生成的樹結構可以被直觀地可視化和理解,決策規則清晰透明(白盒模型),容易向非技術人員解釋預測背后的邏輯。這在需要理解模型決策過程的應用中(如金融風控、醫療診斷輔助)至關重要。
對數據預處理要求相對較低:
-
能直接處理分類特征和數值特征(數值特征需要選擇分割點)。
-
對特征的尺度(量綱)不敏感(因為決策是基于值比較,而不是距離計算)。
-
對缺失值有一定容忍度(可以通過特定策略處理,如分配到出現頻率最高的分支,或單獨創建分支)。
能夠捕捉特征之間的非線性關系: 通過樹的分支結構,可以自然地建模特征之間復雜的相互作用和非線性模式。
計算效率較高(訓練和預測): 訓練算法(如ID3, C4.5, CART)相對高效,預測新樣本的速度非常快,只需要沿著樹從根節點走到一個葉節點即可。
2.技術
決策樹構建的核心在于如何選擇“最佳”特征和分割點來分裂節點,目標是讓分裂后的子節點盡可能“純凈”。衡量“純凈度”的標準主要有兩種:
- 基于信息增益 (Information Gain )
- 信息熵 (Entropy): 衡量數據集
D
的不確定性(混亂度)。熵越高,表示數據類別越混雜;熵為0,表示所有樣本都屬于同一類。公式核心思想:對每個類別k
,計算其占比p_k
,然后求和-p_k * log2(p_k)
。p_k
越平均(接近0.5),熵越大。 - 信息增益 (IG): 衡量使用某個特征
A
對數據集D
進行分割后,不確定性減少的程度。- 計算分裂前數據集
D
的熵H(D)
。 - 根據特征
A
的每個可能取值(或分割點)將D
分成若干子集D_v
。 - 計算分裂后所有子集的熵的加權平均值
H(D|A)
(權重是子集樣本數占總樣本數的比例)。 - 信息增益
IG(D, A) = H(D) - H(D|A)
。
- 計算分裂前數據集
- 特征選擇: 選擇能帶來最大信息增益的特征進行當前節點的分裂。信息增益越大,意味著使用該特征分裂后,子集變得更“純凈”(不確定性降低得最多)。
- 缺點: 信息增益傾向于選擇取值數目多的特征(如“身份證號”),因為分裂后子集純度容易更高(極端情況每個樣本一個子集,熵為0),但這會導致過擬合且沒有泛化能力。
- 改進:信息增益率 (Gain Ratio - C4.5算法): 引入一個懲罰項,稱為“分裂信息”
SplitInfo(A)
,它衡量按特征A
分裂時產生的分支數量的多少(分支越多,SplitInfo(A)
越大)。信息增益率GR(D, A) = IG(D, A) / SplitInfo(A)
。這抑制了對取值多特征的偏好。
- 信息熵 (Entropy): 衡量數據集
- 基于基尼指數 (Gini Index / Gini Impurity )
- 基尼指數: 衡量從數據集
D
中隨機抽取兩個樣本,它們屬于不同類別的概率。概率越大,基尼指數越高,數據越不純。公式核心思想:對每個類別k
,計算其占比p_k
,然后求和1 - Σ(p_k2)
。p_k
越平均(接近0.5),基尼指數越高(最大0.5);p_k
越偏向0或1(純),基尼指數越低(最小0)。 - 特征選擇:
- 計算分裂前數據集
D
的基尼指數Gini(D)
。 - 根據特征
A
的每個可能取值(或分割點)將D
分成若干子集D_v
。 - 計算分裂后所有子集的基尼指數的加權平均值
Gini(D|A)
。 - 選擇能使
Gini(D|A)
最小(即分裂后子集純度提升最大)的特征進行分裂。等價于選擇能使基尼指數減少量(基尼增益)最大的特征。
- 計算分裂前數據集
- 特點: 基尼指數計算比熵稍快(不用算log),實踐中效果通常與信息增益/信息增益率相似。CART算法使用基尼指數,并且其構建的樹是二叉樹(每次分裂只產生兩個子節點),對數值特征處理更自然(尋找一個最佳分割點)。
- 基尼指數: 衡量從數據集
# 決策樹 對葡萄酒進行分類
# 基于信息增益的決策樹
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
# 獲取數據
x,y = load_wine(return_X_y=True)# 劃分數據集
x_train,x_test,y_train,y_test = train_test_split(x,y,train_size=0.8,random_state=22)# 模型訓練
# 當模型訓練時,criterion參數可以指定信息增益的計算方式,默認是gini,也可以指定為entropy
model = DecisionTreeClassifier(criterion='entropy')
model.fit(x_train,y_train)
print('準確率\n',model.score(x_test,y_test))
print('預測結果\n',model.predict(x_test))# 基于基尼指數的決策樹
# 當criterion='gini'時,使用基尼指數
gini = DecisionTreeClassifier(criterion='gini')
gini.fit(x_train,y_train)
print('準確率\n',gini.score(x_test,y_test))
print('預測結果\n',gini.predict(x_test))
二、隨機森林
- 隨機森林是一種基于Bagging(Bootstrap Aggregating)集成學習思想,并引入了隨機特征選擇的算法。它的核心是構建多棵決策樹(稱為“森林”),并通過投票(分類)或平均(回歸)的方式結合這些樹的預測結果,從而獲得比單一決策樹更優、更穩定的性能。
- 簡單來說:隨機森林 = Bagging + 隨機特征子集 + 決策樹(通常是CART樹)。
1.使用理由
- 顯著提高泛化能力,減少過擬合: 這是使用隨機森林最根本的理由。單一決策樹容易過擬合。通過集成大量略微不同且不完全過擬合的樹,隨機森林能夠有效地降低模型的方差(Variance),提高在未知數據上的預測精度和魯棒性。
- 提升預測準確性和穩定性: 通過“眾人智慧”(多棵樹投票/平均),隨機森林通常能獲得比單棵決策樹以及其他許多單一模型更高的預測準確率。同時,它對訓練數據的小擾動不敏感,結果更穩定。
- 處理高維特征: 在每棵樹分裂節點時只考慮隨機選取的部分特征(而不是全部),這在高維數據中非常有效,能降低計算量并減少不相關特征的干擾。
- 提供特征重要性評估: 隨機森林可以方便地計算出每個特征對預測結果的相對重要性,有助于特征選擇和理解數據。
- 保留決策樹的部分優點: 雖然可解釋性不如單棵樹,但仍然能處理混合類型特征、對量綱不敏感、能捕捉非線性關系等。
2.原理核心:Bagging + 隨機特征子集
隨機森林的訓練過程如下:
- Bagging (Bootstrap Aggregating):
- 從原始訓練集
D
中有放回地隨機抽取N
個樣本(形成一個Bootstrap
樣本集D_i
)。這意味著每個樣本集D_i
的大小與D
相同,但包含重復樣本,且平均約有 63.2% 的原始樣本會被抽中,剩下的約 36.8% 成為該樹的袋外樣本 (Out-Of-Bag, OOB),可用于評估該樹的性能或特征重要性。 - 重復上述過程
T
次,得到T
個不同的 Bootstrap 訓練集{D_1, D_2, ..., D_T}
。
- 從原始訓練集
- 構建決策樹 (使用隨機特征子集):
- 對于每個 Bootstrap 訓練集
D_i
,獨立地訓練一棵決策樹。 - 關鍵點:在訓練每棵樹的每個內部節點進行分裂時,不是從所有
M
個特征中選擇最優特征,而是先隨機選取m
個特征(m
通常遠小于M
,如m = sqrt(M)
或m = log2(M)
+ 1),然后從這m
個特征中選擇最優特征進行分裂。 - 讓樹完全生長或接近完全生長(通常不剪枝或輕微剪枝),以達到低偏差(Bias)。通過集成來降低方差。
- 對于每個 Bootstrap 訓練集
- 聚合預測 (Aggregation):
- 分類任務: 對于新樣本,讓
T
棵樹分別進行預測,然后采用多數投票法(Majority Voting)決定最終的類別標簽。 - 回歸任務: 對于新樣本,讓
T
棵樹分別進行預測,然后取所有預測值的平均值作為最終預測值。
- 分類任務: 對于新樣本,讓
核心思想:
- Bagging: 通過 Bootstrap 抽樣引入樣本擾動,構建多樣化的樹(減少因數據擾動引起的方差)。
- 隨機特征子集: 在節點分裂時隨機選擇特征子集,強制樹之間產生差異(降低樹與樹之間的相關性),進一步增加模型的多樣性(減少因特征選擇相關性引起的方差)。
- 集成: 結合多個獨立、多樣化且具有低偏差的弱學習器(樹)的預測結果,通過“平均”效應顯著降低整體模型的方差,提高泛化能力。
# 隨機森林
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split,GridSearchCV# 獲取數據
x,y = load_wine(return_X_y=True)# 劃分數據集
x_train,x_test,y_train,y_test = train_test_split(x,y,train_size=0.8,random_state=22)# 模型訓練
# n_estimators: 樹的數量 默認100 max_depth: 樹的最大深度 默認None criterion: 決策樹屬性劃分算法選擇 默認gini enteropy是信息增益
Model = RandomForestClassifier(n_estimators=100,max_depth=None,criterion='gini')
param_grid = {'max_depth':[3,5,10,20],'n_estimators':[100,200,300,400,500]}
# 使用超參數網格搜索,尋找最佳參數
enstimators = GridSearchCV(Model,param_grid=param_grid,cv=5)
enstimators.fit(x_train,y_train)# 模型評估
print('準確率:\n',enstimators.score(x_test,y_test))
print('預測結果:\n',enstimators.predict(x_test))# 獲取最佳參數
print('最佳參數:\n',enstimators.best_params_)
# 獲取最佳模型
print('最佳模型:\n',enstimators.best_estimator_)
3.優點和缺點
- 優點:
- 高精度: 通常在分類和回歸任務中表現出色,預測準確性高。
- 魯棒性強: 對噪聲數據和異常值不太敏感。
- 不易過擬合: 得益于Bagging和特征隨機性,即使樹很深,整體模型也較難過擬合(相比單棵樹)。
- 處理高維特征: 能有效處理特征數量很多的數據集。
- 提供特征重要性: 可以評估特征對預測的貢獻度。
- 并行化訓練: 每棵樹的訓練是完全獨立的,可以輕松并行化,加速訓練過程。
- 內置驗證: 袋外樣本 (OOB) 可以用于無偏估計模型的泛化誤差,無需額外驗證集。
- 保留決策樹部分優點: 處理混合特征、非線性關系等。
- 缺點:
- 模型可解釋性降低: 雖然比“黑箱”模型(如神經網絡)稍好,但由成百上千棵樹組成的森林難以直觀解釋單個預測(犧牲了單棵樹的最大優勢)。
- 訓練時間和內存消耗較大: 需要訓練多棵樹,尤其是在樹很深或樹的數量
T
很大時。預測速度雖然單次很快,但需要遍歷所有樹,比單棵樹慢T
倍(但仍通常很快)。 - 可能產生偏差較大的模型: 如果數據噪聲很大或特征與目標關系很弱,隨機森林可能會學到有偏差的模型(雖然方差低)。
- 對某些類型的數據關系(如線性關系)可能不如專門模型高效: 雖然能處理,但可能不如線性模型簡單直接。
- 超參數需要調整: 樹的數量
T
、每次分裂考慮的特征數m
、樹的最大深度等超參數需要調整以獲得最佳性能(盡管通常比SVM等調參簡單,且T
越大一般越好,但有計算成本)。