一文学会机器学习中的鸢尾花识别(包含基本流程与最优实践)
前言
作为机器学习KNN算法中典型的案例,鸢尾花识别再经典不过。本文将从机器学习建模流程来逐步完成对鸢尾花识别代码的编写:
1.获取数据——2.数据预处理——3.特征工程——4.模型训练(机器学习)——5.模型预测——6.模型评估
1、工具使用
- 我将使用pycharm结合
Jupyter Notebook工具,优点是可以逐步查看代码效果。 - python的SDK采用
Anaconda的沙箱环境,具体命令我也会简单介绍。 - 使用
wsl2结合ubuntu,wsl比起虚拟机开发要方便得多。 - 机器学习最核心的一个库:
scikit-learn
对于以上提到的工具,我会介绍具体的命令,感兴趣的朋友可以动手跟着进行代码实战。
2、环境搭建
巧妇难为无米之炊,在代码编写开始前要准备好相关环境。
2.1、WSL与Ubuntu
WSL(Windows Subsystem for Linux)是微软为Windows系统开发的兼容层,让用户无需虚拟机或双系统,即可直接在Windows中运行原生Linux发行版。(如Ubuntu、Debian)
简而言之,wsl让我们可以在window系统下使用linux开发环境。
至于安装步骤,大家可以参考微软官方wsl,并升级为wsl2。
我的电脑已经安装好:
而Ubuntu是基于 Debian 的开源Linux发行版,能够无缝兼容运行在wsl中,安装也很简单,直接在微软商店搜索安装即可(我选择Ubuntu22.04):

下载完成后可使用命令查看:wsl --list --verbose:

2.2、Anaconda下载与虚拟环境配置
Anaconda 集成了Conda包管理器 和 虚拟环境功能,帮助我们一建管理依赖、隔离项目环境,避免版本冲突。
在wsl中的安装步骤如下:
- 打开Ubuntu终端,先更新系统包:
sudo apt update && sudo apt upgrade -y - 下载Linux版本安装脚本(以最新版为例,可替换为官网链接):
wget https://repo.anaconda.com/archive/Anaconda3-2024.02-Linux-x86_64.sh - 运行安装脚本,按提示操作(一直回车即可):
bash Anaconda3-2024.02-Linux-x86_64.sh - 重启终端或执行
source ~/.bashrc加载配置 - 输入以下命令检查:
conda --version,出现版本号则成功 - 更新到最新版:
conda update --all -y
比如我的电脑环境:

虚拟环境相关配置
- 创建虚拟环境(需等待一段时间):
conda create -n ML python=3.11- ML是虚拟环境名字,python版本选择3.11
- 进入虚拟环境:
conda activate ML - 安装Jupyter工具:
conda install jupyter notebook - 安装机器学习库:
conda install scikit-learn
以上命令执行完毕后,可以达到图示效果:

至此,开发环境搭建基本结束,Pycharm的安装我就不多介绍,接下来正式开始项目。
3、项目创建与解释器配置
在pycharm中创建python项目,解释器选择conda。

如果显示SDK无效,那说明pycharm的映射有问题,我们需要重新配置解释器:
- 点击添加解释器,选择基于wsl

- 选择下一步

- 注意路径选择

配置完成后就可以使用jupyter notebook、正常导入开发库了,接下来创建文件(名字随意取):

配置Jupyter服务器:
- 在终端运行:
conda activate ML和jupyter notebook
- 复制生成的token值,点击右上角配置jupyter服务器:

- 如果显示 已连接,那么恭喜你,环境搭建成功! 点击确定即可。
Jupyter 相关语法简单,支持markdown、python语法,掌握几个基本的快捷键即可。
4、基本实现
现在进入正式的代码编写阶段,先把机器学习建模流程罗列:
- 获取数据
- 数据预处理
- 特征工程
- 特征提取
- 特征预处理
- 归一化
- 标准化
- 特征降维
- 特征选择等
- 机器学习(模型训练)
- 模型评估
- 模型预测
源代码:
# 导包
from sklearn.datasets import load_iris # 用于加载鸢尾花数据集
from sklearn.model_selection import train_test_split # 分割训练集和测试集
from sklearn.preprocessing import StandardScaler # 数据标准化的
from sklearn.neighbors import KNeighborsClassifier # KNN算法 分类对象
from sklearn.metrics import accuracy_score # 模型评估的,计算模型预测的准确率
# 加载数据集
iris_data = load_iris()
# 数据预处理
x_train,x_test,y_train,y_test=train_test_split(iris_data.data, iris_data.target,test_size=0.2,random_state=36)
# 标准化(特征工程)
transfer = StandardScaler()
x_train=transfer.fit_transform(x_train)
x_test=transfer.transform(x_test)
# 模型训练
estimator = KNeighborsClassifier(n_neighbors=5)
estimator.fit(x_train,y_train)
# 模型评估
# 评估一
score = estimator.score(x_test,y_test)
print(f'评估一的结果:{score}')
# 评估二
accuracy_score(y_test,estimator.predict(x_test))
print(f'评估二的结果:{score}')
# 模型预测
# estimator.predict(x_test)
# y_test
# 使用自定义数据
my_data=[[7.8,2.1,3.9,1.6],[5.4,2.1,3.9,2.0]]
my_data=transfer.transform(my_data)
my_pred = estimator.predict(my_data)
print(my_pred)
# 查看数据集每种分类的预测概率
pre_proba=estimator.predict_proba(my_data)
print(pre_proba)
逐步实现:
-
加载数据集并查看重要数据集重要参数:

解释:该数据集的特征集包含四列,翻译成中文就是鸢尾花的花萼以及花瓣的长度、宽度,单位厘米,上面的Min、Max等分别代表这些特征列的最小值,最大值、均值等;而setosa、versicolor、virginica代表鸢尾花的种类;最下面的0、1、2分别对应三种鸢尾花种类,类似于枚举。
-
预处理之划分数据集,训练集:测试集为8:2

-
特征工程之标准化

解释:transfer是创建的标准化器对象,可以调用fit_transform与transformAPI;
二者区别是fit_transform仅对训练集使用,也就是先学习数据分布,再标准化,后者适用于测试集标准化。 -
机器学习,也叫模型训练

解释:先创建估计器对象,随后调用fit函数,传入训练集的特征与标签进行模型训练
-
模型评估,两种评分方法

-
模型预测,将测试集的特征传入,得到预测值,再与原测试集的特征对比

-
自定义数据的预测

解释:这里预测结果predict是一个列表,将列表传入名称列表就能够直接获取对应的名称;模型也会提供predict_proba方法来查看预测值的预测概率,如果概率相同会根据奥卡姆剃刀原则,优先使用值小的结果。
注意事项:自定义数据使用前一定要先标准化,这是因为模型在训练前使用的训练集是标准化的,要保持一致。
5、最优实践
在机器学习建模流程的模型训练阶段,基本实现过程中是直接使用的无参模型,但往往我们需要为模型指定一些关键参数,而这些用户输入的参数被称为——超参。KNN算法中的模型默认参数n_neighbors等于5,而模型训练评分也达到了惊人的1.0,实属凑巧…
那么接下来我将修改代码,加上网格搜索与交叉验证,得到最优超参,重新训练,查看结果。
交叉验证与网格搜索简单理解:
超参:用户输入的不可控的参数,比如KNN里的n_neighbors参数值。
-
交叉验证法:是划分数据集的一种方法,目的是得到更加准确可信的模型评分
选定一个参数,将数据集分为五份,前四份为训练集,然后训练集3:1,做四次训练评估,求得分均值
-
网格搜索:传入多个超参,根据交叉验证的结果得到最优的那个超参
网格搜索是模型调参的有力工具,能够找到最优超参。
-
将若干参数传递给网格搜索对象,该对象帮我们完成不同超参组合、模型训练以及模型评估,最终返回一组最优超参。
交叉验证解决模型的数据输入问题(数据集划分)得到更可靠的模型,交叉验证+网格搜索能够形成
一个模型参数调优的解决方案。
首先,导入库:from sklearn.model_selection import train_test_split, GridSearchCV
然后修改模型训练前代码:
# 模型训练
# 创建模型
estimator = KNeighborsClassifier()
# 训练之前找超参
param_dict = {'n_neighbors': [i for i in range(1,11)]}
# 创建网格搜索对象
estimator = GridSearchCV(estimator, param_dict, cv=4)
# 训练
estimator.fit(x_train,y_train)
# 打印处理后的模型属性
print(f'最优评分:{estimator.best_score_}')
print(f'最优超参组合:{estimator.best_params_}')
print(f'最优估计器对象:{estimator.best_estimator_}')
print(f'具体的交叉验证结果:{estimator.cv_results_}')
解释:GridSearchCV接收三个参数,参一为模型对象,参二为超参的一个取值范围,参三代表交叉验证的折数,这里cv等于4就代表是四折交叉验证。在网格搜索结束后会返回一个更加强大的模型,通过打印属性我们就可以选择最优的超参,从而完成模型的优化。
结果如下:

那么这里能看出最优的超参n_neighbors就是9,接下来优化模型:

再次测试自定义数据:

值得一提的是:网格搜索结合交叉验证法只是选取最优超参的一个参考工具,不一定完全正确!
那么以上就是本文全部内容了,码文不易,如有错误还请大家批评指正,感谢阅读。
更多推荐
所有评论(0)