あなたの質問は本当にクラスタリングに関するものであり、ID列はどのポイントがどのポイントに対応するかを決定することとは何の関係もないようです。
これを実現するための一般的なアルゴリズムは、k-meansクラスタリングです。ただし、あなたの質問は、クラスターの数が事前にわからないことを意味します。これは問題を複雑にし、この問題に関してStackOverflowですでに多くの質問があります。
- クラスターの数を知らなくてもKmeans?
- kmeansのクラスターサイズを自動的に計算する
- k-meansクラスタリングを使用する場合、kを決定するにはどうすればよいですか?
- K-MeansアルゴリズムでKを最適化する方法
- K-Meansアルゴリズム
残念ながら、これに対する「正しい」解決策はありません。ある特定の問題の2つのクラスターは、実際には別の問題の1つのクラスターと見なすことができます。これが、自分でそれを決定する必要がある理由です。
それでも、単純な(そしておそらく不正確な)ものを探している場合は、ユークリッド距離を尺度として使用できます。ポイント間の距離を計算し(たとえば、を使用してpdist
)、距離が特定のしきい値を下回るポイントをグループ化します。
例
%// Sample input
A = [1, 2.5, 3.5;
1, 85.1, 74.1;
2, 2.6, 3.4;
2, 86.0, 69.8;
3, 25.8, 32.9;
3, 84.4, 68.2;
4, 2.8, 3.2;
4, 24.1, 31.8;
4, 83.2, 67.4];
%// Cluster points
pairs = nchoosek(1:size(A, 1), 2); %// Rows of pairs
d = sqrt(sum((A(pairs(:, 1), :) - A(pairs(:, 2), :)) .^ 2, 2)); %// d = pdist(A)
thr = d < 10; %// Distances below threshold
kk = 1;
idx = 1:size(A, 1);
C = cell(size(idx)); %// Preallocate memory
while any(idx)
x = unique(pairs(pairs(:, 1) == find(idx, 1) & thr, :));
C{kk} = A(x, :);
idx(x) = 0; %// Remove indices from list
kk = kk + 1;
end
C = C(~cellfun(@isempty, C)); %// Remove empty cells
結果はセル配列C
であり、各セルはクラスターを表します。
C{1} =
1.0000 2.5000 3.5000
2.0000 2.6000 3.4000
4.0000 2.8000 3.2000
C{2} =
1.0000 85.1000 74.1000
2.0000 86.0000 69.8000
3.0000 84.4000 68.2000
4.0000 83.2000 67.4000
C{3} =
3.0000 25.8000 32.9000
4.0000 24.1000 31.8000
この単純なアプローチには、クラスター半径をしきい値に制限するという欠点があることに注意してください。ただし、単純なソリューションが必要だったため、アルゴリズムに「クラスタリングロジック」を追加すると、複雑になることに注意してください。