Tại sao Andrew Ng thích sử dụng SVD mà không phải EIG của ma trận hiệp phương sai để làm PCA?


29

Tôi đang học PCA từ khóa học Coursera của Andrew Ng và các tài liệu khác. Trong bài tập đầu tiên của Stanford NLP cs224n , và trong video bài giảng của Andrew Ng , họ thực hiện phân rã giá trị số ít thay vì phân tách eigenvector của ma trận hiệp phương sai, và Ng thậm chí còn nói rằng SVD ổn định hơn về số lượng.

Theo hiểu biết của tôi, đối với PCA, chúng ta nên thực hiện SVD của ma trận dữ liệu có (m,n)kích thước, chứ không phải ma trận hiệp phương sai về (n,n)kích thước. Và phân tách eigenvector của ma trận hiệp phương sai.

Tại sao họ làm SVD của ma trận hiệp phương sai, không phải ma trận dữ liệu?


8
Đối với ma trận bán nguyệt dương đối xứng vuông (như ma trận hiệp phương sai), phân tách giá trị riêng và giá trị số đơn hoàn toàn giống nhau.
amip nói rằng Phục hồi Monica

5
Ý tôi là họ giống nhau về mặt toán học . Về mặt số lượng, họ thực sự có thể sử dụng các thuật toán khác nhau và một thuật toán có thể ổn định hơn các thuật toán khác (như Ng nói). Điều này sẽ rất thú vị khi biết thêm về, +1.
amip nói Phục hồi lại

4
Một số thông tin về điều này ở đây: de.mathworks.com/matlabcentral/newsreader/view_thread/21268 . Nhưng lưu ý rằng bất kỳ lời giải thích nào về lý do tại sao một thuật toán sẽ ổn định hơn thuật toán khác sẽ rất kỹ thuật.
amip nói rằng Phục hồi lại

2
Trong Matlab, x=randn(10000); x=x'*x; tic; eig(x); toc; tic; svd(x); toc;máy của tôi xuất ra 12 giây cho eig () và 26 giây cho svd (). Nếu nó chậm hơn nhiều, thì ít nhất nó phải ổn định hơn! :-)
amip nói Phục hồi lại

4
Điều đó có thể được dựa trên sự hiểu biết không chính xác: làm một SVD của ma trận dữ liệu ổn định hơn so với sử dụng eighoặc svdtrên ma trận hiệp phương sai, nhưng như xa như tôi biết không có sự khác biệt lớn giữa việc sử dụng eighoặc svdtrên ma trận hiệp phương sai --- họ cả hai thuật toán ổn định lạc hậu. Nếu có bất cứ điều gì, tôi sẽ đặt tiền của mình vào eig ổn định hơn , vì nó tính toán ít hơn (giả sử cả hai đều được thực hiện với các thuật toán tiên tiến nhất).
Federico Poloni

Câu trả lời:


17

amip đã đưa ra một câu trả lời tốt trong các ý kiến, nhưng nếu bạn muốn một cuộc tranh luận chính thức, ở đây nó đi.

Phân rã giá trị số ít của ma trận là , trong đó các cột của là các hàm riêng của và các mục chéo của là căn bậc hai của giá trị riêng của nó, tức là .Một = U Σ V T V Một T Một Σ σ i i = MộtMột= =BạnΣVTVMộtTMộtΣσtôitôi= =λtôi(MộtTMột)

