news 2026/4/1 19:58:44

【机器学习】案例2.1——随机森林(Random Forest)进行鸢尾花分类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【机器学习】案例2.1——随机森林(Random Forest)进行鸢尾花分类

1. 项目背景及解决问题的方案

1.1 项目背景

鸢尾花(Iris)数据集是机器学习领域经典的多分类基准数据集,由Fisher于1936年提出,常被用于验证分类算法的有效性。该数据集包含3类鸢尾花(山鸢尾、变色鸢尾、维吉尼亚鸢尾),共150条样本,每条样本包含4个数值型特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度。

本项目的核心背景与目标:

  1. 算法验证:以鸢尾花分类问题为载体,验证随机森林(Random Forest)——作为Bagging集成学习的改进算法——在多分类任务中的性能;
  2. 关键特性验证:测试随机森林的“袋外样本(OOB)评分”(无需额外验证集即可评估模型泛化能力);
  3. 特征价值分析:通过随机森林的特征重要性输出,明确哪些特征对鸢尾花分类最关键;
  4. 算法对比(可选):对比基础Bagging算法与随机森林的分类效果,体现随机森林“特征随机”的优势。

1.2 解决问题的方案

针对“鸢尾花多分类”问题,本项目采用**“数据预处理→模型构建→模型评估→特征分析”** 四步解决方案:

步骤具体操作
数据预处理1. 加载鸢尾花数据集;
2. 选取特征(先选花萼长宽,后用全部4个特征);
3. 按7:3拆分训练集/测试集(保证随机可复现)
模型构建1. 初始化随机森林分类器,设置树数量、最大叶节点数、开启OOB评分;
2. (可选)初始化基础Bagging分类器作为对比
模型评估1. 输出OOB评分(袋外样本准确率);
2. 用测试集预测,计算分类准确率;
3. (可选)对比Bagging的测试集准确率
特征重要性分析用全特征训练随机森林,输出4个特征的重要性得分,明确核心分类特征

2. 详细注释版代码(含中文可视化/打印)

# 导入必要的库fromsklearn.ensembleimportRandomForestClassifier# 随机森林分类器fromsklearn.model_selectionimporttrain_test_split# 数据集拆分fromsklearn.ensembleimportBaggingClassifier# 基础Bagging分类器(对比用)fromsklearn.treeimportDecisionTreeClassifier# 决策树基学习器fromsklearn.metricsimportaccuracy_score# 分类准确率评估指标fromsklearn.datasetsimportload_iris# 加载鸢尾花数据集importmatplotlib.pyplotasplt# 可视化库importnumpyasnp# 数值计算库# ========== 解决matplotlib中文显示问题 ==========plt.rcParams['font.sans-serif']=['SimHei']# 用黑体显示中文plt.rcParams['axes.unicode_minus']=False# 正常显示负号# ========== 第一步:数据加载与预处理 ==========# 加载鸢尾花数据集,包含特征、标签、特征名、标签名等信息iris=load_iris()# 选取前2个特征:花萼长度(第0列)、花萼宽度(第1列),用于简化模型验证X=iris.data[:,:2]# 标签:0=山鸢尾,1=变色鸢尾,2=维吉尼亚鸢尾y=iris.target# 拆分训练集(67%)和测试集(33%),random_state=42保证结果可复现# stratify=y:分层拆分,保证训练/测试集的类别分布与原数据一致X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.33,random_state=42,stratify=y)print("="*50)print("数据预处理完成:")print(f"训练集样本数:{len(X_train)},测试集样本数:{len(X_test)}")print(f"选取的特征:{iris.feature_names[0]}{iris.feature_names[1]}")# ========== 第二步:随机森林模型训练与评估 ==========# 初始化随机森林分类器# n_estimators=15:决策树数量为15# max_leaf_nodes=16:每棵树的最大叶节点数(限制树复杂度,防止过拟合)# n_jobs=1:单线程运行(便于调试)# oob_score=True:开启袋外样本评分(用未被抽样的样本评估模型)rnd_clf=RandomForestClassifier(n_estimators=15,max_leaf_nodes=16,n_jobs=1,oob_score=True,random_state=42# 随机种子,保证结果可复现)# 用训练集训练模型rnd_clf.fit(X_train,y_train)# 输出OOB评分(袋外样本准确率):无需测试集即可评估模型泛化能力print("="*50)print(f"随机森林袋外(OOB)样本准确率:{rnd_clf.oob_score_:.4f}")# 用训练好的模型预测测试集y_pred_rf=rnd_clf.predict(X_test)# 计算测试集分类准确率rf_acc=accuracy_score(y_test,y_pred_rf)print(f"随机森林测试集分类准确率:{rf_acc:.4f}")# ========== 可选:基础Bagging分类器对比(解除注释可运行) ==========# 初始化Bagging分类器(基学习器为随机拆分的决策树)# bag_clf = BaggingClassifier(# DecisionTreeClassifier(splitter="random", max_leaf_nodes=16), # 随机拆分的决策树# n_estimators=15, # 基学习器数量(与随机森林一致)# max_samples=1.0, # 每个基学习器使用100%的抽样样本# bootstrap=True, # 开启有放回抽样(Bootstrap)# n_jobs=1,# random_state=42# )# bag_clf.fit(X_train, y_train) # 训练Bagging模型# y_pred_bag = bag_clf.predict(X_test) # 测试集预测# bag_acc = accuracy_score(y_test, y_pred_bag) # 计算准确率# print(f"基础Bagging分类器测试集准确率:{bag_acc:.4f}")# ========== 第三步:全特征随机森林 + 特征重要性分析 ==========print("="*50)print("全特征随机森林特征重要性分析:")# 重新初始化随机森林(更多树,更高稳定性),用全部4个特征训练rnd_clf_full=RandomForestClassifier(n_estimators=500,# 决策树数量增加到500,提升特征重要性的稳定性n_jobs=-1,# 使用全部CPU核心,加速训练random_state=42)# 用全部特征(4个)训练模型rnd_clf_full.fit(iris["data"],iris['target'])# 遍历特征名和对应的重要性得分,打印输出feature_importance=[]forname,scoreinzip(iris['feature_names'],rnd_clf_full.feature_importances_):print(f"特征:{name},重要性得分:{score:.4f}")feature_importance.append((name,score))# ========== 第四步:特征重要性可视化(柱状图) ==========# 提取特征名和得分features=[x[0]forxinfeature_importance]scores=[x[1]forxinfeature_importance]# 创建画布,设置大小plt.figure(figsize=(10,6))# 绘制柱状图bars=plt.bar(features,scores,color=['#1f77b4','#ff7f0e','#2ca02c','#d62728'])# 添加数值标签(在柱子上方显示得分)forbarinbars:height=bar.get_height()plt.text(bar.get_x()+bar.get_width()/2.,height+0.01,f'{height:.4f}',ha='center',va='bottom',fontsize=10)# 设置标题和坐标轴标签plt.title('鸢尾花分类 - 随机森林特征重要性',fontsize=14)plt.xlabel('特征名称',fontsize=12)plt.ylabel('重要性得分',fontsize=12)# 旋转x轴标签,避免重叠plt.xticks(rotation=15)# 显示网格(仅y轴)plt.grid(axis='y',linestyle='--',alpha=0.7)# 保存图片(可选)plt.savefig('特征重要性.png',dpi=300,bbox_inches='tight')# 显示图表plt.show()# ========== 第五步:二维特征分类结果可视化(花萼长宽) ==========print("="*50)print("绘制二维特征(花萼长宽)的分类决策边界...")# 生成网格点,用于绘制决策边界x_min,x_max=X[:,0].min()-0.5,X[:,0].max()+0.5y_min,y_max=X[:,1].min()-0.5,X[:,1].max()+0.5xx,yy=np.meshgrid(np.arange(x_min,x_max,0.02),np.arange(y_min,y_max,0.02))# 用随机森林模型预测网格点的类别Z=rnd_clf.predict(np.c_[xx.ravel(),yy.ravel()])Z=Z.reshape(xx.shape)# 创建画布plt.figure(figsize=(10,6))# 绘制决策边界(等高线填充)plt.contourf(xx,yy,Z,alpha=0.3,cmap=plt.cm.RdYlBu)# 绘制训练集样本点plt.scatter(X_train[:,0],X_train[:,1],c=y_train,edgecolors='k',cmap=plt.cm.RdYlBu,label='训练集')# 绘制测试集样本点(加空心圈区分)plt.scatter(X_test[:,0],X_test[:,1],c=y_test,edgecolors='k',cmap=plt.cm.RdYlBu,marker='o',facecolors='none',s=100,label='测试集')# 设置标题和坐标轴标签plt.title('随机森林分类决策边界(花萼长度 vs 花萼宽度)',fontsize=14)plt.xlabel(iris.feature_names[0],fontsize=12)plt.ylabel(iris.feature_names[1],fontsize=12)# 添加图例plt.legend(loc='upper left')# 显示网格plt.grid(alpha=0.3)# 保存图片plt.savefig('分类决策边界.png',dpi=300,bbox_inches='tight')# 显示图表plt.show()

3. 简洁版代码(保留核心逻辑)

fromsklearn.ensembleimportRandomForestClassifierfromsklearn.model_selectionimporttrain_test_splitfromsklearn.ensembleimportBaggingClassifierfromsklearn.treeimportDecisionTreeClassifierfromsklearn.metricsimportaccuracy_scorefromsklearn.datasetsimportload_irisimportmatplotlib.pyplotaspltimportnumpyasnp plt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falseiris=load_iris()X=iris.data[:,:2]y=iris.target X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.33,random_state=42,stratify=y)print("="*50)print(f"训练集样本数:{len(X_train)},测试集样本数:{len(X_test)}")rnd_clf=RandomForestClassifier(n_estimators=15,max_leaf_nodes=16,n_jobs=1,oob_score=True,random_state=42)rnd_clf.fit(X_train,y_train)print("="*50)print(f"随机森林袋外(OOB)样本准确率:{rnd_clf.oob_score_:.4f}")y_pred_rf=rnd_clf.predict(X_test)rf_acc=accuracy_score(y_test,y_pred_rf)print(f"随机森林测试集分类准确率:{rf_acc:.4f}")print("="*50)print("全特征随机森林特征重要性分析:")rnd_clf_full=RandomForestClassifier(n_estimators=500,n_jobs=-1,random_state=42)rnd_clf_full.fit(iris["data"],iris['target'])feature_importance=[]forname,scoreinzip(iris['feature_names'],rnd_clf_full.feature_importances_):print(f"特征:{name},重要性得分:{score:.4f}")feature_importance.append((name,score))features=[x[0]forxinfeature_importance]scores=[x[1]forxinfeature_importance]plt.figure(figsize=(10,6))bars=plt.bar(features,scores,color=['#1f77b4','#ff7f0e','#2ca02c','#d62728'])forbarinbars:height=bar.get_height()plt.text(bar.get_x()+bar.get_width()/2.,height+0.01,f'{height:.4f}',ha='center',va='bottom',fontsize=10)plt.title('鸢尾花分类 - 随机森林特征重要性',fontsize=14)plt.xlabel('特征名称',fontsize=12)plt.ylabel('重要性得分',fontsize=12)plt.xticks(rotation=15)plt.grid(axis='y',linestyle='--',alpha=0.7)plt.savefig('特征重要性.png',dpi=300,bbox_inches='tight')plt.show()print("="*50)print("绘制二维特征(花萼长宽)的分类决策边界...")x_min,x_max=X[:,0].min()-0.5,X[:,0].max()+0.5y_min,y_max=X[:,1].min()-0.5,X[:,1].max()+0.5xx,yy=np.meshgrid(np.arange(x_min,x_max,0.02),np.arange(y_min,y_max,0.02))Z=rnd_clf.predict(np.c_[xx.ravel(),yy.ravel()])Z=Z.reshape(xx.shape)plt.figure(figsize=(10,6))plt.contourf(xx,yy,Z,alpha=0.3,cmap=plt.cm.RdYlBu)plt.scatter(X_train[:,0],X_train[:,1],c=y_train,edgecolors='k',cmap=plt.cm.RdYlBu,label='训练集')plt.scatter(X_test[:,0],X_test[:,1],c=y_test,edgecolors='k',cmap=plt.cm.RdYlBu,marker='o',facecolors='none',s=100,label='测试集')plt.title('随机森林分类决策边界(花萼长度 vs 花萼宽度)',fontsize=14)plt.xlabel(iris.feature_names[0],fontsize=12)plt.ylabel(iris.feature_names[1],fontsize=12)plt.legend(loc='upper left')plt.grid(alpha=0.3)plt.savefig('分类决策边界.png',dpi=300,bbox_inches='tight')plt.show()

