随机森林在数学建模中的应用
随机森林是一种强大的集成学习方法,通过组合多个决策树来进行分类和回归任务。其核心思想是通过对训练数据和特征的随机子集进行多次训练,生成一组决策树,并通过对这些树的预测结果进行集成来提高模型的准确性和鲁棒性。在分类问题中,随机森林的最终预测结果是基于所有树的投票决定的,而在回归问题中,结果则是所有树预测值的平均。随机森林具有出色的泛化能力和抗噪声能力,适用于处理各种数据类型和规模的机器学习任务。在数学建模中也可以解决很多问题
作用
预测与分类:随机森林通过集成多个决策树来提高预测的准确性。适用于回归任务(如预测房价、销售量)和分类任务(如疾病分类、客户分群)。能够捕捉特征之间复杂的非线性关系,而无需事先假设这些关系。
特征选择与重要性评估:随机森林可以评估各个特征对模型预测的贡献,帮助识别和选择最重要的特征。这对于理解数据结构和优化模型输入至关重要。通过特征重要性评分,能够进行有效的特征选择,从而减少模型复杂性和计算开销。
模型稳定性:由于随机森林通过平均多个决策树的预测结果来减少过拟合,从而提高模型的泛化能力。在面对噪声数据和异常值时表现稳定。
适用范围
适合大数据量的处理,在大数据环境中,随机森林可以有效利用并行计算来加快训练过程,并通过集成多棵树来提高预测的准确性和稳定性。
适合于特征维度很高的任务,如基因数据分析、文本数据处理等。
适用于回归分析,比如根据房屋的特征(如面积、位置、房间数)预测房价。预测未来的销售量或收入基于历史销售数据和市场因素。
适用于分类任务,比如通过患者的生理特征预测疾病(如癌症、糖尿病)的可能性。评估借款人的信用风险,根据个人的财务信息预测违约概率。
模型建立的基本步骤(以心脏病的分类为例)
数据准备
步骤:
-
数据收集:收集和整理数据,确保数据的质量和完整性。
-
数据清洗:处理缺失值、异常值和重复数据。
-
特征选择:选择与目标变量相关的特征。
-
数据分割:将数据集分为训练集和测试集。
提前准备了这样一个数据集,包括下表所示因素:
变量名 | 描述 |
---|---|
age | 患者的年龄 |
gender | 患者的性别,1表示男性,0表示女性 |
impluse | 患者的脉搏率 |
pressurehight | 患者的收缩压 |
pressurelow | 患者的舒张压 |
glucose | 患者的血糖水平 |
kcm | 某种医学测量值 |
troponin | 患者的肌钙蛋白水平 |
class | 患者的诊断结果,"negative"表示阴性,"positive"表示阳性。 |
代码实现:
导入可能用到的包
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
import pandas as pd
from sklearn.preprocessing import StandardScaler
from deap import base, creator, tools,algorithms
import random
import numpy as np
from deap import base, creator, tools, algorithms
import random
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
from matplotlib import rcParams
导入数据集
df = pd.read_csv('Heart Attack.csv')
数据探索
条形图
下图中,我们可以看到描述性统计数据,例如平均值、标准差、最小值、最大值和四分位数
# 设置字体,以支持中文显示
rcParams['font.sans-serif'] = ['SimHei'] # 黑体
rcParams['axes.unicode_minus'] = False # 解决负号显示问题
# 计算描述性统计量
column = df.drop('class', axis=1)
stat = column.describe()
# 排除所有列的 'count' 值
stat = stat.drop(['count'])
# 设置子图的大小和网格 (2x4)
fig, axes = plt.subplots(nrows=2, ncols=4, figsize=(20, 10))
fig.suptitle('描述性统计', fontsize=16)
# 遍历每一列,创建条形图
for i, col in enumerate(stat.columns):
row_num = i // 4
col_num = i % 4
# 选择列的统计量
column_stats = stat[col]
# 在子图中添加条形图
axes[row_num, col_num].bar(column_stats.index, column_stats.values, color='skyblue')
axes[row_num, col_num].set_title(f'{col} 的统计量')
axes[row_num, col_num].set_ylabel('值')
axes[row_num, col_num].tick_params(axis='x', rotation=45)
# 调整布局以防止重叠
plt.tight_layout(rect=[0, 0, 1, 0.96])
plt.show()
条形图展示了每列的 ‘mean’、‘std’、‘min’、‘25%’、‘50%’、‘75%’ 和 ‘max’ 值。标题和轴标签也在此设置,x轴标签旋转45度以防止重叠。
数据分布图
我们还可以用直方图查看数据分布。用直方图可视化的变量是“年龄”、“性别”、“高压”、“低压”、“脉冲”、“葡萄糖”、“kcm”、“肌钙蛋白”。
# 要绘制直方图的列
columns = ['age', 'gender', 'pressurehight', 'pressurelow', 'impluse', 'glucose', 'kcm', 'troponin']
# 创建 2x4 的子图布局
fig, axes = plt.subplots(2, 4, figsize=(20, 10))
# 遍历列和子图,绘制直方图
for i, column in enumerate(columns):
ax = axes[i // 4, i % 4]
# 对于非数值列,如 'gender',需要先将其转换为数值格式
if df[column].dtype == 'object':
df[column] = df[column].astype('category').cat.codes
ax.hist(df[column], bins=20, color='skyblue')
ax.set_title(f'{column.capitalize()} 的直方图')
ax.spines[['top', 'right']].set_visible(False)
ax.set_xlabel(column.capitalize())
ax.set_ylabel('频率')
# 调整布局
plt.tight_layout()
plt.show()
模型建立
生成决策树:
- 从训练数据中进行自助采样(Bootstrap sampling),生成多个不同的训练子集。
- 在每个训练子集上构建一棵决策树。
- 在每个节点的分裂过程中,只考虑特定数量的随机特征(特征子集)来选择最佳分裂。
模型集成:
- 每棵决策树对输入样本进行预测,随机森林通过投票(分类任务)或取平均(回归任务)来决定最终预测结果。
投票决策(分类任务):
y
^
=
m
o
d
e
(
{
y
^
1
,
y
^
2
,
…
,
y
^
T
}
)
\hat{y}=\mathrm{mode}\left(\{\hat{y}_{1},\hat{y}_{2},\ldots,\hat{y}_{T}\}\right)
y^=mode({y^1,y^2,…,y^T})
其中,
y
^
t
\hat{y}_t
y^t 是第
t
t
t 棵树的预测结果,$\text{mode}
是众数函数,
是众数函数,
是众数函数,\hat{y}$ 是最终的预测结果。
取平均(回归任务):
y
^
=
1
T
∑
t
=
1
T
y
^
t
\hat{y}=\frac1T\sum_{t=1}^T\hat{y}_t
y^=T1t=1∑Ty^t
- 其中,$\hat{y}_t $是第 t t t 棵树的预测值, y ^ \hat{y} y^ 是最终的预测值。
模型训练
训练每棵决策树:
- 在自助采样的训练子集上训练决策树。
- 对每个节点,随机选择一部分特征来决定最佳分裂。
信息增益(用于特征选择)
I
G
(
D
,
A
)
=
E
n
t
r
o
p
y
(
D
)
−
∑
v
∈
V
a
l
u
e
s
(
A
)
∣
D
v
∣
∣
D
∣
E
n
t
r
o
p
y
(
D
v
)
\mathrm{IG}(D,A)=\mathrm{Entropy}(D)-\sum_{v\in\mathrm{Values}(A)}\frac{|D_v|}{|D|}\mathrm{Entropy}(D_v)
IG(D,A)=Entropy(D)−v∈Values(A)∑∣D∣∣Dv∣Entropy(Dv)
其中,
IG
(
D
,
A
)
\text{IG}(D, A)
IG(D,A) 是特征
A
A
A 在数据集
D
D
D 上的信息增益,
Entropy
(
D
)
\text{Entropy}(D)
Entropy(D)是数据集
D
D
D的熵,$\text{Values}
是特征
A
A
A
的所有可能值,
是特征 AAA 的所有可能值,
是特征AAA的所有可能值,\text{Entropy}$是数据子集
D
v
D_v
Dv的熵。
模型预测
对新样本进行预测:
- 将新样本输入到所有决策树中,获取每棵树的预测结果。
- 对于分类任务,使用多数投票方法确定最终分类。
- 对于回归任务,取所有树预测值的平均。
代码实现:
分离x和y
# 生成特征变量数据集和因变量数据集
X = df.drop("class",axis=1)
y = df["class"]
# 切分比例为8:2
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=10)
创建模型
rf = RandomForestClassifier(max_depth=5)
rf.fit(X_train, y_train)
模型预测
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
# 模型预测
y_predict = rf.predict(X_test)
y_pred_quant = rf.predict_proba(X_test)[:,1]
y_pred_bin = rf.predict(X_test)
预测结果分析
混淆矩阵(Confusion Matrix)是一种用于评估分类模型性能的工具。它展示了模型在测试集上的分类结果,并与真实标签进行对比。具体来说,混淆矩阵能够清晰地显示模型的分类情况,包括正确分类和错误分类的数量。
# 混淆矩阵
confusion_matrix = confusion_matrix(y_test,y_pred_bin)
confusion_matrix
True Positives (TP): 173(真正类。模型正确地将正样本预测为正样本的数量。)
True Negatives (TN): 89(真负类。模型正确地将负样本预测为负样本的数量。)
False Positives (FP): 1(假正类。模型错误地将负样本预测为正样本的数量。)
False Negatives (FN): 1(假负类。模型错误地将正样本预测为负样本的数量。)
精确度 (Precision):
P
r
e
c
i
s
i
o
n
=
T
P
T
P
+
F
P
=
173
173
+
1
≈
0.985
\mathrm{Precision}=\frac{TP}{TP+FP}=\frac{173}{173+1}\approx0.985
Precision=TP+FPTP=173+1173≈0.985
精确度是指模型在预测为正样本的所有实例中,实际为正样本的比例。这里,精确度约为 98.5%。
召回率 (Recall):
R
e
c
a
l
l
=
T
P
T
P
+
F
N
=
173
173
+
1
≈
0.985
\mathrm{Recall}=\frac{TP}{TP+FN}=\frac{173}{173+1}\approx0.985
Recall=TP+FNTP=173+1173≈0.985
召回率是指实际为正样本的所有实例中,模型成功预测为正样本的比例。这里,召回率约为 98.5%。
F1 分数 (F1 Score):
F
1
S
c
o
r
e
=
2
×
P
r
e
c
i
s
i
o
n
×
R
e
c
a
l
l
P
r
e
c
i
s
i
o
n
+
R
e
c
a
l
l
=
2
×
0.985
×
0.985
0.985
+
0.985
≈
0.985
\mathrm{F1~Score}=2\times\frac{\mathrm{Precision}\times\mathrm{Recall}}{\mathrm{Precision}+\mathrm{Recall}}=2\times\frac{0.985\times0.985}{0.985+0.985}\approx0.985
F1 Score=2×Precision+RecallPrecision×Recall=2×0.985+0.9850.985×0.985≈0.985
F1 分数是精确度和召回率的调和均值,用于综合考虑这两个指标。这里,F1 分数约为 98.5%。
准确率 (Accuracy):
A
c
c
u
r
a
c
y
=
T
P
+
T
N
T
P
+
T
N
+
F
P
+
F
N
=
173
+
89
173
+
89
+
1
+
1
≈
0.985
\mathrm{Accuracy}=\frac{TP+TN}{TP+TN+FP+FN}=\frac{173+89}{173+89+1+1}\approx0.985
Accuracy=TP+TN+FP+FNTP+TN=173+89+1+1173+89≈0.985
准确率是指所有预测中,正确预测的比例。这里,准确率约为 98.5%。
ecall}}=2\times\frac{0.985\times0.985}{0.985+0.985}\approx0.985
$$
F1 分数是精确度和召回率的调和均值,用于综合考虑这两个指标。这里,F1 分数约为 98.5%。
准确率 (Accuracy):
A
c
c
u
r
a
c
y
=
T
P
+
T
N
T
P
+
T
N
+
F
P
+
F
N
=
173
+
89
173
+
89
+
1
+
1
≈
0.985
\mathrm{Accuracy}=\frac{TP+TN}{TP+TN+FP+FN}=\frac{173+89}{173+89+1+1}\approx0.985
Accuracy=TP+TN+FP+FNTP+TN=173+89+1+1173+89≈0.985
准确率是指所有预测中,正确预测的比例。这里,准确率约为 98.5%。
准确率为 98%。效果良好。