Python大数据分析——K近邻模型(KNN)

news2024/9/28 11:22:59

Python大数据分析——K近邻模型

  • 数学部分
    • 模型思想
    • 模型步骤
    • 距离度量指标
      • 欧氏距离
      • 曼哈顿距离
      • 余弦相似度
    • K值选择
  • 代码部分
    • 函数
    • 示例1——知识掌握程度
    • 示例2——预测发电量

数学部分

模型思想

在这里插入图片描述

如图所示,模型的本质就是寻找k个最近样本,然后基于最近样本做“预测”。对于离散型的因变量来说,从k个最近的已知类别样本中挑选出频率最高的类别用于末知样本的判断;对于连续型的因变量来说,则是将k个最近的已知样本均值用作未知样本的预测。

模型步骤

  1. 确定未知样本近邻的个数k值。
  2. 根据某种度量样本间相似度的指标(如欧氏距离)将每一个未知类别样本的最近k个已知样本搜寻出来,形成一个个簇。
  3. 对搜寻出来的已知样本进行投票,将各簇下类别最多的分类用作未知样本点的预测。

距离度量指标

欧氏距离

在这里插入图片描述
对于多维表示,yn和xn是n维空间
A:(x1, x2, x3 … xn)
B:(y1, y2, y3 … yn)

曼哈顿距离

在这里插入图片描述

余弦相似度

在这里插入图片描述
论文查重用的方法就是余弦相似度。

K值选择

根据经验发现,不同的k值对模型的预测准确性会有比较大的影响,如果k值过于偏小,可能会导致模型的过拟合;反之,又可能会使模型进入欠拟合状态。
在这里插入图片描述
那么解决方法就是,一种是设置k近邻样本的投票权重,使用KNN算法进行分类或预测时设置的k值比较大,担心模型发生欠拟合的现象,一个简单有效的处理办法就是设置近邻样本的投票权重,如果已知样本距离未知样本比较远,则对应的权重就设置得低一些,否则权重就高一些,通常可以将权重设置为距离的倒数。
在这里插入图片描述
还有一种方法是,采用多重交叉验证法,该方法是目前比较流行的方案,其核心就是将k取不同的值,然后在每种值下执行m重的交叉验证,最后选出平均误差最小的k值。当然,还可以将两种方法的优点相结合,选出理想的k值。
在这里插入图片描述

代码部分

函数

neighbors.KNeighborsClassifier(n_neighbors=5, weights=‘uniform’, p=2, metric=‘minkowski’)
n_neighbors:用于指定近邻样本个数K,默认为5
weights:用于指定近邻样本的投票权重,默认为’uniform’,表示所有近邻样本的投票权重一样;如果为’distance’,则表示投票权重与距离成反比,即近邻样本与未知类别的样本点距离越远,权重越小,反之,权重越大
metric:用于指定距离的度量指标,默认为闵可夫斯基距离
p:当参数metric为闵可夫斯基距离时,p=1,表示计算点之间的曼哈顿距离;p=2,表示计算点之间的欧氏距离;该参数的默认值为2

其中闵可夫斯基距离是p次根号下的Σ(x-y)^p

示例1——知识掌握程度

  1. 首先我们来看看数据
# 导入第三方包
import pandas as pd
# 导入数据
Knowledge = pd.read_excel(r'D:\pythonProject\data\Knowledge.xlsx')
# 返回前5行数据
Knowledge.head()

输出:
在这里插入图片描述

  1. 紧接着我们需要构造训练和测试集
# 构造训练集和测试集
# 导入第三方模块
from sklearn import model_selection
# 将数据集拆分为训练集和测试集
predictors = Knowledge.columns[:-1]
X_train, X_test, y_train, y_test = model_selection.train_test_split(Knowledge[predictors], Knowledge.UNS, test_size = 0.25, random_state = 1234)
  1. 我们利用交叉验证来寻找最佳的K值
# 导入第三方模块
import numpy as np
from sklearn import neighbors
import matplotlib.pyplot as plt

