scikit-learn机器学习算法封装

K近邻算法

K-最近邻(KNN)是一种有监督的机器学习算法,可用于解决分类和回归问题。它基于一个非常简单的想法,数据点的值由它周围的数据点决定。考虑的数据点数量由k值确定。因此,k值是算法的核心。

在这里插入图片描述

我们现在已经知道。 这个大量输入的学习资料, 其实更加专业的一个叫法是训练的数据集数据集。那么对于我们的监督学习来说,训练的数据集不仅包括这些数据相应的特征也就是X_train, 还要包括数据所对应的标签, 或者说是最终的这个类别结果通常我们叫它y_train, 那么我们将x_train和y_train送入机器学习算法训练模型的这个过程,通常在英文上管这个过程叫做fit, 我们可以翻译成拟合,也就是说我们的算法要得到一个模型,这个模型要能够拟合我们的训练数据集,输入的样例送到模型之后,这个模型获得输出结果的这个过程通常英文叫做predict,也就是预测。
在这里插入图片描述

更加专业的认识,可能有一些同学再去想我们的KNN算法,就会有这样的一个疑问了,对于我们的KNN算法,我们并没有得到什么模型啊,事实上确实如此, 这可能也是KNN算法的一个非常重要的特性, 近乎可以说KNN算法是机器学习中唯一一个不需要训练过程的算法, 换句话说, 这个输入样例直接可以送给这个训练数据集, 在这个训练数据集上直接找到离输入样例最近的K个点, 然后投票选出来投票数最高的那一个标签就是结果了,

  • k近邻算法是非常特殊的,可以被认为是没有模型的算法
  • 为了和其他算法统一,可以认为训练数据集就是模型本身

事实上在scikitlearn机器学习库库的设计上就是使用这样的一个设计方式,这是为了可以方便的和其他算法统一,这样每一个算法都会有fit这个过程。

对于KNN来说, 机器学习算法其实就是将X_train和y_train这个数据集拷贝过来,形成了我们的模型, 而训练集本身就是模型, 而相对复杂的其实是在这个预测的过程,在预测过程中,我们将输入样例交给模型,并采用以下步骤:

  1. 寻找K个最近的元素。
  2. 统计它们的投票结果。
  3. 最终得出输出的预测结果。

虽然在预测过程中涉及到一些复杂的步骤,但不管怎么样,这种方式为KNN算法找到了适应的模型。

对于KNN算法的训练过程或拟合过程,在scikit-learn框架下,与其他机器学习算法的训练过程是统一的,首先进行fit操作以获得模型,然后进行相应的predict操作。但对于KNN算法来说,fit过程非常简单,稍后我们将深入研究并从底层实现自己的KNN模型。

一、拟合 欠拟合 过拟合

1.拟合:
根据训练样本中学习出适用于所有潜在样本的“普遍规律”,这样在遇到新样本时做出正确的判别,即具有很好的泛化能力。
2.欠拟合
是指对训练样本的一般性质没有学好,即无法更好的判别测试样本, 甚至在训练集上的表现就很差。
3.过拟合
当学习器把训练样本学习的很“优秀”,即在训练集上表现优秀,近似完美的预测或者区分出了所有的数据,但是在新的测试样本集却无法正确预测或者区分,缺乏泛化能力。

K值的重要性

选择最优k值是建立一个合理、精确的knn模型的必要条件。

如果k值太低,则模型会变得过于具体,不能很好地泛化。它对噪音也很敏感。该模型在训练组上实现了很高的精度,但对于新的、以前看不到的数据点,该模型的预测能力较差。因此,我们很可能最终得到一个过拟合的模型。
如果k选择得太大,模型就会变得过于泛化,无法准确预测训练和测试集中的数据点。这种情况被称为欠拟合。

泛化能力

泛化能力(Generalization Ability)是指机器学习模型对于未在训练集中见过的新数据的适应能力或泛化能力。具体来说,它衡量了模型在面对新样本时能否产生准确的预测或正确的分类。泛化能力是评估一个机器学习模型优劣的重要指标之一。

泛化能力的概念可以用以下方式来理解:

  1. 训练集和测试集:在机器学习中,通常将数据集分为两部分:训练集(Training Set)和测试集(Test Set)。模型在训练集上学习模式和规律,然后在测试集上进行性能评估。

  2. 泛化到新数据:泛化能力指的是模型在测试集上表现良好,同时也能够对未在训练集中出现过的新数据做出准确的预测或分类。这意味着模型不仅仅能够背诵训练数据,还能够理解数据背后的真实规律。

  3. 避免过拟合和欠拟合:泛化能力的好坏与过拟合(Overfitting)和欠拟合(Underfitting)密切相关。过拟合指模型在训练集上表现很好,但在测试集或新数据上表现差。欠拟合指模型未能很好地拟合训练数据,因此在训练集和测试集上都表现不佳。泛化能力良好的模型能够在训练集和测试集之间取得平衡,避免过拟合和欠拟合问题。

  4. 交叉验证:为了评估模型的泛化能力,通常会使用交叉验证等技术,将数据集进一步划分为多个子集,以进行模型评估和参数调整,以确保模型在不同数据集上都能够泛化良好。

总的来说,泛化能力是机器学习模型成功应用于实际问题的关键因素之一。一个具有良好泛化能力的模型能够在新数据上产生可靠的结果,而不仅仅是在训练数据上表现良好。因此,在开发和评估机器学习模型时,泛化能力是一个重要的考虑因素。

使用scikit-learn中的KNN

对于sklearn中所有的机器学习算法算法都是以面向对象的形式进行包装的,所以首先我们要做的事情是创建一个实例

可能遇到的bug

注意在我们调用预测方法的时候可能会出现一个bug, 这里可能会出现一个bug, 如果sklearn kmean 算法predict时候出现 ‘NoneType‘ object has no attribute ‘split‘ sklearn, 我们只需要在命令行输入pip install threadpoolctl==3.1.0 然后重新启动jupyter notebook就解决了

我们整理一下用scikitlearn模块使用kNN算法的这个过程

  • ①:加载scikitlearn模块中相应的机器学习的算法
  • ②:然后创建算法所对应的实例, 如果这个算法在构造的过程中需要一些参数,相应的我们也要传入这些参数
  • ③:进行fit我们的训练数据集
  • ④:进行预测

我们有完全的自由来创建自己的机器学习算法,只要我们遵守scikit-learn的标准,这个算法就可以轻松地集成到scikit-learn的其他方法中。

面向函数封装KNN算法

"kNN_function\kNN.py"

# coding:utf-8
# """KNN算法的实现过程"""
import numpy as np
from math import sqrt
from collections import Counterdef KNN_classify(k, X_train, y_train, x):""":param k: 选取的距离最近的K个样本:param X_train、y_train:样本训练数据集:param x:将要预测的特征向量:return: 判断结果"""# 判断数据是否合法assert 1 <= k <= X_train.shape[0], "K must valid"# 我们需要确保X_train中样本的数量和y_train中Label的数量是相等的assert X_train.shape[0] == y_train.shape[0], \"the size of X_train must equal to the size of y_train"# 并且我们需要确保将要预测的样本的特征数量和我们所使用的X_train训练数据集中的特征数量是相同的assert X_train.shape[1] == x.shape[0], \"the feather number of x must be equal to X_train"distances = [sqrt(np.sum((x_train - x) ** 2)) for x_train in X_train]# 得到排序后的数组中的元素分别在原数组中对应的索引nearest = np.argsort(distances)# 查找这几个距离最近的k个样本在y训练集中所对应的类别topk_y = [y_train[i] for i in nearest[:k]]votes = Counter(topk_y)  # 对投票结果进行统计predict = votes.most_common(1)[0][0]  # 得到预测结果if predict == 1:return "该病人可能为恶性肿瘤"if predict == 0:return "该病人可能为良性肿瘤"

面向对象实现KNN算法

"kNN\kNN.py"

# coding:utf-8
"""使用面向对象的方式封装我们的KNN算法"""import numpy as np
from math import sqrt
from collections import Counterclass KNNClassifier:def __init__(self, k):"""初始化KNN分类器"""# 判断数据是否合法assert 1 <= k, "K must valid"# 将k的值传给一个成员变量self.k = kself._X_train = Noneself._y_train = Nonedef fit(self, X_train, y_train):"""Fit函数由用户传来Xtrain和y_train相应的去获得模型,也就是跟据所谓的训练数据集来训练我们的KNN分类器"""# 判断数据是否合法# 我们需要确保X_train中样本的数量和y_train中Label的数量是相等的assert X_train.shape[0] == y_train.shape[0], \"the size of X_train must equal to the size of y_train"# 我们需要确保k的值要在训练数据集的样本数量范围内assert self.k <= X_train.shape[0], \"the size of X_train must be at least k"self._X_train = X_trainself._y_train = y_train# 这里其实可以不用设置返回值, 但我们还是尽量遵循scikit-learn的设置原则来将self对象返回# 我们完全可以设计一个属于我们自己的机器学习的算法, 只要我们完全遵守scikit的标准的话, 那么这个算法就可以无缝的送给sklearn中的其他的算法中return selfdef predict(self, X_predict):"""给定待测二维数据集X_predict, 返回表示X_predict的结果向量"""# 判断用户设置的数据是否合法assert self._X_train is not None and self._y_train is not None, \"must fit before predict"# 特征的个数必须和训练集中的列数特征是一致的assert X_predict.shape[1] == self._X_train.shape[1], \"the feature number of X_predict must be equal to X_train"# 接下来我们对X_train样本中的每一行进行逐行预测, 并把预测后的结果放到一个向量中y_predict = [self._predict(x) for x in X_predict]return np.array(y_predict)def _predict(self, x):"""给定单个待预测预测的数据x, 返回x_predict的预测结果值:param x: predict方法运行所传入的样本数据:return:"""# 判断用户输入的数据集中的样本的特征个数是否和训练集中的样本特征个数一致assert x.shape[0] == self._X_train.shape[1], \"the feather number of x must be equal to X_train"# 求出新输入的样本与训练数据集中每一个样本的距离distances = [sqrt(np.sum((x_train - x) ** 2))for x_train in self._X_train]# 返回排序后的数组中的元素在元素中的位置索引nearest = np.argsort(distances)# 进行投票(也就是分别得出最近的k个样本的类别)topK_y = [self._y_train[i] for i in nearest[:self.k]]# 统计投票结果vote = Counter(topK_y)# 返回预测结果(取出投票结果最大的类别, 也就是最有可能是哪一类)return vote.most_common(1)[0][0]def __repr__(self):return "KNN(k=%d)" % self.k

接下来会将我们实现的模块加载到jupyter中
02-kNN-in-scikit-learn.ipynb

import numpy as np
import matplotlib.pyplot as plt
raw_data_X = [[3.393533211, 2.331273381],[3.110073483, 1.781539638],[1.343808831, 3.368360954],[3.582294042, 4.679179110],[2.280362439, 2.866990263],[7.423436942, 4.696522875],[5.745051997, 3.533989803],[9.172168622, 2.511101045],[7.792783481, 3.424088941],[7.939820817, 0.791637231]]
raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]X_train = np.array(raw_data_X)
y_train = np.array(raw_data_y)x = np.array([8.093607318, 3.365731514])
# 我们加载我们实现的KNN方法
%run ./Pycharm_project/kNN_function/kNN.py
predict_y = KNN_classify(6, X_train, y_train, x)
predict_y
'该病人可能为恶性肿瘤'
from sklearn.neighbors import KNeighborsClassifier
kNN_classifier = KNeighborsClassifier(n_neighbors=6)
kNN_classifier.fit(X_train, y_train)
KNeighborsClassifier(n_neighbors=6)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
KNeighborsClassifier(n_neighbors=6)
x = x.reshape(1, -1)  # 因为我们输入的训练数据集是矩阵, 所以我们也要把将要预测的数据转化为二维数组
kNN_classifier.predict(x)
array([1])
X_predict = x.reshape(1, -1)
X_predict
array([[8.09360732, 3.36573151]])
kNN_classifier.predict(X_predict)
array([1])
y_predict = kNN_classifier.predict(X_predict)
y_predict[0]
1
%run ./Pycharm_project/KNN/kNN.py
knn_clf = KNNClassifier(3)
knn_clf.fit(X_train, y_train)
KNN(k=3)
X_predict = x.reshape(1, -1)  # 因为我们输入的训练数据集是矩阵, 所以我们也要把将要预测的数据转化为二维数组
y_predict = knn_clf.predict(X_predict)
y_predict
array([1])
y_predict[0]
1

以上就是我们实现KNN算法的过程, 事实上sklearn内部的KNN算法的底层实现, 不像我们实现的这么简单, 而使用了更加复杂的方式, 这是因为KNN本身在预测的过程中是非常好使的。对于KNN的缺点在这一章的最后我还会再向大家总结的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac安装chromedriver驱动详细步骤

1.查看浏览器版本 2.下载驱动 3.安装驱动 4.MacOS无法打开“chromedriver”&#xff0c;因为无法验证开发者 1.查看浏览器版本 在这里插入图片描述 2.下载驱动 下载驱动地址&#xff1a;链接: http://chromedriver.storage.googleapis.com/index.html. 下载和浏览器版本一致的…

解决因为修改SELINUX配置文件出错导致Faild to load SELinux poilcy无法进入CentOS7系统的问题

一、问题 最近学习Kubernetes&#xff0c;需要设置永久关闭SELINUX,结果修改错了一个SELINUX配置参数&#xff0c;关机重新启动后导致无法进入CentOS7系统&#xff0c;卡在启动进度条界面。 二、解决 多次重启后&#xff0c;在启动日志中发现 Faild to load SELinux poilcy…

Windows专业版的Docker下载、安装与启用Kubenetes、访问Kubernetes Dashboard

到Docker 官网https://www.docker.com/ 下载windows操作系统对应的docker软件安装 Docker Desktop Installer-Win.exe 2023-09版本是4.23 下载后双击安装 重启windows后&#xff0c;继续安装 接受服务继续安装 解决碰到的Docker Engine stopped 打开 控制面板》程序》启用或关…

基于微服务的第二课堂管理系统(素质拓展学分管理平台)SpringCloud、SpringBoot 分布式,微服务

基于微服务的第二课堂管理系统 一款真正的企业级开发项目&#xff0c;采用标准的企业规范开发&#xff0c;有项目介绍视频和源码&#xff0c;需要学习的同学可以拿去学习&#xff0c;这是一款真正可以写在简历上的校招项目&#xff0c;能够真正学到东西的一个项目&#xff0c;话…

SpringBoot开发实战(微课视频版)

ISBN: 978-7-302-52819-7 编著&#xff1a;吴胜 页数&#xff1a;311页 阅读时间&#xff1a;2023-06-24 推荐指数&#xff1a;★★★★☆ 本文介绍SpringBoot 2.0.5 、JDK 1.8&#xff0c;虽然现在已经不维护了&#xff0c;但是大体的流程还是对口的&#xff0c; 而且书里面讲…

左神高阶进阶班4 (尼姆博弈问题、k伪进制、递归到动态规划、优先级结合的递归套路、子串的递归套路,子序列的递归套路,动态规划的压缩技巧)

目录 【案例1 尼姆博弈问题】 【题目描述】 【思路解析】 【代码实现】 【案例2 k伪进制问题】 【题目描述】 【思路解析】 【代码实现】 【案例3 最大路径和】 【题目描述】 【思路解析】 【代码实现】 【案例4 优先级的递归套路】 【题目描述】 【思路解析】…

黑马JVM总结(二十三)

&#xff08;1&#xff09;字节码指令-init 方法体内有一些字节&#xff0c;对应着将来要由java虚拟机执行方法内的代码&#xff0c;构造方法里5个字节代码&#xff0c;main方法里有9个字节的代码 java虚拟机呢内部有一个解释器&#xff0c;这个解释器呢可以识别平台无关的字…

整合车辆出险报告Api接口,轻松管理车险理赔!

随着车辆保有量的不断增加&#xff0c;车辆出险的情况也越来越普遍。对于车主来说&#xff0c;如何高效地管理车险理赔&#xff0c;处理保险事故是非常重要的。这时候我们就可以借助整合车辆出险报告API接口&#xff0c;实现快速定位理赔信息&#xff0c;轻松管理车险理赔。 一…

MongoDB(一) windows 和 linux 之 Ubuntu 安装

数据库分类 一、关系型数据库&#xff08;RDBMS&#xff09; mysql 、Oracle、DB2、SQL Server 关系数据库中全都是表 二、非关系型数据库&#xff08;NO SQL&#xff09; MongoDB、Redis 键值对数据库 文档数据库MongoDB 下载 mongoDB https://www.mongodb.com/try/downloa…

自动化测试的定位及一些思考

大家对自动化的理解&#xff0c;首先是想到Web UI自动化&#xff0c;这就为什么我一说自动化&#xff0c;公司一般就会有很多人反对&#xff0c;因为自动化的成本实在太高了&#xff0c;其实自动化是分为三个层面的&#xff08;UI层自动化、接口自动化、单元测试&#xff09;&a…

【论文写作】符号:矩阵、向量的乘法、内积、点积等

【论文写作】符号&#xff1a;矩阵、向量乘法、内积、点积等 文章目录 【论文写作】符号&#xff1a;矩阵、向量乘法、内积、点积等1. 矩阵乘法1.1 矩阵乘积1.2 矩阵哈德玛乘积1.3 矩阵克罗内克积 2. 向量乘法2.1 向量点积、内积2.2 向量Hadamard积2.3 向量外积2.4 向量叉积 1.…

[论文笔记]Prefix Tuning

引言 今天带来微调LLM的第二篇论文笔记Prefix-Tuning。 作者提出了用于自然语言生成任务的prefix-tuning(前缀微调)的方法,固定语言模型的参数而优化一些连续的任务相关的向量,称为prefix。受到了语言模型提示词的启发,允许后续的token序列注意到这些prefix,当成虚拟toke…

Go的error接口

从本书的开始&#xff0c;我们就已经创建和使用过神秘的预定义error类型&#xff0c;而且没有解释它究竟是什么。实际上它就是interface类型&#xff0c;这个类型有一个返回错误信息的单一方法&#xff1a; type error interface { Error() string } 创建一个error最简单的方…

高效查询大量快递信息,轻松掌握技巧

在如今快节奏的生活中&#xff0c;快递已经成为我们日常不可或缺的一部分。然而&#xff0c;对于一些忙碌的人来说&#xff0c;单个查询每一个快递单号可能会浪费太多时间。因此&#xff0c;我们需要一款可以帮助我们批量查询快递的软件。 在市场上&#xff0c;有很多款专门用于…

网络知识——局域网和交换机

定义&#xff1a; 局域网&#xff08;Local Area Network&#xff0c;简称LAN&#xff09;是指在某一区域内由多台计算机互联成的计算机组。广域网&#xff08;Wide Area Network&#xff0c;简称WAN&#xff09;是指跨越单个建筑物或大型园区&#xff0c;连接分布在特定地理区…

面向嵌入式系统的轻量级框架分析

mr-library简介 mr-library 是一个面向嵌入式系统的轻量级框架&#xff0c;提供统一的底层驱动设备模型以及基础服务功能&#xff0c;具有模块化设计、可配置性和扩展性的特点&#xff0c; 可帮助开发者快速构建嵌入式应用程序。 mr-library 框架支持互斥锁、对象管理等基础内…

Aqs独占/共享模式

独占锁和共享锁的概念 独占锁也叫排他锁&#xff0c;是指该锁一次只能被一个线程所持有。如果线程T对数据A加上排他锁后&#xff0c;则其他线程不能再对A加任何类型的锁。获得排它锁的线程即能读数据又能修改数据。 共享锁是指该锁可被多个线程所持有。如果线程T对数据A加上共…

Flume最简单使用

文章目录 一、简介1、定义2、基础架构 二、快速入门1、解压Flume2、案例一&#xff1a;监控端口号3、案例二&#xff1a;将空目录下文件 三、Flume进阶1、Flume事务2、Flume Agent内部原理3、案例一&#xff1a;监控日志4、案例二&#xff1a;多路复用和拦截器适应4.1 原理4.2 …

Linux 操作技巧

目录 一、shell-命令解释器 二、Linux中的特殊符号 三、命令历史--history 一、shell-命令解释器 shell——壳&#xff0c;命令解释器&#xff0c;负责解析用户输入的命令 ——内置命令&#xff08;shell内置&#xff09; ——外置命令&#xff0c;在文件系统的某个目录下&…

【学习草稿】背包问题

一、01背包问题 图解详细解析 &#xff08;转载&#xff09; https://blog.csdn.net/qq_37767455/article/details/99086678 &#xff1a;Vi表示第 i 个物品的价值&#xff0c;Wi表示第 i 个物品的体积&#xff0c;定义V(i,j)&#xff1a;当前背包容量 j&#xff0c;前 i 个物…