机器学习(三)——K最临近方法构建分类模型(matlab)

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)]);