【机器学习】KNN算法实战项目二:水果分类_基于knn算法的水果分类-程序员宅基地

技术标签: 算法  数据分析师  机器学习  KNN  最近邻  分类  


手动反爬虫: 原博地址 https://blog.csdn.net/lys_828/article/details/122615360

 知识梳理不易,请尊重劳动成果,文章仅发布在CSDN网站上,在其他网站看到该博文均属于未经作者授权的恶意爬取信息

2 KNN实现水果分类

第一个实战项目中的分类效果很明显, 使用KNN算法的分类结果也不错,第二个例子中的数据分类效果就比较麻烦。

2.1 模块导入与数据加载

导入常用的五个模块

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

加载数据

fruits = pd.read_table('shuiguo.txt')
fruits.head()
fruits = pd.read_csv('shuiguo.txt',sep='\t')
fruits.head()

输出结果如下。对于不是逗号分隔的数据文件,可以尝试使用read_table方法进行数据读取,程序会自动进行解析,也可以通过指定sep参数进行具体分隔的指定。
请添加图片描述

2.2 数据EDA

首先查看各字段的基本详情,以及数值字段的分布情况,通过info和describe方法进行,代码及输出结果如下。
请添加图片描述
如果有缺失值,也可以进一步通过isnull().sum()/isna().sum()方式进行查看各字段缺失值的情况,代码及输出结果如下。
请添加图片描述
然后可以初步预览前五行数据,看看数据的基本样式,代码及输出结果如下。
请添加图片描述
针对分类数据,可以借助unique方法查看具体的分类个数,代码如下。

fruits.fruit_name.unique()
fruits.fruit_label.unique()
fruits.fruit_subtype.unique()

输出结果如下。
请添加图片描述

其中fruit_name字段和fruit_label字段是对应的,都是属于标签字段,一个是文字标签,一个是数字标签,如果有需要也可以将这两字段的类别进行一一对应,代码如下。

dict1=dict(zip(fruits.fruit_name.unique(),fruits.fruit_label.unique()))
for i in dict1.items():
    print(i)

输出结果如下。
请添加图片描述

简单的单一字段的查询完毕后,可以进一步可视化,比如对于分类字段的数据采用柱状图展示,连续字段的数据采用箱型图/散点展示。

先对分类标签的字段进行统计,通过groupby的方式就可以知道每一类别的数量,代码如下。

fruits.groupby('fruit_label').size()

输出结果如下。
请添加图片描述
(1)此外需要注意size和count的区别,如果groupby之后使用count会对除分组依据的字段外,剩余的字段均会被计数,代码及输出结果如下。
请添加图片描述

进一步以通过分组计数的结果进行绘图,也可以通过封装好的countplot方法进行绘制,较为简洁,代码如下。

plt.figure(figsize=(8,6))
sns.countplot(fruits.fruit_label)

输出结果如下。该方法只需要将分类的字段填入到括号中就可以直接出现字段中分类的柱状统计图。
请添加图片描述

(2)对于连续型字段,需要注意标签中的fruit_label中虽然是数值,但是只有1,2,3,4属于分类数据,所以在进行连续型字段的可视化之前需要留意此类字段,直接进行箱型图绘制代码及输出结果如下。
请添加图片描述
通过指定kind=‘box’会自动对数值字段进行绘制,但是其中的fruit_label字段也被加入进来了,故再绘制之前应该将此字段进行剔除,建议采用重新赋值的方式创建新的数据,代码如下。

df2=fruits.drop('fruit_label', axis=1)
df2.plot(kind='box',subplots=True)

输出结果如下。借助subplots参数可以将各个字段进行子图显示。
请添加图片描述

此外通过layput参数可以调整一下布局,比如四个图形以两行两列排布,代码及输出结果如下。
请添加图片描述
图像较小也可以指定figsize参数调整,代码及输出结果如下。
请添加图片描述
(3)对于多字段就可以通过pairplot绘制散点图,代码及输出结果如下。
请添加图片描述
至此关于简单的数据EDA就完成了,也可以通过关联矩阵绘制热力图查看特征字段与标签字段的关联关系。

2.3 模型创建与应用

构建特征数据和标签数据,其中特征数据选取最后四列的连续字段,而标签字段选择数值标签的字段,然后进行训练数据和测试数据的划分,代码如下。

X = fruits[['mass', 'width', 'height', 'color_score']]
y = fruits['fruit_label']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 0)

输出结果如下。
请添加图片描述
数据准备完毕后,创建模型与应用,代码如下。

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 5)
knn.fit(X_train, y_train)
knn.score(X_test, y_test)

输出结果如下。
请添加图片描述
最终的结果可以发现远低于第一个项目中的评分。还需要注意一个客观的事实:当前的分类为4种,那么盲猜的结果就为25%,目前使用KNN模型进行预测的得分是53.33%。对比于瞎猜的得分,经过模型的分类结果是较好的,但是从实际上来说模型只有一般概率预测正确,这个概率也是相对偏低,根本原因在于数据本身无法直接肉眼进行分割,那么直接使用模型也很难得到一个较好的分割结果。

可以通过绘制分类散点图查看对应的分布情况,其中apple和orange两类别中交叉,很难进行完全的分辨,因此最后的分类效果也就较差。
请添加图片描述
在二维的界面中很难进行数据的区分,那么尝试数据提升至三维,看看数据的分布情况。

from mpl_toolkits.mplot3d import Axes3D
%matplotlib notebook
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(111, projection = '3d')
ax.scatter(X_train['width'], X_train['height'], X_train['color_score'], c = y_train, marker = 'o', s=100)
ax.set_xlabel('width')
ax.set_ylabel('height')
ax.set_zlabel('color_score')
plt.show()

输出结果如下。绘制3D图时,%matplotlib notebook指令就会体现出很强大的功能,可以对图形调整角度。如果采用inline的方式,最终只是一个2D的图片,没有办法直观展示。
请添加图片描述
尝试调整一下图形的方向,看一下结果,其中红框圈出来的两类很容易进行分来,但是剩下两类很难直接分类。
请添加图片描述
由于苹果和橘子数据上非常接近,导致可视化状态下数据不可分,那么就把不可分的数据先标记出来,先创建一个备份数据,代码如下。

new_df = fruits.loc[(fruits['fruit_name']=='apple' ) | 
                    (fruits['fruit_name']=='orange' )]
new_df.head()
new_df.shape

输出结果如下。new_df 其实就是一个原始数据的备份 如果后期对数据进行合并,还需要找回原始数据 可以到这个new_df中来找。请添加图片描述
就可以将2个无法精准分割的类别合并为一类,同时对文字标签和数值标签进行操作,代码如下。

fruits.loc[(fruits['fruit_name']=='apple' ) | 
                    (fruits['fruit_name']=='orange' ),['fruit_label']]=1
len(fruits.loc[(fruits['fruit_name']=='apple' ) | 
                    (fruits['fruit_name']=='orange' )])
fruits.loc[(fruits['fruit_name']=='apple' ) | 
           (fruits['fruit_name']=='orange' ),['fruit_name']] = ['Class2']
fruits.shape
print(fruits.groupby('fruit_name').size())

输出结果如下。
请添加图片描述

处理完毕后再次绘制分类散点图,代码及输出结果如下。
请添加图片描述
从图中可以看出只有三类数据,接着再次进行KNN模型的创建,看看此次的模型得分如何。

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 5)
knn.fit(X_train, y_train)
knn.score(X_test, y_test)

输出结果如下。最后输出的模型得分比原来未处理的模型得分要高一些,不妨此时把K值再调整一下。
请添加图片描述
比如随机调整到4或者3,再次跑一下模型,看看结果输出。

knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(X_train, y_train)
knn.score(X_test, y_test)

knn = KNeighborsClassifier(n_neighbors = 4)
knn.fit(X_train, y_train)
knn.score(X_test, y_test)

输出结果如下。当K=3时模型得分和K=5时是一致的,但是当K=4时模型得分明显提升。
请添加图片描述
为了避免盲猜的K值,可以通过遍历循环获得模型得分与K值的散点图,用于判断最佳的K值,代码如下。

k_range = range(1, 20)
scores = []
for k in k_range:
    knn = KNeighborsClassifier(n_neighbors = k)
    knn.fit(X_train, y_train)
    scores.append(knn.score(X_test, y_test))
print(scores)

plt.figure(figsize = (8,6))
plt.xlabel('k')
plt.ylabel('accuracy')
plt.scatter(k_range, scores)
plt.xticks([0,5,10,15,20])

输出结果如下。scores中保存了K取1-19时的模型得分,最后的图中可以发现K=1和K=4模型的得分最高。
请添加图片描述

2.4 绘制决策边界

