Garfield
YZF Admin
NumPy’de tekil değer ayrışımı (SVD), bir matrisi
Ön koşul olarak Python ortamında NumPy’nin kurulu olması ve ayrıştırılacak verinin iki boyutlu bir NumPy dizisi olması gerekir. Aşağıdaki örnekte varsayımsal olarak 2×2 bir matris kullanılmıştır:
NumPy, tekil değerleri köşegen matrisi biçiminde değil, doğrudan dizi olarak döndürür. Yeniden oluşturma sırasında bu değerleri
Beklenen sonuç
Bir
Örneğin 100×20 boyutlu bir matris için indirgenmiş biçimde
Tekil değerler, matrisin yapısındaki bileşenlerin göreli önemini gösterir. En büyük birkaç tekil değeri koruyup geri kalanları atarak yaklaşık bir matris elde edebilirsiniz. Bunun için
Burada
Yaklaşımın ne kadar iyi olduğunu hata normuyla ölçebilirsiniz:
Hatanın küçük olması, seçilen
Bu kullanım, matrisin baskın bileşenlerini veya yaklaşık rütbesini incelemek için uygundur. Fakat daha sonra matrisi yeniden oluşturmak ya da tekil vektörleri kullanmak istiyorsanız
Tekil değerler büyükten küçüğe sıralanır. Çok küçük tekil değerler, matrisin bazı yönlerinin diğerlerine göre daha az bilgi taşıdığını veya matrisin sayısal olarak düşük rütbeli olmaya yakın olduğunu gösterebilir. Bununla birlikte, bir tekil değerin “sıfıra yakın” sayılması ölçeğe ve sayısal toleransa bağlıdır; sabit bir eşik her veri kümesinde doğru sonuç vermez.
Yaklaşık rütbe hesabı için NumPy’nin sayısal toleransına dayalı
Bu değer, matematiksel olarak her zaman kesin ve gürültüden bağımsız bir rütbe kanıtı değildir. Ölçüm gürültüsü veya kayan nokta yuvarlaması varsa küçük tekil değerler gerçek yapıyla gürültüyü birbirinden ayırmayı zorlaştırabilir. Bu durumda tekil değerleri ölçekleriyle birlikte inceleyip uygun toleransı uygulamanız gerekir.
Karmaşık sayılardan oluşan bir matris için ayrıştırmanın eşlenik transpozla ilişkili olduğunu unutmayın. Gerçek sayılı matrislerde
A = UΣVᵀ biçiminde ayırmak için numpy.linalg.svd() işleviyle hesaplanır. İşlev varsayılan olarak U, tekil değerler ve Vᵀ matrisini döndürür; küçük tekil değerleri sıfırlayarak matrisi yaklaşık yeniden oluşturabilir, boyut indirgeme yapabilir veya matrisin sayısal rütbesini inceleyebilirsiniz.Temel hesaplama
Ön koşul olarak Python ortamında NumPy’nin kurulu olması ve ayrıştırılacak verinin iki boyutlu bir NumPy dizisi olması gerekir. Aşağıdaki örnekte varsayımsal olarak 2×2 bir matris kullanılmıştır:
Python:
import numpy as np
A = np.array([
[3.0, 1.0],
[1.0, 3.0]
])
U, s, Vt = np.linalg.svd(A)
print("U =")
print(U)
print("Tekil değerler =")
print(s)
print("Vt =")
print(Vt)
U ve Vt ortogonal matrislerdir. s ise tekil değerleri büyükten küçüğe sıralanmış tek boyutlu bir dizi olarak verir. Bu örnekte iki tekil değer elde edilir; kesin ondalık gösterim, kullanılan NumPy ve yazdırma ayarlarına göre değişebilir.NumPy, tekil değerleri köşegen matrisi biçiminde değil, doğrudan dizi olarak döndürür. Yeniden oluşturma sırasında bu değerleri
Σ matrisinin köşegenine yerleştirmeniz gerekir:
Python:
Sigma = np.zeros_like(A)
np.fill_diagonal(Sigma, s)
A_yeniden = U @ Sigma @ Vt
print(np.allclose(A, A_yeniden))
Beklenen sonuç
True değeridir. Bu, ayrıştırmadan alınan parçaların birlikte özgün matrisi sayısal yuvarlama sınırları içinde yeniden oluşturduğunu gösterir.Dönen değerlerin boyutları ne anlama gelir?
Bir
m × n matriste varsayılan full_matrices=True ayarı, U ve Vt için tam boyutlu matrisler üretir. Birçok uygulamada yalnızca gerekli bileşenleri almak için full_matrices=False kullanılır. Bu seçenek, indirgenmiş SVD olarak da adlandırılan daha küçük biçimi verir.| Çıktı | Anlamı | Kullanım amacı |
|---|---|---|
| U | Sol tekil vektörleri içerir | Dönüşümün çıktı yönlerini incelemek |
| s | Tekil değerleri içerir | Önem sırası, yaklaşık rütbe ve boyut indirgeme |
| Vt | Sağ tekil vektörlerin transpozu olan Vᵀ matrisidir | Girdi yönlerini incelemek ve matrisi yeniden oluşturmak |
| full_matrices=False | Gereksiz tamamlayıcı vektörleri dışarıda bırakır | Daha az bellek kullanmak ve indirgenmiş hesap yapmak |
U yaklaşık 100×20, s 20 elemanlı ve Vt 20×20 boyutlu olur. Bu nedenle büyük ve dikdörtgen matrislerde genellikle aşağıdaki kullanım daha pratiktir:
Python:
U, s, Vt = np.linalg.svd(A, full_matrices=False)
Boyut indirgeme için ilk k tekil değeri kullanma
Tekil değerler, matrisin yapısındaki bileşenlerin göreli önemini gösterir. En büyük birkaç tekil değeri koruyup geri kalanları atarak yaklaşık bir matris elde edebilirsiniz. Bunun için
U ve Vt matrislerinin ilgili sütun ve satırlarını, s dizisinin de ilk k elemanını seçin.
Python:
import numpy as np
A = np.array([
[3.0, 1.0],
[1.0, 3.0]
])
U, s, Vt = np.linalg.svd(A, full_matrices=False)
k = 1
A_yaklasik = (U[:, :k] * s[:k]) @ Vt[:k, :]
print(A_yaklasik)
Burada
U[:, :k] * s[:k] ifadesi, U matrisinin ilk sütununu ilgili tekil değerle çarpar. Ardından Vt matrisinin ilk satırıyla çarpım yapılır. k=1 yalnızca en büyük tekil değeri koruduğu için sonuç genellikle özgün matrise eşit olmaz; amaç daha az bileşenle yaklaşık temsil elde etmektir. k, özgün sütun veya satır sayısından büyük seçilmemelidir.Yaklaşımın ne kadar iyi olduğunu hata normuyla ölçebilirsiniz:
Python:
hata = np.linalg.norm(A - A_yaklasik, ord="fro")
print(hata)
Hatanın küçük olması, seçilen
k bileşeninin matrisi iyi temsil ettiğini gösterir; ancak tek başına modelin veya verinin anlamlı olduğu kanıtlanmaz. k değerini seçerken kabul edilebilir hata, bellek kullanımı ve korunması gereken bilgi birlikte değerlendirilmelidir.Tekil değerleri yalnızca hesaplama
U ve Vt matrislerine ihtiyacınız yoksa gereksiz matrisleri üretmeden yalnızca tekil değerleri alabilirsiniz:
Python:
s = np.linalg.svd(A, compute_uv=False)
print(s)
Bu kullanım, matrisin baskın bileşenlerini veya yaklaşık rütbesini incelemek için uygundur. Fakat daha sonra matrisi yeniden oluşturmak ya da tekil vektörleri kullanmak istiyorsanız
compute_uv=False seçmemelisiniz; çünkü bu seçenek U ve Vt çıktısını döndürmez.Sonuç nasıl yorumlanır?
Tekil değerler büyükten küçüğe sıralanır. Çok küçük tekil değerler, matrisin bazı yönlerinin diğerlerine göre daha az bilgi taşıdığını veya matrisin sayısal olarak düşük rütbeli olmaya yakın olduğunu gösterebilir. Bununla birlikte, bir tekil değerin “sıfıra yakın” sayılması ölçeğe ve sayısal toleransa bağlıdır; sabit bir eşik her veri kümesinde doğru sonuç vermez.
Yaklaşık rütbe hesabı için NumPy’nin sayısal toleransına dayalı
matrix_rank işlevini kullanabilirsiniz:
Python:
rutbe = np.linalg.matrix_rank(A)
print(rutbe)
Bu değer, matematiksel olarak her zaman kesin ve gürültüden bağımsız bir rütbe kanıtı değildir. Ölçüm gürültüsü veya kayan nokta yuvarlaması varsa küçük tekil değerler gerçek yapıyla gürültüyü birbirinden ayırmayı zorlaştırabilir. Bu durumda tekil değerleri ölçekleriyle birlikte inceleyip uygun toleransı uygulamanız gerekir.
Karmaşık sayılardan oluşan bir matris için ayrıştırmanın eşlenik transpozla ilişkili olduğunu unutmayın. Gerçek sayılı matrislerde
Vᵀ, karmaşık matrislerde ise pratikte eşlenik transpoz işlemleri gerekir; bu nedenle yeniden oluşturma kodunda veri tipine uygun NumPy işlemlerini kullanmalısınız.