KNN算法与模型选择及调优

2024-08-22 11:04
文章标签 算法 选择 模型 knn 调优

本文主要是介绍KNN算法与模型选择及调优,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

KNN算法-分类

1 样本距离判断

(1)欧式距离

欧式距离(Euclidean distance),也称为欧氏度量,是用来衡量两个点之间直线距离的方法。

(2)曼哈顿距离

曼哈顿距离(Manhattan distance),也称为城市街区距离,是在网格状坐标系统中,从一个点到另一个点的距离之和。

2 KNN 算法原理

K-近邻算法(K-Nearest Neighbors,简称KNN)是一种基于样本相似性的分类方法。它通过比较目标样本与其最近的 ( K ) 个邻居样本的类别来决定目标样本的类别。

具体步骤如下:

  1. 选择 ( K ):确定要考虑的邻居数量 ( K )。

  2. 计算距离:计算目标样本与所有其他样本的距离,找到距离最近的 ( K ) 个样本。

  3. 投票决策:统计这 ( K ) 个邻居中各类别的出现次数,目标样本将被分配到出现次数最多的类别。

假设我们有 10000 个样本,并且选择 ( K = 5 )。我们需要对一个待分类的样本 B 进行分类。首先,我们找到与样本 B 距离最近的 5 个样本。假设这 5 个邻居的类别分布如下:

  • 类别 A:3 个样本

  • 类别 B:1 个样本

  • 类别 C:1 个样本

在这种情况下,由于类别 A 的邻居样本最多,样本 B 将被分类为类别 A。

弊端:计算量大维度灾难需要选择合适的 ( K ) 值和距离度量

sklearn.neighbors.KNeighborsClassifier 的主要参数和方法如下:
参数
n_neighbors:邻居数量,默认为 5。
algorithm:寻找邻居的算法,默认为 'auto'。
方法
fit(X, y):训练模型。
predict(X):进行预测。

使用KNN算法预测《唐人街探案》电影属于哪种类型?分别计算每个电影和预测电影的距离然后求解:

import pandas as pd
from collections import Counter
​
# 读取电影数据
data = pd.read_csv("./src/movies.csv")
df = pd.DataFrame(data)
​
# 目标电影数据
target_movie = {'电影名称': '唐人街探案','搞笑镜头': 23,'拥抱镜头': 3,'打斗镜头': 17,'距离': None  # 不需要实际的距离值
}
​
# 按距离排序并选择最近的3个邻居
k = 3
nearest_neighbors = df.sort_values(by='距离').head(k)#head(k) 是 pandas 的一个方法,用于从 DataFrame 的顶部获取前 k 行数据
​
# 统计K个邻居的电影类型
neighbor_types = nearest_neighbors['电影类型']
predicted_type = Counter(neighbor_types).most_common(1)[0][0]
#most_common(n) 是 Counter 类的一个方法,它返回出现频率最高的 n 个元素及其计数,返回一个列表,其中包含元组 (元素, 频次)。
#[0][0] 表示取第一个元组,然后取第一个元素,即电影类型
​
print(f"唐人街探案的预测电影类型是: {predicted_type}")
2.sklearn 实现KNN示例

用KNN算法对葡萄酒进行分类

from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_wine
import joblib #模型保存与加载需导入
​
def knn(path):# 加载酒类数据集wine = load_wine()x = wine.data  # 特征数据y = wine.target  # 目标标签
​# 划分训练集和测试集x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
​# 创建并训练 KNN 模型model = KNeighborsClassifier(n_neighbors=7)model.fit(x_train, y_train)
​# 评估模型准确率accuracy = model.score(x_test, y_test)print("准确率:", accuracy)
​# 保存模型joblib.dump(model, path)
​
# 定义模型保存路径并调用函数
path = './src/knn.pkl'
knn(path)
​
# 加载保存的模型
model = joblib.load(path)
​
# 预测新样本的类别
y_predict = model.predict([[2.16, 5.51, 1.34, 1.9, 2.76, 1.35, 4.43, 2.05, 0.94, 1.36, 4.36, 3.59, 1.86]])
print(y_predict)
​
# 输出预测结果对应的标签名
print(load_wine().target_names[y_predict])
​

模型选择与调优

1 交叉验证
(1) 保留交叉验证HoldOut

HoldOut 交叉验证将数据集分为训练集和验证集,通常70%用于训练,30%用于验证。这是一种简单直接的方法。

优点:

  • 实现简单,操作方便。

缺点:

  1. 不适用于不平衡数据集:在不平衡数据集中,训练集和验证集可能不均衡,导致模型无法有效学习少数类的数据。(比如80%的数据属于 “0 “类,其余20%的数据属于 “1 “类)

  2. 数据利用不充分:在小数据集上,一部分数据用于验证,可能导致模型错过关键特征,影响性能。

(2) K-折交叉验证(K-fold)

