簡體   English   中英

在MATLAB中將平面擬合到N維點

[英]Fit plane to N dimensional points in MATLAB

我有一組k維度的N個點作為大小為NX k的矩陣。

如何通過這些點找到最佳擬合線? 該線將是k維的平面(hyerpplane)。 它將具有k系數和一個偏差項。

fit這樣的現有函數似乎只能用於2維或3維的點。

您可以使用主成分分析將超平面(或任何低維仿射空間)擬合到一組D維數據。 這是將平面擬合到一組3D數據的示例。 這在MATLAB文檔中有更詳細的解釋,但我試圖構建我能做的最簡單的例子。

% generate some random correlated data
D = 3;
mu = zeros(1,D);
sqrt_sig = randn(D);
sigma = sqrt_sig'*sqrt_sig;
% generate 50 points in a D x 50 matrix
X = mvnrnd(mu, sigma, 50)';

% perform PCA
coeff = pca(X');

% The last principal component is normal to the best fit plane and plane goes through mean of X
a = coeff(:,D);
b = -mean(X,2)'*a;

% plane defined by a'*x + b = 0
dist = abs(a'*X+b) / norm(a);
mse = mean(dist.^2)

編輯:添加了D = 3的結果示例圖。我在這里利用了其他主要組件的正交性。 如果你想要它,只是為了證明飛機確實很適合數據,忽略代碼。

% plot in 3D
X0 = bsxfun(@minus,X,mean(X,2));
b1 = coeff(:,1);    b2 = coeff(:,2);
y1 = b1'*X0;        y2 = b2'*X0;
y1_min = min(y1);   y1_max = max(y1);
y1_span = y1_max - y1_min;
y2_min = min(y2);   y2_max = max(y2);
y2_span = y2_max - y2_min;
pad = 0.2;
y1_min = y1_min - pad*y1_span;
y1_max = y1_max + pad*y1_span;
y2_min = y2_min - pad*y2_span;
y2_max = y2_max + pad*y2_span;
[y1_m,y2_m] = meshgrid(linspace(y1_min,y1_max,5), linspace(y2_min,y2_max,5));
grid = bsxfun(@plus, bsxfun(@times,y1_m(:)',b1) + bsxfun(@times,y2_m(:)',b2), mean(X,2));
x = reshape(grid(1,:),size(y1_m));
y = reshape(grid(2,:),size(y1_m));
z = reshape(grid(3,:),size(y1_m));

figure(1); clf(1);
surf(x,y,z,'FaceColor','black','FaceAlpha',0.3,'EdgeAlpha',0.6);
hold on;
plot3(X(1,:),X(2,:),X(3,:),' .');
axis equal;
axis vis3d;

在此輸入圖像描述 在此輸入圖像描述

編輯2 :當我說“主要成分”時,我的措辭有點草率(或者說是完全錯誤的)。 我實際上指的是表達主成分的正交基矢量。

這是一個更簡單的解決方案,它只使用MATLAB的\\運算符 我們首先定義k維的平面:

%  0 = a + x(1) * b(1) + x(2) * b(2) + ... + x(k) * 1
k = 8;
a = randn(1);
b = randn(k-1,1);

(注意,我們假設b(k)=1 ,你總是可以將平面參數乘以任意值而不改變平面)。

接下來,我們在此平面內生成N隨機點:

N = 1000;
x = rand(N,k-1);
x(:,k) = -(a + x * b);

...對不起,這不是在飛機上生成隨機點的最佳方法,但這對於此處的演示來說已經足夠了。 添加噪點:

x = x + 0.05*randn(size(x));

為了找到平面的參數,我們求解方程組

%    a + x(1:k-1) * b == -x(k)

在最小二乘意義上。 ab是那里的未知數。 我們可以將左側重寫為[1,x(1:k-1)] * [a;b] 如果我們有一個矩陣方程M*p=v我們可以通過寫p=M\\v求解p:

p = [ones(N,1),x(:,1:k-1)]\(-x(:,k));

disp(['ground truth: [a,b,1] = ',mat2str([a,b',1],3)]);
disp(['estimated   : [a,b,1] = ',mat2str([p',1],3)]);

這給出了輸出:

 ground truth: [a,b,1] = [-1.35 -1.44 -1.48 1.17 0.226 -0.214 0.234 -1.59 1] estimated : [a,b,1] = [-1.41 -1.38 -1.43 1.14 0.219 -0.195 0.221 -1.54 1] 

數據集中的噪點越少或點越多,誤差就越小!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM