PCA bileşenlerini döndürerek her bileşendeki varyansı eşitleyin


9

Veri kümesinde PCA gerçekleştirerek ve son birkaç PC'yi atarak veri kümesinin boyutsallığını ve gürültüsünü azaltmaya çalışıyorum. Bundan sonra, kalan bilgisayarlarda bazı makine öğrenme algoritmaları kullanmak istiyorum ve bu nedenle algoritmaların daha iyi çalışması için PC'lerin varyansını eşitleyerek verileri normalleştirmek istiyorum.

Basit bir yol, birim değerlere olan varyansı normalleştirmektir. Ancak, ilk PC orijinal veri kümesinden aşağıdakilerden daha fazla sapma içerir ve yine de daha fazla "ağırlık" vermek istiyorum. Bu yüzden merak ediyordum: sadece varyansını bölmenin ve daha az varyanslı PC'lerle paylaşmanın basit bir yolu var mı?

Başka bir yol, PC'leri orijinal özellik alanına geri eşlemektir, ancak bu durumda boyutluluk da orijinal değere artacaktır.

Sanırım ortaya çıkan sütunları dik tutmak daha iyidir, ancak şu anda gerekli değildir.


1
Hayır ... varimax , yüklerin kareli varyanslarının toplamını en üst düzeye çıkarır , bu nedenle onları mümkün olduğunca eşitsiz yapmaya çalışır . Ayrıca, bileşenleri neden eşitlemek istersiniz? Bütün mesele, mümkün olduğunca az bileşende mümkün olduğunca çok varyasyonu yakalamaktır.

2
Bileşen puanlarını birim varyanslarına göre standartlaştırmak size uygun değil mi? Neden o zaman? Ne tür bir sonuç istiyorsunuz - ortaya çıkan sütunlar eşit varyanslara ek olarak ilişkisiz olmalı mı?
ttnphns

2
Açıklamanızdan, verileri (küresellik boyutunda) basitçe "küre" etmek istediğinize çok benziyor. Genellikle makine öğreniminde bir önişleme adımı olarak yapılır. Bunu başarmak için, sadece PCA gerçekleştirir, bazı bileşenleri seçer ve standartlaştırırsınız. Sanırım standartlaşmamış bileşenleri ilişkisiz kalacak, ancak tam olarak aynı miktarda varyansı açıklayacak şekilde döndüren dikey bir dönüş (varimax gibi) bulmak mümkündür; bu ilginç bir soru, düşünmem gerek. Ama bunu hiç görmedim, kesinlikle makine öğreniminde değil.
amip

2
Bu arada, PCA'dan sonra uygulamak istediğiniz "bazı makine öğrenme algoritmaları" nelerdir? Bu alakalı olabilir.
amip

1
Standart PC'lerinizi döndürürseniz, mesafelerin hiç değişmeyeceğini unutmayın! Bu yüzden daha sonra herhangi bir mesafe tabanlı algoritma için önemli olmamalıdır.
amip

Yanıtlar:


10

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=USVUkSkVk,
boyutsal küçülmeyi nerede yapacağız kbileşenler. Bu bileşenlerin dikey bir "faktör dönüşü" dikey bir seçim anlamına gelirk×k matris R, ve ayrıştırmaya takılması:
XUkSkVk=UkRRSkVk=n1UkRRotatedstandardized scoresRSkVk/n1Rotated loadings.
Buraya n1UkR,dö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çesben2/(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, LR,, 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.

(LR,)LR,=R,S2n-1R,.
Bu mantıklı: rotasyon, başlangıçta tarafından verilen bileşenlerin varyanslarını basitçe yeniden dağıtır sben2/(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:

  1. İlk bileşeni alın ve kbileşen. İlki varyans varσmaksimum>μ ve sonuncusu varyansa sahip σmin<μ.
  2. 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.
  3. İlk bileşen şimdi yapıldı, varyans var μ.
  4. 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:
  1. 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. 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. 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.

  4. 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 (LR,)LR, 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 σben2, 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).


Sanırım, iki bileşen çifti için (puanları), sapmalarını eşitlemek için dönüş açısı 45 derece olacaktır. Ancak, 3+ bileşenle tüm görevi nasıl yapacağınızı hayal bile edemiyorum.
ttnphns

1
@feilong, bir kerede bir çift bileşenin varyansını eşitlemek çok yetersiz bir algoritma olduğunu düşünüyorum. Önerdiğim, bir bileşenin varyansı küresel ortalama varyansa tam olarak eşit olacak şekilde dönüşleri seçmektir. Sonra bu bileşen "yapılır" ve geri kalanı ile başa çıkabilir. Bu, tüm varyansların sınırlı sayıda adımda eşitleneceği garanti edilir. Bir örnek için önceki yorumuma bakın.
amip

1
@amoeba Haklısın, bu daha iyi bir çözüm ve n-1 adımlarla bitmeli.
feilong

1
@amoeba Python kullanarak minimal uygulamamı ekledim. Büyük matrisler için zaman alıcı olabileceğinden tüm matrisi çoğaltan kısmı değiştirdim.
feilong

1
@amoeba Özellikle temel bileşenler için, maksimum ve minimum arama parçasını kaldırarak daha fazla zaman kazanmak mümkündür. Sadece 1. ve 2. bileşenleri döndürebiliriz (1. bileşenin ortalama varyansa sahip olmasını sağlamak için) ve sonra 2. ve 3. bileşenleri vb. Sadece her bir çiftin toplam varyansının daha büyük olduğundan emin olmalıyız mu.
feilong

2

Perspektif ve kapsamlı cevabında @amoeba - cevabın bir parçası olarak - kendileri için istenen varyansları elde etmek için (ilişkisizliği kaybetme pahasına iken) ilişkisiz iki değişkeni (örneğin ana bileşenler gibi) nasıl döndürebildiğini gösterdi. . Dik değişkenlerX ve Y sapmalar var σmbirx2 (daha büyük) ve σmbenn2(daha küçük). Onları döndürün kiX keyfi, azalan varyans elde edecek μ2 (süre Ysonuç olarak, varyans haline gelecektir σmbirx2+σmbenn2-μ2).

@ amip, bu tür bir dönme açısını hesaplayabileceğimiz formülü gösterir, marulθ:

μ2=marul2θ(σmbirx2)+günah2θ(σmbenn2)

ancak bu denklemin nereden geldiğini göstermemiştir; muhtemelen açıklama yapmadan açık olduğunu düşünüyor. Açık ya da değil, bir şekilde açıklığa kavuşturmaya değer olduğuna inanıyorum. Cevabım bir yol sunuyor.

Böylece, ilişkisiz değişkenler alanında elipsoidal, ortalanmış bir veri bulutumuz var X ve Y. Eksenleri açı ile döndürmeliyizθ. Buluttaki bir veri noktası (resimde yeşil nokta olarak gösterilir)X koordinat x olarak bu koordinatı alacak x* rotasyondan sonra.

rotasyonun gösterimi

Koordinat projeksiyonunun x döndürülmüş eksene çentikX* tarafından verildi x'=xmarulθ(hipotenüs olarak katetus ve aralarındaki açı). Ayrıca şunu da gözlemleyin:x* daha az x' uzunluk kesimi ile x'-x* koordinattan hesaplanabilir y: ygünahθ(başka bir kateter ve hipotenüs). Ve bu yüzden,

x*=x'-(x'-x*)=xmarulθ-ygünahθ

İki değişkenin varyanslarını (veya karelerin toplamlarını) ve varyansını (karelerin toplamını) biliyoruz (başlangıca bakın) μ2 nın-nin X*. Sonra şöyle:

