Tidak sepenuhnya jelas bagi saya bahwa apa yang Anda tanyakan adalah apa yang benar-benar Anda butuhkan: langkah preprocessing yang umum dalam pembelajaran mesin adalah pengurangan dimensi + pemutihan, yang berarti melakukan PCA dan menstandarisasi komponen, tidak ada yang lain. Tetapi saya akan tetap fokus pada pertanyaan Anda seperti yang dirumuskan, karena itu lebih menarik.
Biarkan menjadi pusat data matriks dengan titik data dalam baris dan variabel dalam kolom. PCA sama dengan dekomposisi nilai singular mana untuk melakukan pengurangan dimensionalitas kita hanya menyimpan komponen . "Rotasi faktor" ortogonal dari komponen-komponen ini menyiratkan memilih ortogonal matrix dan menghubungkannya ke dalam dekomposisi: n × d X = U S V ⊤ ≈ U k S k V ⊤ kXn×dk k × k R X ≈ U k S k V ⊤ k = U k R R ⊤ S k V ⊤ k = √
X=USV⊤≈UkSkV⊤k,
kk×kR√X≈UkSkV⊤k=UkRR⊤SkV⊤k=n−1−−−−−√U⊤kRRotatedstandardized scores⋅R⊤SkV⊤k/n−1−−−−−√Rotated loadings⊤.
Di sini adalah komponen yang diputar standar dan istilah kedua mewakili pemuatan yang diputar ditransformasikan. Varians setiap komponen setelah rotasi diberikan oleh jumlah kuadrat dari vektor pemuatan yang sesuai; sebelum rotasi, cukup . Setelah rotasi itu adalah hal lain.
s 2 i /(n-1)n−1−−−−−√UkRs2i/(n−1)
Sekarang kita siap untuk merumuskan masalah dalam istilah matematika: diberikan pembebanan yang tidak diputar , cari matriks rotasi sedemikian rupa sehingga pembebanan yang diputar, , memiliki jumlah kuadrat yang sama di setiap kolom. RLRL=VkSk/n−1−−−−−√RLR
Mari kita selesaikan. Jumlah kolom kuadrat setelah rotasi sama dengan elemen diagonal Ini masuk akal: rotasi hanya mendistribusikan ulang varian komponen, yang awalnya diberikan oleh , di antara mereka, sesuai dengan rumus ini. Kita perlu mendistribusikannya kembali sehingga semuanya menjadi sama dengan nilai rata-rata mereka .s 2 i /(n-1)μ
(LR)⊤LR=R⊤S2n−1R.
s2i/(n−1)μ
Saya tidak berpikir ada solusi bentuk tertutup untuk ini, dan sebenarnya ada banyak solusi berbeda. Tetapi solusi dapat dengan mudah dibangun secara berurutan:
- Ambil komponen pertama dan komponen -th. Yang pertama memiliki varians dan yang terakhir memiliki varians .σ maks > μ σ min < μkσmax>μσmin<μ
- Putar hanya dua ini sehingga varians yang pertama menjadi sama dengan . Matriks rotasi dalam 2D hanya bergantung pada satu parameter dan mudah untuk menuliskan persamaan dan menghitung diperlukan . Memang, dan setelah transformasi PC pertama akan mendapatkan varians dari sana kita segera memperolehθ θ R 2D = ( cos θ sin θ - sin θ cos θ ) cos 2 θμθθ
R2D=(cosθ−sinθsinθcosθ)
cos2θ⋅σmax+sin2θ⋅σmin=cos2θ⋅σmax+(1−cos2θ)⋅σmin=μ,
cos2θ=μ−σminσmax−σmin.
- Komponen pertama sekarang selesai, ia memiliki varian .μ
- Lanjutkan ke pasangan berikutnya, mengambil komponen dengan varian terbesar dan satu dengan varian terkecil. Goto # 2.
Ini akan mendistribusikan ulang semua varian secara merata dengan urutan rotasi 2D. Mengalikan semua matriks rotasi ini bersama-sama akan menghasilkan keseluruhan .(k−1)R
Contoh
Pertimbangkan matriks :Varians rata-rata adalah . Algoritme saya akan diproses sebagai berikut:S2/(n−1)
⎛⎝⎜⎜⎜10000060000300001⎞⎠⎟⎟⎟.
5
Langkah 1: putar PC1 dan PC4 sehingga PC1 mendapat varian . Akibatnya, PC4 mendapat varians .51+(10−5)=6
Langkah 2: putar PC2 (varian maksimal baru) dan PC3 sehingga PC2 mendapatkan varian . Akibatnya, PC3 mendapat varians .53+(6−5)=4
Langkah 3: putar PC4 (varian maksimal baru) dan PC3 sehingga PC4 mendapatkan varian . Akibatnya, PC3 mendapat varians .4 + ( 6 - 1 ) = 554+(6−1)=5
Selesai
Saya menulis skrip Matlab yang mengimplementasikan algoritma ini (lihat di bawah). Untuk matriks input ini, urutan sudut rotasi adalah:
48.1897 35.2644 45.0000
Varians komponen setelah setiap langkah (dalam baris):
10 6 3 1
5 6 3 6
5 5 4 6
5 5 5 5
Matriks rotasi akhir (produk dari tiga matriks rotasi 2D):
0.6667 0 0.5270 0.5270
0 0.8165 0.4082 -0.4082
0 -0.5774 0.5774 -0.5774
-0.7454 0 0.4714 0.4714
Dan matriks terakhir adalah:(LR)⊤LR
5.0000 0 3.1623 3.1623
0 5.0000 1.0000 -1.0000
3.1623 1.0000 5.0000 1.0000
3.1623 -1.0000 1.0000 5.0000
Ini kodenya:
S = diag([10 6 3 1]);
mu = mean(diag(S));
R = eye(size(S));
vars(1,:) = diag(S);
Supdated = S;
for i = 1:size(S,1)-1
[~, maxV] = max(diag(Supdated));
[~, minV] = min(diag(Supdated));
w = (mu-Supdated(minV,minV))/(Supdated(maxV,maxV)-Supdated(minV,minV));
cosTheta = sqrt(w);
sinTheta = sqrt(1-w);
R2d = eye(size(S));
R2d([maxV minV], [maxV minV]) = [cosTheta sinTheta; -sinTheta cosTheta];
R = R * R2d;
Supdated = transpose(R2d) * Supdated * R2d;
vars(i+1,:) = diag(Supdated);
angles(i) = acosd(cosTheta);
end
angles %// sequence of 2d rotation angles
round(vars) %// component variances on each step
R %// final rotation matrix
transpose(R)*S*R %// final S matrix
Berikut adalah kode dalam Python yang disediakan oleh @feilong:
def amoeba_rotation(s2):
"""
Parameters
----------
s2 : array
The diagonal of the matrix S^2.
Returns
-------
R : array
The rotation matrix R.
Examples
--------
>>> amoeba_rotation(np.array([10, 6, 3, 1]))
[[ 0.66666667 0. 0.52704628 0.52704628]
[ 0. 0.81649658 0.40824829 -0.40824829]
[ 0. -0.57735027 0.57735027 -0.57735027]
[-0.74535599 0. 0.47140452 0.47140452]]
http://stats.stackexchange.com/a/177555/87414
"""
n = len(s2)
mu = s2.mean()
R = np.eye(n)
for i in range(n-1):
max_v, min_v = np.argmax(s2), np.argmin(s2)
w = (mu - s2[min_v]) / (s2[max_v] - s2[min_v])
cos_theta, sin_theta = np.sqrt(w), np.sqrt(1-w)
R[:, [max_v, min_v]] = np.dot(
R[:, [max_v, min_v]],
np.array([[cos_theta, sin_theta], [-sin_theta, cos_theta]]))
s2[[max_v, min_v]] = [mu, s2[max_v] + s2[min_v] - mu]
return R
Perhatikan bahwa masalah ini benar-benar setara dengan yang berikut: diberikan variabel tidak berkorelasi dengan varians , temukan rotasi (yaitu basis ortogonal baru) yang akan menghasilkan variabel dengan varians yang sama (tetapi tentu saja tidak berkorelasi lagi).σ 2 i kkσ2ik