你正在组织一场盛大的野餐,你需要为这个野餐选择一个完美的地点。你可能会考虑很多因素,比如天气状况、交通便利性、风景美不美等等。为了做出最佳决策,你决定征求一群朋友的意见,让他们帮你选出最佳的野餐地点。
这就好比我们在使用随机森林算法解决问题时的情景。随机森林算法由众多的决策树组成,每一棵树都像是你的一个朋友,它们基于各自所掌握的不同数据片段(这就像每个朋友因为自己的经历和偏好只考虑一部分因素)独立地做出自己的判断和选择。
你的每一个朋友(决策树)都会考虑不同的因素。例如,一个朋友(决策树)可能会因为天气预报说山上气候宜人而推荐山上,另一个朋友(决策树)可能因为知道沙滩上有一场音乐节而推荐沙滩。他们每个人的推荐都是基于他们所考虑的因素做出的最佳选择。
有句话说得好,“三个臭皮匠,赛过诸葛亮”。这些朋友们(决策树)的推荐汇集起来后,就形成了一个“群体智慧”。在随机森林算法中,我们通过让每棵树进行投票来决定最终的决策。就像如果大多数朋友建议去山上,那么山上就是你野餐的地点。通过这种方式,也就是综合所有决策树的投票结果,随机森林能够给出一个通常比单一决策树更准确、更可靠的预测。
随机森林的“随机”体现在两个方面:一是每棵树在建立时使用的数据集是随机选择的,这就像每个朋友只看到了野餐地点的一部分信息;二是在决策过程中,每棵树只考虑随机选择的一部分特征,这就好比你的朋友们在给建议时只考虑了他们认为重要的几个因素。
通过这种方式,随机森林算法减少了过度依赖单一决策树的风险,从而提高了整体的决策质量。就像集合多个朋友的智慧比单独听一个人的意见更能做出全面的选择一样,随机森林通过整合多棵树的决策,得到一个更加稳健和全面的结果。
决策森林是一种统计分析工具,它通过构建多个决策树并在它们之间进行相互比较来预测结果。每一个单独的决策树都是通过那些影响结果的特性或者特征(也被称为预测变量)进行分割而创建的,并且采用树结构来反映这些特性之间的逻辑关联。最终结果的预测则是基于多个决策树的预测结果的集成(投票)。
在数学建模比赛中,决策森林被广泛用于分类或回归问题中。通过决策森林模型,我们可以对特性进行重要性评估,筛选出十分关键的特性,对模型进行精简和优化。同时,决策森林由于其内在的集成学习特性,往往具有较好的泛化能力和抗噪声能力。
使用决策森林模型时,需要注意以下几点:
在数据处理方面,决策森林通常需要预处理数据,包括填充缺失值,特征选择和特征编码等步骤。决策树在做决策时是基于单个特征的阈值划分数据的,因此对于连续变量,并不需要进行变量缩放,即不需要将所有特征的尺度(例如范围)调整到相同。这是因为无论特征的尺度如何,决策树都可以通过找到合适的阈值来划分数据。但是对于类别型变量,通常需要进行独热编码,即为每个类别创建一个新的二元特征,该特征在该类别出现时取值为1,否则取值为0。同时,对于高维稀疏数据,最好能进行降维处理,以提高模型的效果和减少计算的复杂性。
随机森林是由一定数量的决策树构造而成,这些决策树会根据原始的数据集生成自己的数据集(随机选取样本以及随机选取特征),随机森林会将这些决策树的结果进行投票和汇总,最后进行预测。
在随机森林算法中,构造每棵树的训练集的过程如下:
通过这种方法,每棵树都训练在略微不同的数据集上,这增加了模型的多样性,并有助于提高整个随机森林模型的泛化能力。
对于那些在自助采样中未被选中的样本,也就是“袋外数据”(Out of Bag data,简称OOB),它们约占原始数据集的36.8%。这些袋外数据未参与到树的训练过程中,因此可以作为一个未见过的验证集来估计模型的性能。
例如:
通过上述步骤,我们可以为随机森林中的每一棵树准备好训练数据,并利用袋外数据来验证模型的性能。
为了构建一个决策树,我们需要从Bootstrap抽样得到的数据集开始。
从根节点开始,我们需要按照一定的标准选择一个特征用于节点的分裂。在传统决策树如ID3、C4.5或CART中,我们通常会遍历所有特征,使用诸如信息增益、信息增益率或基尼指数等指标来评估每个特征的分裂效果。
然而,在随机森林中,我们刻意引入了随机性,以避免每棵树都过分关注相同的强特征,从而减少模型的过拟合风险。运用名为“随机子空间法”的随机特征子集方法,它能够在模型中引入多样性,通过这种方式构建的决策树在决策过程中考虑了不同的特征组合,使得随机森林作为整体在面对不同类型的数据时具备更强的泛化能力。主要操作如下:
构造单个决策树的具体步骤如下:
特征选择:首先,在每个决策节点,我们不会考虑所有的特征,而是从 个特征中随机选择一部分特征进行考虑。通常情况下,我们会选择 的平方根(即 )个特征。我们将这个随机选中的特征集合称为A。
寻找最优分裂特征:在选定的特征子集A中,我们需要找到一个最优的分裂特征。这里的“最优”是通过评估分裂后数据集纯度的提升来决定的。在这个例子中,我们使用基尼指数作为评估标准。
基尼指数的计算公式如下:
对于特征 ,其基尼指数 可以表示为:
其中, 是特征a在数据集 中取值为 的子集。我们将计算特征集合 中每个特征的基尼指数,并选择基尼指数最小的特征作为分裂特征,因为基尼指数越小,数据集的不确定性越低,纯度越高。
数据集分裂:按照最优分裂特征的不同取值,将数据集 分裂成两个或多个子集。这个分裂是为了使得每个子集在目标变量上尽可能的纯净。
递归构造子树:对于每个分裂出的子集,重复上述过程,也就是继续选择特征、寻找最优分裂特征并分裂数据集。这个过程会一直持续,直到达到预设的停止条件,比如树达到了最大深度,或者节点中的样本数量小于某个阈值,或者所有的样本都属于同一个类别。
通过上述步骤,我们就可以在随机森林算法中构造出单个的决策树。这些决策树将结合起来进行集体决策,以提高整个模型的预测性能。
在整个随机森林模型中,会重复这个过程构建出许多这样的树,每棵树都是独立且多样的。当需要进行预测时,随机森林通过集成所有树的预测结果来做出最终的决策。
这种方法的好处是,由于我们在不同的节点和不同的树中使用了不同的特征进行分裂,所以可以极大地增加模型的多样性。这既可以降低模型的方差,也可以防止过拟合。
随机森林是一个集成学习模型,关键在于它整合了多颗决策树的预测结果。这个整合过程,我们通常称之为投票(对于分类问题)或汇总(对于回归问题)。通过集成多颗决策树的预测结果,随机森林能够在一定程度上提高预测性能,降低过拟合风险,并且提升模型的稳健性。这是因为集成方法能够平滑单个模型的预测误差,避免模型过于依赖某个特定的特征或数据样本。
在分类问题中,当有一个新的输入样本需要预测时,随机森林会让所有的决策树分别进行预测。每一颗决策树对样本的分类结果可以看作是一次“投票”。最后,哪个类别得到的票数最多,就会被选为该样本的预测类别。
例如,如果随机森林包含了500棵树,其中有300棵树预测某个样本为类别A,而其它200棵树预测为类别B,那么随机森林会将这个样本分类为类别A。
这种方法也被称为“简单投票”或“多数投票”。
在回归问题中,随机森林的预测过程会稍有不同。每一颗决策树会给出一个连续值的预测结果,然后,随机森林会计算这些预测结果的平均值,作为最终的预测结果。
例如,如果随机森林中有500棵树,它们对某个样本的预测结果分别是3.1, 3.5, 2.9, 4.0, ..., 那么我们会将这500个结果相加,然后除以500,得到最终的预测结果。
例如,假设我们有一个随机森林,其中包含500棵树。对于一个输入样本,有300棵树预测它属于类别A,200棵树预测它属于类别B。那么,根据多数投票原则,我们会将这个样本分类为类别A。
这种投票机制的优点在于,即使某些决策树的预测出错,只要大多数决策树的预测是正确的,那么随机森林的最终预测结果就是正确的。这是一种"群体智慧"的体现,通过集成多个模型的预测,我们可以得到比单个模型更好、更稳定的预测结果。
例如,假设我们有一个随机森林,其中包含500棵树。对于一个输入样本,每棵树都会输出一个预测值,比如说,这500棵树的预测值分别为1.1, 1.3, 1.2, ..., 1.4。那么,我们会将这500个预测值相加,然后除以500,得到的结果就是随机森林的最终预测值。
这种平均值机制的优点在于,它可以有效地减小模型的预测误差。因为各个决策树的预测结果可能会有一些噪声,但是这些噪声在求平均值时会相互抵消,从而使得最终的预测结果更加稳定和准确。这也是随机森林在处理回归问题时的一大优势。
数据集:
1# 导入所需的库
2import numpy as np
3import pandas as pd
4from sklearn.model_selection import train_test_split
5from sklearn.ensemble import RandomForestClassifier
6from sklearn.metrics import classification_report
7import matplotlib.pyplot as plt
8import seaborn as sns
9
10# 加载数据集
11df = pd.read_csv('iris.csv',sep = ',',decimal = '.',header = None,names = ['sepal_length','sepal_width','petal_length','petal_width','target'])
12
13# 分析数据
14print(df.head())
15
16# 提取特征和目标变量
17X = df.drop('target', axis=1)
18y = df['target']
19
20# 划分训练集和测试集
21X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
22
23# 创建随机森林分类器
24clf = RandomForestClassifier(n_estimators=100, random_state=42)
25
26# 训练模型
27clf.fit(X_train, y_train)
28
29# 预测测试集
30y_pred = clf.predict(X_test)
31
32# 打印分类报告
33print(classification_report(y_test, y_pred))
34
35# 特征重要性
36feature_imp = pd.Series(clf.feature_importances_,index=df.columns[:-1]).sort_values(ascending=False)
37
38# 可视化特征重要性
39sns.barplot(x=feature_imp, y=feature_imp.index)
40plt.xlabel('特征重要性得分')
41plt.ylabel('特征')
42plt.title("可视化特征重要性")
43plt.show()
1# 导入所需的库
2import numpy as np
3import pandas as pd
4from sklearn.model_selection import train_test_split
5from sklearn.ensemble import RandomForestClassifier
6from sklearn.metrics import classification_report
7import matplotlib.pyplot as plt
8import seaborn as sns
9
10# 加载数据集
11df = pd.read_csv('iris.csv',sep = ',',decimal = '.',header = None,names = ['sepal_length','sepal_width','petal_length','petal_width','target'])
12
13# 分析数据
14print(df.head())
15
16# 提取特征和目标变量
17X = df.drop('target', axis=1)
18y = df['target']
19
20# 划分训练集和测试集
21X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
22
23# 创建随机森林分类器
24clf = RandomForestClassifier(n_estimators=100, random_state=42)
25
26# 训练模型
27clf.fit(X_train, y_train)
28
29# 预测测试集
30y_pred = clf.predict(X_test)
31
32# 打印分类报告
33print(classification_report(y_test, y_pred))
34
35# 特征重要性
36feature_imp = pd.Series(clf.feature_importances_,index=df.columns[:-1]).sort_values(ascending=False)
37
38# 可视化特征重要性
39sns.barplot(x=feature_imp, y=feature_imp.index)
40plt.xlabel('特征重要性得分')
41plt.ylabel('特征')
42plt.title("可视化特征重要性")
43plt.show()
这段代码使用了一个鸢尾花(iris)数据集,对数据进行了初步的分析。然后代码提取了特征和目标变量,将数据分为训练集和测试集。接着创建了一个随机森林分类器,并使用训练集对其进行训练。模型训练完成后,代码对测试集进行预测,然后打印出了分类报告。
最后,代码计算了每个特征的重要性,并将这些重要性以柱状图的形式进行了可视化,让我们更直观地看到哪些特征对模型预测的影响最大。
输出结果:
1 sepal_length sepal_width petal_length petal_width target
20 5.1 3.5 1.4 0.2 setosa
31 4.9 3.0 1.4 0.2 setosa
42 4.7 3.2 1.3 0.2 setosa
53 4.6 3.1 1.5 0.2 setosa
64 5.0 3.6 1.4 0.2 setosa
7 precision recall f1-score support
8
9 setosa 1.00 1.00 1.00 19
10 versicolor 1.00 1.00 1.00 13
11 virginica 1.00 1.00 1.00 13
12
13 accuracy 1.00 45
14 macro avg 1.00 1.00 1.00 45
15weighted avg 1.00 1.00 1.00 45
1 sepal_length sepal_width petal_length petal_width target
20 5.1 3.5 1.4 0.2 setosa
31 4.9 3.0 1.4 0.2 setosa
42 4.7 3.2 1.3 0.2 setosa
53 4.6 3.1 1.5 0.2 setosa
64 5.0 3.6 1.4 0.2 setosa
7 precision recall f1-score support
8
9 setosa 1.00 1.00 1.00 19
10 versicolor 1.00 1.00 1.00 13
11 virginica 1.00 1.00 1.00 13
12
13 accuracy 1.00 45
14 macro avg 1.00 1.00 1.00 45
15weighted avg 1.00 1.00 1.00 45
1# 导入必要的库
2import numpy as np
3import matplotlib.pyplot as plt
4from sklearn.model_selection import train_test_split
5from sklearn.ensemble import RandomForestRegressor
6from sklearn.metrics import mean_squared_error
7from sklearn.datasets import load_boston
8
9# 加载波士顿房价数据集
10boston = load_boston()
11X = boston.data
12y = boston.target
13
14# 划分训练集和测试集
15X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
16
17# 创建随机森林回归器
18rfr = RandomForestRegressor(n_estimators=100, random_state=42)
19
20# 训练模型
21rfr.fit(X_train, y_train)
22
23# 预测测试集
24y_pred = rfr.predict(X_test)
25
26# 计算均方误差
27mse = mean_squared_error(y_test, y_pred)
28print('均方误差:',mse)
29
30# 绘图查看预测值与真实值的对比
31plt.figure(figsize=(10, 6))
32plt.plot(range(len(y_pred)), sorted(y_pred), color='blue', label='预测值')
33plt.plot(range(len(y_test)), sorted(y_test), color='red', label='真实值')
34plt.legend(loc='upper left')
35plt.title('预测值与真实值的对比')
36plt.show()
1# 导入必要的库
2import numpy as np
3import matplotlib.pyplot as plt
4from sklearn.model_selection import train_test_split
5from sklearn.ensemble import RandomForestRegressor
6from sklearn.metrics import mean_squared_error
7from sklearn.datasets import load_boston
8
9# 加载波士顿房价数据集
10boston = load_boston()
11X = boston.data
12y = boston.target
13
14# 划分训练集和测试集
15X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
16
17# 创建随机森林回归器
18rfr = RandomForestRegressor(n_estimators=100, random_state=42)
19
20# 训练模型
21rfr.fit(X_train, y_train)
22
23# 预测测试集
24y_pred = rfr.predict(X_test)
25
26# 计算均方误差
27mse = mean_squared_error(y_test, y_pred)
28print('均方误差:',mse)
29
30# 绘图查看预测值与真实值的对比
31plt.figure(figsize=(10, 6))
32plt.plot(range(len(y_pred)), sorted(y_pred), color='blue', label='预测值')
33plt.plot(range(len(y_test)), sorted(y_test), color='red', label='真实值')
34plt.legend(loc='upper left')
35plt.title('预测值与真实值的对比')
36plt.show()
这段代码使用了波士顿房价数据集,并将数据集划分为训练集和测试集。然后创建了一个随机森林回归器,并用训练集对其进行训练。接下来,用这个模型对测试集进行了预测,并计算了预测结果的均方误差,以评估模型的预测性能。最后,用折线图对预测值和真实值进行了对比。在这个图中,红线代表真实的房价,蓝线代表预测的房价。
输出结果:
1均方误差: 9.619662013157892
1均方误差: 9.619662013157892
决策森林相比于单一的决策树模型,有以下优缺点:
优点:
缺点: