哈喽,我是小白~
今儿和大家聊聊集成算法中非常重要的一个概念:随机森林。
随机森林是一种集成学习算法,意思是它不是单靠一个模型来完成任务,而是通过构建多个模型(通常是决策树)并整合它们的结果来完成预测任务。它主要用来解决分类或回归问题。
如果需要本文PDF版本的同学,文末获取~
另外,文末有总结性的干货~
一起来看下具体细化内容~
随机森林核心思想:
随机性1:样本随机:每棵树不是使用全部数据训练,而是从数据集中随机抽取一部分样本(放回抽样,即“有放回抽样”)。 随机性2:特征随机:在每棵树的每个分裂点,随机选择部分特征,使用这些特征来进行分裂,而不是考虑所有特征。 集成投票/平均:随机森林通过让每棵树投票(分类问题)或者取平均值(回归问题),来决定最终的预测结果。
一个简单案例:学生成绩预测
我们想预测学生考试是否会及格(分类问题)。
假设我们有以下数据:
学生ID | 学习时长(小时) | 上课专注度(满分5) | 课后作业完成率(%) | 是否及格 |
---|---|---|---|---|
1 | 10 | 4 | 90 | 及格 |
2 | 5 | 3 | 80 | 及格 |
3 | 2 | 1 | 50 | 不及格 |
4 | 7 | 3 | 70 | 及格 |
5 | 3 | 2 | 60 | 不及格 |
目标:根据学习时长、上课专注度和课后作业完成率预测新学生是否会及格。
随机森林步骤:
1. 构建多棵决策树:随机森林会随机抽取子数据集和特征来建多棵树。我们假设生成3棵树,分别看每棵树如何做出判断。
决策树1:
使用随机抽取的子数据:
样本:{学生1, 学生3, 学生5} 特征:{学习时长, 上课专注度}
这棵树可能学到的规则:
如果学习时长 > 3小时,则预测及格;否则不及格。
决策树2:
使用随机抽取的子数据:
样本:{学生2, 学生3, 学生4} 特征:{上课专注度, 作业完成率}
这棵树可能学到的规则:
如果上课专注度 > 2分且作业完成率 > 60%,则预测及格;否则不及格。
决策树3:
使用随机抽取的子数据:
样本:{学生1, 学生2, 学生4} 特征:{学习时长, 作业完成率}
这棵树可能学到的规则:
如果作业完成率 > 70%,则预测及格;否则不及格。
2. 预测新学生的数据:假设新学生数据如下:
学习时长(小时) | 上课专注度(满分5) | 课后作业完成率(%) |
---|---|---|
4 | 3 | 75 |
让三棵树分别预测:
决策树1:学习时长4小时 > 3小时,预测及格。 决策树2:上课专注度3分 > 2分,作业完成率75% > 60%,预测及格。 决策树3:作业完成率75% > 70%,预测及格。
3. 集成结果:三棵树都预测“及格”,所以随机森林的最终结果是“及格”。
手动计算
如果我们有更多数据(假设数据点多、特征复杂),通过程序生成多个树并预测,随机森林能有效提升精度,同时避免单棵树的过拟合问题。随机森林的强大之处在于:
减少过拟合:因为随机性和投票机制。 提升准确率:每棵树可能有偏差,但整体平均后偏差减小。
有了这个直观的理解,下面咱们把随机森林的原理和案例和大家聊聊~
公式解析
随机森林(Random Forest)的核心是通过集成学习的思想,将多个决策树的结果结合起来,提高模型的稳定性和精度。以下是随机森林算法的数学公式及推导的详细解释。
1. 算法基本步骤
假设数据集为 ,每个样本 是一个 -维特征向量,目标是预测 (可以是分类标签或回归值)。
随机森林通过以下步骤生成多个决策树并结合结果:
随机样本选取(Bagging)
样本抽样
通过有放回抽样(Bootstrap Sampling)从数据集中抽取 个样本生成子数据集 :
每个子数据集的大小等于原数据集(即 ),但样本可以重复。 平均约有 的原始样本会被包含在子数据集中,其余为“袋外数据”(OOB)。
随机特征选取
每次树的生长时,在每个节点分裂时:
从 个特征中随机选择一个子集 (通常 或 )。 仅使用 个特征计算最优分裂点。
决策树生成
使用数据集 构建决策树 。每棵树使用递归分裂:
分类问题:选择分裂点最大化基尼指数或信息增益。 回归问题:选择分裂点最小化均方误差(MSE)。
集成结果
最终的随机森林输出为所有树预测的集成:
分类问题:通过多数投票(Majority Voting):
其中 是分类标签, 是指示函数,表示某树是否预测为 。
回归问题:通过求平均:
2. 核心公式
Bagging 的理论解释
在 Bagging 中,每棵树的预测 是基于有放回抽样的子集 训练的。如果我们假设每棵树是独立的(实际不完全独立),则通过集成可以减少总体方差。
假设单个树的预测为:
集成 棵树后的预测为:
其期望和方差为:
集成方法显著减少了方差,提高了预测稳定性。
实际中,树之间可能相关,相关性用 表示,则:
当 很大时,降低树之间的相关性(通过随机性)有助于进一步降低方差。
随机特征选择的作用
随机特征选择进一步引入不相关性,减小树之间的相关性 。假设每棵树使用的特征集合为 ,选取子集大小为 ,则每次分裂中,选择特征的随机性可以减少模型对特定特征的依赖,提高泛化能力。
集成投票的理论解释
对于分类问题,最终预测是通过多数投票:
如果每棵树独立且有一定准确率 (即某棵树预测正确的概率为 ),根据大数法则:
当树数 ,随机森林的最终准确率趋于 1。
推导:每棵树预测正确的概率为 ,预测错误的概率为 。多数投票正确的概率为:
随着 增大,随机森林能够有效地提升整体准确率。
总的来说,随机森林通过随机采样、随机特征选择和决策树集成,结合数学上的投票机制或均值运算,增强了模型的预测性能,同时减少了过拟合和方差。这种设计背后有明确的数学基础,能够在实际应用中表现出色。
优缺点和适用场景
优点
强大的泛化能力随机森林通过Bagging(数据随机采样)和随机特征选择引入随机性,降低了过拟合的风险。在分类和回归任务中都表现稳定,对高维数据也有良好的适应能力。
非线性建模能力随机森林无需假设数据分布,可以捕捉复杂的非线性关系。
抗噪性强由于是多个决策树的投票或平均结果,单个噪声样本的影响被稀释。
对特征重要性评估的支持随机森林内置计算特征重要性功能,可以直观评估各特征对结果的贡献,便于特征工程和模型解释。
处理高维稀疏数据随机森林可以在特征数量远大于样本数量的场景下有效工作,例如文本数据或基因数据。
袋外误差估计(OOB)随机森林通过袋外样本(未被抽中的数据)计算误差,无需额外划分验证集。
稳健性对于缺失值或部分特征的噪声数据,表现较好。
缺点
计算成本高:随机森林需要训练大量决策树,训练和预测时间相较于简单模型(如逻辑回归)更长,尤其在大数据场景下。随着树的数量和深度增加,存储需求也随之增加。
难以解释:虽然可以评估特征重要性,但随机森林本身是一个“黑盒模型”,无法直观展示具体决策路径。
不擅长外推:对于回归任务,如果测试集中的特征值超出训练集范围,随机森林的外推能力较弱(因为它依赖于训练数据范围内的分裂点)。
对高相关性特征敏感:如果输入特征之间高度相关,随机森林可能会倾向于选取部分特征,影响其泛化能力。
未必优于单一模型:在简单数据集(线性、噪声少)上,随机森林未必优于更简单的模型(如线性回归、SVM)。
适用场景
分类任务:随机森林是一种经典的分类算法,适合多分类或二分类问题。数据类型:可以处理数值、类别型数据(需要预处理编码)。
回归任务可以预测连续值,例如价格、温度等。
特征选择随机森林可以评估特征的重要性,用于特征筛选和降维。
异常检测通过袋外样本(OOB)误差,可以识别异常点。
处理非结构化数据适用于基因数据(高维稀疏数据)、文本分类(需要向量化)、图像分类
完整案例
我们以分类任务为例,使用「学生成绩预测」的案例,结合随机森林算法进行分类。
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.decomposition import PCA
from mpl_toolkits.mplot3d import Axes3D
import seaborn as sns
import matplotlib.pyplot as plt
# 1. 数据生成
np.random.seed(42)
n_samples = 500
data = {
"Study Hours": np.random.uniform(1, 10, n_samples), # 学习时长
"Attention Score": np.random.randint(1, 6, n_samples), # 专注度
"Homework Completion": np.random.uniform(50, 100, n_samples), # 作业完成率
"Peer Interaction": np.random.uniform(0, 5, n_samples), # 同学互动评分
"Motivation Level": np.random.uniform(1, 10, n_samples) # 学习动力
}
# 目标变量:是否及格
data["Passed"] = (
data["Study Hours"] * 0.25 +
data["Attention Score"] * 0.2 +
data["Homework Completion"] * 0.3 +
data["Peer Interaction"] * 0.15 +
data["Motivation Level"] * 0.1 +
np.random.normal(0, 2, n_samples)
) > 70
df = pd.DataFrame(data)
# 2. 数据拆分
X = df.drop(columns=["Passed"])
y = df["Passed"].astype(int)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 3. 训练随机森林模型
rf = RandomForestClassifier(n_estimators=200, random_state=42)
rf.fit(X_train, y_train)
# 4. 模型评估
y_pred = rf.predict(X_test)
print("分类报告:\n", classification_report(y_test, y_pred))
# 高维分类效果可视化
# 使用 PCA 将高维数据降维到 3D
pca = PCA(n_components=3)
X_pca = pca.fit_transform(X)
df_pca = pd.DataFrame(X_pca, columns=["PC1", "PC2", "PC3"])
df_pca["Passed"] = y
# 绘制 3D 分类效果图
fig = plt.figure(figsize=(12, 10))
ax = fig.add_subplot(111, projection='3d')
scatter = ax.scatter(df_pca["PC1"], df_pca["PC2"], df_pca["PC3"],
c=df_pca["Passed"], cmap="coolwarm", s=50, alpha=0.7, edgecolor="k")
# 添加标题和坐标
ax.set_title("3D PCA Classification by Random Forest", fontsize=16)
ax.set_xlabel("Principal Component 1")
ax.set_ylabel("Principal Component 2")
ax.set_zlabel("Principal Component 3")
legend = ax.legend(*scatter.legend_elements(), title="Passed", loc="upper right")
ax.add_artist(legend)
# 增加网格效果
ax.grid(True)
plt.tight_layout()
plt.show()
3D 分类效果图:通过 PCA 降维后展示了分类结果,体现了不同类别的空间分布。
最后