Bana sorduğunuz şeyin gerçekten ihtiyacınız olan şey olduğu tam olarak belli değil: makine öğreniminde ortak bir ön işleme adımı boyutsallık azaltma + beyazlatmadır, yani PCA yapmak ve bileşenleri standartlaştırmak, başka bir şey değildir. Ama yine de formüle edildiği gibi sorunuza odaklanacağım, çünkü daha ilginç.
İzin Vermek X merkezli ol n×dsatırlardaki veri noktaları ve sütunlardaki değişkenler içeren veri matrisi. PCA tekil değer ayrışmasına karşılık gelir
X=USV⊤≈UkSkV⊤k,
boyutsal küçülmeyi nerede yapacağız
kbileşenler. Bu bileşenlerin dikey bir "faktör dönüşü" dikey bir seçim anlamına gelir
k×k matris
R ve ayrıştırmaya takılması:
X≈UkSkV⊤k=UkRR⊤SkV⊤k=n−1−−−−−√U⊤kRRotatedstandardized scores⋅R⊤SkV⊤k/n−1−−−−−√Rotated loadings⊤.
Buraya
n−1−−−−−√UkRdöndürülmüş standart bileşenlerdir ve ikinci terim aktarılan döndürülmüş yükleri temsil eder. Döndürmeden sonra her bir bileşenin varyansı, karşılık gelen yükleme vektörünün karelerinin toplamı ile verilir; dönmeden önce basitçe
s2ben/ (n-1). Döndürmeden sonra başka bir şeydir.
Şimdi problemi matematiksel terimlerle formüle etmeye hazırız: döndürülmemiş yüklemeler verildi L =VkSk/n - 1-----√, döndürme matrisini bul R, döndürülmüş yükler, L R, her sütunda eşit kareler toplamına sahiptir.
Çözelim. Döndürme sonrasındaki karelerin sütun toplamları, öğenin köşegen öğelerine eşittir.
( L R)⊤L R =R,⊤S2n - 1R ' .
Bu mantıklı: rotasyon, başlangıçta tarafından verilen bileşenlerin varyanslarını basitçe yeniden dağıtır s2ben/ (n-1), aralarında, bu formüle göre. Bunları hepsi ortalama değerlerine eşit olacak şekilde yeniden dağıtmamız gerekiyorμ.
Bunun kapalı bir form çözümü olduğunu düşünmüyorum ve aslında birçok farklı çözüm var. Ancak bir çözüm kolayca sıralı bir şekilde inşa edilebilir:
- İlk bileşeni alın ve kbileşen. İlki varyans varσmaksimum> μ ve sonuncusu varyansa sahip σmin< μ.
- Sadece bu ikisini, ilkinin varyansı eşit olacak şekilde döndürün μ. 2B'deki döndürme matrisi yalnızca bir parametreye bağlıdırθ ve denklemi yazmak ve gerekli hesaplamaları yapmak kolaydır. θ. Aslında,
R,2D= (marulθ- günahθgünahθmarulθ)
ve dönüşümden sonra ilk PC varyans alacak marul2θ ⋅σmaksimum+günah2θ ⋅σmin=marul2θ ⋅σmaksimum+ ( 1 -marul2θ ) ⋅σmin= μ ,
hemen elde ederiz marul2θ =μ -σminσmaksimum-σmin.
- İlk bileşen şimdi yapıldı, varyans var μ.
- En büyük varyansa ve en küçük varyansa sahip olan bileşeni alarak bir sonraki çifte geçin. Git # 2.
Bu, tüm varyansları bir dizi ile eşit olarak yeniden dağıtacaktır. ( k - 1 )2D dönüşler. Tüm bu dönme matrislerini birlikte çarpmak, toplamıR,.
Misal
Aşağıdakileri göz önünde bulundur S2/ (n-1) matris:
⎛⎝⎜⎜⎜10000060000300001⎞⎠⎟⎟⎟.
Ortalama varyans
5. Algoritmam aşağıdaki gibi devam edecek:
Adım 1: PC1 ve PC4'ü döndürün, böylece PC1 değişebilir 5. Sonuç olarak, PC4 değişiyor1 + ( 10 - 5 ) = 6.
2.Adım: PC2'yi (yeni maksimal varyans) ve PC3'ü döndürün, böylece PC2 varyans alır 5. Sonuç olarak, PC3 değişiyor3 + ( 6 - 5 ) = 4.
3.Adım: PC4'ü (yeni maksimal varyans) ve PC3'ü döndürün, böylece PC4 varyans alır 5. Sonuç olarak, PC3 değişiyor4 + ( 6 - 1 ) = 5.
Bitti.
Bu algoritmayı uygulayan Matlab betiğini yazdım (aşağıya bakın). Bu giriş matrisi için dönme açılarının sırası:
48.1897 35.2644 45.0000
Her adımdan sonra bileşen varyansları (satırlar halinde):
10 6 3 1
5 6 3 6
5 5 4 6
5 5 5 5
Son dönme matrisi (üç 2B dönme matrisinin ürünü):
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
Ve son ( L R)⊤L R matris:
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
İşte kod:
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
@Feilong tarafından sağlanan Python kodu şöyledir:
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
Bu sorunun aşağıdakine tamamen eşdeğer olduğunu unutmayın: k varyanslı ilişkisiz değişkenler σ2ben, verim sağlayacak bir dönüş (yani yeni bir dikey temel) bulun k eşit varyansa sahip değişkenler (fakat elbette artık ilişkisiz).