K最临近(K-Nearest Neighbors,KNN)方法是一种简单且直观的分类和回归算法,主要用于分类任务。其基本原理是用到表决的方法,找到距离其最近的K个样本,然后通过K个样本的标签进行表决,预测结果给出的标签是表决多的一方。
在使用K最临近方法的时候,有两个方面可调:
一是K值的大小,K一般选用单数,这样不会导致在进行表决时出现概率相等的情况。
二是样本之间的距离,由于样本特征的分布不同,因此在描述两样本之间的距离时有多种方式可以描述,例如:欧氏距离(Euclidean Distance)、曼哈顿距离(Manhattan Distance)和闵可夫斯基距离(Minkowski Distance)等。而且往往由于选择的距离不同,对应的K值也不一样,大家可以根据自己的数据特点尝试用不用的距离构建分类模型。本文提供了这些方法供大家选择。
在matlab中实现K最临近方法构建分类模型的代码如下:
labels = res(:, 1); % 第一列是标签
features = res(:, 2:end); % 后面的列是特征
features = zscore(features); %归一化处理
% %% 欧式距离
%
%
% % 设置 K 值
% K = 7;
%
% % 初始化分类准确度
% accuracy = 0;
%
% % 留一交叉验证
% for i = 1:size(features, 1)
% % 从样本中选择一个作为验证样本,其余作为训练样本
% validation_sample = features(i, :);
% validation_label = labels(i);
%
% train_samples = features([1:i-1, i+1:end], :);
% train_labels = labels([1:i-1, i+1:end]);
%
% % 计算验证样本与训练样本的距离
% distances = sqrt(sum((train_samples - validation_sample).^2, 2));
%
% % 寻找最近的 K 个邻居
% [~, idx] = mink(distances, K);
%
% % 投票确定验证样本的类别
% predicted_label = mode(train_labels(idx));
%
% % 检查预测结果是否正确
% if predicted_label == validation_label
% accuracy = accuracy + 1;
% end
% end
%
% % 计算分类准确度
% accuracy = accuracy / size(features, 1);
% disp(['分类准确度:', num2str(accuracy)]);
%
%
% % 曼哈顿距离
%
%
% % 设置 K 值
% K = 9;
%
% % 初始化分类准确度
% accuracy = 0;
%
% % 留一交叉验证
% for i = 1:size(features, 1)
% % 从样本中选择一个作为验证样本,其余作为训练样本
% validation_sample = features(i, :);
% validation_label = labels(i);
%
% train_samples = features([1:i-1, i+1:end], :);
% train_labels = labels([1:i-1, i+1:end]);
%
% % 计算曼哈顿距离
% distances = sum(abs(train_samples - validation_sample), 2);
%
% % 寻找最近的 K 个邻居
% [~, idx] = mink(distances, K);
%
% % 投票确定验证样本的类别
% predicted_label = mode(train_labels(idx));
%
% % 检查预测结果是否正确
% if predicted_label == validation_label
% accuracy = accuracy + 1;
% end
% end
%
% % 计算分类准确度
% accuracy = accuracy / size(features, 1);
% disp(['分类准确度:', num2str(accuracy)]);
% %% 闵可夫斯基距离
%
% % 设置 K 值
% K = 5;
%
% % 初始化分类准确度
% accuracy = 0;
%
% % 留一交叉验证
% for i = 1:size(features, 1)
% % 从样本中选择一个作为验证样本,其余作为训练样本
% validation_sample = features(i, :);
% validation_label = labels(i);
%
% train_samples = features([1:i-1, i+1:end], :);
% train_labels = labels([1:i-1, i+1:end]);
%
% % 计算闵可夫斯基距离
% distances = pdist2(train_samples, validation_sample, 'minkowski', 1); % p=1, 曼哈顿距离
%
% % 寻找最近的 K 个邻居
% [~, idx] = mink(distances, K);
%
% % 投票确定验证样本的类别
% predicted_label = mode(train_labels(idx));
%
% % 检查预测结果是否正确
% if predicted_label == validation_label
% accuracy = accuracy + 1;
% end
% end
%
% % 计算分类准确度
% accuracy = accuracy / size(features, 1);
% disp(['分类准确度:', num2str(accuracy)]);
%
%% KD树搜索方法
% 设置 K 值
K = 5;
% 初始化分类准确度
accuracy = 0;
predictedScores=zeros(56,2);
% 留一交叉验证
for i = 1:size(features, 1)
% 从样本中选择一个作为验证样本,其余作为训练样本
validation_sample = features(i, :);
validation_label = labels(i);
train_samples = features([1:i-1, i+1:end], :);
train_labels = labels([1:i-1, i+1:end]);
% 创建KD树
mdl = fitcknn(train_samples, train_labels, 'NumNeighbors', K, 'Distance', 'euclidean', 'NSMethod', 'kdtree');
% 预测验证样本的类别
%predicted_label = predict(mdl, validation_sample);
[predicted_label,predictedScore] = predict(mdl, validation_sample);
predictedScores(i,:)=predictedScore;
% 检查预测结果是否正确
if predicted_label == validation_label
accuracy = accuracy + 1;
end
end
% 计算分类准确度
accuracy = accuracy / size(features, 1);
disp(['分类准确度:', num2str(accuracy)]);