2010-08-05 19 views
15

Chcę odtworzyć poniższy rysunek w programie MATLAB:Elipsa wokół danych w MATLAB

exampleee.png

Istnieją dwa rodzaje punktów ze współrzędnymi X i Y. Chciałbym otoczyć każdą klasę elipsą z jednym parametrem odchylenia standardowego, który określa, jak daleko posunie się elipsa wzdłuż osi.

Rysunek został utworzony przy użyciu innego oprogramowania i nie do końca rozumiem, w jaki sposób oblicza się elipsę.

Oto dane, których używam dla tej liczby. Pierwsza kolumna to klasa, druga - X, trzecia - Y. Mogę użyć gscatter, aby narysować same punkty.

A = [ 
    0 0.89287 1.54987 
    0 0.69933 1.81970 
    0 0.84022 1.28598 
    0 0.79523 1.16012 
    0 0.61266 1.12835 
    0 0.39950 0.37942 
    0 0.54807 1.66173 
    0 0.50882 1.43175 
    0 0.68840 1.58589 
    0 0.59572 1.29311 
    1 1.00787 1.09905 
    1 1.23724 0.98834 
    1 1.02175 0.67245 
    1 0.88458 0.36003 
    1 0.66582 1.22097 
    1 1.24408 0.59735 
    1 1.03421 0.88595 
    1 1.66279 0.84183 
]; 

gscatter(A(:,2),A(:,3),A(:,1)) 

FYI, here jest SO pytanie, w jaki sposób narysować elipsę. Musimy więc znać wszystkie parametry, aby je narysować.


Update:

że zgadzają się, że środek może być obliczona jako środek X i Y. Prawdopodobnie muszę użyć głównej analizy komponentów (PRINCOMP) dla każdej klasy, aby określić kąt i kształt. Wciąż myśli ...

+0

Nawet jeśli nie wiem jak elipsa w oryginalnym rysunku jest obliczana, można prawdopodobnie wyjaśnić nieco więcej, co to ma znaczyć? To nie tylko otaczanie punktów, jak na przykład w przypadku punktów szarości, nie wszystkie punkty są zawarte w elipsie. Jeśli nic nie wiesz, sugerowałbym, aby punkt centralny punktów stanowił środek elipsy. Drugi moment obszaru może dać kierunek większej osi. – groovingandi

+0

@groovingandi: Zasadniczo oznacza to, że jeśli elipsa zostanie narysowana z odchyleniem standardowym 3, przy normalnym rozkładzie będzie zawierać około 99% punktów danych. Elipsy na figurze zostały wygenerowane przy STD = 2. – yuk

Odpowiedz

17

Rozważmy kod:

%# generate data 
num = 50; 
X = [ mvnrnd([0.5 1.5], [0.025 0.03 ; 0.03 0.16], num) ; ... 
     mvnrnd([1 1], [0.09 -0.01 ; -0.01 0.08], num) ]; 
G = [1*ones(num,1) ; 2*ones(num,1)]; 

gscatter(X(:,1), X(:,2), G) 
axis equal, hold on 

