【发布时间】:2014-08-08 10:31:42
【问题描述】:
我正在使用 Matlab 中的 k-最近邻算法进行数据分析。我的数据由大约 11795 x 88 数据矩阵组成,其中行是观察值,列是变量。
我的任务是为 n 个选定的测试点找到 k 最近邻。目前我正在使用以下逻辑:
对于所有的测试点
LOOP all the data and find the k-closest neighbors (by euclidean distance)
换句话说,我循环了所有 n 个测试点。对于每个测试点,我通过欧几里得距离搜索数据(不包括测试点本身)中的 k 最近邻。对于每个测试点,这大约需要 k x 11794 次迭代。所以整个过程大约需要 n x k x 11794 次迭代。如果 n = 10000 且 k = 7,这将是大约 8.256 亿次迭代。
有没有更有效的方法来计算 k 近邻?现在大部分计算都会浪费,因为我的算法很简单:
计算到所有其他点的欧几里德距离,选取最近的点并排除最近的点,不再考虑 --> 计算到所有其他点的欧几里德距离并选取最近的点 --> 等等 -->等等。
有没有一种聪明的方法可以摆脱这种“浪费计算”?
目前这个过程在我的电脑上大约需要 7 个小时(3.2 GHz,8 GB RAM,64 位 Win 7)... :(
以下是一些明确说明的逻辑(这不是我的全部代码,但这是消耗性能的部分):
for i = 1:size(testpoints, 1) % Loop all the test points
neighborcandidates = all_data_excluding_testpoints; % Use the rest of the data excluding the test points in search of the k-nearest neighbors
testpoint = testpoints(i, :); % This is the test point for which we find k-nearest neighbors
kneighbors = []; % Store the k-nearest neighbors here.
for j = 1:k % Find k-nearest neighbors
bdist = Inf; % The distance of the closest neighbor
bind = 0; % The index of the closest neighbor
for n = 1:size(neighborcandidates, 1) % Loop all the candidates
if pdist([testpoint; neighborcandidates(n, :)]) < bdist % Check the euclidean distance
bdist = pdist([testpoint; neighborcandidates(n, :)]); % Update the best distance so far
bind = n; % Save the best found index so far
end
end
kneighbors = [kneighbors; neighborcandidates(bind, :)]; % Save the found neighbour
neighborcandidates(bind, :) = []; % Remove the neighbor from further consideration
end
end
【问题讨论】:
-
加个小例子说明清楚。
-
有很多循环——如果你只是在整个矩阵上运行
pdist2作为一个输入,然后将n观察的子集作为第二个输入矩阵,会发生什么?你的电脑能处理吗/你知道这需要多长时间吗?因为这样您就可以在一行中获得您正在寻找的所有元素的成对距离,并为每个n找到顶部的n观察结果应该非常简单...... -
嗨@Dan 我用
pdist2来计算距离。只用了不到一分钟。休息应该没问题=)所以这是一个显着的改进=) -
@jjepsuomi 没问题,我已经添加了一个答案,展示了我将如何使用它
-
@jjepsuomi 另请参阅我对使用 Matlab 内置的答案
knnsearch
标签: performance algorithm matlab nearest-neighbor