Analisis komponen utama tertimbang

17

Setelah beberapa pencarian, saya menemukan sangat sedikit pada penggabungan bobot pengamatan / kesalahan pengukuran ke dalam analisis komponen utama. Apa yang saya temukan cenderung mengandalkan pendekatan berulang untuk memasukkan bobot (misalnya, di sini ). Pertanyaan saya adalah mengapa pendekatan ini perlu? Mengapa kita tidak bisa menggunakan vektor eigen dari matriks kovarian tertimbang?

tanpa nama
sumber
1
Selain jawaban di bawah ini, silakan lihat stat thread.stackexchange.com/q/141754/3277 , di mana PCA tertimbang (dengan bobot pada kolom dan / atau baris) dijelaskan sebagai setara dengan bobot (umum) svd / biplot.
ttnphns

Jawaban:

33

Tergantung pada apa sebenarnya bobot Anda berlaku.

Bobot baris

Misalkan menjadi matriks data dengan variabel dalam kolom dan n observasi x i dalam baris. Jika setiap pengamatan memiliki berat terkait w i , maka itu memang mudah untuk menggabungkan bobot ini ke dalam PCA.Xnxsayawsaya

Pertama, kita perlu menghitung rata-rata tertimbang dan kurangi dari data untuk memusatkannya .μ=1wsayawsayaxsaya

Kemudian kita menghitung matriks kovarians tertimbang , di mana adalah matriks diagonal dari bobot, dan menerapkan PCA standar untuk menganalisisnya.1wsayaXWXW=diag(wsaya)

Bobot sel

Makalah oleh Tamuz et al., 2013 , yang Anda temukan, menganggap kasus yang lebih rumit ketika bobot berbeda diterapkan pada setiap elemen dari matriks data. Maka memang tidak ada solusi analitis dan kita harus menggunakan metode berulang. Perhatikan bahwa, sebagaimana diakui oleh penulis, mereka menemukan kembali roda, karena bobot umum seperti itu tentu telah dipertimbangkan sebelumnya, misalnya dalam Gabriel dan Zamir, 1979, Perkiraan Tingkat Bawah dari Matriks oleh Kuadrat Terkecil Dengan Setiap Pilihan Berat . Ini juga dibahas di sini .wsayaj

Sebagai komentar tambahan: jika bobot bervariasi dengan variabel dan pengamatan, tetapi simetris, sehingga , maka solusi analitik dimungkinkan lagi, lihat Koren dan Carmel, 2004, Robust Pengurangan Dimensi Linier .wsayajwsayaj=wjsaya

amuba kata Reinstate Monica
sumber
Terimakasih atas klarifikasinya. Bisakah Anda menjelaskan mengapa tidak ada solusi analitik yang mungkin dengan bobot diagonal? Saya ini adalah apa yang saya lewatkan dari kedua Tamuz et al 2013 dan Gabriel dan Zamir 1979.
noname
@ Noname: Saya tidak menyadari bukti seperti itu, dan terlebih lagi saya tidak akan terkejut jika itu tidak diketahui. Secara umum cukup sulit untuk membuktikan bahwa sesuatu itu tidak mungkin , khususnya bahwa sesuatu itu tidak mungkin secara analitis. Ketidakmungkinan pemotongan sudut terkenal menunggu buktinya selama lebih dari 2000 tahun ... (lanjutan)
amoeba berkata Reinstate Monica
3
@name: (lanjt.) Yang Anda minta adalah untuk menunjukkan bahwa masalah meminimalkan sehubungan dengan dibatasi untuk memiliki peringkat rendah . tidak dapat direduksi menjadi masalah vektor eigen. Saya khawatir Anda akan membutuhkan forum lain untuk itu (mungkin mathoverflow?). Tetapi perhatikan bahwa menemukan vektor eigen juga bukan solusi analitis : hanya saja itusaya,jwsayaj(Xsayaj-SEBUAHsayaj)2SEBUAHq iterasi biasanya dilakukan secara diam-diam oleh fungsi perpustakaan standar.
Amuba kata Reinstate Monica
2
+1. Bagian pertama dari jawaban dapat dikonseptualisasikan juga dalam hal Biplot Tertimbang (Umum) seperti yang dijelaskan di sini . Ingatlah bagaimana PCA adalah "kasus spesifik" Biplot (juga terkait dengan jawaban yang diuraikan).
ttnphns
@ttnphns: Setelah komentar Anda dan utas lainnya ditutup sebagai duplikat, saya membaca kembali jawaban saya dan memperluas penjelasan tentang cara menangani bobot baris. Saya pikir sebelumnya itu tidak sepenuhnya benar atau setidaknya tidak lengkap karena saya tidak menyebutkan pemusatan dengan rata-rata tertimbang. Saya harap ini lebih masuk akal sekarang!
Amuba mengatakan Reinstate Monica
5

