最近在做人脸识别毕业设计,用到模糊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
K-NN(K-Nearest Neighbor)算法的Matlab实现
原文:http://my.oschina.net/keyven/blog/523789