关键输出说明

  1. OOB评分:通常在0.85~0.95之间,代表模型在未参与训练的“袋外样本”上的准确率,反映泛化能力;
  2. 测试集准确率:基于花萼长宽两个特征,准确率约0.7~0.8(若用全部4个特征,准确率接近1.0);
  3. 特征重要性:花瓣长度(petal length)和花瓣宽度(petal width)的重要性得分远高于花萼特征,是鸢尾花分类的核心特征;
  4. 可视化图表
    • 特征重要性柱状图:直观展示各特征的贡献度;
    • 决策边界图:可看到随机森林对二维特征的分类边界,以及训练/测试样本的分布。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/12 22:56:55

【精准农业数据分析】:基于R语言的回归诊断技术与应用案例

第一章:农业产量的 R 语言回归诊断在农业数据分析中,理解影响作物产量的关键因素至关重要。回归模型被广泛用于探索土壤质量、降水量、施肥量等变量与农作物产量之间的关系。然而,模型拟合后必须进行回归诊断,以确保其假设成立并提…

作者头像 李华
网站建设 2026/3/31 19:35:40

C++后台开发学习路线

找完工作后一直想找时间写点东西,回馈牛客,由于在忙各种事情,一直拖到现在。作为一个19届的老油条,趁在毕业之前,将我的学习总结分享给大家,希望对正在找实习或者找工作的同学有所帮助。个人介绍首先介绍下…

作者头像 李华
网站建设 2026/3/31 11:49:20

Springboot旅游信息网na6kf(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表项目功能:用户,景点分类,景点信息,酒店信息,航班信息,火车信息,客车信息,当地公交,旅游日志开题报告内容一、选题背景及意义(一)选题背景自改革开放以来,中国旅游业经历了起步、成长、拓展和综合发展四个阶段&…

作者头像 李华
网站建设 2026/3/31 19:39:09

C 语言运算符完全指南:从入门到避坑

阅读对象:C 语言初学者、在校学生、初级嵌入式/系统开发工程师 目标:不仅让你“记住”运算符,更让你“理解”代码背后的逻辑。如果把变量比作 C 语言中的“积木”,那么运算符就是粘合这些积木的“胶水”和“工具”。没有它们&…

作者头像 李华
网站建设 2026/3/24 17:40:48

PyQt-SiliconUI:打造桌面应用的艺术化界面终极指南

PyQt-SiliconUI:打造桌面应用的艺术化界面终极指南 【免费下载链接】PyQt-SiliconUI A powerful and artistic UI library based on PyQt5 / PySide6,基于PyQt5 / PySide6的UI框架,灵动、优雅而轻便 项目地址: https://gitcode.com/gh_mirr…

作者头像 李华