3

現時点ではpdist、Matlab の関数を使用して、3 次元デカルト系のさまざまな点間のユークリッド距離を計算しています。これを行っているのは、他のすべてのポイント (メドイド) との平均距離が最も小さいポイントを知りたいからです。の構文はpdist次のようになります。

% calculate distances between all points
distances = pdist(m);

しかし、pdist は距離の 1 次元配列を返すため、平均距離が最小のポイントを (直接) 把握する簡単な方法はありません。squareformこれが、次のように最小の平均距離を使用して計算している理由です。

% convert found distances to matrix of distances
distanceMatrix = squareform(distances);

% find index of point with smallest average distance
[~,j] = min(mean(distanceMatrix,2));

距離は列ごとに平均化され、変数jは最小の平均距離を持つ列 (およびポイント) のインデックスです。

これは機能しますが、squareform には多くの時間がかかるため (このコードは何千回も繰り返されます)、最適化する方法を探しています。の結果から平均距離が最小のポイントを推測するより高速な方法を知っている人はいますpdistか?

4

4 に答える 4

3

ベクトル化の観点からは、SQUAREFORM関数を使用するのが最善の方法だと思います。この関数の内容を見ると、

edit squareform

もちろん、時間がかかる多くのチェックを実行することがわかります。squareform への入力がわかっているので、確実に機能するので、squareform のコアのみを使用してカスタム関数を作成できます。

[r, c] = size(m);
distanceMatrix = zeros(r);
distanceMatrix(tril(true(r),-1)) = distances;
distanceMatrix = distanceMatrix + distanceMatrix';

次に、メディオイドを見つけるために行ったのと同じコードを実行します。

于 2012-03-12T05:41:32.510 に答える
1

これは、squareformの呼び出しを必要としない実装です。

N1 = 10;
dim = 5;

% generate points
X = randn(N1, dim);

% find mean distance
for iter=N1:-1:1
    d_mean(iter) = mean(pdist2(X(iter,:),X([1:(iter-1) (iter+1):end],:),'euclidean'));
    % D(iter,:) = pdist2(X(iter,:),X([1:(iter-1) (iter+1):end],:),'euclidean');
end

[val ind] = min(d_mean);

しかし、あなたの問題についてもっと知らなければ、もっと速くなるかどうかはわかりません。

これがプログラムのパフォーマンスの要である場合は、mexなどの他の高速化オプションを検討する必要があります。

幸運を。

于 2012-03-12T00:19:41.120 に答える
0

使用する必要はありませんsquareform

distances = pdist(m);
l=length(distances);
n=(1+sqrt(1+4*l))/2;
m=[];
for i=1:n
  idx=[1+i:n:length(distances)];
  m(i)=mean(distances(idx));
end

j=min(m);

よくわかりませんが、これもベクトル化できるかもしれませんが、今では遅れています。

于 2012-03-12T01:27:11.633 に答える