Terima kasih banyak amuba untuk wawasan tentang bobot baris. Saya tahu bahwa ini bukan stackoverflow, tetapi saya mengalami beberapa kesulitan untuk menemukan implementasi PCA berbobot baris dengan penjelasan dan, karena ini adalah salah satu hasil pertama ketika googling untuk PCA tertimbang, saya pikir akan lebih baik untuk melampirkan solusi saya , mungkin bisa membantu orang lain dalam situasi yang sama. Dalam cuplikan kode Python2 ini, PCA yang diberi bobot dengan kernel RBF seperti yang dijelaskan di atas digunakan untuk menghitung garis singgung dari dataset 2D. Saya akan sangat senang mendengar tanggapan!

def weighted_pca_regression(x_vec, y_vec, weights):
    """
    Given three real-valued vectors of same length, corresponding to the coordinates
    and weight of a 2-dimensional dataset, this function outputs the angle in radians
    of the line that aligns with the (weighted) average and main linear component of
    the data. For that, first a weighted mean and covariance matrix are computed.
    Then u,e,v=svd(cov) is performed, and u * f(x)=0 is solved.
    """
    input_mat = np.stack([x_vec, y_vec])
    weights_sum = weights.sum()
    # Subtract (weighted) mean and compute (weighted) covariance matrix:
    mean_x, mean_y =  weights.dot(x_vec)/weights_sum, weights.dot(y_vec)/weights_sum
    centered_x, centered_y = x_vec-mean_x, y_vec-mean_y
    matrix_centered = np.stack([centered_x, centered_y])
    weighted_cov = matrix_centered.dot(np.diag(weights).dot(matrix_centered.T)) / weights_sum
    # We know that v rotates the data's main component onto the y=0 axis, and
    # that u rotates it back. Solving u.dot([x,0])=[x*u[0,0], x*u[1,0]] gives
    # f(x)=(u[1,0]/u[0,0])x as the reconstructed function.
    u,e,v = np.linalg.svd(weighted_cov)
    return np.arctan2(u[1,0], u[0,0]) # arctan more stable than dividing


# USAGE EXAMPLE:
# Define the kernel and make an ellipse to perform regression on:
rbf = lambda vec, stddev: np.exp(-0.5*np.power(vec/stddev, 2))
x_span = np.linspace(0, 2*np.pi, 31)+0.1
data_x = np.cos(x_span)[:-1]*20-1000
data_y = np.sin(x_span)[:-1]*10+5000
data_xy = np.stack([data_x, data_y])
stddev = 1 # a stddev of 1 in this context is highly local
for center in data_xy.T:
    # weight the  points based on their euclidean distance to the current center
    euclidean_distances = np.linalg.norm(data_xy.T-center, axis=1)
    weights = rbf(euclidean_distances, stddev)
    # get the angle for the regression in radians
    p_grad = weighted_pca_regression(data_x, data_y, weights)
    # plot for illustration purposes
    line_x = np.linspace(-5,5,10)
    line_y = np.tan(p_grad)*line_x
    plt.plot(line_x+center[0], line_y+center[1], c="r")
    plt.scatter(*data_xy)
    plt.show()

Dan output sampel (melakukan hal yang sama untuk setiap titik): masukkan deskripsi gambar di sini

Ceria,
Andres

fr_andres MendukungMonicaCellio
sumber