集成学习之随机森林

集成学习之随机森林

一棵决策树容易"死记硬背"过拟合,那就种一片森林让它们集体投票------这就是随机森林的核心哲学。本文将从"为什么需要随机森林"出发,结合两个实战案例(垃圾邮件识别、银行贷款违约预测)逐行解析代码逻辑,详细讲解参数调优方法,并对比随机森林与决策树的差异。


📚 目录


一、从决策树的痛点说起:为什么需要随机森林?

在学习决策树时我们已经知道:一棵没有约束的决策树会不断生长,直到把每个训练样本都"完美"分对为止。这就像一个学生把考试题原题死记硬背下来,遇到新题就傻眼了------这就是过拟合(Overfitting)

那有没有办法让模型既保留决策树"可解释、易实现"的优点,又不容易过拟合呢?思路很朴素:

"三个臭皮匠,顶个诸葛亮" ------ 既然一棵树容易犯错,那就训练很多棵树,让它们集体决策。

这就是集成学习(Ensemble Learning) 的思想:组合多个"弱学习器",得到一个更强的"强学习器"。


二、集成学习的两大流派

在进入随机森林之前,先厘清集成学习的两大流派,避免混淆:

流派 代表算法 核心思想 类比
Bagging(装袋法) 随机森林 多个模型并行训练,相互独立,最终投票/平均 多个学生独立做题,最后对答案取多数
Boosting(提升法) GBDT、XGBoost、AdaBoost 模型串行训练,后一个模型纠正前一个的错误 学生做完题对答案,下个学生专攻上个人做错的题

随机森林(Random Forest)属于 Bagging 流派,它的"弱学习器"就是决策树。


三、随机森林算法详解

3.1 核心思想

随机森林 = Bagging + 决策树 + 特征随机化

它通过**两个"随机"**来保证每棵树都不一样,从而让森林"既聪明又多样":

  1. 样本随机(Row Random) :每棵树从训练集中有放回地 抽取相同数量的样本(Bootstrap 抽样)。这样每棵树看到的样本不一样,有的样本会被重复抽中,有的样本一次都抽不到(约 36.8% 的样本不会被抽中,称为袋外数据 OOB)。
  2. 特征随机(Column Random) :每次节点分裂时,不是从所有特征里选最优分裂点,而是先随机抽一部分特征,再在这部分特征里选最优。

💡 通俗类比:假设你要判断一封邮件是不是垃圾邮件。

  • 如果只问一个人(一棵树),他可能只盯着"免费"这个词就下结论,太片面。
  • 随机森林的做法是:找 100 个人,每个人只看邮件的一部分内容(特征随机)和一部分案例(样本随机),最后举手表决。这样结论更稳健。

3.2 工作流程

训练阶段:

复制代码
输入:训练集 D,决策树数量 T,每次分裂随机选的特征数 m
1. for i = 1 to T:
2.     从 D 中有放回抽样得到子集 D_i(Bootstrap)
3.     用 D_i 训练一棵决策树 T_i,每次分裂只从 m 个随机特征中选最优
4.     决策树完全生长(不剪枝,靠随机性防过拟合)
输出:森林 {T_1, T_2, ..., T_T}

预测阶段:

  • 分类任务 :所有树各自预测一个类别,多数投票(Majority Voting) 决定最终结果。
  • 回归任务 :所有树预测值的平均值作为最终结果。

3.3 袋外数据(OOB)------免费的验证集

由于 Bootstrap 是有放回抽样,每棵树大约有 36.8% 的训练样本没有被抽到,这部分叫袋外数据(Out-Of-Bag, OOB)

这相当于每棵树自带了一个"没见过的验证集",可以直接用它评估模型,不用额外划分验证集 。sklearn 中设置 oob_score=True 即可启用。

3.4 算法结构示意图

下图直观展示了随机森林的训练与预测流程:训练阶段通过 Bootstrap 抽样生成多棵相互独立的决策树,预测阶段对所有树的输出进行投票(分类)或平均(回归)。

