发布时间:2026/9/3 6:42:30
从零实现KNN算法:Matlab实战指南与核心原理深度解析 简介本资源是面向计算机、电子信息工程及数学等专业本科生的机器学习基础实践材料聚焦KNNK近邻算法原理与Matlab实现适用于课程设计、期末大作业或毕业设计中的分类任务参考实现。压缩包共4个文件3个.m脚本文件1个.mat数据文件总大小仅3KB结构精炼包含核心KNN分类函数、主程序调用逻辑、预置样本数据集及欧氏距离计算模块便于读者理解算法流程、调试参数并拓展至多类别场景。已有282人下载学习适合作为入门级算法复现范例——无需复杂依赖开箱即用代码注释清晰覆盖数据加载、距离度量、邻居搜索与投票决策全流程同时提供可替换的数据接口与参数配置入口支持用户快速迁移至自定义数据集并开展对比实验。1. 项目概述从一份压缩包到理解KNN手头拿到一个叫“基于Matlab实现KNN算法源码数据.rar”的文件这大概是很多同学入门机器学习时都会遇到的一个经典场景。一个压缩包里面包含了代码和一些示例数据看起来像是能“开箱即用”。但我的经验是直接双击运行然后看结果往往学不到东西甚至会因为环境或数据的一点小问题就卡住。这个项目标题虽然简单但它背后串联起来的是机器学习中一个非常核心且直观的算法——K最近邻K-Nearest Neighbors, KNN以及如何在一个强大的数学计算环境Matlab中将其实现和应用的全过程。KNN算法本质上是一种“物以类聚人以群分”的思想在数据世界的体现。它没有复杂的训练过程模型就是整个训练数据集本身。当需要对一个新的数据点进行分类或回归预测时它就在训练集中找到距离这个新点最近的K个“邻居”然后根据这些邻居的标签分类或值回归来“投票”决定新点的归属。这种懒惰学习Lazy Learning的方式使得其原理异常直观非常适合作为机器学习的第一个实战算法。而Matlab作为一个集成了数值计算、矩阵运算、数据可视化和算法开发于一体的环境对于实现和验证KNN这类算法有着天然的优势。它的语法贴近数学公式矩阵操作高效绘图功能强大能让我们把更多精力放在算法逻辑和理解上而不是纠结于底层编程细节。这个“源码数据”的压缩包就是一个完整的实践单元我们可以通过它来亲手搭建、运行并深入理解KNN的每一个步骤。接下来我将带你一起拆解这个项目。我们不会止步于运行现成的代码而是会深入探讨KNN的核心思想到底是什么在Matlab中如何一步步实现它代码里的每一行都在做什么如何准备和看待那份“数据”在实际操作中有哪些参数需要精心调校又有哪些“坑”在等着我们无论你是刚开始接触机器学习还是想巩固Matlab编程相信这份从实战出发的拆解都能给你带来收获。2. KNN算法核心原理与Matlab实现优势2.1 KNN算法的工作机制距离、邻居与投票要动手实现必须先吃透原理。KNN算法的工作流程可以清晰地分为三步距离计算、邻居选取和决策投票。第一步距离计算。这是KNN的基石。算法需要量化数据点之间的“相似度”或“接近程度”这通常通过距离度量来实现。最常用的是欧几里得距离也就是我们中学学的两点间直线距离。在二维或三维空间里很好想象对于更高维的特征空间其公式是通用的。假设我们有两个数据点A和B各有n个特征那么它们之间的欧氏距离就是每个特征差值的平方和再开方。除了欧氏距离曼哈顿距离各维度绝对差之和、切比雪夫距离各维度绝对差的最大值以及余弦相似度衡量方向而非绝对距离等也是常见的选择。不同的距离度量适用于不同的数据特性比如曼哈顿距离对异常值更不敏感。第二步邻居选取。计算完新样本点到训练集中所有样本点的距离后接下来就是“找朋友”。我们将所有距离从小到大排序然后选出距离最小的前K个训练样本。这个K就是算法名称中的“K”是一个需要我们自己设定的超参数。K的大小直接影响模型的性能K太小比如K1模型会非常敏感容易受到噪声数据的影响导致过拟合K太大则可能将实际上不相似的远距离样本也包含进来使得决策边界模糊导致欠拟合。第三步决策投票分类或平均回归。找到K个最近的邻居后就要听它们的“意见”了。对于分类任务这K个邻居各自属于哪个类别是已知的。我们采用“少数服从多数”的原则将这K个邻居中出现次数最多的类别赋给新样本。这就是所谓的“投票法”。有时为了更精细还可以根据距离的远近赋予邻居不同的权重距离越近权重越大进行加权投票。对于回归任务目标是预测一个连续值。此时我们将这K个邻居的标签值真实值直接取算术平均值作为新样本的预测值。同样也可以进行距离加权平均。KNN的这种“记忆式”学习使其模型非常简单——就是存储整个训练集。预测阶段的计算开销很大因为每次预测都需要计算与所有训练样本的距离这在数据量巨大时会成为瓶颈这也是KNN被称为“懒惰学习”的原因。2.2 为什么选择Matlab来实现KNN看到“Matlab实现”你可能会问用Python的scikit-learn不是一行代码就搞定吗确实对于快速应用现成的库是最高效的。但对于学习和深入理解算法本质亲手用Matlab实现一遍价值巨大。首先Matlab的矩阵化运算与KNN的天生契合。KNN中核心的距离计算本质上就是矩阵运算。Matlab在处理矩阵和向量时极其高效和简洁。例如计算一个测试样本到所有训练样本的欧氏距离在Matlab中往往可以通过一次矩阵减法、点乘和求和操作完成无需显式的多层循环。这种写法不仅代码优雅执行速度也往往快于新手写的循环版本。通过实现这个过程你能深刻体会到向量化编程的威力。其次无“黑箱”的透明实现。使用scikit-learn的KNeighborsClassifier你调用的fit和predict方法背后封装了所有细节。而自己用Matlab从零写你需要亲自设计函数接口、组织数据、实现距离计算、排序、投票等每一个环节。这个过程中你会被迫思考训练数据怎么存距离矩阵会不会太大排序用sort函数时要注意什么如何处理平票情况这些都是在调用库函数时容易被忽略但对理解算法至关重要的细节。再者强大的可视化调试能力。Matlab的绘图功能是教学和调试的利器。对于二维或三维数据你可以轻松地将训练数据点用不同颜色/形状代表不同类别、新样本点以及根据K值画出的“邻居圈”或决策边界可视化出来。亲眼看到随着K值变化决策边界如何从崎岖不平变得平滑这种直观感受是任何文字描述都无法替代的。它让你对“过拟合”和“欠拟合”有了最形象的认识。最后对数学思维的锻炼。Matlab的语法鼓励你用数学和矩阵的思维方式去解决问题。实现KNN的过程就是将算法数学描述翻译成高效矩阵运算的过程这能显著提升你将理论算法落地为实际代码的能力。所以这个Matlab版的KNN项目其核心价值不在于提供一个可以替代scikit-learn的工具而在于提供一个深度理解算法和锻炼科学计算编程能力的沙箱。3. 源码深度拆解从函数到每一行代码拿到源码我们不应该直接运行了事。让我们像一个工程师审查代码一样逐部分拆解理解作者的设计意图和实现细节。一个典型的KNN Matlab实现通常会包含几个核心函数距离计算函数、KNN预测函数以及一个主脚本用于组织流程。我们假设源码结构大致如此。3.1 数据加载与预处理模块任何机器学习项目的起点都是数据。源码中一般会有一个load_data.m脚本或直接在主脚本里使用load命令读取数据文件可能是.mat,.csv,.txt格式。% 假设数据保存在 ‘data.mat‘ 文件中包含变量 train_data, train_label, test_data, test_label load(data.mat); % 或者从CSV读取 % data readmatrix(dataset.csv); % train_data data(1:800, 1:end-1); % 前800行作为训练特征 % train_label data(1:800, end); % 最后一列是标签 % test_data data(801:end, 1:end-1); % test_label data(801:end, end);关键操作与注意事项数据审视加载后立即使用size()、whos命令查看数据的维度样本数×特征数用unique()查看标签的种类。这是了解数据集基本情况的第一步。特征缩放标准化/归一化这是KNN中至关重要且极易被忽略的一步。因为KNN基于距离如果某个特征的值域范围很大比如“年薪”从0到百万而另一个特征值域很小比如“年龄”0-100那么值域大的特征将在距离计算中占据绝对主导地位这显然是不合理的。因此通常需要对特征进行标准化使均值为0标准差为1或归一化缩放到[0,1]区间。% 标准化 (Z-score) [train_data, mu, sigma] zscore(train_data); % 计算训练集的均值和标准差 test_data (test_data - mu) ./ sigma; % 使用训练集的参数标准化测试集 % 归一化 (Min-Max) train_min min(train_data); train_max max(train_data); train_data (train_data - train_min) ./ (train_max - train_min); test_data (test_data - train_min) ./ (train_max - train_min);注意必须使用训练集计算得到的缩放参数均值、标准差、最小值、最大值来变换测试集绝不能将训练集和测试集混合在一起计算参数再缩放。这是数据泄露的典型错误会导致模型评估结果过于乐观。3.2 核心距离计算函数的实现距离计算是KNN的性能瓶颈也是优化重点。一个高效的实现会利用Matlab的广播机制。function distances euclidean_dist(X_train, X_test) % 计算测试集X_test中每个样本到训练集X_train中所有样本的欧氏距离 % 输入: X_train - m x n 矩阵 (m个训练样本 n个特征) % X_test - p x n 矩阵 (p个测试样本 n个特征) % 输出: distances - p x m 矩阵 distances(i,j) 是第i个测试样本到第j个训练样本的距离 [m, n] size(X_train); p size(X_test, 1); distances zeros(p, m); % 预分配内存提升效率 % 方法一利用矩阵运算和广播避免双层循环 (高效) for i 1:p % 计算第i个测试样本与所有训练样本的差平方按特征求和再开方 diff X_train - X_test(i, :); % 广播m x n 矩阵 squared_diff diff .^ 2; sum_squared sum(squared_diff, 2); % 按行求和得到 m x 1 向量 distances(i, :) sqrt(sum_squared); end % 方法二更向量化的写法使用repmat可能更耗内存但代码更简洁 % 这里不展开但实际项目中对于特别大的数据需要权衡内存和速度。 end实现要点解析预分配内存distances zeros(p, m);这一行至关重要。在Matlab中如果不预分配而直接在循环中扩展数组每次迭代都会导致内存重新分配和复制当数据量大时速度会急剧下降。向量化操作循环for i 1:p是针对测试样本的而对训练样本m的计算是通过矩阵运算一次性完成的。这比双层循环对i和j都循环要高效得多。距离度量的扩展如果要实现曼哈顿距离只需将.^ 2和sqrt替换为abs取绝对值和求和。可以在函数中增加一个参数metric来控制距离类型。3.3 KNN预测函数的完整实现这是算法的中枢它调用距离计算函数并完成排序和投票。function [predicted_labels, neighbor_indices] knn_predict(X_train, y_train, X_test, K, metric) % KNN预测函数 % 输入: X_train, y_train - 训练数据和标签 % X_test - 测试数据 % K - 邻居数量 % metric - 距离度量类型如 ‘euclidean‘, ‘manhattan‘ % 输出: predicted_labels - 测试集的预测标签 % neighbor_indices - 每个测试样本的K个最近邻索引可选用于分析 if nargin 5 metric euclidean; % 默认欧氏距离 end [num_test, ~] size(X_test); predicted_labels zeros(num_test, 1); neighbor_indices zeros(num_test, K); % 存储邻居索引 % 1. 计算距离矩阵 dist_matrix pdist2(X_train, X_test, metric); % 如果使用内置函数更高效 % 或者使用自定义的 euclidean_dist 函数: dist_matrix euclidean_dist(X_train, X_test); % 2. 对每个测试样本找到最近的K个邻居 for i 1:num_test [~, sorted_indices] sort(dist_matrix(:, i)); % 对距离排序获取索引 k_nearest_indices sorted_indices(1:K); neighbor_indices(i, :) k_nearest_indices; % 记录邻居索引 % 3. 获取这K个邻居的标签 k_nearest_labels y_train(k_nearest_indices); % 4. 投票决定预测标签 (处理分类任务) % 使用 mode 函数找出出现次数最多的标签 predicted_labels(i) mode(k_nearest_labels); % 注意mode函数在平票时返回最小值。如果需要更复杂的平票处理需要自己实现投票逻辑。 % 例如 % unique_labels unique(k_nearest_labels); % counts histcounts(k_nearest_labels, [unique_labels; max(unique_labels)1]); % max_count max(counts); % candidates unique_labels(counts max_count); % predicted_labels(i) candidates(randi(length(candidates))); % 随机选择一个 end end代码细节与陷阱内置函数pdist2Matlab的统计与机器学习工具箱提供了pdist2函数用于计算两组观测值之间的两两距离。它经过高度优化支持多种距离度量通常比自己写的循环版本快很多。强烈建议在确认有该工具箱后使用它。dist_matrix pdist2(X_train, X_test, metric);返回的是一个 m x p 的矩阵注意其维度与之前自定义函数的输出是转置关系。排序与索引[~, sorted_indices] sort(dist_matrix(:, i));这里我们不需要排序后的具体距离值用~忽略只需要排序后的索引因为我们需要的是邻居在训练集中的位置。mode函数的平票问题这是实现中的一个关键陷阱。Matlab的mode函数在出现多个众数即平票时默认返回其中最小的那个值。这在很多情况下可能不是我们期望的行为。例如两类平票可能我们希望随机选择其中一个或者结合距离加权。因此在生产环境或严肃的实验中需要自己实现一个更稳健的投票函数如上文注释中所写。回归任务修改如果是回归问题将投票步骤改为求平均即可predicted_labels(i) mean(k_nearest_labels);。3.4 主脚本与评估流程主脚本main.m负责将各个模块串联起来形成一个完整的实验流程。%% 1. 清空与初始化 clear; clc; close all; %% 2. 加载与预处理数据 load(iris_data.mat); % 示例鸢尾花数据集 % 假设数据已分为 trainX, trainY, testX, testY % 特征标准化 [trainX_norm, mu, sigma] zscore(trainX); testX_norm (testX - mu) ./ sigma; %% 3. 设置K值并调用KNN预测 K 5; % 尝试不同的K值如 1, 3, 5, 7, 10... predicted_labels knn_predict(trainX_norm, trainY, testX_norm, K, euclidean); %% 4. 模型评估 % 计算准确率 accuracy sum(predicted_labels testY) / length(testY); fprintf(K %d 时测试集准确率为%.2f%%\n, K, accuracy * 100); % 生成混淆矩阵 (需要深度学习工具箱或自己实现) % figure; plotconfusion(categorical(testY), categorical(predicted_labels)); % 自己计算混淆矩阵 unique_labels unique(testY); conf_mat zeros(length(unique_labels)); for i 1:length(testY) row_idx find(unique_labels testY(i)); col_idx find(unique_labels predicted_labels(i)); conf_mat(row_idx, col_idx) conf_mat(row_idx, col_idx) 1; end disp(混淆矩阵); disp(conf_mat); %% 5. 可视化针对二维特征 if size(trainX_norm, 2) 2 figure; gscatter(trainX_norm(:,1), trainX_norm(:,2), trainY); % 绘制训练数据 hold on; gscatter(testX_norm(:,1), testX_norm(:,2), predicted_labels, kr, xo); % 绘制测试数据及预测 xlabel(Feature 1 (Normalized)); ylabel(Feature 2 (Normalized)); title(sprintf(KNN Classification Result (K%d), K)); legend(Location, best); hold off; end这个主脚本展示了一个标准的机器学习工作流数据准备 - 模型训练对于KNN就是存储数据- 预测 - 评估 - 可视化。你可以通过修改K值反复运行第3、4步来观察模型性能的变化。4. 数据理解、处理与模型调优实战有了代码骨架我们需要用“数据”来赋予其生命。源码包里的数据是我们一切工作的基础。4.1 剖析你的数据集以经典鸢尾花数据集为例很多教学用的KNN源码包会附带像鸢尾花Iris这样的经典数据集。它包含150个样本每个样本有4个特征花萼长度、花萼宽度、花瓣长度、花瓣宽度标签是3种鸢尾花的品种。首先加载并观察数据load fisheriris; % Matlab内置鸢尾花数据集 X meas; % 特征矩阵 150x4 Y species; % 标签细胞数组 150x1 % 将文本标签转为数字标签 [~, ~, Y_num] unique(Y); % Y_num现在是 1,2,3 的数字标签使用summary、histogram或gscatter对特征两两组合来查看特征分布和类别分离情况。你会发现花瓣长度和花瓣宽度这两个特征对区分种类非常有效。接着划分训练集和测试集。这是评估模型泛化能力的关键。绝对不能用全部数据做训练然后又用它来测试那会得到接近100%的虚假准确率。rng(42); % 设置随机种子确保结果可复现 cv cvpartition(Y_num, HoldOut, 0.3); % 70%训练30%测试 trainIdx cv.training; testIdx cv.test; X_train X(trainIdx, :); Y_train Y_num(trainIdx); X_test X(testIdx, :); Y_test Y_num(testIdx);使用cvpartition可以方便地进行各种数据划分包括留出法Hold-out、K折交叉验证K-fold等。4.2 核心超参数K的选择与调优K是KNN唯一的、也是最重要的超参数。选择K的过程就是模型调优的过程。1. 肘部法则Elbow Method与交叉验证最可靠的方法是使用交叉验证。我们将训练集进一步分成多份轮流用其中一份做验证其余做训练来评估不同K值下的平均性能。K_range 1:2:20; % 尝试一系列K值取奇数避免平票 cv_accuracy zeros(length(K_range), 1); for k_idx 1:length(K_range) K K_range(k_idx); % 使用5折交叉验证 cv cvpartition(Y_train, KFold, 5); fold_acc zeros(cv.NumTestSets, 1); for fold 1:cv.NumTestSets trainIdx_fold cv.training(fold); valIdx_fold cv.test(fold); X_train_fold X_train(trainIdx_fold, :); Y_train_fold Y_train(trainIdx_fold); X_val_fold X_train(valIdx_fold, :); Y_val_fold Y_train(valIdx_fold); % 标准化注意用训练折的参数标准化验证折 [X_train_fold_norm, mu_fold, sigma_fold] zscore(X_train_fold); X_val_fold_norm (X_val_fold - mu_fold) ./ sigma_fold; % 预测并计算准确率 pred_fold knn_predict(X_train_fold_norm, Y_train_fold, X_val_fold_norm, K); fold_acc(fold) sum(pred_fold Y_val_fold) / length(Y_val_fold); end cv_accuracy(k_idx) mean(fold_acc); end % 绘制K值与交叉验证准确率的关系图 figure; plot(K_range, cv_accuracy, bo-, LineWidth, 2); xlabel(K值); ylabel(交叉验证平均准确率); title(K值选择 - 肘部法则); grid on;在得到的曲线上准确率通常会随着K增大先上升后下降。我们寻找那个“肘点”——准确率在达到一个相对高点后开始趋于平稳或下降的转折点对应的K值往往是一个较好的选择。2. 领域知识与经验法则对于类别数较少如2类的问题K通常取一个较小的奇数如3,5,7。对于类别数较多的问题K值可以适当增大以确保投票有足够的代表性。一个常用的启发式方法是设置 K sqrt(训练样本数)但最终仍需通过交叉验证确认。4.3 距离度量的选择与影响距离度量定义了数据空间的几何形状。欧氏距离是最常见的但它假设各维度是独立且同等重要的。如果你的数据维度具有不同的物理意义或量纲即使经过了标准化欧氏距离也可能不是最优的。曼哈顿距离对异常值比欧氏距离更不敏感。如果你的数据中有许多零值稀疏数据曼哈顿距离有时效果更好。余弦相似度衡量的是方向的一致性而非绝对距离。在文本分类如TF-IDF向量或高维稀疏数据中非常常用。对于KNN我们通常用1 - 余弦相似度作为距离。马氏距离考虑了特征之间的相关性是欧氏距离在多维空间中的推广但计算成本更高。在Matlab中使用pdist2函数可以轻松切换这些度量‘euclidean‘,‘cityblock‘曼哈顿,‘cosine‘,‘mahalanobis‘等。一个实用的做法是将距离度量的选择也纳入交叉验证的网格搜索中与K值一同优化。4.4 特征工程提升KNN性能的关键KNN的性能极度依赖于特征空间的质量。糟糕的特征会导致“垃圾进垃圾出”。特征缩放前文已强调这是必须做的步骤。不缩放值域大的特征会“淹没”值域小的特征。特征选择不是所有特征都是有用的。冗余或无关的特征会增加计算量并引入噪声降低模型性能这被称为“维度灾难”的负面影响之一。可以使用过滤法如基于相关系数、包裹法如递归特征消除或嵌入法来选择对分类最有用的特征子集。在Matlab中可以使用fsrftest秩和检验或relieff等函数进行特征权重排序。降维如果特征数量非常多成百上千即使经过选择高维空间中的距离也会变得失去意义所有点对之间的距离都趋于相似。此时可以考虑使用主成分分析PCA或线性判别分析LDA等降维方法将数据投影到低维、信息量最大的子空间中再进行KNN分类。Matlab的pca函数可以很方便地实现这一点。% 使用PCA降维示例 [coeff, score, latent] pca(X_train_norm); % latent是主成分的方差贡献可以决定保留多少维度 explained_variance_ratio cumsum(latent) / sum(latent); num_components find(explained_variance_ratio 0.95, 1); % 保留95%方差的成分 X_train_pca score(:, 1:num_components); % 用同样的变换处理测试集 X_test_pca (X_test_norm - mean(X_train_norm)) * coeff(:, 1:num_components); % 在降维后的数据上运行KNN pred_pca knn_predict(X_train_pca, Y_train, X_test_pca, K);5. 实战避坑指南与高级技巧纸上得来终觉浅绝知此事要躬行。在实际动手实现和运行KNN的过程中你会遇到各种各样的问题。下面是我总结的一些常见“坑”和应对技巧。5.1 性能瓶颈与优化策略问题当训练集样本数m或特征数n很大时预测速度会非常慢因为每次预测都需要计算O(m*n)量级的距离。优化策略使用高效的距离计算函数优先使用Matlab内置的pdist2或knnsearch函数它们底层由C/C实现并可能使用了多线程或更优的算法。降维如上节所述减少特征数n能显著降低计算量。使用KD-Tree或Ball Tree数据结构对于低维到中等维度数据例如20维可以使用空间划分数据结构来加速最近邻搜索。Matlab的knnsearch函数在指定‘NSMethod‘为‘kdtree‘时会自动构建KD-Tree。对于更高维数据Ball Tree可能更有效但Matlab内置支持有限。% 使用KD-Tree加速搜索 Mdl KDTreeSearcher(X_train_norm); % 构建搜索器 [Idx, D] knnsearch(Mdl, X_test_norm, ‘K‘, K); % Idx就是邻居索引D是距离 % 然后基于Idx进行投票即可考虑近似最近邻算法如果对精度要求不是极端严格可以研究如FLANNFast Library for Approximate Nearest Neighbors等库它们通过近似计算大幅提升搜索速度。5.2 类别不平衡问题的处理问题如果训练数据中某些类别的样本数远多于其他类别那么在进行“多数投票”时大类别会占据天然优势导致模型偏向于预测大类别而忽略小类别。解决方案加权投票不再是一人一票而是根据距离赋予权重。一个常见的方法是给每个邻居的投票权重设置为1 / (distance epsilon)epsilon是一个很小的数防止除零这样距离近的邻居话语权更重。这在一定程度上可以缓解问题因为小类别的样本如果更“靠近”测试点其投票权重会更大。% 在投票循环中实现加权投票 distances_i dist_matrix(sorted_indices(1:K), i); % 获取K个最近邻的距离 weights 1 ./ (distances_i eps); % 计算权重 % 为每个候选类别计算加权票数 unique_labels unique(y_train); weighted_votes zeros(size(unique_labels)); for label_idx 1:length(unique_labels) mask (k_nearest_labels unique_labels(label_idx)); weighted_votes(label_idx) sum(weights(mask)); end [~, max_idx] max(weighted_votes); predicted_labels(i) unique_labels(max_idx);数据重采样过采样复制小类别的样本或使用SMOTE等算法生成合成样本。欠采样随机丢弃一些大类别的样本。 Matlab的datasample函数可以用于随机采样。更高级的方法可以使用fitcsvm等函数进行集成学习。使用不同的评估指标在类别不平衡时准确率Accuracy具有欺骗性。一个把所有样本都预测为大类的模型也能获得高准确率。应该关注精确率Precision、召回率Recall和F1分数尤其是小类别的这些指标。Matlab的confusionmat函数可以帮你计算这些指标。5.3 多分类与回归任务适配多分类我们上面实现的投票法天然支持多分类无需修改。只需确保标签是数字或可比较的类别即可。回归任务将KNN用于预测连续值如房价、温度非常简单只需将投票步骤改为求K个邻居标签值的平均值或加权平均值。% 在KNN预测函数的回归分支 if task ‘regression‘ % 简单平均 predicted_value(i) mean(k_nearest_labels); % 或距离加权平均 % weights 1 ./ (distances_i eps); % predicted_value(i) sum(k_nearest_labels .* weights) / sum(weights); end评估指标也从准确率变为均方误差MSE、均方根误差RMSE或平均绝对误差MAE。5.4 模型保存与部署的思考KNN模型“训练”后其实就是保存了标准化参数mu,sigma和整个训练集X_train_norm,y_train。在部署时每次预测都需要加载这些数据并进行距离计算。部署注意事项内存占用训练集很大时模型文件会很大。需要考虑存储和加载的开销。预测延迟每次预测都是O(m*n)的计算对于实时性要求高的场景如毫秒级响应大数据集上的KNN可能不适用。模型更新如果需要在线学习新增数据KNN只需要将新数据加入到训练集中即可非常方便。但这也意味着模型会越来越大预测会越来越慢。需要设计一个机制来淘汰旧数据或进行数据摘要。一个简单的模型保存与加载示例如下% 保存模型 KNN_Model.mu mu; KNN_Model.sigma sigma; KNN_Model.X_train X_train_norm; KNN_Model.y_train y_train; KNN_Model.K optimal_K; KNN_Model.metric ‘euclidean‘; save(‘my_knn_model.mat‘, ‘KNN_Model‘); % 加载模型并预测 load(‘my_knn_model.mat‘, ‘KNN_Model‘); new_data_norm (new_raw_data - KNN_Model.mu) ./ KNN_Model.sigma; prediction knn_predict(KNN_Model.X_train, KNN_Model.y_train, new_data_norm, KNN_Model.K, KNN_Model.metric);通过以上五个部分的拆解我们从理论到代码从数据到调优完整地走了一遍基于Matlab实现KNN算法的全流程。这个“.rar”压缩包不再是一个黑盒而是一个可以任由你拆卸、改装和学习的教学模具。真正的掌握始于你关闭这篇文章打开Matlab亲手运行、修改并尝试解决自己遇到的新问题之时。本文还有配套的精品资源点击获取

相关新闻

2026/9/3 6:42:30

STM32智能小车工程闭环:从芯片选型到PID调参实战

简介:本资源是一套完整的STM32智能小车开发学习套件,面向嵌入式初学者、电子类专业学生及课程设计/毕业设计实践者,解决智能小车项目从硬件搭建、程序编写到功能验证的全流程学习需求。压缩包共248个文件,涵盖53个.h头文件与52个.…

2026/9/3 6:37:30

FreeModbus在STM32F103裸机环境实战部署指南

简介:本资源是一套完整的FreeModbus协议栈在STM32F103平台上的裸机移植工程,面向嵌入式初学者与工业通信开发工程师,解决Modbus RTU从零移植到Cortex-M3芯片的核心技术难点。压缩包共257个文件,含48个C源码(含stm32f10…

2026/9/3 6:52:31

基于BERT的细粒度文本情绪风格分类实战:从原理到部署

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 6:52:31

Hint家居AI助手:大模型驱动的智能房屋维护与装修规划

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 6:52:31

AI模型API智能路由:降本增效的Token调度策略与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 6:52:31

CAD图块在位编辑:不炸开也能改,所有实例同步更新

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 6:52:31

STM32F103嵌入式恒温控制系统工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 6:47:31

CrispVoice本地语音增强:隐私保护的AI音频处理实践

在远程会议、在线教学和内容创作日益普及的今天,语音质量直接影响沟通效率和专业形象。然而传统语音增强方案往往需要将音频上传到云端处理,带来隐私泄露风险。CrispVoice 作为一款开源本地语音增强工具,能够在完全离线环境下实现录音棚级别的…

2026/9/1 16:02:17

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/2 9:00:32

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/2 8:41:06

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/3 0:02:06

零基础装 OpenClaw 小龙虾 AI:Windows 一键部署教程与避坑要点

Windows 部署 OpenClaw 完整教程|本地 AI 智能体 5 分钟落地,环境配置一次搞定 版本说明:Windows 3.1.0 / Mac 2.7.9 写在前面 近两年开源 AI 领域有一款被称作「数字员工」的工具持续走热,它就是 OpenClaw,圈内人更习…

2026/9/3 0:02:06

Hermes Agent 本地部署新方案:Windows 整合包减少依赖报错

Windows 本地部署 Hermes 太麻烦?这版一键包 5 分钟快速跑通 很多人想体验 Hermes Agent,但真正开始部署时,往往会卡在环境配置这一步。 需要安装各类依赖、调试运行环境、处理路径问题,还容易遇到命令行报错、系统拦截、文件缺…

2026/9/3 0:02:06

实测 OpenClaw 一键包,5 分钟完成本地自动化环境搭建

OpenClaw 本地 AI 自动化工具部署指南|使用一键包规避环境配置难题 痛点:部署 AI 自动化工具常常要处理 Python、Node.js 各类依赖,版本冲突、环境配置耗费大量时间,OpenClaw 提供一键安装包,降低部署门槛。 适配系统&…

2026/9/2 1:15:22

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/2 1:15:22

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/2 1:15:20

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…