机器学习实战:Python基于K近邻KNN进行分类预测(四)

news2025/6/19 1:13:36

文章目录

    • 1 前言
      • 1.1 K近邻的介绍
      • 1.2 K近邻的应用
    • 2 二维数据集演示
      • 2.1 导入函数
      • 2.2 导入数据
      • 2.3 训练模型及可视化
    • 3 莺尾花数据集全数据演示
      • 3.1 导入函数
      • 3.2 导入数据
      • 3.3 训练模型及预测
    • 4 模拟数据集演示
      • 4.1 导入函数
      • 4.2 模拟数据集
      • 4.3 建模比较
    • 5 马绞痛数据+pipeline演示
      • 5.1 下载数据集
      • 5.2 导入函数
      • 5.3 填充空值
      • 5.4 建模计算
    • 6 讨论

1 前言

1.1 K近邻的介绍

K近邻(K-Nearest Neighbor, KNN)是一种基本的分类与回归算法。其基本思想是将新的数据样本与已知类别的数据样本进行比较,根据K个最相似的已知样本的类别进行预测。

具体来说,KNN算法通过计算待分类样本与已知样本之间的距离(欧式距离曼哈顿距离等),选取距离待分类样本最近的K个已知样本,再通过对这K个已知样本的类别进行投票、取平均等方式确定待分类样本的类别。KNN算法中,K的取值是一个重要的超参数,不同的取值可能会影响算法的性能。

优点:

  • 简单易懂:KNN算法的原理简单,易于理解和实现。
  • 无需训练:KNN算法是一种基于实例的学习方法,它不需要显式地训练模型,而是直接使用训练集中的实例进行预测。
  • 适用于多分类问题:KNN算法可以应用于多分类问题,不需要额外的处理。
  • 对异常值不敏感:KNN算法不受异常值的影响,因为它是基于相邻的投票决定结果,不会受到单个数据点的影响。
  • 模型可解释性高:KNN算法的结果可以被解释为离查询点最近的邻居的平均值或众数。

缺点:

  • 需要大量内存:KNN算法需要存储所有的训练样本,因此随着样本数量的增加,内存开销也会相应增加。
  • 计算量大:对于每个测试样本,KNN算法需要计算它与所有训练样本之间的距离,因此随着样本数量的增加,计算量也会相应增加。
  • 效果受参数K的影响:KNN算法中的K值是一个重要参数,需要根据实际问题进行选择,K值过大或过小都会影响预测结果。
  • 受特征空间的影响:KNN算法的效果受特征空间的影响,如果特征空间维度过高,会影响算法的准确性。
  • 对于不平衡数据集的处理效果较差:如果训练集中的某个类别的数据样本比其他类别的数据样本数量少,那么KNN算法会偏向于选择数量较多的类别进行预测,从而影响预测结果的准确性。

1.2 K近邻的应用

应用相对广泛:

  1. 图像识别:KNN算法可以用于图像识别领域,例如面部识别、手写数字识别等。

  2. 推荐系统:KNN算法可以用于基于用户行为和喜好的推荐系统,例如在线商店和社交媒体平台。

  3. 金融领域:KNN算法可以用于信用评分和风险管理,例如预测客户违约概率和市场波动。

  4. 医疗诊断:KNN算法可以用于医疗诊断,例如预测病人患某种疾病的可能性。

  5. 文本分类:KNN算法可以用于文本分类领域,例如垃圾邮件过滤、情感分析等。

  6. 时间序列预测:KNN算法可以用于时间序列预测,例如股票价格预测和气象预测。

  7. 其他领域:KNN算法还可以用于语音识别、游戏AI、生物信息学、物流和交通等领域。

提一下,单是生信领域使用的场景其实还是挺多的

  1. 基因分类:KNN可以用于对基因进行分类,例如在癌症研究中,可以使用KNN分类器来识别患有癌症的患者和健康人之间的基因表达模式的差异。

  2. 蛋白质结构预测:KNN可以用于预测蛋白质的三维结构,例如使用KNN回归来预测残基-残基相互作用的能量。

  3. 突变预测:KNN可以用于预测基因突变的影响,例如在基因组学中,可以使用KNN分类器来预测某种突变对蛋白质功能的影响。

  4. 数据集分类:KNN也可以用于分类未知数据集中的样本,例如在微生物组学中,可以使用KNN分类器来对未知的微生物样本进行分类。

  5. 基因表达数据分析:KNN可以用于分析基因表达数据,例如在单细胞RNA测序中,可以使用KNN来对细胞进行分类和聚类。

2 二维数据集演示

2.1 导入函数

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets
# 作图
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
import seaborn as sns

2.2 导入数据

# 莺尾花数据集的前两维数据
iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target

2.3 训练模型及可视化

k_list = [1, 3, 5, 8, 10, 15]
h = .02
# 创建不同颜色的画布
cmap_light = ListedColormap(['#a6cee3', '#1f78b4', '#b2df8a'])
cmap_bold = ListedColormap(['#e41a1c', '#377eb8', '#4daf4a'])

plt.figure(figsize=(15,14))
# 根据不同的k值进行可视化
for ind,k in enumerate(k_list):
    clf = KNeighborsClassifier(k)
    clf.fit(X, y)
    # 画出决策边界
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    # 根据边界填充颜色
    Z = Z.reshape(xx.shape)

    plt.subplot(321+ind)  
    plt.pcolormesh(xx, yy, Z, cmap=cmap_light)
    # 数据点可视化到画布
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold,
                edgecolor='k', s=20)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.title("3-Class classification (k = %i)"% k)

plt.show()

k=1的时候,在分界点位置的数据很容易受到局部的影响,图中会有蓝绿相间,主要是数据太局部敏感。当k=15的时候,不同的数据基本根据颜色分开,当时进行预测的时候,会直接落到对应的区域,模型相对为“粗糙”。

3 莺尾花数据集全数据演示

3.1 导入函数

### iris数据集
import numpy as np
# 加载莺尾花数据集
from sklearn import datasets
# 导入KNN分类器
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split

3.2 导入数据

iris = datasets.load_iris()

X = iris.data
y = iris.target
# 7/3分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

3.3 训练模型及预测

# 训练模型
clf = KNeighborsClassifier(n_neighbors=5, p=2, metric="minkowski")
clf.fit(X_train, y_train)

# 预测
X_pred = clf.predict(X_test)
acc = sum(X_pred == y_test) / X_pred.shape[0]
print("预测的准确率ACC: %.3f" % acc)

很可,能达到0.978。训练和预测的过程大家可以自行去算,用knn.predict(x)算出每个样本的欧式距离,给每个样本编一个独立的id、排序、打分

4 模拟数据集演示

4.1 导入函数

import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor

4.2 模拟数据集

np.random.seed(0)
# 随机生成40个(0, 1)之前的数,乘以5,再进行升序
X = np.sort(5 * np.random.rand(40, 1), axis=0)
# 创建[0, 5]之间的500个数的等差数列, 作为测试数据
T = np.linspace(0, 5, 500)[:, np.newaxis]
# 使用sin函数得到y值,并拉伸到一维
y = np.sin(X).ravel()
# Add noise to targets[y值增加噪声]
y[::5] += 1 * (0.5 - np.random.rand(8))

4.3 建模比较

# 设置多个k近邻进行比较
n_neighbors = [1, 3, 5, 8, 10, 40]

# 设置图片大小
plt.figure(figsize=(20,14))

# 输出设为两列三行
rows = 3
cols = 2

for i, k in enumerate(n_neighbors):
    # 默认使用加权平均进行计算predictor
    clf = KNeighborsRegressor(n_neighbors=k, p=2, metric="minkowski")
    # 训练
    clf.fit(X, y)
    # 预测
    y_ = clf.predict(T)
    
    plt.subplot(rows, cols, i + 1)
    plt.scatter(X, y, color='red', label='data')
    plt.plot(T, y_, color='navy', label='prediction')
    plt.axis('tight')
    plt.legend()
    plt.title("KNeighborsRegressor (k = %i)" % (k))

plt.tight_layout()
plt.show()

很明显,当k=1时,预测的结果只和最近的一个训练样本相关,从预测曲线中可以看出当k很小时候很容易发生过拟合。当k=40时,预测的结果和最近的40个样本相关,因为我们只有40个样本,此时是所有样本的平均值,此时所有预测值都是均值,很容易发生欠拟合。

因此根据结果,3,5,8,10都是可以考虑的。

5 马绞痛数据+pipeline演示

5.1 下载数据集

这里包括了数据集和表头信息,确保自己已经安装了wget

# 下载需要用到的数据集
!wget https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/3K/horse-colic.csv
# 下载数据集介绍
!wget https://tianchi-media.oss-cn-beijing.aliyuncs.com/DSW/3K/horse-colic.names

5.2 导入函数

## 导入函数
import numpy as np
import pandas as pd
# kNN分类器
from sklearn.neighbors import KNeighborsClassifier
# kNN数据空值填充
from sklearn.impute import KNNImputer
# 计算带有空值的欧式距离
from sklearn.metrics.pairwise import nan_euclidean_distances
# 交叉验证
from sklearn.model_selection import cross_val_score
# KFlod的函数
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.pipeline import Pipeline
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

5.3 填充空值

这个数据集里面有很多,因此还是用欧式距离计算后填充

## 空值填充
X = [[1, 2, np.nan], [3, 4, 3], [np.nan, 6, 5], [8, 8, 7]]
imputer = KNNImputer(n_neighbors=2, metric='nan_euclidean')
imputer.fit_transform(X)

## 带空值的欧式距离计算公式
nan_euclidean_distances([[np.nan, 6, 5], [3, 4, 3]], [[3, 4, 3], [1, 2, np.nan], [8, 8, 7]])

# load dataset, 将?变成空值
input_file = './horse-colic.csv'
df_data = pd.read_csv(input_file, header=None, na_values='?')

# 得到训练数据和label, 第23列表示是否发生病变, 1: 表示Yes; 2: 表示No. 
data = df_data.values
ix = [i for i in range(data.shape[1]) if i != 23]
X, y = data[:, ix], data[:, 23]

# 查看所有特征的缺失值个数和缺失率
for i in range(df_data.shape[1]):
    n_miss = df_data[[i]].isnull().sum()
    perc = n_miss / df_data.shape[0] * 100
    if n_miss.values[0] > 0:
        print('>Feat: %d, Missing: %d, Missing ratio: (%.2f%%)' % (i, n_miss, perc))

# 查看总的空值个数
print('KNNImputer before Missing: %d' % sum(np.isnan(X).flatten()))
# 定义 knnimputer
imputer = KNNImputer()
# 填充数据集中的空值
imputer.fit(X)
# 转换数据集
Xtrans = imputer.transform(X)
# 打印转化后的数据集的空值
print('KNNImputer after Missing: %d' % sum(np.isnan(Xtrans).flatten()))

5.4 建模计算

## 构建pipeline
results = list()
strategies = [str(i) for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 16, 18, 20, 21]]
for s in strategies:
    # create the modeling pipeline
    pipe = Pipeline(steps=[('imputer', KNNImputer(n_neighbors=int(s))), ('model', KNeighborsClassifier())])
    # 数据多次随机划分取平均得分
    scores = []
    for k in range(20):
        # 得到训练集合和验证集合, 8: 2
        X_train, X_test, y_train, y_test = train_test_split(Xtrans, y, test_size=0.2)
        pipe.fit(X_train, y_train)
        # 验证model
        score = pipe.score(X_test, y_test)
        scores.append(score)
    # 保存results
    results.append(np.array(scores))
    print('>k: %s, Acc Mean: %.3f, Std: %.3f' % (s, np.mean(scores), np.std(scores)))
# print(results)
# plot model performance for comparison
plt.boxplot(results, labels=strategies, showmeans=True)
plt.show()

可以观察到结果是随着k值增大先上升后下降再上升的一个波浪趋势,在模拟数据集的结果提到,k取太小太大会过拟合和欠拟合,**因此在第一次下降谷底时可简单认为不再发生过拟合,因而取此前的结果。**这里的话3、4、5都可以考虑,可以结合accstd来选。

6 讨论

KNN是一种惰性学习算法,可用于回归或分类。主要就是关注两个点:k值的选择距离的计算

一般情况下这个k和数据有很大关系,都是交叉验证进行选择,但是建议使用交叉验证的时候,k∈[2,20],使用交叉验证得到一个很好的k值。

样本之间的距离的计算,我们一般使用对于一般使用Lp距离进行计算。当p=1时候,称为曼哈顿距离(Manhattan distance),当p=2时候,称为欧氏距离(Euclidean distance),当p=∞时候,称为极大距离(infty distance), 表示各个坐标的距离最大值,另外也包含夹角余弦等方法。一般采用欧式距离较多,但是文本分类则倾向于使用余弦来计算相似度。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

App 自动化测试

一、移动端测试基础 1 移动端自动化环境搭建 1.1 java安装 1.2 Android SDK安装 SDK (Software Development Kit) 软件开发工具包是软件开发工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。Android SDK 就是 Android 专属的软件开…

ERTEC200P-2 PROFINET设备完全开发手册(5-1)

5.1 非周期通讯 非周期通讯,顾名思义,表示这种通讯并不是在每个通讯周期都要进行的通讯,也叫做异步通讯或者非实时通讯。非周期通讯访问的数据叫做数据记录(record data)。一般情况下,以下三个名词表示的是…

ubuntu下常用命令(嵌入式)

开发环境: ubuntu-14.04.1-desktop-i386 VMware-workstation-full-10.0.2-1744117.1398244508.exe lsb_release -a 查看ubuntu版本 ctrlalta 打开控制台 du -sh 文件/文件夹 查看文件或文件夹的大小 su 或 su root 都是切换到root账户 su 普通用户 切换到普…

CSS2023年面试题汇总~~~~持续更新中!!!!

文章目录1.元素水平垂直居中的方法有哪些?2.flex布局3.position定位4.display:none与visibility:hidden的区别1.元素水平垂直居中的方法有哪些? 利用定位margin:auto利用定位margin:负值利用定位transformtable布局flex布局grid布局 其中2,…

风电的Weibull分布及光电的Beta分布组合研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

二、线程的Thread 类及常见方法【2/12】【多线程】

线程的Thread 类及常见方法2. Thread 类及常见方法2.1 Thread 的常见构造方法2.2 Thread 的几个常见属性2.3 启动一个线程-start()★★★start和run的区别★★★run不会创建线程 是在原来的基础上 执行代码start 创建线程,在新的线程 执行代码2.4 中断一个线程★★★…

常见面试题之Redis篇

1.1.Redis与Memcache的区别? redis支持更丰富的数据类型(支持更复杂的应用场景):Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache支持…

Open Inventor 2023.1 Crack

发行说明 Open Inventor 2023.1(次要版本) 文档于 2023 年 4 月发布。 此版本中包含的增强功能和新功能: Open Inventor 10 版本编号更改体积可视化 单一分辨率的体绘制着色器中与裁剪和 ROI 相关的新功能MeshVizXLM 在 C 中扩展的剪辑线提…

拟牛顿法:python代码实现

文章目录拟牛顿法待优化实例scipy工具包实现BFGS自编Python实现BFGS拟牛顿法 在梯度类算法原理:最速下降法、牛顿法和拟牛顿法中,介绍了梯度类算法求解优化问题的设计思路,并以最速下降法、牛顿法和拟牛顿法为例,描述了具体的算法…

3.9、互斥锁(互斥量)

3.9、互斥锁(互斥量)1.互斥锁(互斥量)的介绍2. 互斥量相关操作函数3.互斥量函数的使用介绍①pthread_mutex_init②pthread_mutex_destroy③pthread_mutex_lock④pthread_mutex_trylock⑤pthread_mutex_unlock3.利用互斥锁实现线程…

计讯物联双网口工业路由器TR321助力货轮冷链监测解决方案高质量落地

政策背景 国务院办公厅印发我国冷链物联流域第一份五年规划——《“十四五”冷链物流发展规划》(以下简称“规划”)。《规划》聚焦冷链物流体系、冷链运输、冷链物流服务、冷链物流创新及冷链物流监管体系等方面,对冷链物流的全流程、全环节…

Ficow 的 AI 平台快速上手指南(ChatGPT, NewBing, ChatGLM-6B, cursor.so)

本文首发于 Ficow Shen’s Blog,原文地址: Ficow 的 AI 平台快速上手指南(ChatGPT, NewBing, ChatGLM-6B, cursor.so)。 内容概览 前言OpenAI —— ChatGPT微软 —— NewBing智谱AI —— ChatGLM-6BAI生成代码 —— cursor.so总结 前言 现在各种AI工具大…

虚拟机网络配置

点击【编辑虚拟机设置】,点击【网络适配器】,选择【桥接模式】 选择好之后退回主页,点击【编辑】,选择【虚拟网络编辑器】 添加一个【VMnet8】的网络名称 点击【开启虚拟机】 输入账户密码,输入【cd /etc/sysconfig/ne…

springcloud——gateway功能拓展

目录 1.获取用户真实IP 2.统一跨域配置 3.redis令牌桶算法限流 1.获取用户真实IP 在我们的日常业务中,我们时常需要获取用户的IP地址,作登录日志、访问限制等相关操作。 而在我们的开发架构中,一般我们将服务分为多个微服务,…

熟练了Flex布局之后,该学学Grid布局了

介绍 CSS Gird布局也叫二维网格布局系统,可用于布局页面主要的区域布局或小型组件。网格是一组相交的水平线和垂直线,它定义了网格的列和行。我们可以指定将网格元素放置在与这些行和列相关的位置上。 一维布局 和 二维布局 像流布局和Flex布局&#…

Windows10系统安装perl命令

文章目录1,下载ActivePerl 5.28(基于Windows 10系统):1.1,Perl 主页: https://www.perl.org/get.html1.2,选择windows1.3,选择Binaries---activeperla版本1.3,直接选择windows 5.36版…

【观察】神州数码高质量发展背后,是技术创新“叠加效应”的释放

毫无疑问,在百年变局和世纪疫情的双重影响下,整个2022年科技行业的增速都在放缓,更对身处其中的科技企业的业务连续性和成长性提出了更高的考验。尽管如此,神州数码(000034.SZ)仍然交出了一份令市场亮眼的成…

【iOS逆向与安全】使用ollvm混淆你的源码

前言 当你在研究别人源码的时候,是不是期望着别人代码没有进行任何的防护和混淆。这时的你,是不是应该考虑一下自己代码的安全.本篇文章将告诉你,如何使用ollvm来混淆iOS端的代码【此文为入门贴,大佬请绕道】。 一、目标 编译o…

【MybatisPlus快速入门】—— 拓展入门

逻辑删除 前面我们完成了基本的增删改查操作,但是对于删除操作来说,我们思考一个问题,在实际开发中我们真的会将数据完成从数据库中删除掉么?很多情况下我们是需要保留要删除的数据用来总结统计的,所以我们是不能将数…

从零学习SDK(5)SDK文档的学习和参考

要想充分利用SDK的优势,仅仅下载和安装SDK是不够的,还需要学习和参考SDK提供的文档和资源。文档和资源是SDK的重要组成部分,它们可以帮助开发者掌握SDK的基本概念、结构、用法、限制和最佳实践,以及解决常见的问题和错误。 查找…