Như bạn đã biết, các thành phần chính là các hình chiếu trực giao của các biến của bạn vào không gian của các hàm riêng của ma trận hiệp phương sai theo kinh nghiệm . Phương sai của các thành phần được cho bởi giá trị riêng của nó, .λi(11n-1MộtTMộtλtôi(1n-1MộtTMột)

Xét bất kỳ ma trận vuông , và một vectơ sao cho . Sau đóalpha R v B v = λ vBαRvBv= =λv

  1. Bkv= =λkv
  2. λ(αB)= =αλ(B)

Hãy để chúng tôi xác định . SVD của sẽ tính toán sự xuất tinh của để mang lạiSSTS=1S= =1n-1MộtTMộtSSTS=1(n1)2ATAATA

  1. các hàm riêng của , mà thuộc tính 1 là củaA T A(ATA)TATA=ATAATAATA
  2. căn bậc hai của các giá trị riêng của , theo thuộc tính 2, sau đó 1, sau đó 2 lần nữa, là .1(n1)2ATAATA1(n1)2λi(ATAATA)=1(n1)2λi2(ATA)=1n1λi(ATA)=λtôi(1n-1MộtTMột)

Võngà!

Liên quan đến sự ổn định về số, người ta sẽ cần phải tìm ra các thuật ngữ được sử dụng là gì. Nếu bạn đồng ý, tôi tin rằng đây là những thói quen LAPACK được sử dụng bởi numpy:

Cập nhật: Về tính ổn định, việc triển khai SVD dường như đang sử dụng phương pháp phân chia và chinh phục, trong khi đó, eigendecro sử dụng thuật toán QR đơn giản. Tôi không thể truy cập một số bài báo SIAM có liên quan từ tổ chức của mình (đổ lỗi cho việc cắt giảm nghiên cứu) nhưng tôi đã tìm thấy điều gì đó có thể hỗ trợ cho việc đánh giá rằng thói quen SVD ổn định hơn.

Trong

Nakatsukasa, Yuji và Nicholas J. Higham. "Các thuật toán phân chia và chinh phục phổ ổn định và hiệu quả cho phân rã eigenvalue đối xứng và SVD." Tạp chí SIAM về tính toán khoa học 35.3 (2013): A1325-A1349.

họ so sánh tính ổn định của các thuật toán eigenvalue khác nhau và dường như phương pháp phân chia và chinh phục (họ sử dụng cùng một phương pháp như numpy trong một trong các thử nghiệm!) ổn định hơn thuật toán QR. Điều này, cùng với tuyên bố ở nơi khác rằng các phương pháp D & C thực sự ổn định hơn, hỗ trợ cho sự lựa chọn của Ng.


Các giá trị riêng tôi thu được từ svd trên hiệp phương sai và svd trên dữ liệu trung tâm trung bình không giống nhau.
theGD

Tuy nhiên, điểm số, đó là X * V (trong đó V thu được từ [U, S, V] = svd (x) hoặc svd (covx)), là như nhau.
17:30

1
@theGD Eigenvalues ​​của cov (X) và các giá trị số ít của (X) không giống nhau, xem stats.stackexchange.com/questions/134282 .
amip nói rằng Phục hồi Monica

không cần phải tuyệt vọng khi không có quyền truy cập vào các tạp chí SIAM: bài báo bạn trích dẫn ở đây: opt.mist.iu-tokyo.ac.jp/~nakatsukasa/publishedpdf/pub13.pdf
Dima Pasechnik

2
@broncoAbierto công nghệ. báo cáo ở đây: cpsc.yale.edu/sites/default/files/files/tr932.pdf (người ta có thể không dễ dàng tìm thấy nó do một lỗi đánh máy "Symetric" trong tiêu đề trên cpsc.yale.edu/research/technical-reports / 1992-báo cáo kỹ thuật :-))
Dima Pasechnik

12

@amoeba đã có câu trả lời tuyệt vời cho các câu hỏi PCA, bao gồm câu hỏi này liên quan đến SVD với PCA. Trả lời cho câu hỏi chính xác của bạn, tôi sẽ đưa ra ba điểm:

  • về mặt toán học, không có sự khác biệt cho dù bạn tính PCA trực tiếp trên ma trận dữ liệu hay trên ma trận hiệp phương sai của nó
  • sự khác biệt hoàn toàn là do độ chính xác và độ phức tạp của số. Áp dụng áp dụng SVD trực tiếp vào ma trận dữ liệu ổn định hơn về số lượng so với ma trận hiệp phương sai
  • SVD có thể được áp dụng cho ma trận hiệp phương sai để thực hiện PCA hoặc thu được các giá trị riêng, trên thực tế, đó là phương pháp ưa thích của tôi để giải quyết các vấn đề bản địa

Nó chỉ ra rằng SVD ổn định hơn các thủ tục xác định vị trí eigenvalue điển hình, đặc biệt, đối với học máy. Trong học máy, thật dễ dàng để kết thúc với các hồi quy cộng tuyến cao. SVD hoạt động tốt hơn trong những trường hợp này.