3.5 RandomForestClassifier API 参数详解

sklearn 中随机森林分类器的完整签名:

python 复制代码
from sklearn.ensemble import RandomForestClassifier

RandomForestClassifier(
    n_estimators=100,      # 森林中决策树的数量
    criterion='gini',      # 分裂质量的度量标准
    max_depth=None,        # 决策树最大深度
    min_samples_split=2,   # 节点继续分裂所需的最小样本数
    min_samples_leaf=1,    # 叶子节点最少样本数
    min_weight_fraction_leaf=0.0,  # 叶子节点最小权重和占比
    max_features='auto',   # 每次分裂随机选用的特征数
    max_leaf_nodes=None,   # 叶子节点最大数量
    min_impurity_decrease=0.0,     # 分裂引起的最小不纯度下降值
    bootstrap=True,        # 是否进行 Bootstrap 有放回抽样
    oob_score=False,       # 是否使用袋外数据评估
    n_jobs=None,           # 并行训练的 CPU 核数
    random_state=None,     # 随机种子
    verbose=0,             # 日志冗余度
    warm_start=False,      # 是否在已有模型基础上继续训练
    class_weight=None,     # 类别权重(处理样本不平衡)
    ccp_alpha=0.0,         # 最小代价复杂度剪枝参数
)

按作用分组介绍:

① 森林规模与随机性
参数 说明
n_estimators 决策树数量。越多越稳定,但收益递减且训练变慢。通常 100~500 足够,本文代码用 50/100。
bootstrap 是否 Bootstrap 抽样,默认 True。若设 False,则每棵树用全部样本训练(失去样本随机性,不推荐)。
random_state 随机种子,固定后结果可复现。调参时务必固定,否则无法判断参数效果。
n_jobs 并行训练核数,-1 表示用全部 CPU 核。案例二用了 n_jobs=-1 加速。
② 特征随机化
参数 说明
max_features 每次分裂随机选用的特征数。可取值: • 'auto'/'sqrt':√总特征数(分类默认) • 'log2':log₂(总特征数) • 浮点数 0.8:总特征数 × 0.8(本文代码用法) • 整数 5:固定 5 个 • None:用全部特征(失去特征随机性) 越小,树之间差异越大,越抗过拟合,但单棵树准确率下降。
③ 树的结构(控制过拟合的核心,本文重点调优对象)
参数 说明
criterion 分裂标准,'gini'(基尼系数,默认)或 'entropy'(信息熵)。两者效果通常接近。
max_depth 树的最大深度。越大越容易过拟合,None 表示不限。本文调优区间 5,10,15,20
min_samples_split 节点继续分裂所需最小样本数。越大越保守,本文调优区间 2,3,4,5
min_samples_leaf 叶子节点最少样本数。越大越平滑,本文调优区间 1,2,3,4,5
max_leaf_nodes 叶子节点最大数量,None 表示不限。可替代 max_depth 控制复杂度。
min_impurity_decrease 分裂必须带来的最小不纯度下降,否则不分裂。值越大越保守。
ccp_alpha 最小代价复杂度剪枝参数(后剪枝)。值越大剪枝越狠,0 表示不剪枝。
④ 样本权重与评估
参数 说明
class_weight 类别权重,处理样本不平衡。可取 'balanced'(自动按频率反比加权)、字典 {0:1, 1:5}、None。案例二用的是下采样,也可改用此参数。
min_weight_fraction_leaf 叶子节点最小权重和占比,作用类似 min_samples_leaf 但基于权重。
oob_score 是否用袋外数据评估,默认 False。设 True 可通过 rf.oob_score_ 查看袋外准确率,省去划分验证集
warm_start 是否在已有模型上继续添加树,适合逐步增大 n_estimators 观察 OOB 曲线。

💡 调参优先级建议

  1. 先固定 random_state,设 n_estimators 足够大(如 100)。
  2. 重点调 max_depthmin_samples_splitmin_samples_leaf 三个结构参数(本文做法)。
  3. 视情况调整 max_featuresclass_weightoob_score
  4. 最后微调 n_estimators 至性能稳定(再增大无提升)。

四、代码实战一:垃圾邮件识别

数据集 spambase.csv 包含 4601 封邮件,57 个特征(单词频率、字符频率、大写字母统计等),标签 label:1=垃圾邮件,0=正常邮件。

4.1 数据加载与划分

python 复制代码
import pandas as pd
from sklearn.model_selection import train_test_split

df = pd.read_csv("/Classical_Machine_Learning/data/spambase.csv")

x = df.iloc[:, :-1]   # 前 57 列为特征
y = df.iloc[:, -1]    # 最后一列为标签

xtrain, xtest, ytrain, ytest = train_test_split(x, y, test_size=0.2, random_state=42)
  • test_size=0.2:80% 训练,20% 测试。
  • random_state=42:固定随机种子,保证结果可复现。

4.2 网格搜索 + 交叉验证调参

这是本文的核心,重点讲解:

python 复制代码
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

# 待调优的三组参数
max_depth = [5, 10, 15, 20]          # 决策树最大深度
min_samples_split = [2, 3, 4, 5]     # 节点继续分裂所需的最小样本数
min_samples_leaf = [1, 2, 3, 4, 5]   # 叶子节点最少样本数

best_score = 0
i = 1
for depth in max_depth:
    for split in min_samples_split:
        for leaf in min_samples_leaf:
            rf1 = RandomForestClassifier(
                n_estimators=100,        # 森林里决策树的数量
                max_features=0.8,        # 每次分裂随机选 80% 特征
                max_depth=depth,
                min_samples_split=split,
                min_samples_leaf=leaf,
                random_state=42,
            )
            # 8 折交叉验证,评价指标用 recall(召回率)
            score = cross_val_score(rf1, xtrain, ytrain, cv=8, scoring='recall')
            mean_score = score.mean()

            if mean_score > best_score:
                best_score = mean_score
                best_depth = depth
                best_split = split
                best_leaf = leaf
            print(f"第{i}条:Depth={depth},Split={split},Leaf={leaf} -> Recall: {mean_score:.4f}")
            i += 1

print(f"Best_depth={best_depth},Best_split={best_split},Best_leaf={best_leaf},Best Score={best_score:.4f}")

运行结果(节选):

复制代码
第1条:Depth=5,Split=2,Leaf=1 -> Recall: 0.8341
第2条:Depth=5,Split=2,Leaf=2 -> Recall: 0.8262
...
第80条:Depth=20,Split=5,Leaf=5 -> Recall: 0.8805
Best_depth=20,Best_split=2,Best_leaf=1,Best Score=0.8856

共 4×4×5=80 组参数组合,代码遍历所有组合,记录使召回率最高的一组。

4.3 用最优参数训练最终模型

python 复制代码
rf = RandomForestClassifier(
    n_estimators=100,
    max_features=0.8,
    max_depth=best_depth,
    min_samples_split=best_split,
    min_samples_leaf=best_leaf,
    random_state=42,
)
rf.fit(xtrain, ytrain)

train_predicted = rf.predict(xtrain)
test_predicted = rf.predict(xtest)

from sklearn import metrics
print("训练集测试结果:")
print(metrics.classification_report(ytrain, train_predicted, digits=9))
print("测试集训练结果:")
print(metrics.classification_report(ytest, test_predicted, digits=9))

运行结果示例:

复制代码
训练集测试结果:
              precision    recall  f1-score   support
           0  0.998930  0.997322  0.998125      2611
           1  0.995885  0.998354  0.997118      1069
    accuracy                      0.997798      3680
   macro avg  0.997408  0.997838  0.997621      3680

