Python'da bir scree arsa nasıl çizilir? [kapalı]


11

Bir matris üzerinde tekil vektör ayrışımı kullanıyorum ve U, S ve Vt matrislerini elde ediyorum. Bu noktada, elde edilecek boyutların sayısı için bir eşik seçmeye çalışıyorum. Bir dağ eteğindeki arsa bakmak için teklif edildi ama numpy çizme hakkında gitmek nasıl merak ediyorum. Şu anda, python numpy ve scipy kütüphaneleri kullanarak aşağıdakileri yapıyorum:

U, S, Vt = svd(A)

Herhangi bir öneri?


1
diyagonalini al S, eğer zaten bir diyagonal değilse, onu kare, azalan düzende sırala, kümülatif toplamı al, son değere böl, sonra çiz.
shabbychef

@shabbychef: Yani, toplamı al ve tüm değerlerin toplamına böl, doğru mu?
Efsane

Evet. Matlab, olurdu[U,S,V] = svd(X);S = cumsum(sort(diag(S).^2,1,'descend'));S = S ./ S(end);plot(S);
shabbychef

Yanıtlar:


13

Aşağıda bir IPython istemine yapıştırılabilecek ve aşağıdaki gibi bir görüntü oluşturabilecek bir örnek bulunmaktadır (rastgele veriler kullanır):

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

#Make a random array and then make it positive-definite
num_vars = 6
num_obs = 9
A = np.random.randn(num_obs, num_vars)
A = np.asmatrix(A.T) * np.asmatrix(A)
U, S, V = np.linalg.svd(A) 
eigvals = S**2 / np.sum(S**2)  # NOTE (@amoeba): These are not PCA eigenvalues. 
                               # This question is about SVD.

fig = plt.figure(figsize=(8,5))
sing_vals = np.arange(num_vars) + 1
plt.plot(sing_vals, eigvals, 'ro-', linewidth=2)
plt.title('Scree Plot')
plt.xlabel('Principal Component')
plt.ylabel('Eigenvalue')
#I don't like the default legend so I typically make mine like below, e.g.
#with smaller fonts and a bit transparent so I do not cover up data, and make
#it moveable by the viewer in case upper-right is a bad place for it 
leg = plt.legend(['Eigenvalues from SVD'], loc='best', borderpad=0.3, 
                 shadow=False, prop=matplotlib.font_manager.FontProperties(size='small'),
                 markerscale=0.4)
leg.get_frame().set_alpha(0.4)
leg.draggable(state=True)
plt.show()

resim açıklamasını buraya girin


Hermann: +1 Zaman ayırdığınız için teşekkür ederiz! Ben uzun zaman oldu biliyorum ama yine de bu gerçekten çok iyi :)
Legend

nedir num_vars? betiğinizde tanımlanmış gibi görünmüyor.
TheChymera

@TheChymera - Bunu yakaladığınız için teşekkürler, yanıtımı güncelledim.
Josh Hemann

@Josh Hemann evet, ben de bu arada anladım - ama A
TheChymera

1
@JoshHemann bunu açıklayabilir misiniz: eigvals = S ** 2 / np.cumsum (S) [- 1] ?? Ben bazı özellikler eigvals = S ** 2 / (n-1) dayalı gördüm burada n özellik sayısı
seralouk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.