for k=1:2 
    %# indices of points in this group 
    idx = (G == k); 

    %# substract mean 
    Mu = mean(X(idx,:)); 
    X0 = bsxfun(@minus, X(idx,:), Mu); 

    %# eigen decomposition [sorted by eigen values] 
    [V D] = eig(X0'*X0 ./ (sum(idx)-1));  %#' cov(X0) 
    [D order] = sort(diag(D), 'descend'); 
    D = diag(D); 
    V = V(:, order); 

    t = linspace(0,2*pi,100); 
    e = [cos(t) ; sin(t)];  %# unit circle 
    VV = V*sqrt(D);    %# scale eigenvectors 
    e = bsxfun(@plus, VV*e, Mu'); %#' project circle back to orig space 

    %# plot cov and major/minor axes 
    plot(e(1,:), e(2,:), 'Color','k'); 
    %#quiver(Mu(1),Mu(2), VV(1,1),VV(2,1), 'Color','k') 
    %#quiver(Mu(1),Mu(2), VV(1,2),VV(2,2), 'Color','k') 
end 

screenshot


EDIT

Jeśli chcesz elipsa reprezentować określony poziom odchylenia standardowego, poprawna sposobem działania jest skalowanie macierzy kowariancji:

STD = 2;      %# 2 standard deviations 
conf = 2*normcdf(STD)-1;  %# covers around 95% of population 
scale = chi2inv(conf,2);  %# inverse chi-squared with dof=#dimensions 

Cov = cov(X0) * scale; 
[V D] = eig(Cov); 

OP_DATA

+0

Możesz również sprawdzić skrypt demonstracyjny 'eigshow' w MATLAB: http://www.mathworks.com/company/newsletters/news_notes/clevescorner/win98cleve.html – Amro

+0

To jest świetne. Dziękuję bardzo. Nie wiedziałem, jak używać wektorów własnych/wartości własnych, ale teraz mogę wyraźnie zobaczyć, jak to działa. Drobna rzecz. Jeśli uruchomię twój kod, otrzymam mniejsze elipsy. Jeśli wykonam 'STD = 2; VV = V * sqrt (D) * STD; ', elipsy mają ten sam rozmiar, co na oryginalnym wykresie. Czy to jest poprawne? Czy ten mnożnik rzeczywiście odpowiada temu, co inne oprogramowanie (którego użyłem do narysowania pierwotnej figury) nazywa standardowe odchylenie? – yuk

+1

@yuk: masz rację co do powyższego rysunku, ale właściwym sposobem na to jest skalowanie macierzy kowariancji. Proszę zobaczyć moją edycję powyżej – Amro

2

bym spróbować następujące podejście:

  1. Oblicz xy ciężkości na środku elipsy (x, y) w linked question
  2. Oblicz regresji liniowej dopasowaną linię aby uzyskać orientację elipsy na osi głównej (kąt)
  3. Oblicz odchylenie standardowe w osiach X i Y
  4. Przekłada xy odchylenia standardowe są więc prostopadle do dopasowanej linii (a, b)
+0

Chcesz wyjaśnić sprawę? Czy z moim podejściem jest coś koncepcyjnie nie tak? – Doresoom

+0

Czy to nie ja. Nadal myślę, jak to zaimplementować. – yuk

+0

Takie podejście dałoby podobny wygląd (ale nie identyczny). Istnieją duże różnice między regresją liniową, gdzie rozważane jest odchylenie tylko w osi Y, a wektorem własnym. Możliwe, że obliczenie regresji liniowej, rotacja danych i powtórzenie tego procesu dałoby identyczny wynik. Byłoby to zminimalizowanie sumy kwadratów wzdłuż osi prostopadłej do linii regresji zamiast tylko na osi Y. –

1

Założę, że istnieje tylko jeden zestaw punktów podany w pojedynczej macierzy, np.

B = A(1:10,2:3); 

Możesz odtworzyć tę procedurę dla każdego zestawu danych.

  1. Oblicz centrum elipsoidy, która jest średnią punktów. Funkcja Matlab: mean
  2. Wyśrodkuj swoje dane. Funkcja Matlab bsxfun
  3. Obliczyć główną oś elipsoidy i ich odpowiednią wielkość. Funkcja MATLAB: eig

Kolejne etapy są przedstawione poniżej:

Center = mean(B,1); 
Centered_data = bsxfun(@minus,B,Center); 
[AX,MAG] = eig(Centered_data' * Centered_data); 

Kolumny AX zawierają wektory określające oś główną elipsoidy podczas przekątnej MAG zawiera informacje o ich wielkości. Aby narysować elipsoidę, skaluj każdą główną oś z pierwiastkiem kwadratowym o jego wielkości.

Mam nadzieję, że to pomoże.

A.

Powiązane problemy