测试集训练结果:
              precision    recall  f1-score   support
           0  0.948000  0.970109  0.958923       549
           1  0.945098  0.904478  0.924340       335
    accuracy                      0.946798       884

可以看到训练集准确率 99.8%,测试集 94.7%,存在轻微过拟合(正常现象),但泛化能力已相当不错。

4.4 特征重要性可视化

随机森林有个非常有用的副产品------特征重要性(Feature Importance),它可以告诉我们哪些特征对分类贡献最大:

python 复制代码
import matplotlib.pyplot as plt

importances = rf.feature_importances_   # 模型自带的特征重要性属性
im = pd.DataFrame(importances, columns=['importances'])
clos = df.columns.tolist()[:-1]         # 去掉标签列
im['clos'] = clos

im = im.sort_values(by='importances', ascending=False)[:10]  # 取前 10 重要特征

index = range(len(im))
plt.yticks(index, im.clos)
plt.barh(index, im['importances'])
plt.show()

输出图形(横向条形图,越靠上越重要):

复制代码
Char_freq_!  ████████████████████  0.15
Word_freq_free ███████████████  0.11
Word_freq_remove ██████████  0.07
Capital_run_length_longest ███████  0.06
Word_freq_$ ██████  0.05
...(共 10 条)

这说明邮件中感叹号 !freeremove$ 等出现频率越高,越可能是垃圾邮件------非常符合直觉。


五、代码实战二:银行贷款违约预测(含样本不平衡处理)

第二个案例 银行贷款(随机森林).py 使用信用卡交易数据 creditcard.csv 检测欺诈交易。它的难点在于:正常交易(Class=0)远多于欺诈交易(Class=1),正负样本比例悬殊。

5.1 数据预处理与标准化

python 复制代码
import pandas as pd
from sklearn.preprocessing import StandardScaler

data = pd.read_csv(r".../creditcard.csv")

scaler = StandardScaler()
data['Amount'] = scaler.fit_transform(data[['Amount']])   # 对金额列做 Z 标准化
data = data.drop(['Time'], axis=1)                        # 删除无用的 Time 列
  • Z 标准化:把数据转成均值 0、方差 1 的分布,消除量纲影响。
  • Amount 列原本数值范围很大(0 ~ 几万),标准化后与其他特征处于同一量级,避免大数值特征"压制"小数值特征。

5.2 下采样解决样本不平衡

python 复制代码
from sklearn.model_selection import train_test_split

x_whole = data.drop(['Class'], axis=1)
y_whole = data['Class']
x_train_w, x_test_w, y_train_w, y_test_w = train_test_split(
    x_whole, y_whole, test_size=0.3, random_state=42)

x_train_w['Class'] = y_train_w
data_train = x_train_w

# 下采样:从多数类(正常)中抽取与少数类(欺诈)相同数量的样本
positive_eg = data_train[data_train['Class'] == 0]
negative_eg = data_train[data_train['Class'] == 1]
positive_eg = positive_eg.sample(len(negative_eg))   # 随机抽样使两类数量相等
data_c = pd.concat([positive_eg, negative_eg])

x_whole = data_c.drop('Class', axis=1)
y_whole = data_c.Class
x_train_w, x_test_w, y_train_w, y_test_w = train_test_split(
    x_whole, y_whole, test_size=0.3, random_state=1000)

💡 为什么要下采样?

假设欺诈样本只占 0.5%,如果直接训练,模型只要全部预测为"正常"就能达到 99.5% 准确率------但完全没识别出欺诈,毫无意义。下采样让两类样本数量相等,强迫模型认真学习少数类的特征。

5.3 调参与训练(带进度条)

逻辑与案例一相同,这里用 tqdm 增加了进度条,且评价指标仍是 recall

python 复制代码
from tqdm import tqdm

max_depth = [5, 10, 15]
min_samples_split = [2, 3, 4, 5]
min_samples_leaf = [1, 2, 3, 4, 5]

