机器学习/数据分析--通俗语言带你入门K-邻近算法(结合案例)

本文主要是介绍机器学习/数据分析--通俗语言带你入门K-邻近算法(结合案例),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

前言

  • 机器学习是深度学习和数据分析的基础,接下来将更新常见的机器学习算法
  • 注意:在打数学建模比赛中,机器学习用的也很多,可以一起学习
  • 欢迎收藏 + 点赞 + 关注

文章目录

  • K-邻近算法模型简介
    • 1、模型简介
    • 2、模型难点与求解
      • KNN难点
      • 解决方法
        • K值选取问题
        • 选取K值后,如何遍历速度最快
        • 距离选取
          • 欧式距离
          • 曼哈顿距离
          • 切比雪夫距离
  • 案例求解
    • 1、导入数据
    • 2、统计分析
    • 3、数据预处理
    • 4、划分数据集
    • 5、模型的创建与训练
    • 6、预测结果
    • 7、模型评估

K-邻近算法模型简介

1、模型简介

解决了什么问题?

  • K-邻近,简称KNN,KNN解决了的分类与回归问题,主要运用解决分类问题

例子说明

在这里插入图片描述

首先上图,上图有三类不同形状,O是要预测他属于那一类,KNN算法的思想就是,选取与他最近的K的点,那个类别占比大,他就属于那个类别。上图中:

  • K值为3时候,三角形最多,故它属于三角形类
  • K值为5的时候,正方形最多,故它属于正方形那一类

2、模型难点与求解

KNN难点

  1. K值的选取问题
  2. 选取K值后,如何遍历速度最快?
  3. 距离如何计算问题

解决方法

K值选取问题

在李航老师的《统计学习方法》上所说:

  1. 选择较小的K值,就相当于用较小的领域中的训练实例进⾏预测, “学习”近似误差会减小,只有与输⼊实例较近或相似的训练实例才会对预 测结果起作⽤,与此同时带来的问题是“学习”的估计误差会增⼤, 换句话说,**K值的减小就意味着整体模型变得复杂,容易发生过拟合; **
  2. 选择较大的K值,就相当于⽤较⼤领域中的训练实例进⾏预测, 其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增⼤。这时候,与输⼊实例较远(不相似的)训练实例也会对预测器作⽤,使预测发⽣错误。 且**K值的增大就意味着整体的模型变得简单。 **
  3. K=N(N为训练样本个数),则完全不足取, 因为此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单,忽略了训练实例中大量有用信息。 在实际应⽤中,K值⼀般取⼀个比较小的数值,例如采⽤交叉验证法(简单来 说,就是把训练数据在分成两组:训练集和验证集)来选择最优的K值。

方法:网格搜索

网格搜索解决的问题是,当有多个参数选择的时候,选取最优解的参数,如下:

model = KNeighborsClassifier()   # algorithm:自动选择算法确定K值
# 网格搜索查找最优 n_neighors
grid_search = {"n_neighbors": [1, 3, 5, 7, 9]}
model = GridSearchCV(model, param_grid=grid_search, cv=5)  # 交叉验证设置为 5
选取K值后,如何遍历速度最快

这个方法在sklearn库中很好解决,在使用KNeighborsClassifier()创建模型的时候,KNeighborsClassifier()参数列表中有一个algorithm的参数,它包含了一下几个参数,默认是auto,有兴趣的同学可以查阅资料学习Kd_tree的原理,推荐在b站中kd树相关的教程。

  1. ‘auto’:
    • 当选择 'auto' 时,scikit-learn 会根据训练数据的大小和维度自动选择最合适的算法。这是默认选项,通常是一个好的起点,因为它可以根据数据的特性来选择最佳算法。
  2. ‘ball_tree’:
    • 使用 Ball Tree 数据结构。适用于高维空间中的最近邻搜索。Ball Tree 是一种树形数据结构,它可以有效地处理高维数据。
  3. ‘kd_tree’:
    • 使用 KD Tree 数据结构。适用于低至中等维度的空间中的最近邻搜索。KD Tree 也是一种树形数据结构,但更适合低维数据。
  4. ‘brute’:
    • 使用蛮力(Brute Force)方法来计算最近邻。这种方法直接计算每个样本之间的距离,没有使用任何加速数据结构。虽然简单,但在大样本集或高维数据中效率较低。
距离选取

通过查阅资料,发现主要的距离选取分为以下几种类型:

欧式距离

欧氏距离(Euclidean Distance)是最容易直观理解的距离度量方法,我们小学、初中和高中接触到的两个点在空间中的距离一般都是指欧氏距离,他的公式如下:

在这里插入图片描述

曼哈顿距离

在曼哈顿街区要从一个十字路口开车到另一个十字路口,驾驶距离显然不是两点间的直线距离。这个实际驾驶距离就是“曼哈顿距离(Manhattan Distance)”。曼哈顿距离也称为“城市街区距离”(City Block distance)。

在这里插入图片描述

切比雪夫距离

国际象棋中,国王可以直行、横行、斜行,所以国王走一步可以移动到相邻8个方格中的任意一个。国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?这个距离就叫切比雪夫距离(Chebyshev Distance)。

在这里插入图片描述

在这里插入图片描述

案例求解

背景: 海伦一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但她没有从中找到喜欢的人。经过一番总结,她发现曾交往过三种类型的人:

  • ①不喜欢的人;
  • ②魅力一般的人;
  • ③极具魅力的人。

她现在总结好的数据中(即训练集)包含三种特征:

  • ①每年获得的飞行常客里程数
  • ②玩视频游戏所耗时间百分比
  • ③每周消费的冰淇淋公升数

她希望根据现有的数据来判断一个陌生男人会被她归到哪一类。

求解步骤

  1. 导入数据
  2. 统计分析
  3. 数据预处理
  4. 划分数据集
  5. 模型的创建与训练
  6. 预测结果
  7. 模型评估

1、导入数据

import pandas as pd data = pd.read_table('./datingTestSet2.txt', sep='\t', header=None)    
data.head()
0123
0409208.3269760.9539523
1144887.1534691.6739042
2260521.4418710.8051241
37513613.1473940.4289641
4383441.6697880.1342961

分析:pd.read_table(‘./datingTestSet2.txt’, sep=‘\t’, header=None)

  • 第一个参数:路径
  • sep:表示数据字段中用什么分割
  • header:第一行是否是标题,不是,则用0、1、2……代替

2、统计分析

# 查看维度
data.shape

答案:

(1000, 4)
# 查看数据基本信息
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 4 columns):#   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  0   0       1000 non-null   int64  1   1       1000 non-null   float642   2       1000 non-null   float643   3       1000 non-null   int64  
dtypes: float64(2), int64(2)
memory usage: 31.4 KB
# 查看统计
data.describe()
0123
count1000.0000001000.0000001000.0000001000.000000
mean33635.4210006.5599610.8320731.985000
std21957.0068334.2436180.4972390.818196
min0.0000000.0000000.0011561.000000
25%13796.0000002.9339630.4089951.000000
50%31669.0000006.5952040.8094202.000000
75%47716.25000010.0565011.2728473.000000
max91273.00000020.9193491.6955173.000000
# 查看缺失值
data.isnull().sum()   

答案:

0    0
1    0
2    0
3    0
dtype: int64

经过分析,每一列都没有缺失值

# 每个特征之间的相关性
data.iloc[:, :3].corr()
012
01.0000000.465847-0.009171
10.4658471.0000000.008874
2-0.0091710.0088741.000000

3、数据预处理

KNN,特征值来源于生活统计,特征一与特征二、三差距很大,故为了确保特征值在计算距离的时候准确率高一点,故这里对特征数据进行归一化处理

from sklearn.preprocessing import MinMaxScaler
import seaborn as sns
import matplotlib.pyplot as plt 
import numpy as np# 标准化,对特征
scaler = MinMaxScaler()
data_scaled = scaler.fit_transform(data.iloc[:, :3])   
# 将标准化后的数据转为DataFrame
data_scaled = pd.DataFrame(data_scaled)
# 标准化后数据统计信息
print("标准化后数据统计信息:\n", data_scaled.describe())
# 可视化前后数据分布
plt.figure(figsize=(16, 6))
# 标准化前的分布
plt.subplot(1, 2, 1)
sns.histplot(data.iloc[:, 0], kde=True, color='blue')
plt.title('Distribution of Median Income before Standardization')
# 标准化后的分布
plt.subplot(1, 2, 2)
sns.histplot(data_scaled.iloc[:, 0], kde=True, color='red')
plt.title('Distribution of Median Income after Standardization')
plt.show()
标准化后数据统计信息:0            1            2
count  1000.000000  1000.000000  1000.000000
mean      0.368514     0.313583     0.490401
std       0.240564     0.202856     0.293467
min       0.000000     0.000000     0.000000
25%       0.151151     0.140251     0.240703
50%       0.346970     0.315268     0.477032
75%       0.522786     0.480727     0.750543
max       1.000000     1.000000     1.000000

在这里插入图片描述

# 赋值给原数据
data.iloc[:, :3] = data_scaled.iloc[:, :3]
data
0123
00.4483250.3980510.5623343
10.1587330.3419550.9872442
20.2854290.0689250.4744961
30.8232010.6284800.2524891
40.4201020.0798200.0785781
...............
9950.1221060.1630370.3722242
9960.7542870.4768180.3946211
9970.2911590.5091030.5107953
9980.5271110.4366550.4290053
9990.4794080.3768090.7857183

1000 rows × 4 columns

4、划分数据集

from sklearn.model_selection import train_test_splitX = data.iloc[:, :3]
y = data.iloc[:, 3]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

5、模型的创建与训练

from sklearn.neighbors import  KNeighborsClassifier
from sklearn.model_selection import GridSearchCVmodel = KNeighborsClassifier()   # algorithm:自动选择算法确定K值
# 网格搜索查找最优 n_neighors
grid_search = {"n_neighbors": [1, 3, 5, 7, 9]}
model = GridSearchCV(model, param_grid=grid_search, cv=5)  # 交叉验证设置为 5
model.fit(X_train, y_train)

6、预测结果

# 对整个模型进行预测
data["预测结果"] = model.predict(data.iloc[:, :3])
data.head(10)
0123预测结果
00.4483250.3980510.56233433
10.1587330.3419550.98724422
20.2854290.0689250.47449611
30.8232010.6284800.25248911
40.4201020.0798200.07857811
50.7997220.4848020.60896111
60.3938510.3265300.71533533
70.4674550.6346450.32031233
80.7395070.4126120.44153611
90.3887570.5866900.88936033
# 查看后 10 行
data.tail(10)
0123预测结果
9900.3040330.4085570.07527933
9910.1081150.1288270.25476422
9920.2008590.1888800.19602922
9930.0414140.4711520.19359822
9940.1992920.0989020.25305822
9950.1221060.1630370.37222422
9960.7542870.4768180.39462111
9970.2911590.5091030.51079533
9980.5271110.4366550.42900533
9990.4794080.3768090.78571833

7、模型评估

scorek = model.score(X_test, y_test)scorek

答案:

0.93

这篇关于机器学习/数据分析--通俗语言带你入门K-邻近算法(结合案例)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1097755

相关文章

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

Go语言利用泛型封装常见的Map操作

《Go语言利用泛型封装常见的Map操作》Go语言在1.18版本中引入了泛型,这是Go语言发展的一个重要里程碑,它极大地增强了语言的表达能力和灵活性,本文将通过泛型实现封装常见的Map操作,感... 目录什么是泛型泛型解决了什么问题Go泛型基于泛型的常见Map操作代码合集总结什么是泛型泛型是一种编程范式,允

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤

使用DeepSeek API 结合VSCode提升开发效率

《使用DeepSeekAPI结合VSCode提升开发效率》:本文主要介绍DeepSeekAPI与VisualStudioCode(VSCode)结合使用,以提升软件开发效率,具有一定的参考价值... 目录引言准备工作安装必要的 VSCode 扩展配置 DeepSeek API1. 创建 API 请求文件2.

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

基于Go语言实现一个压测工具

《基于Go语言实现一个压测工具》这篇文章主要为大家详细介绍了基于Go语言实现一个简单的压测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录整体架构通用数据处理模块Http请求响应数据处理Curl参数解析处理客户端模块Http客户端处理Grpc客户端处理Websocket客户端