Đây là mã Python để demo điểm. Tôi đã tạo ra một ma trận dữ liệu cộng tuyến cao, có ma trận hiệp phương sai của nó và cố gắng đạt được các giá trị riêng sau này. SVD vẫn hoạt động, trong khi phân tách eigen thông thường thất bại trong trường hợp này.

import numpy as np
import math
from numpy import linalg as LA

np.random.seed(1)

# create the highly collinear series
T = 1000
X = np.random.rand(T,2)
eps = 1e-11
X[:,1] = X[:,0] + eps*X[:,1]

C = np.cov(np.transpose(X))
print('Cov: ',C)

U, s, V = LA.svd(C)
print('SVDs: ',s)

w, v = LA.eig(C)
print('eigen vals: ',w)

Đầu ra:

Cov:  [[ 0.08311516  0.08311516]
 [ 0.08311516  0.08311516]]
SVDs:  [  1.66230312e-01   5.66687522e-18]
eigen vals:  [ 0.          0.16623031]

Cập nhật

Trả lời nhận xét của Federico Poloni, đây là đoạn mã kiểm tra độ ổn định của SVD so với Eig trên 1000 mẫu ngẫu nhiên của cùng một ma trận ở trên. Trong nhiều trường hợp, Eig hiển thị 0 giá trị eigen nhỏ, điều này sẽ dẫn đến tính đơn lẻ của ma trận và SVD không làm điều đó ở đây. SVD chính xác hơn gấp đôi so với xác định giá trị bản địa nhỏ, điều này có thể hoặc không quan trọng tùy thuộc vào vấn đề của bạn.

import numpy as np
import math
from scipy.linalg import toeplitz
from numpy import linalg as LA

np.random.seed(1)

# create the highly collinear series
T = 100
p = 2
eps = 1e-8

m = 1000 # simulations
err = np.ones((m,2)) # accuracy of small eig value
for j in range(m):
    u = np.random.rand(T,p)
    X = np.ones(u.shape)
    X[:,0] = u[:,0]
    for i in range(1,p):
        X[:,i] = eps*u[:,i]+u[:,0]

    C = np.cov(np.transpose(X))

    U, s, V = LA.svd(C)

    w, v = LA.eig(C)

    # true eigen values
    te = eps**2/2 * np.var(u[:,1])*(1-np.corrcoef(u,rowvar=False)[0,1]**2)
    err[j,0] = s[p-1] - te
    err[j,1] = np.amin(w) - te


print('Cov: ',C)
print('SVDs: ',s)
print('eigen vals: ',w)
print('true small eigenvals: ',te)

acc = np.mean(np.abs(err),axis=0)    
print("small eigenval, accuracy SVD, Eig: ",acc[0]/te,acc[1]/te)

Đầu ra:

Cov:  [[ 0.09189421  0.09189421]
 [ 0.09189421  0.09189421]]
SVDs:  [ 0.18378843  0.        ]
eigen vals:  [  1.38777878e-17   1.83788428e-01]
true small eigenvals:  4.02633695086e-18
small eigenval, accuracy SVD, Eig:  2.43114702041 3.31970128319

Ở đây mã mã hoạt động. Thay vì tạo ma trận hiệp phương sai ngẫu nhiên để kiểm tra các thói quen, tôi đang tạo ma trận dữ liệu ngẫu nhiên với hai biến:

x1=ux2=u+εv
u,v
(σ12σ12+ερσ1σ2σ12+ερσ1σ2σ12+2ερσ1σ2+ε2σ22σ2)
σ12,σ22,ρ

λ=12(σ22ε2σ24ε4+4σ23ρσ1ε3+8σ22ρ2σ12ε2+8σ2ρσ13ε+4σ14+2σ2ρσ1ε+2σ12)
ε
λσ22ε2(1ρ2)/2

j=1,,mλ^jej=λλ^j


4
Có, nhưng ở đây OP đang hỏi về SVD và EIG được áp dụng cả cho ma trận hiệp phương sai.
amip nói rằng Phục hồi lại

1
@amoeba, tôi đã làm rõ mối quan hệ của SVD và PCA
Aksakal

Đây là một câu trả lời tốt. Tuy nhiên, tôi muốn đề cập rằng svd không thể phát hiện các giá trị riêng âm khi có bất kỳ và bạn muốn xem chúng (nếu ma trận hiệp phương sai không phải là nguyên bản mà là, được làm mịn hoặc ước tính bằng cách nào đó hoặc được suy ra hoặc xóa khỏi cặp đôi của các giá trị còn thiếu). Hơn nữa, eig trên ma trận cov vẫn nhanh hơn một chút so với svd trên nó.
ttnphns

@ttnphns, ma trận xác định không tích cực là một vấn đề, tất nhiên
Aksakal

1
@FedericoPoloni, về số học FP và không biết câu trả lời chính xác tôi không đồng ý. Trong trường hợp này tôi biết câu trả lời với độ chính xác đủ cho nhiệm vụ này. Trên 2x2 bạn có một điểm công bằng. Tôi sẽ nghĩ về một vài thứ.
Aksakal

6

Đối với người dùng Python, tôi muốn chỉ ra rằng đối với các ma trận đối xứng (như ma trận hiệp phương sai), tốt hơn là sử dụng numpy.linalg.eighhàm thay vì numpy.linalg.eighàm chung .

eighnhanh hơn 9-10 lần so với eigtrên máy tính của tôi (bất kể kích thước ma trận) và có độ chính xác tốt hơn (dựa trên thử nghiệm độ chính xác của @ Aksakal).

Tôi không bị thuyết phục với việc chứng minh lợi ích chính xác của SVD với các giá trị riêng nhỏ. Thử nghiệm của @ Aksakal là 1-2 bậc độ nhạy cảm với trạng thái ngẫu nhiên hơn so với thuật toán (thử vẽ tất cả các lỗi thay vì giảm chúng đến một mức tối đa tuyệt đối). Điều đó có nghĩa là các lỗi nhỏ trong ma trận hiệp phương sai sẽ có ảnh hưởng lớn hơn đến độ chính xác so với việc lựa chọn thuật toán eigendecysis. Ngoài ra, điều này không liên quan đến câu hỏi chính, đó là về PCA. Các thành phần nhỏ nhất được bỏ qua trong PCA.

Một lập luận tương tự có thể được thực hiện về sự ổn định số. Nếu tôi phải sử dụng phương pháp ma trận hiệp phương sai cho PCA, tôi sẽ phân tách nó bằng eighthay vì svd. Nếu nó không thành công (chưa được chứng minh ở đây), thì có lẽ nên xem xét lại vấn đề mà bạn đang cố gắng giải quyết trước khi bắt đầu tìm kiếm một thuật toán tốt hơn.



2

mnmn

Tính toán ma trận hiệp phương sai và sau đó thực hiện SVD trên đó nhanh hơn rất nhiều so với tính toán SVD trên ma trận dữ liệu đầy đủ trong các điều kiện này, cho cùng một kết quả.

Ngay cả đối với các giá trị khá nhỏ, hiệu suất đạt được là hàng nghìn (mili giây so với giây). Tôi đã chạy một vài thử nghiệm trên máy để so sánh bằng Matlab: nhập mô tả hình ảnh ở đây

Đó chỉ là thời gian của CPU, nhưng nhu cầu lưu trữ cũng quan trọng không kém. Nếu bạn thử SVD trên một triệu bởi một nghìn ma trận trong Matlab, nó sẽ bị lỗi theo mặc định, vì nó cần kích thước mảng làm việc là 7.4TB.


Điều này không trả lời câu hỏi về EIG của ma trận cov so với SVD của ma trận hiệp phương sai .
amip nói phục hồi Monica

1
Câu hỏi của anh ở cuối, được nhấn mạnh bằng chữ in đậm, "Tại sao họ làm SVD của ma trận hiệp phương sai, không phải ma trận dữ liệu?" mà tôi đã trả lời
cộc cằn

Tôi sẽ chỉnh sửa câu mở đầu để làm rõ rằng tôi đang trả lời một phần câu hỏi của OP. Tôi thấy làm thế nào có thể gây nhầm lẫn. Cảm ơn.
Cộc cằn

Nếu bạn thử SVD trên một triệu ma trận trong Matlab, nó sẽ bị lỗi theo mặc định Thực hành số tốt là sử dụng SVD mỏng, trong những trường hợp này. Điều này sẽ cải thiện đáng kể kích thước lưu trữ và hiệu suất.
Federico Poloni
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.