best_score = 0
total = len(max_depth) * len(min_samples_split) * len(min_samples_leaf)
with tqdm(total=total, desc="随机森林调参") as pbar:
    for depth in max_depth:
        for split in min_samples_split:
            for leaf in min_samples_leaf:
                rf1 = RandomForestClassifier(
                    n_estimators=50,
                    max_features=0.8,
                    max_depth=depth,
                    min_samples_split=split,
                    min_samples_leaf=leaf,
                    random_state=42,
                )
                score = cross_val_score(rf1, x_train_w, y_train_w,
                                        cv=8, scoring='recall', n_jobs=-1)
                mean_score = score.mean()
                if mean_score > best_score:
                    best_score = mean_score
                    best_depth = depth
                    best_split = split
                    best_leaf = leaf
                pbar.set_postfix({"最佳Recall": f"{best_score:.4f}"})
                pbar.update(1)

print(f"Best_depth={best_depth},Best_split={best_split},Best_leaf={best_leaf},Best Score={best_score:.4f}")

运行结果示例:

复制代码
随机森林调参: 100%|████████████████| 60/60 [02:13<00:00,  2.22s/it, 最佳Recall=0.9123]
Best_depth=10,Best_split=2,Best_leaf=1,Best Score=0.9123

后续 fit + predict + classification_report 与案例一一致,此处不再赘述。

关键差异点 :本例 n_jobs=-1 启用多核并行加速(cross_val_score 的参数),在大数据集上能显著缩短调参时间。


六、算法逻辑深度解析(基于代码)

6.1 整体执行流程

复制代码
原始数据 → 划分训练/测试集 → 网格搜索+交叉验证找最优参数
       → 用最优参数训练最终模型 → 训练集/测试集评估 → 特征重要性可视化

6.2 交叉验证(Cross Validation)的作用

代码中 cross_val_score(rf1, xtrain, ytrain, cv=8, scoring='recall') 是关键:

  • cv=8:把训练集分成 8 份,每次用 7 份训练、1 份验证,轮换 8 次,取平均。
  • 这样能避免"参数碰巧在某一划分下表现好"的偶然性,评估更稳健
  • 注意:交叉验证只在训练集 上做,测试集全程不参与调参,保证评估的客观性。

6.3 投票机制

RandomForestClassifier 内部预测时,100 棵树各自给出一个类别预测,最终取多数票。例如 100 棵树中 73 棵判定为垃圾邮件,27 棵判定为正常,则最终预测为垃圾邮件。这种"集体决策"比单棵树稳定得多。


七、参数调优详解(重点)

7.1 需要调优的参数一览

RandomForestClassifier 的参数可分为三类:

类别 参数 代码中的值 作用 是否需调优
森林规模 n_estimators 50 / 100 树的数量,越多越稳定但越慢 ⭐ 一般设大点(100~500),不必精细调
特征随机 max_features 0.8 每次分裂随机选 80% 特征 ⭐ 可调,分类常用 √总特征数
树的结构 max_depth 5,10,15,20 树的最大深度,控制过拟合 ⭐⭐⭐ 必调
min_samples_split 2,3,4,5 节点继续分裂所需最小样本数 ⭐⭐⭐ 必调
min_samples_leaf 1,2,3,4,5 叶子节点最少样本数 ⭐⭐⭐ 必调
随机性 random_state 42 固定随机种子,保证可复现 不调(固定即可)

💡 记忆口诀

  • max_depth:树能长多"高"------越大越容易过拟合。
  • min_samples_split:节点要"分裂"至少需要多少样本------越大越保守。
  • min_samples_leaf:叶子要"结出"至少多少样本------越大越平滑。

三个参数都越大越保守、越小越激进,调参时在"欠拟合"和"过拟合"之间找平衡。

7.2 看什么"率"?------评价指标选择

代码中 scoring='recall'(召回率),这是有讲究的