和项目一一样,可以直接调用封装的函数,指定K的值,然后进行结果的绘制。

from adspy_shared_utilities2 import plot_fruit_knn
plot_fruit_knn(X_train, y_train,4, 'uniform')

输出结果如下。
请添加图片描述
绘制决策边界的过程基本上都是一致的,不一样的就是对于数据的选取和最后颜色及标签信息的指定,封装的全部代码如下。

def plot_fruit_knn(X, y, n_neighbors, weights):
    X_mat = X[['height', 'width']].values
    y_mat = y.values

    cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF','#AFAFAF'])
    cmap_bold  = ListedColormap(['#FF0000', '#00FF00', '#0000FF','#AFAFAF'])

    clf = neighbors.KNeighborsClassifier(n_neighbors, weights=weights)
    clf.fit(X_mat, y_mat)
    
    mesh_step_size = 0.01  
    plot_symbol_size = 50
    
    x_min, x_max = X_mat[:, 0].min() - 1, X_mat[:, 0].max() + 1
    y_min, y_max = X_mat[:, 1].min() - 1, X_mat[:, 1].max() + 1
    xx, yy = numpy.meshgrid(numpy.arange(x_min, x_max, mesh_step_size),
                         numpy.arange(y_min, y_max, mesh_step_size))
    Z = clf.predict(numpy.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    plt.figure()
    plt.pcolormesh(xx, yy, Z, cmap=cmap_light)
    plt.scatter(X_mat[:, 0], X_mat[:, 1], s=plot_symbol_size, c=y, cmap=cmap_bold, edgecolor = 'black')
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    patch0 = mpatches.Patch(color='#FF0000', label='Class2')
    patch1 = mpatches.Patch(color='#00FF00', label='mandarin')
    patch3 = mpatches.Patch(color='#AFAFAF', label='lemon')
    plt.legend(handles=[patch0, patch1,  patch3])
    plt.xlabel('height (cm)')
    plt.ylabel('width (cm)')
    plt.show()

分割数据默认是 75%和25%,如果我们把原始数据切分成不同的比例 是否对结果有影响。

t = [0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2]
knn = KNeighborsClassifier(n_neighbors = 4)
for s in t:
    scores = []
    for i in range(1, 100):
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 1-s)
        knn.fit(X_train, y_train)
        scores.append(knn.score(X_test, y_test))
    plt.plot(s, np.mean(scores), 'bo')
plt.xlabel('Training set proportion (%)')
plt.ylabel('accuracy')

输出结果如下。图形中可以发现并不是训练集的数量越多模型准确度越高,反而是在6:4和7:3附近模型得分较高,8:2时模型的得分反而下降了。
请添加图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lys_828/article/details/122615360

智能推荐

koa如何进行token设置和进行token过期验证_koa token-程序员宅基地

文章浏览阅读1.4k次。koa如何进行token设置和进行token过期验证_koa token

DPDK中文编程指南_dpdk编程指南-程序员宅基地

文章浏览阅读2.2k次,点赞4次,收藏15次。编程指南1. 简介 1.1. 文档地图 1.2. 相关刊物 2. 概述 2.1. 开发环境 2.2. 环境适配层EAL 2.3. 核心组件 2.3.1. 环形缓冲区管理(librte_ring) 2.3.2. 内存池管理(librte_mempool) 2.3.3. 网络报文缓冲区管理(librte_mbuf) 2.3.4. 定时器管理(librte_timer) 2.4. 以太网轮询驱动架构 2.5. 报文转发算法支持 2.6. 网络协议_dpdk编程指南

CSI300 ARIMA模型走势分析源程序_可能遇到了收斂问题:optim信息code=1-程序员宅基地

文章浏览阅读2.3k次。R语言CSI数据的ARIMA模型建立过程。有ARIMA模型调整的方法。_可能遇到了收斂问题:optim信息code=1

linux sudo 命令详解_sudo hraddr=-程序员宅基地

文章浏览阅读2.1k次。“Sudo”是Unix/Linux平台上的一个非常有用的工具,它允许系统管理员分配给普通用户一些合理的“权利”,让他们执行一些只有超级用户或其他 特许用户才能完成的任务,比如:运行一些像mount,halt,su之类的命令,或者编辑一些系统配置文件,像/etc/mtab,/etc /samba/smb.conf等。这样以来,就不仅减少了root用户的登陆次数和管理时间,也提高了系统安全性。_sudo hraddr=

win7安装python3.7_解决win7操作系统Python3.7.1安装后启动提示缺少.dll文件问题-程序员宅基地

文章浏览阅读95次。错误提示图片首先,我的操作系统是win7旗舰版,安装Python3.7.1之后启动时,提示如图错误,网上比较多的是两种处理方法:(1)安装Windows补丁程序(2)安装VC redit.exe第一种方案我这边下载了KB3118401、KB2999226,但是双击安装的时候安装不了;第二种方案大家都推荐的是安装v++2015,也安装成功了,但是安装后仍然报错。然后看着网上的推荐时间都比较早,我这边..._win7 python 3.86提示缺少.dll

Oracle学习(1)-程序员宅基地

文章浏览阅读122次。1、 数据库的简介英文DabaBase,是一种软件产品,用于存储数据,管理数据的存储仓库(容器)。把数据库理解为U盘。U盘或者硬盘是实物,数据库是软件产品。Java语言的应用领域(1) 桌面级程序应用开发Client客户端-架构 Client/Server服务器-架构的程序(2)互联网程序应用开发Browser浏览器/Server服务器-架构的程序淘宝网页 www.tao...

随便推点

贝壳钱包sig分析_pws/8.3.1.0.8-程序员宅基地

文章浏览阅读1.3k次。15951088268 147852lj18031529044----18031529044.. 随便输了条帐号,分析登陆sig===========================================POST https://api.account.meitu.com/oauth/access_token.json HTTP/1.1Unlogin-Tok..._pws/8.3.1.0.8

YOLOV5 训练自己的数据集_torchvision0.9.2-程序员宅基地

文章浏览阅读688次。1.环境Ubuntu 20.04显卡驱动 470.74CUDA 11.5查看Ubuntu版本号cat /proc/version查看显卡驱动版本nvidia-smi查看CUDA版本nvcc --version2.代码模型下载下载模型git clone https://github.com/ultralytics/yolov5下载预训练模型建议在模型文件夹下新建一个weights,放置下载的预训练模型权重..._torchvision0.9.2

支持串口上传图片和数据到服务器的4G低功耗摄像头方案_串口摄像头接入平台-程序员宅基地

文章浏览阅读1.6k次。当今网络信息自动化的时代,通过网络进行远程监控和远程数据采集成为一种最经济最可靠的方式。但由于部分场景现场监控并不需要过多的检测,只需定时返回现场环境即可,4G串口摄像头极大的方便这方面的需求。不需过多的流量,及能反馈现场环境。针对目前野外的环境,无电无网情况下,需要使用全网通的4G网络,低功耗也是4G模块的硬伤,寻觅了很久,朋友介绍过合方圆的4G低功耗模块G8100B,该模块的特点是功耗同比其它模块降低了%50的功耗,能很好地控制整个产品的功耗。刚好合方圆原厂也提供有4G低功耗摄像头方案,在厂家的技_串口摄像头接入平台

安卓开发用红米手机进行调试_红米手机配合安卓开发-程序员宅基地

文章浏览阅读1.5k次。要想要红米手机连接电脑并被91助手、360手机助手等成功识别,手机必须打开USB调试模式,但是在安卓4.2版本中,系统的USB调试模式不是非常简单地被打开的。对于红米手机,其预装的就是4.2操作系统,故不能直接打开USB调试模式。_红米手机配合安卓开发

QML BOOK 第十章 Networking_qmlscene 一次只能加载一个文件吗-程序员宅基地

文章浏览阅读1.9k次,点赞2次,收藏6次。11. NetworkingQt5在C++中有丰富的网络相关的类。例如在http协议层上使用请求回答方式的高级封装类如QNetworkRequest,QNetworkReply,QNetworkAccessManageer。也有在TCP/IP或者UDP协议层封装的低级类如QTcpSocket,QTcpServer和QUdpSocket。还有一些额外的类用来管理代理,网络缓冲和系统网络配置。_qmlscene 一次只能加载一个文件吗

java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 6(offset:6).state-程序员宅基地

文章浏览阅读2.3k次。如果你在界面中使用了RecyclerView,并且添加了上拉加载和下拉刷新的功能的话,一定对这个异常不会陌生。因为这个异常就时常发生在刷新清除数据的时候,刚好上拉加载的也调用了notifyDataSetChange();然后就会跑出如下异常:java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item_inconsistency detected. invalid item position 6(offset:6)

推荐文章

热门文章

相关标签