目录
一. 项目介绍
鸢尾花数据集是机器学习入门的一个十分经典的数据集,这里依然简单的介绍一下这个项目是做什么的,通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。在这篇博客中,我们将在此数据集上同时构建多个机器学习模型,并对比它们分类效果的好坏,从实际项目上对机器学习的各个基础算法的应用背景能有一个初步的掌握,将这些基础算法从理论中实际运用起来。
这是项目中将会用到的库
from sklearn.datasets import load_iris # 鸢尾花数据集
from sklearn.model_selection import train_test_split # 分割测试集和训练集
import seaborn as sns # 画图
import matplotlib.pyplot as plt # 画图
import pandas as pd # 数据处理
from sklearn.preprocessing import StandardScaler # 标准化处理数据
from sklearn.neighbors import KNeighborsClassifier # KNN算法
from sklearn.metrics import accuracy_score # 模型评估
二. 加载数据集
在机器学习中有一个sklearn库这是机器学习中常用的第三方模块,对常用的机器学习方法进行了封装,包括回归(Regression)、降维(Dimensionality Reduction)、分类(Classfication)、聚类(Clustering)等方法同时Sklearn自带部分数据集,其中包含鸢尾花数据集
from sklearn.datasets import load_iris
# todo 1.加载数据
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
iris = load_iris() # 加载数据集
# print(iris)
print(iris.keys())
# print(iris.feature_names) # 目标值信息
# print('iris####',iris.data[:10]) # 只打印数据
# print()
在iris中有很多信息,我们需要在这里找到需要的,因此我们可以先将iris.key输出看看都有什么键
由图1可以看出有八种键,其中主要的是data(特征),target(标签),target_name(标签名字),feature_name(目标值信息)
三. 数据展示(观察)
为了更好地观察数据的分布情况,借助图形是必不可少的,这里引入了matplotlib和seaborn库进行可视化展示。
依次两两结合找到较容易划分的
isit_d = pd.DataFrame(iris.data,columns=iris.feature_names) # 将数据清晰展示
# print('isit_d-->',isit_d)
isit_d['target'] = iris.target # 在isit_d下加上iris.target标签数据
# print('isit_d-->',isit_d)
def show_iris_data():
name = iris.feature_names
# sns.lmplot(x='sepal length (cm)',y='sepal width (cm)',hue='target',data=isit_d)
plt.show()
for i in range(len(name)):
for j in range(i+1,len(name)):
col1=name[i]
col2=name[j]
sns.lmplot(x=col1, y=col2, hue='target', data=isit_d, fit_reg=False)
plt.xlabel(col1)
plt.ylabel(col2)
plt.title(f'{col1} and {col2}')
plt.show()
# col1 = 'sepal length (cm)'
# col2 = 'petal width (cm)'
show_iris_data()
图片展示如下,通过对比选择了
'sepal length (cm)' 和 'petal width (cm)'
四. 数据基本处理
使用
from sklearn.model_selection import train_test_split
对数据集进行划分,按照7:3的比例
# 数据集划分
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.3,random_state=32)
# print(x_train)
# print(f'数据总数量-->{len(iris.data)}') # 150
# print(f'训练集数量-->{len(x_train)}') # 105
# print(f'测试集数量-->{len(x_test)}') # 45
五. 特征处理
下面就是上一章KNN学习的知识,对数据进行标准化处理
# from sklearn.preprocessing import StandardScaler
transfomer = StandardScaler() # 初始化归一化对象StandardScaler 标准库
x_train = transfomer.fit_transform(x_train) # 对于原始特征进行变换
x_test = transfomer.fit_transform(x_test)
# print(f'标准化后的x_train-->{x_train}')
六. 实例化K折交叉验证选择K值
调用KNN算法,并把K值设置为5但是这个是一个人为设置的超参数,不一定是最优的参数,因此还需要进行
model = KNeighborsClassifier(n_neighbors=5)
七. K折交叉验证选择K值
7.1K折交叉验证
K折交叉验证(K-fold cross validation)指的是把训练数据D 分为 K份,用其中的(K-1)份训练模型,把剩余的1份数据用于评估模型的质量。将这个过程在K份数据上依次循环,并对得到的K个评估结果进行合并,如求平均或投票
如下图训练数据D被分为了 𝐷1,𝐷2,𝐷3...𝐷10 ,每次取其中9份数据作为训练集,1份作为测试集,最终将循环后所有的评估结果取平均。
7.2 网格搜索
模型有很多超参数,其能力也存在很大的差异。需要手动产生很多超参数组合,来训练模型,每组超参数都采用交叉验证评估,最后选出最优参数组合建立模型。
网格搜索+交叉验证的强力组合(模型选择和调优)交叉验证解决模型的数据输入问题(数据集划分)得到更可靠的模,网格搜索解决超参数的组合两个组合再一起形成一个模型参数调优的解决方案
from sklearn.model_selection import GridSearchCV
model = KNeighborsClassifier()
model = GridSearchCV(estimator=model,cv=3,param_grid={'n_neighbors':[2,3,4,5,6,7]})
model.fit(x_train,y_train)
八. 训练
这是Scikit-learn中用于训练模型的一个常见命令。使用x_train
作为特征数据(输入数据),y_train
作为目标数据(标签或输出数据)来训练model
。
model.fit(x_train,y_train)
九. 评估
使用Scikit-learn中的accuracy_score
函数计算模型在测试集上的准确率。y_test
是测试集的真实标签,y_pre
是模型对测试集的预测标签。准确率是指模型正确预测的样本数占总样本数的比例
# from sklearn.metrics import accuracy_score
y_pre = model.predict(x_test)
score = accuracy_score(y_test,y_pre) # 对预测结果进行评估
print(f'score-->{score}')
score2 = model.score(x_test,y_test)
print(f'score2-->{score2}')
十.预测
最后进行数据的预测,人造了两条数据进行模拟,将模型设置为预测模式
predata = model.predict(mydata)
mydata = [[5.1, 3.5, 1.4, 0.2], # 模拟数据
[4.6, 3.1, 1.5, 0.2]]
mydata = transfomer.fit_transform(mydata) # 标准化
predata = model.predict(mydata) # 加载模型进行预测
print(f'predata-->{predata}')
结果:
输出了两个数据的置信度和预测的标签
项目整体代码:
# 鸢尾花分类
# -*- coding: UTF-8 -*-
"""
--------------------------------------------
File Name: 01KNN
Author: wenying
Date 2024/4/23 17:41
--------------------------------------------
Desc TODO knn实现鸢尾花案例分类
todo 1.加载数据集
todo 2.数据展示
todo 3.数据基本处理
todo 4.特征处理
todo 5.实例化
todo 6.训练
todo 7.评估
todo 8.预测
--------------------------------------------
"""
from sklearn.datasets import load_iris # 鸢尾花数据集
from sklearn.model_selection import train_test_split # 分割测试集和训练集
import seaborn as sns # 画图
import matplotlib.pyplot as plt # 画图
import pandas as pd # 数据处理
from sklearn.preprocessing import StandardScaler # 标准化处理数据
from sklearn.neighbors import KNeighborsClassifier # KNN算法
from sklearn.metrics import accuracy_score # 模型评估
# todo 1.加载数据
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
iris = load_iris() # 加载数据集
# print(iris)
# print(iris.keys())
# print(iris.feature_names) # 目标值信息
# print('iris####',iris.data[:10]) # 只打印数据
# print()
# todo 2.数据展示
isit_d = pd.DataFrame(iris.data,columns=iris.feature_names) # 将数据清晰展示
# print('isit_d-->',isit_d)
isit_d['target'] = iris.target # 在isit_d下加上iris.target标签数据
# print('isit_d-->',isit_d)
def show_iris_data():
name = iris.feature_names
# sns.lmplot(x='sepal length (cm)',y='sepal width (cm)',hue='target',data=isit_d)
plt.show()
for i in range(len(name)):
for j in range(i+1,len(name)):
col1=name[i]
col2=name[j]
sns.lmplot(x=col1, y=col2, hue='target', data=isit_d, fit_reg=False)
plt.xlabel(col1)
plt.ylabel(col2)
plt.title(f'{col1} and {col2}')
plt.show()
# col1 = 'sepal length (cm)'
# col2 = 'petal width (cm)'
# show_iris_data()
# # todo 3.数据基本处理
# 数据集划分
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target,test_size=0.3,random_state=32)
# print(x_train)
# print(f'数据总数量-->{len(iris.data)}') # 150
# print(f'训练集数量-->{len(x_train)}') # 105
# print(f'测试集数量-->{len(x_test)}') # 45
# # todo 4.特征处理
# 数据标准化
# from sklearn.preprocessing import StandardScaler
transfomer = StandardScaler() # 初始化归一化对象StandardScaler 标准库
x_train = transfomer.fit_transform(x_train) # 对于原始特征进行变换
x_test = transfomer.fit_transform(x_test)
# print(f'标准化后的x_train-->{x_train}')
# todo 5.实例化
# from sklearn.neighbors import KNeighborsClassifier # 导包
model = KNeighborsClassifier(n_neighbors=5) # 设置K为5
# todo 5.实例化
model = KNeighborsClassifier(n_neighbors=5)
# todo 6.训练
model.fit(x_train,y_train)
# todo 7.评估
# from sklearn.metrics import accuracy_score
# y_pre = model.predict(x_test)
# score = accuracy_score(y_test,y_pre) # 对预测结果进行评估
# print(f'score-->{score}')
# score2 = model.score(x_test,y_test)
# print(f'score2-->{score2}')
# todo 8.预测
mydata = [[5.1, 3.5, 1.4, 0.2], # 模拟数据
[4.6, 3.1, 1.5, 0.2]]
mydata = transfomer.fit_transform(mydata) # 标准化
predata = model.predict(mydata) # 加载模型进行预测
print(f'predata-->{predata}')
十.总结与展望
1. 总结
K最近邻(KNN)算法是机器学习领域中一个基础且经典的分类算法。它基于实例的学习,即通过测量不同数据点之间的距离进行分类。具体来说,当有一个新的数据点需要被分类时,算法会查找训练数据集中与其最相近的K个数据点,并依据这K个数据点所属的类别来对新数据点进行投票分类。
鸢尾花数据集(Iris dataset)是机器学习领域常用的一个数据集,它包含了三类鸢尾花的四个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)的测量值。这个数据集的特点在于其数据分布清晰,类别之间有一定的区分度,因此非常适合用于初学者了解和学习分类算法。
通过使用KNN算法对鸢尾花数据集进行分类,我们可以直观地感受到KNN算法的工作原理和分类效果。在实际操作中,我们需要选择合适的K值、距离度量方式等参数,这些参数的选择会对分类结果产生较大影响。通过调整参数,我们可以不断优化模型的分类性能。
2. 展望
虽然KNN算法在鸢尾花数据集上取得了不错的分类效果,但我们也应该意识到它存在一些局限性。例如,KNN算法在分类时需要计算所有训练数据点与新数据点之间的距离,因此当数据集非常大时,计算成本会非常高。此外,KNN算法对数据的分布和噪声也比较敏感,如果数据分布不均匀或存在较多噪声,分类效果可能会受到影响。