Algorithm 在散乱数据中寻找区域
我在Nx3矩阵中有许多分散的数据集,下面是一个用Algorithm 在散乱数据中寻找区域,algorithm,matlab,Algorithm,Matlab,我在Nx3矩阵中有许多分散的数据集,下面是一个用scatter3绘制的简单示例(): 我的每个数据集都有任意数量的区域/blob;例如,上面的例子有4个 有没有人知道一种简单的方法,可以通过编程来查找这种数据形式中的区域数 我最初的想法是使用delaunay三角剖分,convexHull方法,但没有任何数据处理,这仍然只能找到整个绘图的外部体积,而不是每个区域 我的下一个想法是获取每个点的最近邻统计数据,询问它是否在另一个点的网格大小距离内,然后将其中的数据集中到单独的斑点/簇中 有没有一个我不
scatter3
绘制的简单示例():
我的每个数据集都有任意数量的区域/blob;例如,上面的例子有4个
有没有人知道一种简单的方法,可以通过编程来查找这种数据形式中的区域数
我最初的想法是使用delaunay三角剖分
,convexHull
方法,但没有任何数据处理,这仍然只能找到整个绘图的外部体积,而不是每个区域
我的下一个想法是获取每个点的最近邻统计数据,询问它是否在另一个点的网格大小距离内,然后将其中的数据集中到单独的斑点/簇中
有没有一个我不知道的更高级别的Matlab函数可以帮助我,或者有没有人对如何从这样的数据中提取区域计数有更好的建议?确定数据集中不同簇的数量是一个棘手的问题,可能比我们第一眼看到的要困难。事实上,像k-means这样的算法在很大程度上依赖于此。有一篇很好的文章,但是没有清晰简单的方法 其中提到的方法似乎比较容易实现,但计算成本可能较高。本质上,您可以尝试使用不同数量的集群,并选择方差增长不大且趋于平稳的集群
此外,集群的概念需要明确定义-如果放大任何一个blob显示出与图片中的角结构相似的结构会怎么样?确定数据集中不同集群的数量是一个棘手的问题,可能比我们第一眼看到的要难。事实上,像k-means这样的算法在很大程度上依赖于此。有一篇很好的文章,但是没有清晰简单的方法 其中提到的方法似乎比较容易实现,但计算成本可能较高。本质上,您可以尝试使用不同数量的集群,并选择方差增长不大且趋于平稳的集群
此外,集群的概念需要明确定义-如果放大任何一个blob显示出与图片中的角结构相似的结构,该怎么办?听起来您需要一个集群算法。幸运的是,MATLAB提供了许多现成的功能。有很多算法可供选择,听起来你需要一些事先不知道集群数量的算法,对吗 如果是这种情况,并且您的数据与您的示例一样“好”,我建议结合一种技术,按照建议正确选择“k”
当然还有其他选项,我建议您在MATLAB中学习更多关于集群选项的知识,这里有一个很好的例子供您阅读 听起来你需要一个聚类算法。幸运的是,MATLAB提供了许多现成的功能。有很多算法可供选择,听起来你需要一些事先不知道集群数量的算法,对吗 如果是这种情况,并且您的数据与您的示例一样“好”,我建议结合一种技术,按照建议正确选择“k”
当然还有其他选项,我建议您在MATLAB中学习更多关于集群选项的知识,这里有一个很好的例子供您阅读 我建议实施高斯混合模型的“轻”版本。 让每个点为一个立方体“投票”。在上面的示例中,以(-1.5,-1.5,0)为中心的所有点
每一个都会在正方形[-1,-2]x[-1,-2]x[0.2,-0.2]上加一个+1。最后,您可以分析投票矩阵中的峰值。我建议实现高斯混合模型的“光”版本。 让每个点为一个立方体“投票”。在上面的示例中,以(-1.5,-1.5,0)为中心的所有点
每一个都会在正方形[-1,-2]x[-1,-2]x[0.2,-0.2]上加一个+1。最后,您可以分析投票矩阵中的峰值。为了完整性起见,对于这个问题(我已经构建了)有一个比分层聚类更简单的答案;这提供了更好的结果,可以区分1个集群或2个集群(我无法用MarkV的建议解决这个问题)。这假设您的数据位于已知大小的常规网格上,并且您有未知数量的群集,这些群集之间至少间隔2*(网格大小):
%的想法如下:
%*我们有一个已知的网格大小dx。
%*随机点[也可以是极小值(1,:)]将位于
%如果列表中的任何其他值位于dx之外(具有一个维度
%变化),sqrt(2)*dx(二维变化)或sqrt(3)*dx(三维变化)
%尺寸不同)。
%*将这些对象链接在一起,直到找到所有对象,任意距离
%现在忽略集群的sqrt(3)*dx以外的部分。
%*将此群集放在一边,重复此操作,直到没有剩余最小值数据。
函数[blobs,clusterIdx]=findClusters(极小值,dx)
%问题设置
dx2=sqrt(2)*dx;
dx3=sqrt(3)*dx;
eqf=@(列表,dx,dx2,dx3)(abs(列表dx)<0.001;abs(列表dx2)<0.001;abs(列表dx3)<0.001);
notDoneClust=true;
notDoneMinima=true;
clusterIdx=零(大小(最小值,1),1);
点=最小值(1,:);
列表=最小值(2:结束,:);
blobs=0;
而不是多奈米玛
集群=nan(1,3);
而不是不信任
[~,dist]=knSearch(点,列表);%数据中每个点之间的所有距离
nnidx=eqf(距离,dx,dx2,dx3);%查找要指向的nn值的索引
群集=类别(1,群集,点,列表(nnidx,:);%将点添加到当前群集
点=列表(nnidx,:);%要检查的点现在是相对于初始点nn的所有值
列表=列表(~nnidx,:);%列表现在是不在该列表中的所有其他值
notDoneClust=~isempty(点);%如果有
% Idea is as follows:
% * We have a known grid size, dx.
% * A random point [may as well be minima(1,:)] will be in a cluster of
% values if any others in the list lie dx away (with one dimention
% varied), sqrt(2)*dx (two dimensions varied) or sqrt(3)*dx (three
% dimensions varied).
% * Chain these objects together until all are found, any with distances
% beyond sqrt(3)*dx of the cluster are ignored for now.
% * Set this cluster aside, repeat until no minima data is left.
function [blobs, clusterIdx] = findClusters(minima,dx)
%problem setup
dx2 = sqrt(2)*dx;
dx3 = sqrt(3)*dx;
eqf = @(list,dx,dx2,dx3)(abs(list-dx) < 0.001 | abs(list-dx2) < 0.001 | abs(list-dx3) < 0.001);
notDoneClust = true;
notDoneMinima = true;
clusterIdx = zeros(size(minima,1),1);
point = minima(1,:);
list = minima(2:end,:);
blobs = 0;
while notDoneMinima
cluster = nan(1,3);
while notDoneClust
[~, dist] = knnsearch(point,list); %All distances to each other point in data
nnidx = eqf(dist,dx,dx2,dx3); %finds indexes of nn values to point
cluster = cat(1,cluster,point,list(nnidx,:)); %add points to current cluster
point = list(nnidx,:); %points to check are now all values that are nn to initial point
list = list(~nnidx,:); %list is now all other values that are not in that list
notDoneClust = ~isempty(point); %if there are no more points to check, all values of the cluster have been found
end
blobs = blobs+1;
clusterIdx(ismemberf(minima,cluster(2:end,:),'rows')) = blobs;
%reset points and list for a new cluster
if ~isempty(list)
if length(list)>1
point = list(1,:);
list = list(2:end,:);
notDoneClust = true;
else
%point is a cluster of its own. Don't reset loops, add point in
%as a cluster and exit (NOTE: I have yet to test this portion).
blobs = blobs+1;
clusterIdx(ismemberf(minima,point,'rows')) = blobs;
notDoneMinima = false;
end
else
notDoneMinima = false;
end
end
end