1

Nx3 行列に多数の散在するデータ セットがあります。プロットされた簡単な例をscatter3以下に示します (生の値のペーストビン): 明らかな領域を持つ分散データ 各データ セットには任意の数の領域/ブロブがあります。たとえば、上記の例には 4 があります。

この形式のデータの領域数をプログラムで見つける簡単な方法を知っている人はいますか?

私の最初のアイデアはdelaunayTriangulation,convexHullアプローチを使用することでしたが、データ処理を行わなくても、各領域ではなくプロット全体の外側のボリュームしか検出されません。

私が持っている次のアイデアは、各ポイントの最近傍統計を取得し、それが別のポイントのグリッドサイズの距離内にあるかどうかを尋ね、それらを別々のブロブ/クラスターにまとめることです。

ここで私を助けることができる、私が認識していないより高いレベルのMatlab関数はありますか、またはこのようなデータから領域カウントを引き出す方法についてより良い提案を持っている人はいますか?

4

4 に答える 4

1

クラスタリングアルゴリズムが必要なようです。幸いなことに、MATLAB には、すぐに使えるこれらの機能が多数用意されています。選択できるアルゴリズムはたくさんありますが、クラスターの数が事前にわからないものが必要なようですね。

これが事実であり、あなたのデータがあなたの例と同じくらい「いい」場合は、ここで提案されているように、「k」を適切に選択する手法と組み合わせたkmeansをお勧めします。

もちろん、他にもオプションがあります。MATLAB のクラスタリング オプションについて詳しく学ぶことをお勧めします。詳細については、こちらのリファレンスを参照してください。

于 2013-06-16T04:48:56.913 に答える
0

完全を期すために、階層的クラスタリングよりもはるかに簡単なこの問題 (私が構築したもの) に対する答えがあります。これにより、はるかに優れた結果が得られ、1 つのクラスターまたは 2 つのクラスターを区別できます (MarkV の提案では修正できなかった問題です)。これは、データが既知のサイズの規則的なグリッド上にあり、少なくとも 2*(グリッド サイズ) で区切られた不明な量のクラスターがあることを前提としています。

% 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

範囲外のデータは別のクラスターとしてマークされるため、この方法は一般的な意味でのデータのクラスター化には役に立たないことを十分に理解しています。とにかくこれが必要なので、これは単なるエッジケースのシナリオかもしれません。

于 2013-06-17T05:21:51.153 に答える
0

データセット内の異なるクラスターの数を決定することはトリッキーな問題であり、おそらく一見したよりも難しいでしょう。実際、k-means などのアルゴリズムはこれに大きく依存しています。ウィキペディアには素晴らしい記事がありますが、明確で簡単な方法はありません。

そこに記載されているElbowメソッドは、計算コストがかかる可能性がありますが、比較的簡単に実行できるようです。本質的には、異なる数のクラスターを使用して、説明された分散があまり大きくならず、横ばいになる数を選択することができます。

また、クラスターの概念を明確に定義する必要があります。ブロブのいずれかを拡大すると、写真の隅の構造と同様の構造が表示される場合はどうなるでしょうか?

于 2013-06-16T04:48:29.217 に答える
0

ガウス混合モデルの「軽量」バージョンを実装することをお勧めします。立方体に各ポイントを「投票」させます。上記の例では、(-1.5,-1.5,0) を中心とするすべての点は、正方形 [-1,-2]x[-1,-2]x[0.2,-0.2] にそれぞれ +1 を追加します。最後に、投票行列のピークを分析できます。

于 2013-06-16T06:17:06.230 に答える