K-Fold 交叉验证将数据集划分为K个大小相同的部分(Fold)。每次用一个Fold作为验证集,其余K-1个Fold作为训练集。这一过程重复K次,确保每个Fold都被用作验证集。

最终模型的准确度通过计算K次验证结果的平均值来获得。

(3) 分层k-折交叉验证Stratified k-fold

分层 K-Fold 交叉验证是 K-Fold 交叉验证的变种。在每一折中保持原始数据中各类别的比例。例如,如果原始数据有三类,比例为 1:2:1,那么每一折中的类别比例也保持 1:2:1。这种方法使得每一折的验证结果更加可靠。

(4) 其它验证
去除p交叉验证)
留一交叉验证)
蒙特卡罗交叉验证
时间序列交叉验证

(5)API的使用

strat_k_fold=sklearn.model_selection.KNeighborsClassifier(n_splits=5, shuffle=True, random_state=42)
​
•   n_splits划分为几个折叠 
•   shuffle是否在拆分之前被打乱(随机化),False则按照顺序拆分
•   random_state随机因子

from sklearn.datasets import load_wine
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import StratifiedKFold
import numpy as np
​
# 加载葡萄酒数据集
wine = load_wine()
x = np.array(wine.data)  
y = np.array(wine.target)  
​
dts = []  
# 初始化分层 K-Fold 交叉验证器
kf = StratifiedKFold(n_splits=5, shuffle=True, random_state=44)
​
# 遍历每个折叠
for train_index, test_index in kf.split(x, y):x_train, x_test = x[train_index], x[test_index]  # 划分训练集和测试集y_train, y_test = y[train_index], y[test_index]# 初始化 KNN 分类器并训练knn = KNeighborsClassifier(n_neighbors=5)knn.fit(x_train, y_train)# 计算测试集的准确率并存储dt = knn.score(x_test, y_test)dts.append(dt)
​
print("每个折叠的准确率:", dts)
print("平均准确率:", np.mean(dts))
2 超参数搜索及其API使用

超参数搜索也叫网格搜索(Grid Search)

比如在KNN算法中,k是一个可以人为设置的参数,所以就是一个超参数。网格搜索能自动的帮助我们找到最好的超参数值。

sklearn.model_selection.GridSearchCV 是一个工具,用于同时进行网格搜索和交叉验证。它也被视为一个估计器(estimator)。

class sklearn.model_selection.GridSearchCV(estimator, param_grid)best_params_  最佳参数best_score_ 在训练集中的准确率best_estimator_ 最佳估计器cv_results_ 交叉验证过程描述best_index_最佳k在列表中的下标
参数:
estimator:待优化的 scikit-learn 估计器
param_grid:参数名称(字符串)和对应值列表的字典,如 {"n_neighbors": [1, 3, 5, 7, 9, 11]}
cv:交叉验证策略
None:默认5折
integer:指定折数
分类器使用“分层K折交叉验证”(StratifiedKFold),其他情况使用KFold。
3 示例-葡萄酒分类

用KNN算法对葡萄酒进行分类,添加网格搜索和交叉验证

from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_wine
import joblib
​
x, y = load_wine(return_X_y=True)
​
knn = KNeighborsClassifier()
​
model = GridSearchCV(knn, {"n_neighbors": [5, 6, 9, 10]})
​
​
re = model.fit(x, y)
​
print("最佳参数:\n", model.best_params_)
print("最佳k在列表中的下标", model.best_index_)
print("最佳准确率:\n", model.best_score_)
print("最佳估计器:\n", model.best_estimator_)
print("交叉验证过程描述:\n", model.cv_results_)
​
# 使用最佳模型进行预测
y_predict = re.predict([[2.06, 5.41, 1.34, 1.85, 2.73, 1.65, 3.83, 2.05, 1.04, 1.36, 4.36, 3.49, 1.96]])
print(y_predict)
​
# 验证是否模型与最佳估计器相同
print(re == model.best_estimator_)
joblib.dump(model.best_estimator_, "./src/knn2.pkl")
​
model = joblib.load("./src/knn2.pkl")
​
# 使用加载的模型进行预测
y_predict = model.predict([[2.16, 5.51, 1.34, 1.9, 2.76, 1.35, 4.43, 2.05, 0.94, 1.36, 4.36, 3.59, 1.86]])
print(y_predict)
​

这篇关于KNN算法与模型选择及调优的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

如何选择适合孤独症兄妹的学校?

在探索适合孤独症儿童教育的道路上,每一位家长都面临着前所未有的挑战与抉择。当这份责任落在拥有孤独症兄妹的家庭肩上时,选择一所能够同时满足两个孩子特殊需求的学校,更显得尤为关键。本文将探讨如何为这样的家庭做出明智的选择,并介绍星贝育园自闭症儿童寄宿制学校作为一个值得考虑的选项。 理解孤独症儿童的独特性 孤独症,这一复杂的神经发育障碍,影响着儿童的社交互动、沟通能力以及行为模式。对于拥有孤独症兄

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount