Yaptığınız şey yanlış: PCA için PRESS'i böyle hesaplamak mantıklı değil! Özellikle, sorun 5. adımınızda yatmaktadır.
PCA için PRESS'e naif yaklaşım
Veri kümesi oluşur olsun noktaları D : boyutlu uzayda x ( i ) ∈ R, d ,ndx( i )∈ Rd,i = 1 … nx(i)X(−i)kU(−i)∥∥x(i)−x^(i)∥∥2=∥∥x(i)−U(−i)[U(−i)]⊤x(i)∥∥2P R E S S ? = n ∑ i = 1 ‖ x ( i ) - U ( - i ) [ U ( - i ) ] ⊤ x ( i ) ‖ 2 .i
PRESS=?∑i=1n∥∥x(i)−U(−i)[U(−i)]⊤x(i)∥∥2.
Kolaylık olması açısından, burada merkezleme ve ölçekleme konularını görmezden geliyorum.
Saf yaklaşım yanlış
Yukarıdaki sorun kullandığımız olmasıdır tahmin hesaplamak için , ve bu çok kötü bir şey olduğunu.x ( i )x(i)x^(i)
Yeniden oluşturma hatası formülünün temelde aynı olduğu bir regresyon senaryosundaki önemli farka dikkat edin , ancak tahmini , değil , tahmin değişkenleri kullanılarak hesaplanır . PCA'da bu mümkün değildir, çünkü PCA'da bağımlı ve bağımsız değişkenler yoktur: tüm değişkenler birlikte ele alınır.∥∥y(i)−y^(i)∥∥2y^(i)y(i)
Pratikte bu, yukarıda hesaplandığı gibi PRESS'in artan sayıda bileşen ile azalabileceği ve asla minimum seviyeye ulaşamayacağı anlamına gelir . Bu da tüm bileşenlerinin önemli olduğunu düşünmesini sağlayacaktır . Ya da belki bazı durumlarda asgari seviyeye ulaşır, ancak yine de optimal boyutluluğa fazla uyma ve fazla tahmin etme eğilimi gösterir.kd
Doğru yaklaşım
Birkaç olası yaklaşım vardır, bakınız Bro ve ark. (2008) Bileşen modellerinin çapraz doğrulaması: genel bir bakış ve karşılaştırma için mevcut yöntemlere eleştirel bir bakış. Bir yaklaşım, bir kerede bir veri noktasının bir boyutunu dışarıda bırakmaktır (yani , yerine ), böylece eğitim verileri bir eksik değere sahip bir matris haline gelir ve sonra bu eksik değeri PCA ile tahmin etmek ("impute"). (Tabii ki, matris elemanlarının daha büyük bir kısmını, örneğin% 10'u rastgele tutabilir). Sorun, PCA'nın eksik değerlerle hesaplanmasının hesaplama olarak oldukça yavaş olabilmesidir (EM algoritmasına dayanır), ancak burada birçok kez tekrarlanması gerekir. Güncelleme: bkz. Http://alexhwilliams.info/itsneuronalblog/2018/02/26/crossval/x(i)jx(i) güzel bir tartışma ve Python uygulaması için (eksik değerlere sahip PCA, alternatif en küçük kareler aracılığıyla uygulanır).
Çok daha pratik bulduğum bir yaklaşım, bir seferde bir veri noktasını bırakmak , eğitim verilerinde PCA'yı (tam olarak yukarıdaki gibi) hesaplamak, ancak , bunları teker teker bırakın ve geri kalanını kullanarak bir yeniden oluşturma hatası hesaplayın. Bu başlangıçta oldukça kafa karıştırıcı olabilir ve formüller oldukça dağınık olma eğilimindedir, ancak uygulama oldukça basittir. Önce (biraz korkutucu) formülü vereyim ve sonra kısaca açıklayayım:x(i)x(i)
PRESSPCA=∑i=1n∑j=1d∣∣∣x(i)j−[U(−i)[U(−i)−j]+x(i)−j]j∣∣∣2.
Buradaki iç döngüyü düşünün. Bir noktayı bıraktık ve eğitim verilerinde temel bileşenlerini hesapladık . Şimdi, her bir değer tutmak test olarak ve geri kalan boyutlarını kullanmak gerçekleştirmek için kestirim . Kestirim olan arasında (en küçük kareler), "çıkıntı" koordinatı inci matrisini yayılmış tarafından . Bunu hesaplamak için, bir nokta bulmak PC uzayda en yakın olanx(i)kU(−i)x(i)jx(i)−j∈Rd−1x^(i)jjx(i)−jU(−i)z^Rkx(i)−j hesaplanarak burada olduğunu ile -inci satır başladı ve yalancı ters anlamına gelir. Şimdi i orijinal boşluğa geri : ve koordinatını alın . z^=[U(−i)−j]+x(i)−j∈RkU(−i)−jU(−i)j[⋅]+z^U(−i)[U(−i)−j]+x(i)−jj[⋅]j
Doğru yaklaşıma yaklaşım
PLS_Toolbox'ta kullanılan ek normalleştirmeyi tam olarak anlamıyorum, ama burada aynı yöne giden bir yaklaşım var.
temel bileşenlerin alanı ile eşlemenin başka bir yolu daha vardır : , yani yalnızca sahte ters yerine devri al. Başka bir deyişle, test için dışarıda bırakılan boyut hiç sayılmaz ve karşılık gelen ağırlıklar da basitçe dışarı atılır. Bunun daha az doğru olması gerektiğini düşünüyorum, ancak çoğu zaman kabul edilebilir olabilir. İyi olan şey, ortaya çıkan formülün şimdi aşağıdaki gibi vektörleştirilebilmesidir (hesaplamayı atlarım):x(i)−jz^approx=[U(−i)−j]⊤x(i)−j
PRESSPCA,approx=∑i=1n∑j=1d∣∣∣x(i)j−[U(−i)[U(−i)−j]⊤x(i)−j]j∣∣∣2=∑i=1n∥∥(I−UU⊤+diag{UU⊤})x(i)∥∥2,
burada kompaktlık için olarak yazdım ve tüm çapraz olmayan öğeleri sıfıra ayarlamak anlamına geliyor. Bu formülün, küçük bir düzeltmeyle tam olarak ilk formüle (saf PRESS) benzediğini unutmayın! Bu düzeltmenin PLS_Toolbox kodunda olduğu gibi yalnızca diyagonaline bağlı olduğunu da unutmayın . Bununla birlikte, formül hala PLS_Toolbox'ta uygulanmış gibi görünüyor ve bu farkı açıklayamıyorum. U d i a g {⋅} U U ⊤U(−i)Udiag{⋅}UU⊤
Güncelleme (Şubat 2018): Yukarıda bir prosedürü "doğru" ve başka bir "yaklaşık" olarak adlandırdım, ancak artık bunun anlamlı olduğundan emin değilim. Her iki prosedür de mantıklı ve bence ikisi de daha doğru değil. "Yaklaşık" prosedürünün daha basit bir formüle sahip olmasını gerçekten seviyorum. Ayrıca, "yaklaşık" prosedürünün daha anlamlı görünen sonuçlar verdiği bazı veri setim olduğunu hatırlıyorum. Ne yazık ki, artık ayrıntıları hatırlamıyorum.
Örnekler
Bu yöntemlerin iyi bilinen iki veri kümesi için karşılaştırması: Iris veri kümesi ve şarap veri kümesi. Naif yöntemin monoton olarak azalan bir eğri oluşturduğunu, diğer iki yöntemin ise minimum bir eğri verdiğini unutmayın. İris durumunda, yaklaşık yöntemin en uygun sayı olarak 1 PC önerdiğini, ancak sözde ters yöntemin 2 PC önerdiğini unutmayın. (Ve Iris veri kümesi için herhangi bir PCA dağılım grafiğine bakıldığında, her iki ilk PC'nin de bir miktar sinyal taşıdığı görülüyor.) Ve şarap durumunda, sahte ters yöntem açıkça 3 PC'yi gösteriyor, ancak yaklaşık yöntem 3 ile 5 arasında karar veremiyor.
Çapraz doğrulama yapmak ve sonuçları çizmek için Matlab kodu
function pca_loocv(X)
%// loop over data points
for n=1:size(X,1)
Xtrain = X([1:n-1 n+1:end],:);
mu = mean(Xtrain);
Xtrain = bsxfun(@minus, Xtrain, mu);
[~,~,V] = svd(Xtrain, 'econ');
Xtest = X(n,:);
Xtest = bsxfun(@minus, Xtest, mu);
%// loop over the number of PCs
for j=1:min(size(V,2),25)
P = V(:,1:j)*V(:,1:j)'; %//'
err1 = Xtest * (eye(size(P)) - P);
err2 = Xtest * (eye(size(P)) - P + diag(diag(P)));
for k=1:size(Xtest,2)
proj = Xtest(:,[1:k-1 k+1:end])*pinv(V([1:k-1 k+1:end],1:j))'*V(:,1:j)';
err3(k) = Xtest(k) - proj(k);
end
error1(n,j) = sum(err1(:).^2);
error2(n,j) = sum(err2(:).^2);
error3(n,j) = sum(err3(:).^2);
end
end
error1 = sum(error1);
error2 = sum(error2);
error3 = sum(error3);
%// plotting code
figure
hold on
plot(error1, 'k.--')
plot(error2, 'r.-')
plot(error3, 'b.-')
legend({'Naive method', 'Approximate method', 'Pseudoinverse method'}, ...
'Location', 'NorthWest')
legend boxoff
set(gca, 'XTick', 1:length(error1))
set(gca, 'YTick', [])
xlabel('Number of PCs')
ylabel('Cross-validation error')
tempRepmat(kk,kk) = -1
hattın rolü nedir? Önceki satır zatentempRepmat(kk,kk)
-1'e eşit değil mi? Ayrıca neden eksiler? Hata yine de kare olacak, bu yüzden eksileri kaldırılırsa hiçbir şeyin değişmeyeceğini doğru anladım mı?