全面讲透一个强大算法模型,随机森林!!
全面讲透一个强大算法模型,随机森林!!
原创 MLer 机器学习和人工智能AI 2025年05月18日 22:06 北京
首先,随机森林是一种集成学习方法,属于Bagging范畴。它是由多个决策树组成的一个森林,并通过投票或平均的方法来提高模型的稳定性和预测能力。
随机森林的核心思想是:
-
随机采样(Bootstrap Sampling):从原始数据集中随机抽取多个子样本集(有放回抽样)。
-
构建多棵决策树(Decision Trees):每个子样本集都用于训练一棵决策树,且每次分裂节点时,随机选择部分特征进行计算,避免单一特征的过拟合。
-
投票或平均:
-
分类任务(Classification):多数投票(majority vote),即哪个类别被最多的树预测,就选择哪个类别。
-
回归任务(Regression):取所有决策树预测结果的平均值。
-
很简单的一个案例,假如你是个餐馆老板,想要知道新开的某家餐厅是否受欢迎,但你自己没办法准确判断。所以,你决定找一群有经验的美食博主来帮你分析。
这些博主的思考方式类似于「决策树」,而这群博主组成了「随机森林」。
步骤 1:随机挑选博主(数据采样)
你不能让所有博主都用同样的信息来分析,否则他们的答案可能会高度一致,缺乏多样性。
因此,你决定:
-
从 100 个博主中随机选 30 个来做决策(这就像 Bootstrap 采样)。
-
每个博主只参考一部分餐厅的数据(随机选取的特征,如餐厅位置、价格、装修等)。
步骤 2:每个博主单独做决策(决策树)
每个博主有自己的分析方式,比如:
-
博主 A 认为:「这家餐厅在市中心,很多人流,所以应该受欢迎。」
-
博主 B 觉得:「这家餐厅价格太贵,可能不太受欢迎。」
-
博主 C 关注装修:「装修很精致,高端客户可能喜欢。」
这样,每个博主相当于一棵「决策树」,基于他们手上的信息进行判断。
步骤 3:综合意见得出最终结论(投票)
-
如果大多数博主说「这家餐厅会受欢迎」,那么你就相信这个预测;
-
反之,如果大多数博主说「这家餐厅不会受欢迎」,你就不会投资。
这个集体决策就像「随机森林」中的「投票机制」,可以降低个别博主(单棵决策树)判断错误带来的影响,使结果更稳健。
简单来说,它的逻辑就像找一群专家来投票,而不是依赖某一个人的单一意见。
理论基础
随机森林的核心是构造多棵决策树,并通过投票或平均的方式进行最终预测。
它在决策树的基础上引入了随机性,使得模型的泛化能力更强,减少过拟合问题。
1. 数学原理
Bagging
Bagging 是一种集成学习方法,核心思想是:
-
通过自助采样法(Bootstrap Sampling)创建多个不同的训练子集;
-
在每个子集上独立训练一个模型(通常是决策树);
-
通过集成多个模型的预测结果(如投票或平均)得到最终预测。
假设原始数据集为:
其中 是特征向量, 是对应的标签。
在 Bagging 过程中,我们从 中随机抽取 个有放回的子样本集:
这样,每个 可能包含重复的样本,也可能遗漏部分样本。
生成多棵决策树
对于每个训练子集 ,我们训练一棵决策树 。
为了引入随机性,每棵决策树的构造过程中:
节点分裂时,随机选择 个特征(而不是所有特征),然后在这 个特征中选择最佳特征进行分裂。
-
对于分类任务,通常 ;
-
对于回归任务,通常 ;
-
是总特征数。
计算特征分裂标准
分裂时通常使用如下标准:
-
分类问题(Gini 不纯度):
其中, 是类别数, 是类别 在数据集 中的概率。 选择使 Gini 不纯度减少最多的特征进行分裂。
-
回归问题(均方误差 MSE):
其中 是数据集的均值,选择使 MSE 降低最多的特征进行分裂。
随机森林的最终预测
训练好 棵决策树后,对于新的样本 ,我们通过以下方式进行预测:
-
分类任务(投票法 Majority Voting)
其中, 是指示函数,即如果 预测类别为 ,则值为 1,否则为 0。
-
回归任务(平均法 Mean Prediction)
2. 算法流程
输入
-
训练数据集:
-
决策树数量:
-
选取的特征数:
步骤 1:随机采样训练集
对 进行 Bagging 采样,创建 个训练子集 :
-
从原始数据集中随机抽取 个样本(有放回);
-
每个子集可能包含重复样本,并可能遗漏某些样本。
步骤 2:训练决策树
对于每个子集 ,训练一棵随机决策树:
-
在每个分裂节点:
-
随机选择 个特征(从所有 个特征中抽取);
-
在这 个特征中,选择使 Gini 不纯度或 MSE 最小的特征进行分裂;
-
-
递归地重复此过程,直到满足停止条件:
-
叶子节点样本数小于某个阈值;
-
没有足够的样本进行进一步分裂。
-
步骤 3:集成预测
对新样本 :
-
分类任务:每棵树 进行预测,最终类别由投票法决定。
-
回归任务:每棵树 进行预测,最终结果取平均值。
3. 复杂度分析
假设:
-
训练集大小为
-
特征数为
-
生成 棵决策树
-
每棵树的最大深度为
那么:
-
训练时间复杂度:
-
训练一棵树的时间复杂度约为 ;
-
训练 棵树的总复杂度为 。
-
-
预测时间复杂度:
-
单棵树的预测时间是 ,因为预测时只需沿着树的路径走 步;
-
棵树的总预测时间为 。
-
4. 关键优势
高准确率:通过多棵树集成,提升模型稳定性。
抗过拟合:通过随机特征选择和 Bagging 降低单棵树的过拟合问题。
适用于高维数据:随机选择部分特征,适用于特征数较多的情况。
可计算特征重要性:通过衡量不同特征在树的分裂过程中贡献的程度,评估特征的重要性。
应用场景
随机森林适用于分类(Classification)和回归(Regression)任务,尤其适合以下场景:
-
高维数据:当特征数量较多时,随机森林可以自动选择重要特征。
-
数据噪声较大的情况:由于集成学习的特性,随机森林可以降低单棵决策树的过拟合风险。
-
特征之间存在复杂关系的情况:随机森林可以学习到复杂的非线性关系。
-
数据不平衡问题:随机森林可以通过调整投票机制或权重来缓解数据不平衡问题。
优缺点
优势
-
高准确率:通过集成多棵树,减少单棵树的过拟合,提高预测性能。
-
抗过拟合能力强:由于采用了随机子样本和特征选择,随机森林比单棵决策树更具泛化能力。
-
可处理高维数据:随机森林能够在高维空间中有效建模,并且能评估各个特征的重要性。
-
对异常值和噪声鲁棒:单棵树容易被异常值影响,而随机森林通过多数投票或均值降低异常值的影响。
-
并行化计算:随机森林的每棵树是独立的,可以并行训练,提高计算效率。
劣势
-
计算成本较高:相比单棵决策树,随机森林训练多个树,计算开销较大,训练时间较长。
-
内存占用较大:由于存储多棵树的结构,随机森林在处理大规模数据时,内存需求较高。
-
不易解释:虽然可以计算特征重要性,但整体模型较复杂,不像单棵决策树那样直观。
-
对于极高维稀疏数据,效果可能不佳:当特征维度远大于样本数时(如文本数据),随机森林可能表现不如线性模型或深度学习模型。
使用随机森林前提条件
-
数据规模适中:虽然随机森林能处理大数据,但训练时间和计算资源是限制因素。
-
特征数量不能过少:如果特征很少,随机选择特征的作用有限,可能无法充分发挥随机森林的优势。
-
类别平衡性需考虑:在类别不均衡的数据集中,可以调整采样策略(如 SMOTE)或设置类权重来优化效果。
-
特征之间的相关性不宜过高:如果特征高度相关,可能会降低随机森林的效果,因为不同树的多样性减少。
Python案例
咱们这里使用sklearn实现随机森林算法,进行分析~
步骤:
-
生成一个虚拟数据集。
-
使用随机森林算法进行训练。
-
对数据结果进行分析。
-
优化算法,进行模型评估。
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.inspection import plot_partial_dependence
# 1. 数据集
X, y = make_classification(n_samples=10000, n_features=20, n_informative=10, n_clusters_per_class=2, random_state=42)
# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 3. 使用随机森林模型进行训练
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
rf_model.fit(X_train, y_train)
# 4. 进行预测
y_pred = rf_model.predict(X_test)
# 5. 打印模型的准确性和分类报告
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred)
# 输出准确率和分类报告
print(f"Accuracy: {accuracy:.4f}")
print("Classification Report:")
print(report)
# 6. 混淆矩阵
conf_matrix = confusion_matrix(y_test, y_pred)
# 7. 可视化分析
# 创建图形
fig, axs = plt.subplots(2, 2, figsize=(14, 10))
# 图1: 特征重要性
# 绘制特征重要性图
feature_importances = rf_model.feature_importances_
axs[0, 0].barh(range(len(feature_importances)), feature_importances, color='skyblue')
axs[0, 0].set_title("Feature Importance")
axs[0, 0].set_xlabel("Importance")
axs[0, 0].set_ylabel("Features")
# 图2: 混淆矩阵
# 绘制混淆矩阵图
cax = axs[0, 1].matshow(conf_matrix, cmap='coolwarm')
fig.colorbar(cax, ax=axs[0, 1])
axs[0, 1].set_title("Confusion Matrix")
axs[0, 1].set_xlabel("Predicted")
axs[0, 1].set_ylabel("True")
axs[0, 1].set_xticks([0, 1])
axs[0, 1].set_yticks([0, 1])
# 图3: 部分依赖图
# 绘制部分依赖图
plot_partial_dependence(rf_model, X_train, features=[0, 1, 2], ax=axs[1, 0], grid_resolution=50)
axs[1, 0].set_title("Partial Dependence (Features 0, 1, 2)")
# 图4: ROC曲线
# 绘制ROC曲线
from sklearn.metrics import roc_curve, auc
fpr, tpr, _ = roc_curve(y_test, rf_model.predict_proba(X_test)[:, 1])
roc_auc = auc(fpr, tpr)
axs[1, 1].plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.2f})')
axs[1, 1].plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
axs[1, 1].set_title('Receiver Operating Characteristic (ROC)')
axs[1, 1].set_xlabel('False Positive Rate')
axs[1, 1].set_ylabel('True Positive Rate')
axs[1, 1].legend(loc="lower right")
# 调整布局
plt.tight_layout()
# 显示图形
plt.show()
# 8. 模型优化:使用GridSearchCV进行超参数调优
from sklearn.model_selection import GridSearchCV
# 设置超参数范围
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [10, 20, None],
'min_samples_split': [2, 10, 20],
'min_samples_leaf': [1, 5, 10]
}
# 使用GridSearchCV进行超参数调优
grid_search = GridSearchCV(estimator=RandomForestClassifier(random_state=42), param_grid=param_grid, cv=3, verbose=2, n_jobs=-1)
grid_search.fit(X_train, y_train)
# 输出最优超参数
print("Best Parameters found: ", grid_search.best_params_)
# 使用最优超参数训练新的模型
best_rf_model = grid_search.best_estimator_
# 预测并评估新模型
best_y_pred = best_rf_model.predict(X_test)
best_accuracy = accuracy_score(y_test, best_y_pred)
# 输出优化后的准确率
print(f"Optimized Accuracy: {best_accuracy:.4f}")
-
生成数据集:我们使用
sklearn.datasets.make_classification()生成了一个包含10万个样本和20个特征的数据集,并且其中10个特征是具有信息量的。通过train_test_split()将数据集划分为训练集和测试集。 -
训练模型:我们使用
RandomForestClassifier来训练随机森林模型,并对测试集进行预测。通过accuracy_score()评估准确率,并使用classification_report()输出详细的分类报告。

-
图1:特征重要性:展示了模型中各个特征的相对重要性。
-
图2:混淆矩阵:通过混淆矩阵来分析模型预测的真实与虚假情况。
-
图3:部分依赖图:展示了指定特征对预测结果的影响。
-
图4:ROC曲线:展示了模型的受试者工作特征(ROC)曲线,反映了分类性能。
-
模型优化:通过
GridSearchCV进行超参数调优,优化模型的参数,包括n_estimators、max_depth、min_samples_split、min_samples_leaf,从而进一步提高模型的性能。
算法优化方面:
-
超参数调优:通过网格搜索(
GridSearchCV)来调优随机森林的超参数,以获得最佳的模型表现。 -
交叉验证:我们在超参数调优中使用了交叉验证(
cv=3),确保优化的稳定性。
以上代码是一个完整的案例,整个过程包括数据生成、模型训练、分析和优化步骤~
最后
最近准备了16大块的内容,124个算法问题的总结,完整的机器学习小册,免费领取~

领取:
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)