K-NN(K-Nearest Neighbor)算法的Matlab实现

前记

        最近在做人脸识别毕业设计,用到模糊KNN算法(FuzzyKNN,FKNN)。FKNN是在KNN基础上发展而来,上网搜寻博客缺乏该算法的资料,等有空写一篇该算法的详细介绍。本篇使用Matlab简单地实现KNN(未实现Kd-Tree算法)主要针对科研工作

代码实现

function y = knn(x, x_train, y_train, K)
% KNN K-Nearest Neighbors Algorithm
% Input:  x:        待分类预测点集
%         x_train:  训练点集
%         y_train:  训练点集标类
%         K:        K值
%
% Output: y:        待分类预测点集标类
%
% Author: Keyven_guo

[size_x,~] = size(x);    % 确定有多少个待分类预测点,不管这些点的特征维度

predicted_label = zeros(size_x,1); % 产生矩阵Matrix[size_x][1]并铺0
for i = 1:size_x
    [dist,neighbors] = top_K_neighbors(x_train,x(i,:),K); 
    % x(i,:)表示取矩阵x的第i行,:代表全部
    predicted_label(i) = keyclass(y_train(neighbors),max(y_train(neighbors)); 
    % y_train(neighbors)表示取下标∈neighbors的y_train元素
end

y = predicted_label;
end
function [dist, neighbors] = top_K_neighbors(x_train, y_train, x, K)
% Input:    x_train:    训练点集
%           y_train:    训练点集标类
%           x:          待分类预测点
%           K:          K值
%
% Output:   dist:       K个邻居距x的距离(升序排序)
%           neighbors:  K个邻居的原下标
%
% Author:   Keyven_guo

[size_x,~] = size(x_train);
test_mat = repmat(x,size_x,1); % 产生矩阵Matrix[size_x][1]并将值设为x
% 本例产生一个与x_train大小一样的矩阵,每一行为x的特征向量
dist_mat = (x_train-double(test_mat)).^2; % 欧式距离
dist_array = sum(dist_mat'); % 对dist_mat转置('表示转置矩阵)后使用sum函数,注意sum函数是对列求和
[dists,neighbors] = sort(dist_arry); % 对dist_arry排序并用neighbors记录下标的变化情况
dists = dists(1:K); % 取前k小
neighbors = neighbors(1:K);

end
function result = keyclass(k_labels, class_num)
% 类个数比较少,不想用map,直接用Hash数组来统计
%
% Author:    Keyven_guo

k = size(k_labels);
class_count = zeros(1,class_num);
for i=1:k
    class_index = k_labels(i) + 1;
    class_count(class_index) = class_count(class_index) + 1;
end

result = max(class_count);
result = result - 1;

end

后记

        实际开发中,如果不使用Kd-Tree的话,上述K近邻算法可以使用以下算法改进:

(1) ACM算法题中的寻找前k小元素(最大堆思路,适合海量数据处理,空间复杂度小,时间复杂度接近O(n);

(2) 数据结构Map

你可能感兴趣的:(matlab,knn,K-Nearest,Neighbors,K近邻算法)