python实战(一)——iris鸢尾花数据集分类

一、任务背景

        本文是python实战系列专栏的第一篇文章,我们将从分类开始由浅入深逐步学习如何使用python完成常规的机器学习/深度学习任务。iris数据集是经典的机器学习入门数据集,许多分类任务教程都会以这个数据集作为示例,它的数据量是150条,由三种不同品种的鸢尾花数据构成,每种鸢尾花各50条数据。显然,这是一个多分类(三分类)任务,我们将从头开始进行探索性数据分析及机器学习建模。

二、机器学习建模流程

1、探索性数据分析

        探索性数据分析是建模的第一步,尤其是机器学习任务。尽管这是一个很标准、很干净的数据集,我们还是按照惯例对它进行基础的分析(特征列、空值、各列取值范围等),以对该数据集有个初步的了解和认知。

(1)数据集读取

        由于iris数据集实在太经典,所以很多python库都内置了该数据集的调用代码,例如在scikit-learn中可以这样调用:

from sklearn import datasets

# 加载iris数据集
iris = datasets.load_iris()
# 获取特征数据
iris_X = iris.data
# 获取目标(类别)数据
iris_y = iris.target

        但是实际应用中,我们更多的是读取本地文件,所以这里笔者从Kaggle下载了iris数据文件并本地读取:

# 读取csv文件数据
path = './data/iris.csv'
df = pd.read_csv(path)
print('数据量:', len(df))
print(df.head())

        结果如下,可见该数据集总共有150行,6列,其中一列是Id,在我们这次任务中作用不大,后面会去掉:

        根据官方的介绍,各列的含义如下:

  • SepalLengthCm:花萼长度,即花萼的最长部分,单位是厘米。
  • SepalWidthCm:花萼宽度,即花萼的最宽部分,单位是厘米。
  • PetalLengthCm:花瓣长度,即花瓣的最长部分,单位是厘米。
  • PetalWidth Cm:花瓣宽度,即花瓣的最宽部分,单位是厘米。

        而标签列Species中的类别有:

  • Iris setosa:山鸢尾
  • Iris virginica:变色鸢尾
  • Iris versicolor:维吉尼亚鸢尾

(2)查看各列中是否有空值

        去空值是数据处理阶段的重要步骤,存在空值的数据会导致后面的特征工程或者建模报错。下面的代码逐列统计是否有空值:

print('空值数量统计:')
print(df.isnull().sum())

        结果如下,每一列都很干净:

(3)简要统计各列的数据数值分布

        统计各列的数据分布主要目的是看看每一列各自以及相互之间的数据差异。如果某一列的数据取值之间非常接近(例如一个极端情况是整一列的取值都是1),那么可能这一列对于建模来说是没有意义的,可以去掉。同时,分位数也能帮我们判断当前列数据中是否存在离群点,可以考虑去掉离群点。此外,如果列和列之间取值范围差得较大(比如一列的取值范围是0-1,另一列是100-200)就需要进行归一化/标准化操作,量纲差异太大会导致模型学习过程中对特征重要性的判别出现误差。这里我们选择不对原始数据进行归一化或者标准化,一是各列之间的量纲接近,二是我们后面用的是决策树模型建模,决策树不需要归一化/标准化操作。

print(df.describe())

(4)检查标签列是否符合建模要求

        从上面的图中我们可以看到,标签列是文本类型,无法进行建模。因此需要将标签转换成模型可理解的数值类型(转为数值类型才可以计算损失)。

# 定义各类别对应的索引号
label_index = {'Iris-setosa':0, 'Iris-versicolor':1, 'Iris-virginica':2}
# apply方法应用到标签列中的每一个标签
df['Species'] = df['Species'].apply(lambda x: label_index[x])

2、数据可视化

        我们可以使用sklearn提供的PCA降维方法将原始数据降维成2维(也可以进行3维可视化),并且可视化出来。

# 分出特征列和标签列
X = df[['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm']].values.tolist()
y = df['Species'].tolist()
# 降维
pca = PCA(n_components=2)
pca_data = pca.fit_transform(X)
# 可视化
plt.scatter(pca_data[:, 0], pca_data[:, 1], c=y)
plt.show()

        可视化结果如下图,虽然可视化的过程没有标出来哪个颜色对应哪一类的鸢尾花,但我们可以看到某一类鸢尾花很轻易就可以与另外两类区分开来,而距离较近的两类似乎数据也是线性可分的,那么我们可以考虑用一个简单的模型完成这个任务。

3、数据划分

        了解了数据分布之后,我们可以开始进行数据的划分了,即划分训练集和测试集。其中,训练集用于训练模型,测试集用于测试模型的效果(测试集数据应当是在模型的训练阶段是未出现过的,否则就存在模型作弊的问题了)。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=2024)
print('训练集数据量:', len(X_train))
print('测试集数据量:', len(X_test))

        这里讲一下几个比较重要的参数:

  • stratify:控制训练集和测试集的标签类别比例,默认是无,但是我们一般会根据y进行划分。假如我们有100个数据,70个属于A类,30个属于B类,如果不指定该参数且test_size恰好是0.3,那么就有可能出现我们训练集中的70个都是A类数据,这样子模型只学了A的数据规律,使用测试集的30个数据进行测试的时候效果就很糟糕了。而如果指定了该参数,那么算法会确保训练集中各类别的比例和测试集中的各类别比例一致(如果算出来的数量不是整数会自动取整),假设这个例子我们指定的stratify是y,那么训练集中A和B类别的比例和测试集一致,都是7:3,则训练集中A类有49个,B类有21个,测试集中A类有21个,B类有9个,保持了数据集划分的公平性。
  • test_size:指定训练集和测试集划分过程中的比例,用0-1开区间之间的小数就可以了。
  • random_state:指定随机数,以保证模型结果可复现。

        打印数据划分结果如下:

4、模型训练

        这里我们使用一个决策树分类器作为模型,使用训练数据迭代训练决策树模型并输出模型的各项性能指标。

dt = DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=5, class_weight='balanced', random_state=2024)
dt.fit(X_train, y_train)
y_pred = dt.predict(X_test)
# 多分类问题需要指定average,其中:
# micro计算全局精确度:通过将所有类别的真正例和假正例汇总,然后计算整体的精确度。
# macro计算未加权平均精确度:简单地计算每个类别的精确度,然后求平均值,不考虑每个类别的样本数量。
# weighted计算加权平均精确度:计算每个类别的精确度,然后根据每个类别的样本数量进行加权平均。
print('Precision:', precision_score(y_test, y_pred, average='macro'))
print('Recall:', recall_score(y_test, y_pred, average='macro'))
print('F1:', f1_score(y_test, y_pred, average='macro'))

        这里有几个模型参数需要注意:

  • criterion:可选的有“gini”、“entropy”、“log_loss”,用于指定构建树时用于分裂节点的准则,默认是”gini”,即基尼不纯度。当使用gini作为参数的值时,决策树在每个节点的分裂都旨在最小化基尼不纯度;而使用entropy时,决策树在每个节点的分裂都旨在最大化信息增益,这意味着最小化熵。
  • splitter:可选的有“best”、“random”,用于指定如何选择分裂节点的方法,默认是”best”。当设置为best时,决策树会考虑所有可能的特征和所有可能的分割点,并选择能够最好地减少criterion取值的最佳分裂点。
  • max_depth:指定树的深度,默认是不限制,也就是树可以无限生长直到满足损失要求,但是对于一些模型规模有限制的场景建议限制树的深度在一定范围,否则模型可能非常大。
  • class_weight:默认为无,可以输入字典(键为类别,值为当前类别的样本数)也可以直接写“balanced”。建议直接指定“balanced”,这样模型会自动为不同类别的样本赋予权重。这个参数在样本类别不平衡的时候非常重要,假设一个二分类任务中样本A有98个,B有2个,不设置权重模型可能只学A的特征,从而忽略B类(因为即便B类预测错误,总体数据上仍然能够有一个很好的指标结果),但设置class_weight后,模型会认为A和B同样重要,从而避免样本类别不平衡造成的模型问题。
  • random_state:指定随机数以便复现模型结果。

        以下是训练后的模型在测试集上的表现,由于数据集较为简单,模型的指标效果不错。当然,如果进行更细致的参数调优,模型可以取得更好的效果,这里就不演示了。

三、完整代码

import pandas as pd
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import precision_score, recall_score, f1_score

path = './data/iris.csv'
df = pd.read_csv(path)
print('数据量:', len(df))
print(df.head())
print('空值数量统计:')
print(df.isnull().sum())
print(df.describe())
df.drop(['Id'], axis=1)
label_index = {'Iris-setosa':0, 'Iris-versicolor':1, 'Iris-virginica':2}
df['Species'] = df['Species'].apply(lambda x: label_index[x])

X = df[['SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm']].values.tolist()
y = df['Species'].tolist()
pca = PCA(n_components=2)
pca_data = pca.fit_transform(X)
plt.scatter(pca_data[:, 0], pca_data[:, 1], c=y)
plt.show()

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=2024)
print('训练集数据量:', len(X_train))
print('测试集数据量:', len(X_test))
dt = DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=5, class_weight='balanced', random_state=2024)
dt.fit(X_train, y_train)
y_pred = dt.predict(X_test)
print('Precision:', precision_score(y_test, y_pred, average='macro'))
print('Recall:', recall_score(y_test, y_pred, average='macro'))
print('F1:', f1_score(y_test, y_pred, average='macro'))

四、总结

        本文使用决策树模型对iris鸢尾花数据集进行了分类建模,由于数据量小、数据集简单且各特征含义明确,本文直接使用所有特征进行建模。实际的建模任务中,特征选择也是重要的一步,我们需要选择对建模真正有用的特征(特征选择),而不是所有特征都用于建模(比如一份数据可能有100多个特征列,但实际对建模有用的可能只有5、6个特征)。后面的博文将会陆续介绍这些技巧,并展示如何在更复杂的生产数据中使用这些技巧进行建模。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/901199.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型微调方法详解【全量微调、PEFT、LoRA、Adapter】

NLP-大语言模型学习系列目录 一、注意力机制基础——RNN,Seq2Seq等基础知识 二、注意力机制【Self-Attention,自注意力模型】 三、Transformer图文详解【Attention is all you need】 四、大语言模型的Scaling Law【Power Low】 五、大语言模型微调 文章目录 NLP-大语言模型学…

12个免费商用视频素材网站,助你打造高质量短视频!

我来啦,作为一个资深短视频运营! 在剪辑了1362条片子后,我总结出下面的这些素材网站~ 基本上都是剪辑中常用到的,下载的视频也是MP4格式,直接就可以用,还有图片、音效和Pr教程推荐,总有一款适…

使用Llama Index与Streamlit实现一个从文本中提取专业术语和定义网页小程序

Llama Index有许多用例(语义搜索、摘要等),并且都有很好的记录。然而,这并不意味着我们不能将Llama Index应用到非常具体的用例中! 在本教程中,我们将介绍使用Llama Index从文本中提取专业术语和定义的设计…

迭代器边遍历边删除存在的问题

迭代器边遍历边删除存在的问题以及原理 01-问题 ​ 我们先来看看如下代码 public static void main(String[] args) {List<Integer> list new ArrayList<>();list.add(5);list.add(4);list.add(3);list.add(2);list.add(7);list.add(0);Iterator<Integer>…

CSP-J代码解析!最新2024CSP-J题解及参考代码

经过整理&#xff0c;老师已经整理了今年CSP-J复赛的题目和代码解析&#xff01; T4题目名称有误&#xff0c;更正&#xff1a;接龙&#xff01; 需要PDF版本的→malaoshi606 T1 扑克牌 poker 算法&#xff1a;模拟&#xff0c;桶数组思路&#xff1a;创建一个标记数组vis&…

贪心算法记录 - 下

135. 分发糖果 困难 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0c…

OpenCV中的图像通道合并

在计算机视觉和图像处理领域&#xff0c;OpenCV是一个强大的工具库&#xff0c;它提供了从基本操作到复杂算法的广泛功能。今天&#xff0c;我们将通过一个简单的示例来探索OpenCV中的图像通道处理&#xff0c;特别是如何操作和理解BGR与RGB颜色空间的差异。 Lena图像&#xf…

LinkedList和链表(下)

1. 什么是LinkedList 在练习了单链表的自我实现和单链表的一些习题之后,我们正式来认识一下java提供的LinkedList,这是一种双向链表结构,在增删元素的时候效率比较高,不需要像ArrayList一样搬运元素.但是在查找方面效率比较低(需要遍历链表),ArrayList效率就比较高(直接由数组下…

JS+Springboot做一个交互Demo

背景&#xff1a;老大做了一个 SDK&#xff0c;包含字符加解密、文件加解密&#xff0c;要求能从前端访问&#xff0c;并且能演示的 Demo。 思路&#xff1a;html 写页面&#xff0c;js 发送请求&#xff0c;freemarker 做简单的参数交互&#xff0c;JAVA 后端处理。 一、项目依…

CSS 样式 box-sizing: border-box; 用于控制元素的盒模型如何计算宽度和高度

文章目录 box-sizing: border-box; 的含义默认盒模型 (content-box)border-box 盒模型 在微信小程序中的应用示例 在微信小程序中&#xff0c;CSS 样式 box-sizing: border-box; 用于控制元素的盒模型如何计算宽度和高度。具体来说&#xff0c; box-sizing: border-box; 会改…

【已解决】C# NPOI如何在Excel文本中增加下拉框

前言 上图&#xff01; 解决方法 直接上代码&#xff01;&#xff01;&#xff01;&#xff01;综合了各个大佬的自己修改了一下&#xff01;可以直接规定在任意单元格进行设置。 核心代码方法块 #region Excel增加下拉框/// <summary>/// 增加下拉框选项/// </s…

Python游戏开发超详细(基础理论知识篇)

一、引导&#xff1a; Python游戏开发是一个非常有趣且富有挑战性的领域。通过Python&#xff0c;你可以利用其强大的库和框架来创建各种类型的游戏&#xff0c;从简单的2D游戏到复杂的3D游戏。以下是第一课的基础理论知识&#xff0c;帮助你入门Python游戏开发。 二、理论知识…

中小企业设备资源优化:Spring Boot系统实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

部署seatunnel2.3.8

部署seatunnel web参考&#xff1a;SeaTunnel Web1.0.0安装_plugindiscoveryutil.getallconnectors-CSDN博客 配置&#xff1a;两台centos服务器&#xff0c;2master2worker 一、下载包 v2.3.8[bin] apache-seatunnel-2.3.8-bin.tar.gz 将包上传到master节点和worker节点所…

Python开发日记 -- 实现bin文件的签名

目录 1.数据的不同表现形式签名值不一样&#xff1f; 2.Binascii模块简介 3.问题定位 4.问题总结 1.数据的不同表现形式签名值不一样&#xff1f; Happy Muscle试运行了一段时间&#xff0c;组内同事再一次提出了新的需求&#xff1a;需要对bin文件签名。 PS&#xff1a;服…

使用代码编辑组件的npm包

使用代码编辑组件的npm包 文章说明核心代码运行截图源码下载 文章说明 我将书写的代码编辑组件打包为npm包&#xff0c;下载即可使用&#xff0c;目前是1.0.4版本&#xff0c;虽然功能还有一些bug&#xff0c;但是可以较为简单的使用 npm地址 核心代码 安装依赖 npm i bingbing…

H7-TOOL的LUA小程序教程第16期:脉冲测量,4路PWM,多路GPIO和波形打印(2024-10-25, 更新完毕)

LUA脚本的好处是用户可以根据自己注册的一批API&#xff08;当前TOOL已经提供了几百个函数供大家使用&#xff09;&#xff0c;实现各种小程序&#xff0c;不再限制Flash里面已经下载的程序&#xff0c;就跟手机安装APP差不多&#xff0c;所以在H7-TOOL里面被广泛使用&#xff…

OpenCV-物体跟踪

文章目录 一、物体跟踪的定义二、OpenCV中的物体跟踪算法三、OpenCV物体跟踪的实现步骤四、代码实现五、注意事项 OpenCV是一个开源的计算机视觉和机器学习软件库&#xff0c;它提供了丰富的功能来实现物体跟踪。以下是对OpenCV中物体跟踪的详细解释&#xff1a; 一、物体跟踪的…

清华大学《2022年+2021年822自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《清华大学822自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2022年真题 2021年真题 Part1&#xff1a;2022年2021年完整版真题 2022年真题 2021年真题…

论文笔记:通用世界模型WorldDreamer

整理了WorldDreamer: Towards General World Models for Video Generation via Predicting Masked Tokens 论文的阅读笔记 背景模型实验 背景 现有的世界模型仅限于游戏或驾驶等特定场景&#xff0c;限制了它们捕捉一般世界动态环境复杂性的能力。针对这一挑战&#xff0c;本文…