matlab中的KNN算法
Posted
技术标签:
【中文标题】matlab中的KNN算法【英文标题】:KNN algo in matlab 【发布时间】:2012-06-07 00:00:59 【问题描述】:我正在研究拇指识别系统。我需要实现 KNN 算法来对我的图像进行分类。根据this,它只有2个测量值,通过它计算找到最近邻居的距离,但在我的例子中,我有400张25 X 42的图像,其中200张用于训练,200张用于测试。我正在寻找几个小时,但我没有找到找到点之间距离的方法。
编辑:
我已将第 200 张图像重新整形为 1 X 1050,并将它们存储在 200 X 1050 的矩阵 trainingData
中。同样,我制作了 testingData
。
【问题讨论】:
无法打开您的链接,如果您搜索“上传文件”,您会发现很多托管替代方案 我想找到点之间的距离,以便我可以应用 k-nn 算法。 【参考方案1】:这里是k近邻分类的图解代码(使用的一些函数需要统计工具箱):
%# image size
sz = [25,42];
%# training images
numTrain = 200;
trainData = zeros(numTrain,prod(sz));
for i=1:numTrain
img = imread( sprintf('train/image_%03d.jpg',i) );
trainData(i,:) = img(:);
end
%# testing images
numTest = 200;
testData = zeros(numTest,prod(sz));
for i=1:numTest
img = imread( sprintf('test/image_%03d.jpg',i) );
testData(i,:) = img(:);
end
%# target class (I'm just using random values. Load your actual values instead)
trainClass = randi([1 5], [numTrain 1]);
testClass = randi([1 5], [numTest 1]);
%# compute pairwise distances between each test instance vs. all training data
D = pdist2(testData, trainData, 'euclidean');
[D,idx] = sort(D, 2, 'ascend');
%# K nearest neighbors
K = 5;
D = D(:,1:K);
idx = idx(:,1:K);
%# majority vote
prediction = mode(trainClass(idx),2);
%# performance (confusion matrix and classification error)
C = confusionmat(testClass, prediction);
err = sum(C(:)) - sum(diag(C))
【讨论】:
谢谢先生。我告诉过你我有trainingData
的顺序为 200 X 1050。这意味着 200 是总图像,1050 是图像的尺寸(实际上是 25 X 42)。我的问题是如何用我的代码替换 trainClass = randi([1 5], [numTrain 1]);
。
@user1420026:这些是在执行分类(监督学习)时必须给出的类目标(每个实例的标签)..
这是我的标签数据labelData = zeros(200,1); labelData(1:100,:) = 0; labelData(101:200,:) = 1;
。那么这里怎么用呢?
@user1420026:这些正是训练数据的标签:trainData = labelData;
。然后对测试数据做同样的事情(如果你有它们——只有当你想像我在代码部分中那样测量分类器的性能时才需要测试标签)【参考方案2】:
如果要计算向量 a
和 b
之间的 Euclidean distance,只需使用 Pythagoras。在 Matlab 中:
dist = sqrt(sum((a-b).^2));
但是,您可能希望使用pdist
一次性计算矩阵中所有向量组合的值。
dist = squareform(pdist(myVectors, 'euclidean'));
我将列解释为要分类的实例,将行解释为潜在的邻居。不过这是任意的,您可以切换它们。
如果有单独的测试集,您可以使用pdist2
计算到训练集中实例的距离:
dist = pdist2(trainingSet, testSet, 'euclidean')
您可以使用此距离矩阵对向量进行 knn 分类,如下所示。我将生成一些随机数据作为示例,这将导致低(大约机会级别)准确性。但是当然你应该插入你的实际数据,结果可能会更好。
m = rand(nrOfVectors,nrOfFeatures); % random example data
classes = randi(nrOfClasses, 1, nrOfVectors); % random true classes
k = 3; % number of neighbors to consider, 3 is a common value
d = squareform(pdist(m, 'euclidean')); % distance matrix
[neighborvals, neighborindex] = sort(d,1); % get sorted distances
查看neighborvals
和neighborindex
矩阵,看看它们是否对您有意义。第一个是早期d
矩阵的排序版本,后者给出了对应的实例编号。请注意,自距离(在d
的对角线上)已浮动到顶部。我们对此不感兴趣(始终为零),因此我们将在下一步中跳过第一行。
assignedClasses = mode(neighborclasses(2:1+k,:),1);
所以我们在 k 个最近邻中分配最常见的类!
您可以将分配的班级与实际班级进行比较以获得准确度分数:
accuracy = 100 * sum(classes == assignedClasses)/length(classes);
fprintf('KNN Classifier Accuracy: %.2f%%\n', 100*accuracy)
或者做一个混淆矩阵,看看分类的分布:
confusionmat(classes, assignedClasses)
【讨论】:
knn 有什么功能吗?其实我想训练我的系统 你通过计算距离来“训练”(实际上没有必要,除非你想知道并比较训练集上的表现)KNN。您计算所有成对距离,然后找到离您要分类的实例最近(最小距离)的 K 个实例。将这些邻居中最常见的类分配给实例。 好吧,我通过对整个 knn 过程的解释来扩展我的答案。并且没有任何 for 循环! @Junuxx:当您有单独的训练/测试数据时,您应该使用 PDIST2 计算测试集中点与训练集中点之间的所有成对距离 @Amro:好建议,不知道pdist2
,但我会更新我的答案:)【参考方案3】:
是的,knn 有一个函数:knnclassify
调整您想要保留的邻居数量以获得最佳结果(使用混淆矩阵)。当然,这个函数会处理距离。
【讨论】:
并没有真正回答如何找到距离的问题,也没有阐明 knn 的工作原理,但除此之外是一个不错且简单的解决方案 :) KNN 是最简单的机器学习算法! K 表示“您考虑的个人周围要保留多少最近的邻居”,保留在这些邻居中更存在的类,以及距离,基本上是欧几里德距离......此外,user1420026 明确要求“功能knn”。 说实话,OP并没有在问题中明确要求knn函数,只是在以后的评论中。但除非这是家庭作业或一些学习项目,否则knnclassify
可能是 OP 使用最方便的东西。所以+1有用的功能和示例链接:)以上是关于matlab中的KNN算法的主要内容,如果未能解决你的问题,请参考以下文章