指标 含义 通俗解释 适用场景
accuracy(准确率) 预测正确的比例 100 题做对几道 样本均衡时
precision(精确率) 预测为正的里真正为正的比例 报警的里有几个真坏蛋 误报代价高时(如垃圾邮件误判正常邮件)
recall(召回率) 真正为正的被找出来的比例 坏蛋有没有被抓全 漏报代价高时(如欺诈检测、疾病筛查)
f1 precision 和 recall 的调和平均 综合平衡 两者都重要时

为什么两个案例都用 recall?

  • 垃圾邮件:宁可把正常邮件误判为垃圾邮件(误报),也不能让垃圾邮件漏网(漏报)------但其实这里用 f1 更平衡,作者选 recall 强调"不漏检"。

  • 银行欺诈 :欺诈交易漏掉一笔可能损失巨大,必须高召回------漏报代价远高于误报代价,所以 recall 是核心指标。
    💡 记忆口诀

  • T/F = 判断对错(True/False = 对/错)

  • P/N = 预测类别(Positive/Negative = 预测为正/负)

  • Recall = TP / (TP + FN) = 真正的正类中,被正确预测出来的比例 = "坏蛋有没有抓全"

7.3 调参方法:网格搜索 + 交叉验证

代码采用最直观的网格搜索(Grid Search)

  1. 列出候选参数:3~4 个关键参数各列几个候选值。
  2. 穷举所有组合:三重 for 循环遍历每个组合(案例一 80 组,案例二 60 组)。
  3. 交叉验证评估:每组参数用 8 折交叉验证算平均 recall。
  4. 选最优组合:记录 recall 最高的参数组合。

进阶方法(代码未用,但值得了解):

  • GridSearchCV:sklearn 封装好的网格搜索,写法更简洁:

    python 复制代码
    from sklearn.model_selection import GridSearchCV
    param_grid = {
        'max_depth': [5, 10, 15, 20],
        'min_samples_split': [2, 3, 4, 5],
        'min_samples_leaf': [1, 2, 3, 4, 5],
    }
    grid = GridSearchCV(RandomForestClassifier(n_estimators=100, random_state=42),
                        param_grid, cv=8, scoring='recall', n_jobs=-1)
    grid.fit(xtrain, ytrain)
    print(grid.best_params_)
  • RandomizedSearchCV:参数组合太多时,随机抽样搜索,效率更高。

  • 调参顺序经验 :先调 n_estimators(让它足够大),再调 max_depth,最后微调 min_samples_splitmin_samples_leaf


八、特征重要性的意义

代码末尾用 rf.feature_importances_ 绘制了特征重要性条形图,这一步看似简单,实则价值巨大:

  1. 特征筛选:剔除重要性极低特征,降维提速、减少噪声。
  2. 业务洞察:告诉业务方"哪些因素最影响结果",如银行可重点关注 Amount、某些交易模式。
  3. 可解释性:随机森林虽是"黑箱"集成模型,但特征重要性提供了部分解释能力。

⚠️ 注意 :sklearn 的特征重要性基于"不纯度下降(MDI)",对高基数(取值多)特征有偏好。若要更可靠的重要性,可用 permutation_importance(排列重要性)。


九、随机森林的意义

随机森林在机器学习发展史上地位重要,原因在于:

  1. "开箱即用"的强基线:无需复杂调参,默认参数就能拿到不错的成绩,是工业界首选的 baseline 模型之一。
  2. 兼顾准确与稳健:通过双重随机性有效抑制过拟合,泛化能力强。
  3. 推动集成学习普及:它是 Bagging 思想的集大成者,理解了随机森林,再学 GBDT/XGBoost 会顺畅很多。
  4. 提供特征解释:弥补了深度学习等黑箱模型的可解释性短板。

十、随机森林的优缺点

10.1 优点

优点 说明
✅ 准确率高 多树投票,通常优于单棵决策树
✅ 抗过拟合 双重随机性 + 集成,泛化能力强
✅ 处理高维数据 特征随机选择,无需特征选择也能跑
✅ 可评估特征重要性 自带 feature_importances_
✅ 对缺失值/异常值鲁棒 比逻辑回归、SVM 更"皮实"
✅ 并行训练 各树独立,可多核并行(n_jobs=-1
✅ 不需太多特征工程 不需要标准化、归一化(但本案例标准化是为了统一量纲,非必须)

10.2 缺点

缺点 说明
❌ 可解释性差 比单棵决策树难解释,无法画出清晰的判断路径
❌ 预测速度较慢 树多时预测需遍历所有树
❌ 内存占用大 需存储所有树
❌ 对极稀疏特征(如文本 one-hot)效果一般 不如线性模型
❌ 外推能力差 不能预测训练集范围外的值(回归任务)

十一、随机森林 vs 决策树

对比维度 决策树 随机森林
模型结构 单棵树 多棵树集成
训练方式 直接训练 Bootstrap 抽样 + 多树并行训练
预测方式 单树输出 多树投票/平均
过拟合风险 高(易"死记硬背") 低(随机性 + 集成抑制)
准确率 一般 通常更高
稳定性 数据微小变化可能导致树结构剧变 稳定,对噪声鲁棒
可解释性 强(可画出决策路径) 弱(但有特征重要性)
训练速度 慢(树多)
预测速度
特征选择 用全部特征 每次分裂只用部分随机特征
超参数 少(depth、split、leaf) 多(再加 n_estimators、max_features)

💡 一句话总结:决策树是"单兵作战",随机森林是"集团军作战"------牺牲了部分可解释性和速度,换来更高的准确率和稳定性。


十二、总结

本文从决策树过拟合的痛点出发,系统讲解了随机森林算法:

  1. 思想:Bagging + 决策树 + 双重随机性(样本随机 + 特征随机),多树投票抑制过拟合。
  2. 实战:两个案例(垃圾邮件、银行欺诈)展示了完整流程:数据划分 → 网格搜索+交叉验证调参 → 训练评估 → 特征重要性可视化。
  3. 调优 :核心调 max_depthmin_samples_splitmin_samples_leaf 三个结构参数;评价指标根据业务选择------漏报代价大选 recall,误报代价大选 precision,二者兼顾选 f1
  4. 优劣:准确稳健、抗过拟合、易用;但可解释性差、预测慢、内存大。
  5. 对比决策树:用"集成"换"稳定与准确",用"随机"换"多样性",是决策树的自然进化。

学习建议:理解随机森林后,下一步可对比学习 Boosting 流派的 GBDT、XGBoost、LightGBM,体会"并行投票"与"串行纠错"的本质差异,这会极大加深对集成学习的理解。


相关推荐
南吕十七5 小时前
RAG与Agent_体系
人工智能·机器学习
xwz小王子7 小时前
Nature Sensors封面:清华“天眸芯”,类脑互补视觉范式重塑AI感知世界的方式
人工智能·深度学习·机器学习
shxjnpl7 小时前
AI会议助手选型的三个“容易被宣传页隐藏”的指标
人工智能·机器学习·语音识别·智能硬件
老王以为8 小时前
走进 AI Agent 第二篇:决定 AI Agent 能力上限的关键技术
前端·人工智能·机器学习
薛定e的猫咪9 小时前
(arXiv 2026)GLiBRL :可学习基函数的深度贝叶斯元强化学习 ----待补充
人工智能·深度学习·学习·算法·机器学习
古城小栈10 小时前
QLoRA 训练参数 专题
人工智能·深度学习·机器学习
逻辑君10 小时前
ANNA 意识驱动 RAG 系统
人工智能·机器学习·数据挖掘
CIO_Alliance11 小时前
AI深度系列(1)|神经元激活函数与MLP原理:理解神经网络的基础
人工智能·深度学习·神经网络·机器学习·tensorflow·ai+ipaas·企业cio联盟