μ2=Σx*2=Σ(xmarulθ-ygünahθ)2=Σ(x2marul2θ+y2günah2θ-2xymarulθgünahθ)=marul2θΣx2+günah2θΣy2-2marulθgünahθΣxy= 0 (X ve Y ilişkisiz)=marul2θ(σmbirx2)+günah2θ(σmbenn2)

Tahmin ettiğiniz marulθ@amoeba'nın gösterdiği gibi rotasyonu gerçekleştirin.


2
+1. Bunun açık olduğunu düşünmüyordum (değil), ama doğrulamanın kolay olduğunu düşündüm :-) Bir de doğrudan cebirle yazabilir (cevabımda olduğu gibi)
(marulθgünahθ-günahθmarulθ)(σmaksimum200σmin2)(marulθgünahθ-günahθmarulθ),
ve ürünün sol üst elemanının hesaplanması. Tabii ki aynı mantık, sadece farklı şekilde ifade edildi. Teşekkürler!
amip

Ve geometrik açıklamanızın ve "doğrudan" hesaplamanızın (matrisler olmadan) anlaşılması daha kolay ve doğru sezgileri geliştirmek için çok yararlı olduğunu düşünüyorum.
amip

0

Bazı şeyleri doğru bir şekilde yorumlarsam, ilk prensip bileşeninin (özdeğer) verilerdeki varyansın çoğunu açıkladığı anlamına gelir. Bu, sıkıştırma yönteminiz doğrusal olduğunda gerçekleşebilir. Ancak, özellik alanınızda doğrusal olmayan bağımlılıklar olabilir .

TL / DR: PCA doğrusal bir yöntemdir. Boyut küçültme için Otomatik Kodlayıcıları (doğrusal olmayan pca) kullanın. Makine öğrenme bölümü denetimli öğrenme ise, otomatik kodlayıcı için (hiper) parametreleri ayarlarken kayıp fonksiyonunuzu izlemeniz yeterlidir. Bu şekilde orijinal verilerinizin çok daha iyi sıkıştırılmış bir versiyonunu elde edersiniz.

Burada, PCA kullanarak tutulacak en iyi ana bileşen sayısını (hiper parametre) bulmak için ızgara araması yaptıkları bir scikit örneği. Son olarak alt boyutlu uzaya Lojistik Regresyon uygularlar: http://scikit-learn.org/stable/auto_examples/plot_digits_pipe.html#example-plot-digits-pipe-py

Protip: Otomatik kodlayıcıların kapalı bir form çözümü (afaik) yoktur, bu nedenle bağlamınız veri akışı yapıyorsa, otomatik kodlayıcınızı (sıkıştırılmış gösterim) sürekli olarak güncelleyebileceğiniz ve böylece konsept sapması gibi şeyleri telafi edebileceğiniz anlamına gelir. Pca ile yeni veriler geldiğinde zaman zaman parti modunu yeniden eğitmeniz gerekir.

Bazı özelliklere daha fazla "ağırlık" vermek için, düzenlemeye bakınız ( https://en.wikipedia.org/wiki/Norm_(mathematics normlarından başlıyorum ). Ayrıca lojistik regresyonun algıya ne kadar benzediğine şaşırabilirsiniz.


Bunun OP'nin sorusuna nasıl cevap verdiğini anlamıyorum; cevabınız soru ile tamamen alakasız görünüyor.
amip

Bu yüzden merak ediyordum: sadece varyansını bölmenin ve daha az varyanslı PC'lerle paylaşmanın basit bir yolu var mı? OP boyutsal küçültme yapmak istiyor. Sorununu çözmek için bir alternatif sundum, çünkü sonuçta OP'nin istediği performans ölçülmedikçe daha iyi performansla sonuçlanmayı garanti etmez. Hilbert uzaylarında / normlu alanlarda çalışmak daha iyi sonuçları garanti etmez. Performans ölçümü daha iyi sonuç verir.
shuriken x blue
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.