# 设置待测试的不同k值
K = np.arange(1,np.ceil(np.log2(Knowledge.shape[0]))).astype(int) # 计算样本数的log2,n个样本就是log2(n)
# 构建空的列表,用于存储平均准确率
accuracy = []
for k in K:
    # 使用10重交叉验证的方法,比对每一个k值下KNN模型的预测准确率
    cv_result = model_selection.cross_val_score(neighbors.KNeighborsClassifier(n_neighbors = k, weights = 'distance'), X_train, y_train, cv = 10, scoring='accuracy')
    accuracy.append(cv_result.mean())

# 从k个平均准确率中挑选出最大值所对应的下标    
arg_max = np.array(accuracy).argmax()
# 中文和负号的正常显示
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
# 绘制不同K值与平均预测准确率之间的折线图
plt.plot(K, accuracy)
# 添加点图
plt.scatter(K, accuracy)
# 添加文字说明
plt.text(K[arg_max], accuracy[arg_max], '最佳k值为%s' %int(K[arg_max]))
# 显示图形
plt.show()

输出:
在这里插入图片描述

  1. 我们利用计算的最佳K值进行拟合和验证
# 导入第三方模块
from sklearn import metrics

# 重新构建模型,并将最佳的近邻个数设置为5
knn_class = neighbors.KNeighborsClassifier(n_neighbors = 5, weights = 'distance')
# 模型拟合
knn_class.fit(X_train, y_train)
# 模型在测试数据集上的预测
predict = knn_class.predict(X_test)
# 构建混淆矩阵
cm = pd.crosstab(predict,y_test)
cm

输出:
注意看对角线的值
在这里插入图片描述

  1. 查看精确度
# 模型整体的预测准确率
metrics._scorer.accuracy_score(y_test, predict)
# 分类模型的评估报告
print(metrics.classification_report(y_test, predict))

输出:
在这里插入图片描述
precision是精确度;recall覆盖率;f1是两者综合指标。

示例2——预测发电量

  1. 导入数据并分析
# 读入数据
ccpp = pd.read_excel(r'D:\pythonProject\data\CCPP.xlsx')
ccpp.head()

输出:
PE是发电量,前面四个变量是影响PE大小的因素
在这里插入图片描述

# 返回数据集的行数与列数
ccpp.shape

(9568, 5)

  1. 处理数据
    由于数据的量纲不一致,有千有个,所以我们需要进行数据标准化
# 导入第三方包
from sklearn.preprocessing import minmax_scale
# 对所有自变量数据作标准化处理
predictors = ccpp.columns[:-1]
X = minmax_scale(ccpp[predictors])
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, ccpp.PE, test_size = 0.25, random_state = 1234)
  1. 交叉验证寻找最佳K值
# 设置待测试的不同k值
K = np.arange(1,np.ceil(np.log2(ccpp.shape[0]))).astype(int)
# 构建空的列表,用于存储平均MSE
mse = []
for k in K:
    # 使用10重交叉验证的方法,比对每一个k值下KNN模型的计算MSE
    cv_result = model_selection.cross_val_score(neighbors.KNeighborsRegressor(n_neighbors = k, weights = 'distance'), X_train, y_train, cv = 10, scoring='neg_mean_squared_error') # 找均方误差最小
    mse.append((-1*cv_result).mean())

# 从k个平均MSE中挑选出最小值所对应的下标  
arg_min = np.array(mse).argmin()
# 绘制不同K值与平均MSE之间的折线图
plt.plot(K, mse)
# 添加点图
plt.scatter(K, mse)
# 添加文字说明
plt.text(K[arg_min], mse[arg_min] + 0.5, '最佳k值为%s' %int(K[arg_min]))
# 显示图形
plt.show()

输出:
在这里插入图片描述

  1. 构建模型,查看准确
# 重新构建模型,并将最佳的近邻个数设置为7
knn_reg = neighbors.KNeighborsRegressor(n_neighbors = 7, weights = 'distance')
# 模型拟合
knn_reg.fit(X_train, y_train)
# 模型在测试集上的预测
predict = knn_reg.predict(X_test)
# 计算MSE值
metrics.mean_squared_error(y_test, predict)
# 对比真实值和实际值
pd.DataFrame({'Real':y_test,'Predict':predict}, columns=['Real','Predict']).head(10)

在这里插入图片描述

我们去比较下决策树

# 导入第三方模块
from sklearn import tree

# 预设各参数的不同选项值
max_depth = [19,21,23,25,27]
min_samples_split = [2,4,6,8]
min_samples_leaf = [2,4,8,10,12]
parameters = {'max_depth':max_depth, 'min_samples_split':min_samples_split, 'min_samples_leaf':min_samples_leaf}
# 网格搜索法,测试不同的参数值
grid_dtreg = model_selection.GridSearchCV(estimator = tree.DecisionTreeRegressor(), param_grid = parameters, cv=10)
# 模型拟合
grid_dtreg.fit(X_train, y_train)
# 返回最佳组合的参数值
grid_dtreg.best_params_
# 构建用于回归的决策树
CART_Reg = tree.DecisionTreeRegressor(max_depth = 19, min_samples_leaf = 10, min_samples_split = 6)
# 回归树拟合
CART_Reg.fit(X_train, y_train)
# 模型在测试集上的预测
pred = CART_Reg.predict(X_test)
# 计算衡量模型好坏的MSE值
metrics.mean_squared_error(y_test, pred)

输出:{‘max_depth’: 19, ‘min_samples_leaf’: 10, ‘min_samples_split’: 6}

# 构建用于回归的决策树
CART_Reg = tree.DecisionTreeRegressor(max_depth = 19, min_samples_leaf = 10, min_samples_split = 6)
# 回归树拟合
CART_Reg.fit(X_train, y_train)
# 模型在测试集上的预测
pred = CART_Reg.predict(X_test)
# 计算衡量模型好坏的MSE值
metrics.mean_squared_error(y_test, pred)

输出:16.17598770280405
发现效果没有KNN的效果好。

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

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

相关文章

qml 实现一个带动画的switch 按钮

一.效果图 》 二.qml 代码 import QtQuick 2.12 import QtQuick.Controls 2.12Switch {id: controlimplicitWidth: 42implicitHeight: 20indicator: Rectangle {id: bkRectangleanchors.fill: parentx: control.leftPaddingy: parent.height / 2 - height / 2radius: height …

C语言有哪些特点?

C语言是一种结构化语言,它有着清晰的层次,可按照模块的方式对程序进行编写,十分有利于程序的调试,且c语言的处理和表现能力都非常的强大,依靠非常全面的运算符和多样的数据类型,可以轻易完成各种数据结构的…

Linux系统日志管理服务和配置

文章目录 Linux系统日志服务rsyslog日志分类rsyslog相关文件/var/log/message重启失败分析 /var/log/secure自定义日志输出路径1.修改sshd_config配置文件2.修改rsyslog.conf3.重启服务 常见日志文件日志管理工具journalctl选项说明journalctl用法示例 日志分析实战host无法解析…

qt creator中右边的的类和对象如何显示出来

qt creator中右边的的类和对象如何显示出来? 解决方法: 鼠标右键,重置为默认布局。

未来互联网的新篇章:深度解析Web3技术

随着技术的不断演进,Web3正逐渐成为引领未来互联网发展的关键驱动力。本文将深入探讨Web3技术的核心概念、关键特征以及其对未来互联网生态的深远影响,旨在帮助读者全面理解和把握这一新兴技术的发展方向和潜力。 1. Web3的基本概念和演进 Web3并非简单…

【AI大模型】通义灵码的部署与使用

【AI大模型】通义灵码的部署与使用 目前已支持: JetBrains IDEsIDE 版本:IntelliJ IDEA、PyCharm、GoLand、WebStorm、Android Studio 等 2020.3 及以上操作系统:Windows 7 及以上、macOS、LinuxVisual Studio CodeIDE 版本:1.68.…

minio在redhat7.9上面的单节点单驱动离线安装(docker)

问题 最近需要在红帽上面离线安装minio,并且还是要离线安装到服务器中的Docker里面去。 检查服务器磁盘 # lsblk -f NAME FSTYPE LABEL UUID MOUNTPOINT sda ├─sda1 xfs xxxxsx-xxx-xxx…

软链接node_modules

公司项目很多微应用的子项目公用同一套模板,也就会使用同一个node_modules 1.先创建3个同样的项目,并安装一个其中的一个node_modules给他丢到外边 2.win r -------> cmd --------> ctrlshift enter(已管理员身份打开cmd) 3.在窗口分别执行以下代码…

【手撸RPC框架】zookeeper入门(安装+常用命令)

🐼作者简介:一名大三在校生🎋 空有想法,没有实践,难成大事 专栏前言:探索RPC框架的奥秘 简介:在现代软件开发中,随着微服务架构的普及,远程过程调用(RPC&…

Mybatis左连接的实现方式

在使用 MyBatis Plus 进行数据库操作时,我们有时需要从多个表中获取数据。这篇文章将介绍如何在 MyBatis Plus 中实现左连接查询。我们将以两个表格为例,一个是部门领导表 (system_dept_leader),另一个是用户表 (system_user),并演…

tk 对文本设置下划线

import tkinter as tkdef underline_text():# 获取当前选中的文本范围selected_text text_widget.tag_ranges(tk.SEL)if selected_text:# 如果有文本被选中tag_name "underline"# 检查选中文本是否已经有下划线if text_widget.tag_names(selected_text[0]):if &quo…

Qt | 绘制直线与 QLineF 类

点击上方"蓝字"关注我们 01、绘制直线 02、Qline和QLineF 【1】QLine 是整型版本,成员函数较少,QLineF 是精度更高的浮点型版本,本文以 QLineF 类 进行讲解。 QLineF 类提供了一个二维向量,使用 QLineF 类绘制直线可以利用该类中的成员函数方便 的对线条的属…

【EIScopus稳检索-高录用】第五届大数据与社会科学国际学术会议(ICBDSS 2024)

大会官网:www.icbdss.org 大会时间:2024年8月16-18日 大会地点:中国-上海 接受/拒稿通知:投稿后1-2周内 收录检索:EI,Scopus *所有参会者现场均可获取参会证明,会议通知(邀请函)&…

vscode里最好用的A股量化神器

shares vscode 插件A 股量化交易系统后台开发语言 Go/Python gmsec算法使用:pytorchK 线标注中意榜黄金上穿全链路量化,行业板块分析,直接贴图。欢迎体验 源码地址: GitHub - xxjwxc/shares: A-share quantitative system. A股量…

Python学习笔记35:进阶篇(二十四)pygame的使用之音频文件播放

前言 基础模块的知识通过这么长时间的学习已经有所了解,更加深入的话需要通过完成各种项目,在这个过程中逐渐学习,成长。 我们的下一步目标是完成python crash course中的外星人入侵项目,这是一个2D游戏项目。在这之前&#xff…

对接高德开放平台API

高德开放平台API: https://lbs.amap.com/ 一、天气查询 天气查询: https://lbs.amap.com/api/webservice/guide/api/weatherinfo adcode城市码表下载: https://lbs.amap.com/api/webservice/download Component public class WeatherUtil {Resourceprivate GdCon…

异步任务中传递用户信息的一种优雅写法

目录 前言基础写法测试示例 升级写法测试示例 前言 在异步任务中,我们通常会遇到子任务获取当前用户的场景。我们可能会采取ThreadLocal来存储主线程传递的用户信息。然后在业务开始时set,业务结束时remove,来保证不会出现OOM的场景。 基础…

vue使用 “xlsx-style“: “^0.8.13“ 报错

关于jszip not a constructor报错配置config.js文件后可能还报错的问题: 在node_modules处找到node_modules\xlsx-style\xlsx.js 文件。 将 if(typeof jszip undefined) jszip require(./jszip).JSZip;(应该在xlsx.js文件1339行左右) 替换成 if(typeof jszip und…

聚类分析方法(三)

目录 五、聚类的质量评价(一)簇的数目估计(二)外部质量评价(三)内部质量评价 六、离群点挖掘(一)相关问题概述(二)基于距离的方法(三)…

外贸达人的秘密武器:提升效率的插件神器

每一位外贸从业者都在寻找能够提升工作效率、优化业务流程的利器。今天,我要向大家介绍几款外贸工作中的实用的浏览器插件工具,它们将是你业务成功的得力助手。 语言翻译类: Acronyms:外贸交流中,缩写的快速识别至关重…