Làm thế nào để vẽ một âm mưu scree trong python? [đóng cửa]


11

Tôi đang sử dụng phân rã vectơ số ít trên một ma trận và thu được ma trận U, S và Vt. Tại thời điểm này, tôi đang cố gắng chọn ngưỡng cho số lượng kích thước được giữ lại. Tôi đã được đề nghị để xem xét một âm mưu scree nhưng đang tự hỏi làm thế nào để đi về âm mưu nó trong numpy. Hiện tại, tôi đang thực hiện các thao tác sau bằng thư viện numpy và scipy trong python:

U, S, Vt = svd(A)

Bất kỳ đề xuất?


1
lấy đường chéo của S, nếu nó chưa phải là đường chéo, bình phương nó, sắp xếp nó theo thứ tự giảm dần, lấy tổng tích lũy, chia cho giá trị cuối cùng, sau đó vẽ đồ thị.
shabbychef

@shabbychef: Ý bạn là, lấy tổng tích lũy và chia cho tổng của tất cả các giá trị phải không?
Truyền thuyết

Đúng. Trong matlab, nó sẽ là[U,S,V] = svd(X);S = cumsum(sort(diag(S).^2,1,'descend'));S = S ./ S(end);plot(S);
shabbychef

Câu trả lời:


13

Dưới đây là một ví dụ có thể được dán vào dấu nhắc IPython và tạo một hình ảnh như bên dưới (nó sử dụng dữ liệu ngẫu nhiên):

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()

nhập mô tả hình ảnh ở đây


Hermann: +1 Cảm ơn bạn đã dành thời gian! Tôi biết đó là một thời gian dài nhưng tuy nhiên điều này thực sự tốt để có :)
Truyền thuyết

num_varsgì nó dường như không được định nghĩa trong kịch bản của bạn.
TheChymera

@TheChymera - Cảm ơn bạn đã nắm bắt được điều này, tôi đã cập nhật phản hồi của mình.
Josh Hemann

@Josh Hemann yeah, tôi cũng đã tìm ra điều này trong lúc này - nhưng tôi nghĩ có lẽ tốt hơn để tính toán nó từ hình dạng của A
TheChymera

1
@JoshHemann bạn có thể giải thích điều này: eig đạn = S ** 2 / np.cumsum (S) [- 1] ?? Tôi đã thấy dựa trên một số giấy tờ eig đạn = S ** 2 / (n-1) trong đó n là số lượng tính năng
makis
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.