使用Scikit-learn包训练基于随机森林的分类器模型
引言
在机器学习的世界中,随机森林(Random Forest)凭借其强大的性能和出色的泛化能力,成为了最受欢迎的分类算法之一。无论你是在进行客户流失预测、垃圾邮件检测,还是疾病诊断,随机森林都能以极少的配置工作交付高准确率的结果。
什么是随机森林?
随机森林是一种集成学习(Ensemble Learning)方法,它通过构建大量决策树并综合它们的预测结果来工作。对于分类任务,最终结果由所有树的投票决定——即选择得票最多的类别。
“森林”一词源于它使用了多棵决策树,而“随机”则体现在两个层面:
- 数据采样随机:每棵树使用Bootstrap方式(有放回抽样)从原始数据集中抽取不同的子集进行训练。
- 特征选择随机:在每棵树的每个节点分裂时,只随机考虑一部分特征来确定最佳分裂方式。
这两重随机性使得随机森林既能保留决策树的预测能力,又能有效降低过拟合风险。
为什么选择随机森林?
- 高准确率:通过集成多棵树,显著降低了方差和过拟合
- 处理大规模数据:能够高效处理大型数据集
- 容忍缺失值:即使存在较多缺失数据,仍能保持较高准确率
- 特征重要性评估:可以输出每个特征对预测的贡献度,帮助你理解哪些因素最重要
- 不易过拟合:相比单棵决策树,随机森林的泛化能力更强
环境准备
在开始之前,请确保已安装必要的库:
pip install scikit-learn pandas matplotlib seaborn
实战:使用鸢尾花数据集训练随机森林分类器
我们将使用机器学习中最经典的鸢尾花(Iris)数据集作为示例。该数据集包含三种鸢尾花的花萼长度、花萼宽度、花瓣长度和花瓣宽度四个特征,非常适合作为分类算法的入门案例。
步骤1:导入所需库
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
步骤2:加载并探索数据
# 加载鸢尾花数据集
iris = load_iris()
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['species'] = iris.target
# 查看数据前几行
print(df.head())
数据集包含150个样本,每个样本有4个特征,目标变量为3种类别(0=setosa,1=versicolor,2=virginica)。
步骤3:划分训练集和测试集
X = df.drop('species', axis=1)
y = df['species']
# 按80%训练、20%测试的比例划分
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
设置 random_state=42 可以保证每次运行结果可复现。
步骤4:构建并训练随机森林模型
# 创建随机森林分类器,使用100棵决策树
clf = RandomForestClassifier(n_estimators=100, random_state=42)
# 训练模型
clf.fit(X_train, y_train)
就是这么简单!一行 fit 就完成了模型训练。
步骤5:预测与评估
# 在测试集上进行预测
y_pred = clf.predict(X_test)
# 输出混淆矩阵
print("混淆矩阵:")
print(confusion_matrix(y_test, y_pred))
# 输出详细的分类报告
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
classification_report 会输出每个类别的精确率(Precision)、召回率(Recall)和F1-score。
步骤6:特征重要性可视化
随机森林的一大优势是可以输出特征重要性,帮助我们理解哪些特征对预测贡献最大:
# 获取特征重要性
feature_importances = pd.Series(
clf.feature_importances_,
index=X.columns
)
# 绘制水平条形图
plt.figure(figsize=(8, 5))
sns.barplot(x=feature_importances, y=feature_importances.index)
plt.title("随机森林特征重要性")
plt.xlabel("重要性分数")
plt.tight_layout()
plt.show()
从可视化结果中可以直观地看出哪些特征对分类决策影响最大。
完整代码
以下是完整的代码,可以直接复制运行:
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
# 1. 加载数据
iris = load_iris()
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['species'] = iris.target
# 2. 划分训练集和测试集
X = df.drop('species', axis=1)
y = df['species']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 3. 训练随机森林模型
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train, y_train)
# 4. 预测与评估
y_pred = clf.predict(X_test)
print("混淆矩阵:")
print(confusion_matrix(y_test, y_pred))
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
# 5. 特征重要性可视化
feature_importances = pd.Series(clf.feature_importances_, index=X.columns)
plt.figure(figsize=(8, 5))
sns.barplot(x=feature_importances, y=feature_importances.index)
plt.title("随机森林特征重要性")
plt.xlabel("重要性分数")
plt.tight_layout()
plt.show()
核心参数解析
RandomForestClassifier 有几个关键参数值得关注:
| 参数 | 默认值 | 说明 |
|---|---|---|
n_estimators |
100 | 森林中决策树的数量。树越多效果通常越好,但训练时间也更长 |
max_depth |
None | 每棵树的最大深度。不限制时节点会一直分裂到纯节点或达到最小样本数 |
max_features |
‘sqrt’ | 每次分裂时考虑的最大特征数 |
min_samples_split |
2 | 内部节点再分裂所需的最小样本数 |
min_samples_leaf |
1 | 叶节点所需的最小样本数 |
bootstrap |
True | 是否使用Bootstrap采样 |
random_state |
None | 随机种子,设置后可复现结果 |
调参建议:
n_estimators和max_features是最常调整的两个参数——树越多效果越好但计算越慢,而max_features控制每棵树的随机程度。
模型优化与调参
1. 使用交叉验证
from sklearn.model_selection import cross_val_score
scores = cross_val_score(clf, X, y, cv=5)
print(f"交叉验证平均准确率: {scores.mean():.3f}")
2. 网格搜索调参
from sklearn.model_selection import GridSearchCV
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [None, 10, 20],
'max_features': ['sqrt', 'log2']
}
grid_search = GridSearchCV(
RandomForestClassifier(random_state=42),
param_grid, cv=5, n_jobs=-1
)
grid_search.fit(X_train, y_train)
print(f"最佳参数: {grid_search.best_params_}")
3. 处理类别不平衡
如果数据集的类别分布不均衡,可以设置 class_weight='balanced' 来自动调整类别权重:
clf = RandomForestClassifier(
n_estimators=100,
class_weight='balanced',
random_state=42
)
- 点赞
- 收藏
- 关注作者
评论(0)