Makine öğrenimine gerçekten dalmak için bilmeniz gerekenlerin önemli bir kısmı lineer cebirdir ve bu eğitim tam olarak bunu ele alıyor. Bugünkü yazı, vektörler ve matrisler düzeyine inerek, makine öğrenimi yöntemlerinin nasıl ve ne zaman çalıştığına dair sezginizi geliştirmenize yardımcı olacak lineer cebir konularını kapsıyor.
Eğitimin sonunda, umarız bir algoritmaya yakından bakma konusunda kendinizi daha özgüvenli hissedersiniz!
İçindekiler
Giriş
Veri bilimini öğrenmek istiyorsanız ustalaşmanız gereken üç temel konudan biri makine öğrenimidir. Ve makine öğrenimine gerçekten girdiğinizde, daha derine inmek ve algoritmaların nasıl çalıştığına dair sezgi ve anlayış kazanmak önemlidir.
Ve bence siz, (aday) veri bilimci, bu noktaya ulaşmanın zor olabileceği konusunda muhtemelen benimle hemfikirsiniz.
Ancak böyle olmak zorunda değil.
SciPy ve NumPy Karşılaştırması
DataCamp’in NumPy eğitiminden, bu kütüphanenin Python’da bilimsel hesaplamanın çekirdek kütüphanelerinden biri olduğunu anlamış olacaksınız. Bu kütüphane, Fen ve Mühendislikteki problemlerin matematiksel modellerini bilgisayarda çözmek için kullanılabilecek bir dizi araç ve teknik içerir. Ancak en sık kullanacağınız araç, yüksek performanslı çok boyutlu bir dizi (array) nesnesidir: diziler ve matrisleri verimli biçimde hesaplamanıza olanak veren güçlü bir veri yapısıdır.
Şimdi, SciPy temelde NumPy üzerine kuruludur.
O da matematiksel algoritmalar ve yardımcı işlevler sağlayan, bilimsel hesaplama için çekirdek paketlerden biridir; ancak Python’un NumPy uzantısı üzerinde inşa edilmiştir. Bu, SciPy ve NumPy’nin sıklıkla birlikte kullanıldığı anlamına gelir!
Bu eğitimin ilerleyen kısımlarında, bu iki kütüphane arasındaki iş birliğinin nasıl kendiliğinden geliştiğini daha net göreceksiniz.
NumPy ve SciPy ile Etkileşim
Her iki paketle de verimli biçimde etkileşim kurmak için, öncelikle bu kütüphanenin ve güçlü veri yapısının bazı temellerini bilmeniz gerekir. Bu dizilerle çalışmak için, bu matrisler ve diziler üzerinde çalışan çok sayıda üst düzey matematiksel işlev vardır.
Devamında, SciPy ile verimli çalışabilmek için hakim olmanız gereken konulara hızlı bir genel bakış elde edeceksiniz. Özünde, dizi yapısını, veri türlerini nasıl ele alacağınızı ve dizi şekillerini nasıl değiştirebileceğinizi bilmeniz gerekir. Bunlar size yabancı geliyorsa, DataCamp’in Python NumPy Eğitimini almaya ve öğrenirken NumPy kopya kağıdına göz atmayı düşünün.
Tüm bunları zaten biliyorsanız, sonraki bölümü atlayıp “SciPy ile Lineer Cebir” kısmına geçin; ancak lineer cebir için SciPy kopya kağıdınızı hazır bulundurun!
NumPy ndarray Nesnelerinin Temelleri
Yapısal olarak bir dizi, işaretçilerden ibarettir. Bir bellek adresi, bir veri türü, bir şekil ve adımların (strides) birleşimidir. Ham veri hakkında, bir öğenin nasıl bulunacağı ve yorumlanacağı hakkında bilgi içerir.
Bellek adresi ve adımlar, dizilerin daha alt düzey detaylarına indiğinizde önem kazanırken, veri türü ve şekil, yeni başlayanların mutlaka bilmesi ve anlaması gereken şeylerdir. Göz önünde bulundurmak isteyebileceğiniz iki başka öznitelik de diziniz hakkında daha fazla bilgi toplamanızı sağlayan data ve size’dır.
Aşağıdaki DataCamp Light parçasında ndarray özniteliklerinin kullanımını tazeleyin. myArray dizisi zaten yüklendi. IPython kabuğuna yazarak ve ENTER’a basarak inceleyebilirsiniz.
# Inspect the data of `myArray`
print(myArray.data)
# Inspect the data type of `myArray`
print(_________________)
# Inspect the shape of `myArray`
print(__________________)
# Inspect the size of `myArray`
print(__________________)
Yukarıdaki kod parçasında yer alan sonuçlarda myArray’in veri türünün int64 olduğunu göreceksiniz. Dizilerle yoğun çalışırken, astype() yöntemiyle dizilerinizi bir veri türünden diğerine dönüştürmenin yolları olduğunu kesinlikle hatırlarsınız.
Bununla birlikte, SciPy ve NumPy’yi birlikte kullanırken, özellikle karmaşık sayılarla çalışıyorsanız, aşağıdaki NumPy tür yönetimi işlevlerini de çok kullanışlı bulabilirsiniz:
# Return the real part of `myArray` elements
np.real(myArray)
# Return the imaginary part of `myArray` elements
np.imag(myArray)
# Return a real array if the complex parts are close to 0
np.real_if_close(myArray,tol=1000)
# Cast `myArray` to float
np.cast['f'](myArray)
Sonuçları görmek için print() çağrıları eklemeyi deneyin. Ardından karmaşık sayıların gerçek ve sanal kısımları olduğunu göreceksiniz. np.real() ve np.imag() işlevleri sırasıyla bu kısımları döndürmek üzere tasarlanmıştır.
Alternatif olarak, bir dizi nesnesini farklı bir veri türüne dökmek için yukarıdaki örnekte olduğu gibi np.cast da kullanabilirsiniz.
Yukarıdaki kod parçasında gerçekten zor görünen tek şey np.real_if_close() işlevidir. myArray gibi karmaşık bir girdi verdiğinizde, karmaşık kısımlar sıfıra yakınsa gerçek bir dizi elde edersiniz. Bu son kısım, “0’a yakınlık”, işlevine iletebileceğiniz tol argümanıyla kendiniz tarafından ayarlanabilir. Eşiikle oynayıp neler olduğunu görün!
Dizi (Array) Oluşturma
Artık dizinizi nasıl inceleyeceğinizi ve veri türünde nasıl ayarlamalar yapacağınızı gördünüz; fakat dizileri nasıl oluşturacağınızı açıkça görmediniz. Bunu yapmak için np.array() kullanabileceğinizi zaten biliyor olmalısınız; ancak bilmeniz gereken başka dizi oluşturma yordamları da var: np.eye() ve np.identity().
np.eye() işlevi, argüman olarak verdiğiniz pozitif tam sayıya eşit boyutlarda kare bir matris oluşturmanıza olanak tanır. Elemanlar genellikle sıfırlarla doldurulur, yalnızca matrisin köşegeni birlerle doldurulur. np.identity() işlevi de aynı şekilde çalışır ve birim (identity) bir dizi döndürür.
Ancak, unutmayın ki np.eye(), hangi köşegenin birlerle doldurulacağını belirtmek için belirtebileceğiniz ek bir k argümanı alabilir.
Lineer cebir için matrislerle çalışırken işinize kesinlikle yarayacak diğer dizi oluşturma işlevleri şunlardır:
np.arange() işlevi, iki sayı arasında eşit aralıklı değerlere sahip bir dizi oluşturur. Elemanlar arasındaki aralığı belirtebilirsiniz,
Aynısı np.linspace() için de geçerlidir; ancak bu işlevle dizinizde kaç eleman istediğinizi belirtirsiniz.
Son olarak np.logspace(), yine eşit aralıklı değerlerden oluşan diziler oluşturur; fakat bu kez logaritmik ölçekte. Bu, aralığın artık logaritmik olduğu anlamına gelir: iki sayı, bu sayıların 10 tabanındaki logaritmaları arasında eşit aralıklıdır.
Bu işlevler, önce bu yazıda okuduğunuz ağ (mesh) ızgaralarını oluşturmak için kullanılabilecek ağ biçiminde diziler oluşturur.
Not: Aşağıdaki kod parçasında numpy zaten np olarak içe aktarılmıştır!
# Create a 2X2 identity matrix with `np.eye()`
__________________
# Create a 3X3 identity matrix with `np.identity()`
__________________
# Uniformly spaced values: spacing
_________(3, 7, 2)
# Uniformly spaced values: number of samples
___________(2, 3, 5)
# Uniformly spaced values: logarithmic spacing
___________(2, 3, 4)
Artık hafızanızı tazelediniz ve dizilerinizin veri türlerini nasıl ele alacağınızı biliyorsunuz; şimdi indeksleme ve dilimleme konusunu da ele alma zamanı.
İndeksleme ve Dilimleme
İndeksleme ile, köşeli parantezleri [] kullanarak dizi değerlerini indekslersiniz. Başka bir deyişle, bir dizinin seçili öğelerine (bir alt kümeye) erişmek istiyorsanız indekslemeyi kullanabilirsiniz. Verinizi dilimlemek, alt kümeye ayırmaya oldukça benzer; ancak biraz daha gelişmiş sayılabilir. Bir diziyi dilimlediğinizde yalnızca belirli değerlere odaklanmaz, “konumlar” yerine “bölgeler” ile çalışırsınız.
Aşağıdaki kod örnekleriyle her iki kavramı da tazeleyin:
# Slice `myArray` at index 0 and 1
print(____________)
# Slice `my_2dArray` at row 0 and 1, column 1
print(________________)
# Slice `my_3dArray` at row 1
print(my_3dArray[1,...])
# Boolean indexing: only values < 2
print(myArray[____________])
# Fancy indexing
print(my_2dArray[[1, 0, 1, 0],[0, 1, 2, 0]])
Artık zihin dilimleme ve indekslemeyle taze iken, SciPy ile birlikte bilimsel hesaplamaya girerken işinizi daha verimli hale getirebilecek bazı indeks hileleriyle de ilgilenebilirsiniz. Dört işlev özellikle karşınıza çıkacaktır: np.mgrid(), np.ogrid(), np.r ve np.c.
NumPy ile biraz deneyiminiz varsa son iki işleve aşina olabilirsiniz. np.r ve np.c, sırasıyla dizileri satır veya sütun bazında yığmanız gerektiğinde sıkça kullanılır. Bu işlevlerle, np.concatenate() kullanmak yerine dizileri hızlıca inşa edebilirsiniz.
# Create a dense meshgrid
np.mgrid[1:11:2, -12:-3:3]
# Create an open meshgrid
np.ogrid[1:11:2, -12:-3:3]
# Stack arrays vertically
np.r_[3,[0]*5,-1:1:10j]
# Stack arrays horizontally
np.c_[array, my_2dArray]
Bu dört işlevin ilk ikisine bakarken neden bir ağ ızgarasına ihtiyaç duyacağınızı sorabilirsiniz. Ağ ızgaralarını, dikdörtgensel bir ızgaradaki her konumda x ve y koordinatlarını içeren iki dizi üretmek için kullanabilirsiniz. np.meshgrid() işlevi, iki 1B diziyi alır ve iki dizideki tüm (x, y) çiftlerine karşılık gelen iki 2B matris üretir.
np.mgrid() işlevi MATLAB’in meshgrid’inin bir uygulamasıdır ve aynı şekle sahip diziler döndürür. Bu, çıktı dizilerinin boyutlarının ve sayısının indeksleme boyutlarının sayısına eşit olduğu anlamına gelir.
Öte yandan np.ogrid() açık bir ağ ızgarası verir ve np.mgrid()’in verdiği sonuç kadar yoğun değildir. Yukarıdaki kod parçasında ikisi arasındaki görsel farkı görebilirsiniz.
Bu iki işlev arasındaki farklar hakkında buradan da okuyabilirsiniz.
İndeksleme/dilimleme amaçları için kullanabileceğiniz bir diğer işlev np.select()’tir. Bunu, işlevin ilk argümanında kendiniz belirleyebileceğiniz koşullara bağlı olarak bir dizi listesinden değer döndürmek için kullanabilirsiniz. İkinci argümanda ise bu seçim süreci için dikkate almak istediğiniz diziyi iletirsiniz.
Şu örneğe göz atın:
# Initialize a 2D array
my_2dArray = np.array([[1,2,3,4], [5,6,7,8]], dtype=np.int64)
# Select values from `my_2dArray`
np.select([my_2dArray < 4],[my_2dArray * 2])
Harika! Artık orijinal dizinizin doğru değerlerini seçtiğinize göre, yeni dizinizin şeklini hâlâ seçebilir ve onu manipüle edebilirsiniz.
Şekil Seçimi ve Manipülasyonu
NumPy, dizilerinizin şeklini seçmek ve manipüle etmek için pek çok yol sunar ve muhtemelen bunların çoğunu zaten biliyorsunuzdur. Aşağıdaki bölüm, işinize yarayabilecek işlevlere kısa bir genel bakış sunacak; bu nedenle yazı hepsini kapsamıyor.
Peki, SciPy ile çalışırken özellikle kullanışlı olan işlevler var mı?
Aslında en kullanışlı olanlar; dizileri düzleştirmenize, yığmanıza ve bölmenize yardımcı olanlardır. np.concatenate() yerine sıklıkla tercih edeceğiniz np.c ve np.r işlevlerini zaten gördünüz; fakat bilmek isteyeceğiniz daha birçok işlev var!
Örneğin dizilerinizi yatay olarak yığmak için np.hstack() veya dikey olarak yığmak için np.vstack(). Benzer şekilde, dizilerinizi yatay ve dikey olarak bölmek için np.vsplit() ve np.hsplit() kullanabilirsiniz. Ancak muhtemelen bütün bunları zaten biliyorsunuz.
Bunu aşağıdaki kod parçasında kanıtlayın:
#Stack arrays horizontally (column-wise)
print(_________((np.eye(2), my_2dArray)))
# Stack arrays vertically (row-wise)
print(__________((myArray, my_2dArray)))
# Split the array horizontally at the 2nd index
print(___________(my_2dArray, 2))
# Split the array vertically at the 2nd index
print(____________(my_2dArray, 2))
Unutmayın ki np.eye() işlevi 2x2 birim bir dizi oluşturur; bu da yukarıdaki kod parçasında sizin için yüklenen 2 boyutlu diziyle yığmak için idealdir.
Dizileri yığarken dikkate almanız gereken koşullar hakkında daha fazla bilgi edinmek istiyorsanız buraya gidin. Ancak, iki diziyi satır veya sütun bazında birleştirmek istiyorsanız, dizilere ve işlevlerin ne yaptığına bakarak hangi ‘kurallara’ uymanız gerektiğine dair bir sezgi de geliştirebilirsiniz.
Dizileri bölerken dikkat etmeniz gereken en önemli şey muhtemelen dizinizin şeklidir; çünkü bölmenin gerçekleşmesini istediğiniz doğru indeksi seçmek istersiniz.
Yığma ve bölme işlevlerinin yanı sıra, dizilerinizin belirli bir boyutta olmasını sağlamaya yardımcı olan işlevlerin de bilimsel hesaplamaya daha derinlemesine daldığınızda vazgeçilmez olacağını aklınızda tutun.
Şu işlevleri düşünün:
#Permute `myArray` dimensions
print(np.transpose(myArray))
# Flatten `my_3dArray`
print(my_3dArray.flatten())
# Reshape but don't change the data
print(my_2dArray.reshape(4,2))
# Resize to (6,4)
print(np.resize(my_3dArray, (6,4)))
Not: Dizinizin şeklini yeniden düzenlemek (reshape) ile yeniden boyutlandırmak (resize) arasındaki farkı unutmayın. İlkinde verinin şeklini değiştirirsiniz ancak verinin kendisini değiştirmezsiniz. Yeniden boyutlandırmada ise, seçtiğiniz şekle bağlı olarak dizideki verinin değişmesi mümkündür.
Dizilerinizi daha fazla manipüle etmenizi sağlayan işlevlerin yanı sıra, dikkate almanız gereken bir de “vektörleştirme” vardır. Bir işlevi bir diziye uyguladığınızda, genellikle o işlevi dizinin her bir elemanına uygularsınız. Örneğin, bir diziye np.cos(), np.sin() veya np.tan() uygulamayı düşünün. İşlevin tüm dizi elemanlarında çalıştığını göreceksiniz. Bunu gördüğünüzde, işlevin vektörleştirildiğini bilirsiniz.
Ancak kendi işlevlerinizi tanımladığınızda—ki bilimsel hesaplamaya girdiğinizde muhtemelen yapacaksınız—onları da vektörleştirmek isteyebilirsiniz. Bu durumlarda np.vectorize() çağrısını kullanabilirsiniz:
# Define a function `myfunc`
def myfunc(a,b):
if a > b:
return a - b
else:
return a + b
# Vectorize `myfunc`
vectorizedFunc = np.vectorize(myfunc)
# Apply
vectorizedFunc(myArray, 2)
Bilinmesi faydalı diğer vektörleştirilmiş matematiksel işlevler arasında, karmaşık dizi elemanlarının açısını veren np.angle() ve temel trigonometrik, üstel veya logaritmik işlevler yer alır.
SciPy ile Lineer Cebir
Artık her iki paketi de lehinize nasıl kullanmanız gerektiğini bildiğinize göre, bu eğitimin konusu olan lineer cebire dalma zamanı.
Ancak Python’u nasıl kullanabileceğinize geçmeden önce, çalışma alanınızın tamamen hazır olduğundan emin olun!
SciPy Kurulumu
Elbette önce Python’un kurulu olduğundan emin olmanız gerekir. Bunu hâlâ yapmanız gerekiyorsa bu sayfaya gidin :) Windows üzerinde çalışıyorsanız, Python’u PATH ortam değişkenine eklediğinizden emin olun. Ek olarak, Python’un açık kaynak kütüphanelerini kullanabilmenizi sağlayacak bir paket yöneticisini, örneğin pip’i kurmayı unutmayın.
Python 3’ün güncel sürümlerinin pip ile geldiğini unutmayın; bu nedenle pip’iniz olup olmadığını iki kez kontrol edin; varsa, başka paketler kurmadan önce yükseltin:
Ama sadece bir paket yöneticisi kurmak yeterli değil; Kütüphane için wheel dosyasını da indirmeniz gerekir: SciPy wheel’ınızı almak için buraya gidin. İndirdikten sonra, bilgisayarınızda indirme dizininde bir terminal açın ve kurulumu yapın. Ek olarak, kurulumun başarılı olup olmadığını kontrol edebilir ve çalıştırdığınız paket sürümünü doğrulayabilirsiniz:
İpucu: paketi, Anaconda Python dağıtımını indirerek kurun. Başlamak için kolay bir yoldur; çünkü Anaconda yalnızca veri bilimi için en popüler 100 Python, R ve Scala paketini içermekle kalmaz, aynı zamanda Jupyter ve Spyder gibi çeşitli açık kaynak geliştirme ortamlarını da içerir. Jupyter Notebook ile çalışmaya başlamak isterseniz, şu Jupyter notebook eğitimine göz atın.
Artık çalışma alanınızı hazırladığınıza göre, Python’da lineer cebire nihayet başlayabilirsiniz. Özünde bu disiplin, vektör uzaylarının ve aralarındaki lineer dönüşümlerin incelenmesiyle ilgilenir. Bu lineer dönüşümler matrislerle ifade edilebilir; bu da hesaplamayı kolaylaştırır.
Unutmayın: Bir vektör uzayı, lineer cebirde temel bir kavramdır. Vektörlerden oluşan bir koleksiyona sahip olduğunuz ve iki vektörü topladığınızda veya ölçeklendirdiğinizde, ortaya çıkan vektörün uzayın dışına çıkmadığı bir uzaydır. Ayrıca vektörlerin, bir matrisin satırları (veya sütunları) olduğunu hatırlayın.
Peki bu Python’da nasıl çalışır?
np.array() işleviyle kolayca bir vektör oluşturabilirsiniz. Benzer şekilde, her bir bir veya iki boyutlu ndarray’e np.matrix() veya np.mat() komutlarıyla bir matris yapısı kazandırabilirsiniz.
Aşağıdaki kod parçasında deneyin:
# Create a vector
myVector = np.array([1,2,3,4])
# Create a matrix
myMatrix = np.matrix(np.random.random((5,5)))
Yani diziler ve matrisler biçimlendirme dışında aynı şey mi?
Tam olarak değil. Bazı farklılıklar var:
Matris 2 boyutludur; diziler genellikle n boyutludur,
Yukarıdaki işlevlerin de ima ettiği gibi, matris ndarray’in bir alt sınıfıdır,
Hem dizilerin hem matrislerin .T()’si vardır; ancak yalnızca matrislerin .H() ve .I()’si bulunur,
Matris çarpımı, eleman düzeyinde dizi çarpımından farklı çalışır ve
Buna ek olarak ** işleminin matrisler ve diziler için sonuçları farklıdır
Matrislerle çalışırken, elemanlarının çoğu sıfır olan bazı matrislere rastlayabilirsiniz. Bu matrislere “seyrek matrisler” denir; çoğu elemanı sıfır olmayanlara ise “yoğun matrisler”.
Bu kendi başına önemsiz görünebilir; ancak SciPy ile lineer cebir çalışırken bazı şeyleri yapmak için kullanacağınız modüllerde fark yaratabilir. Daha somut olarak, yoğun matrisler için scipy.linalg kullanabilirsiniz; seyrek matrislerle çalışırken ise kendi scipy.sparse.linalg’ını da içeren scipy.sparse modülünü kontrol etmeyi düşünebilirsiniz.
Seyrek matrisler için onları oluşturmanın bir hayli seçeneği vardır. Aşağıdaki kod parçası bazılarını listeler:
Ek olarak, seyrek matris oluşturmak için kullanabileceğiniz başka işlevler de vardır: bsr_matrix() ile Blok Seyrek Satır matrisleri, coo_matrix() ile Koordinat formatında seyrek matrisler, dia_matrix() ile Diyagonal depolama seyrek matrisleri ve lil_matrix() ile satır tabanlı bağlı liste seyrek matrisleri.
Gerçekten çok fazla seçenek var; peki kendi seyrek matrisinizi oluştururken hangisini seçmelisiniz?
O kadar da zor değil.
Özetle, önce nasıl başlatacağınıza bakmalısınız. Sonra, seyrek matrisinizle ne yapmak istediğinizi düşünün.
Daha somut olarak, hangi tür seyrek matrisi kullanacağınıza karar vermek için aşağıdaki kontrol listesinden geçebilirsiniz:
Matrisi tek tek sayılarla doldurmayı planlıyorsanız, oluşturmak için coo_matrix() veya dok_matrix() seçin.
Matrisi köşegen olarak bir diziyle başlatmak istiyorsanız, başlatma için dia_matrix() seçin.
Dilim tabanlı matrisler için lil_matrix() kullanın.
Matrisi daha küçük matris bloklarından oluşturuyorsanız, bsr_matrix() kullanmayı düşünün.
Satır ve sütunlarınıza hızlı erişim istiyorsanız, matrislerinizi sırasıyla csr_matrix() ve csc_matrix() işlevlerini kullanarak dönüştürün. Bu son iki işlev, matrislerinizi başlatırken harika değildir; ancak çarparken hız farkını kesinlikle fark edeceksiniz.
Çok kolay!
Vektör İşlemleri
Artık vektörler, yoğun matrisler ve seyrek matrisler arasındaki farkı öğrendiğinize veya tazelediğinize göre, vektörlere ve onlarla yapabileceğiniz matematiksel işlemlere daha yakından bakma zamanı. Eğitim burada özellikle matematiksel işlemlere odaklanıyor; böylece matrislerle benzerlikleri ve farkları göreceksiniz; ayrıca lineer cebirin büyük bir kısmı nihayetinde matrislerle çalışmaktır.
np.array() ile kolayca bir vektör oluşturabileceğinizi zaten gördünüz. Ancak artık elinizde vektörler olduğuna göre, onlara uygulanabilecek bazı temel işlemleri de bilmek isteyebilirsiniz. Aşağıdaki kod parçasında vector1 ve vector2 sizin için zaten yüklendi:
# Addition of `vector1` and `vector2`
vector3 = vector1 + vector2
# Print `vector3`
print(_______)
# Subtraction of `vector2` and `vector1`
vector4 = ________ - vector1
# print `vector4`
print(vector4)
# Dot product of `vector1` and `vector2`
dotProduct = np.dot(vector1, vector2)
# Print `dotProduct`
print(dotProduct)
# Cross product of `vector1` and `vector2`
crossProduct = np.cross(________, vector2)
# Print `crossProduct`
print(____________)
Artık bazı vektör işlemlerini başarıyla gördüğünüze göre, asıl matris işine başlama zamanı!
Matrisler: İşlemler ve Yordamlar
Önceki bölümün başında bıraktığınız yere benzer şekilde, matrisleri nasıl oluşturacağınızı biliyorsunuz; ancak bunları lehinize nasıl kullanabileceğinizi henüz bilmiyorsunuz. Bu bölüm, verimli çalışmak için kullanabileceğiniz bazı matris işlevlerine ve temel matris yordamlarına genel bir bakış sunar.
Öncelikle bazı işlevleri gözden geçirelim. Daha önce NumPy ile çalıştıysanız bunlar size oldukça kolay gelecektir; ancak henüz deneyiminiz yoksa bile, bu işlevlerin kullanıma kolay olduğunu göreceksiniz.
Bazı işlev örneklerine bakalım.
Dizileri veya matrisleri toplamak ve çıkarmak için np.add() ve np.subtract(), bölme ve çarpma için np.divide() ve np.multiply vardır. Bu gerçekten büyük bir gizem gibi görünmüyor, değil mi? Ayrıca, önceki bölümde skaler çarpımı hesaplamak için gördüğünüz np.dot() işlevi matrislerle de kullanılabilir. Ancak vektörler yerine iki matris verdiğinizden emin olun.
Bunlar temel, değil mi?
Biraz daha az temel olana geçelim. Çarpımlara geldiğinde, düşünebileceğiniz başka işlevler de vardır; vektörlerin skaler çarpımı için np.vdot(), dizilerin iç veya dış çarpımları için np.inner() veya np.outer(), np.tensordot() ve iki dizinin Kronecker çarpımı için np.kron() gibi:
İpucu: Yukarıdaki kod parçasına çıktı almak için print deyimleri ekleyerek tek tek çarpım sonuçlarını görün.
Bunların dışında, linalg modülünün bazı işlevlerini de düşünmek faydalı olabilir: matris üstel işlevleri linalg.expm(), linalg.expm2() ve linalg.expm3(). Bu üçü arasındaki fark, üstelin hesaplanma yöntemlerinde yatar. Genel bir matris üstel için ilkine bağlı kalın; ancak sonuçlardaki farkı görmek için üçünü de mutlaka deneyin!
Ayrıca linalg.cosm(), linalg.sinm() ve linalg.tanm() gibi trigonometrik işlevler; linalg.coshm(), linalg.sinhm() ve linalg.tanhm() gibi hiperbolik trigonometrik işlevler; linalg.signm() işaret işlevi; linalg.logm() matris logaritması ve linalg.sqrtm() matris karekökü.
Ek olarak, linalg.funm() işlevinin yardımıyla bir matris işlevini de değerlendirebilirsiniz. Aşağıdaki örneğe bakın:
linalg.funm(myMatrix, lambda x: x*x)
Gördüğünüz gibi birinci argüman olarak işlev uygulamak istediğiniz matrisi, ikinci argüman olarak ise matrise uygulamak istediğiniz bir işlevi (bu örnekte bir lambda işlevi) geçiriyorsunuz. linalg.funm()’e ilettiğiniz işlevin vektörleştirilmiş olması gerektiğini unutmayın.
Şimdi bazı temel matris yordamlarına bakalım. Muhtemelen ilk bakmak isteyeceğiniz şey matris öznitelikleridir: devrik (transpoz) için T, eşlenik devrik için H, ters için I ve diziye dökmek için A.
Bir matrisi devirdiğinizde, satırları orijinalin sütunları olan yeni bir matris elde edersiniz. Eşlenik devrik ise her matris elemanı için satır ve sütun indeksini değiştirir. Bir matrisin tersi, orijinal matrisle çarpıldığında birim matris veren matristir.
Bu özniteliklerin yanı sıra, sırasıyla devrik almak ve matris tersini hesaplamak için np.transpose() ve linalg.inv() gibi bazı temel matris yordamlarını kullanabileceğiniz işlevler de vardır.
Bunların dışında, ana köşegendeki elemanların toplamını np.trace() ile alabilirsiniz. Benzer şekilde, bir dizinin matris rütbesini (rank) veya belirli bir eşikten büyük Tekil Değer Ayrışımı tekil değerlerinin sayısını NumPy’nin linalg.matrix_rank işleviyle elde edebilirsiniz.
Matris rütbesi şu an için anlam ifade etmiyorsa endişelenmeyin; bu eğitimin ilerleyen kısımlarında bununla ilgili daha fazlasını göreceksiniz.
Şimdilik, kullanabileceğiniz iki yordam daha üzerinde duralım:
Bir matrisin normu linalg.norm ile hesaplanabilir: matris normu, matrisin elemanları cinsinden tanımlanan bir sayıdır. Norm, elemanların ne kadar büyük olduğunu söylediği için matris hakkında önemli bilgi verebilen yararlı bir niceliktir.
Ek olarak, kare bir matrisin elemanlarından hesaplanabilen yararlı bir değer olan determinantı linalg.det() ile hesaplayabilirsiniz. Determinant, kare matrisi tek bir sayıya indirger; bu da kare matrisin tersinir olup olmadığını belirler.
Son olarak, büyük doğrusal denklem sistemlerini çözmek, matrislerin en temel uygulamalarından biridir. \(Ax = b\) sisteminiz varsa; burada \(A\) kare bir matris, \(b\) genel bir matris olsun; çalıştığınız matris türüne bağlı olarak \(x\)’i bulmak için kullanabileceğiniz iki yöntem vardır:
# Dense matrix solver
linalg.solve(A, b)
# Linear least-square solver
linalg.lstsq(F,E)
Seyrek matrisleri çözmek için linalg.spsolve() kullanabilirsiniz. Denklemi çözemediğinizde, linalg.lstsq() komutunun yardımıyla yaklaşık bir \(x\) elde etmek yine de mümkün olabilir.
Artık matrisleri nasıl oluşturabileceğiniz ve onları matematiksel işlemler için nasıl kullanabileceğiniz hakkında fikir sahibi olduğunuza göre, makine öğrenimine gerçekten girmeniz için gereken daha ileri konuları ele alma zamanı.
Özdeğerler ve Özvektörler
Ele alacağınız ilk konu özdeğerler ve özvektörlerdir.
Özdeğerler, bir matrisin özüne bakmanın yeni bir yoludur. Ancak daha fazla detaya inmeden önce, önce özvektörlerin ne olduğunu açıklayalım. Neredeyse tüm vektörler, bir matrisle çarpıldıklarında yön değiştirir. Ancak belirli istisnai, ortaya çıkan vektörler, çarpımın sonucu olan vektörlerle aynı yöndedir. Bunlar özvektörlerdir.
Başka bir deyişle, bir özvektörü bir matrisle çarpın; bu çarpımın sonucu, orijinal özvektörün \(\lambda\) (özdeğer) ile çarpımına eşittir: \[Ax = \lambda x. \]
Bu, özdeğerin size çok değerli bilgi verdiği anlamına gelir: bir özvektörün bir matrisle çarpıldığında gerilip gerilmediğini, küçülüp küçülmediğini, tersine dönüp dönmediğini veya değişmeden kalıp kalmadığını söyler.
# Solve eigenvalue problem
la, v = linalg.eig(myMatrix)
# Unpack eigenvalues
l1, l2 = la
# First eigenvector
v[:,0]
# Second eigenvector
v[:,1]
# Or unpack eigenvalues with `eigvals()`
linalg.eigvals(myMatrix)
Kare matrisler için olağan veya genelleştirilmiş özdeğer problemlerini çözmek üzere SciPy’nin linalg modülünden eig() işlevini kullanırsınız.
eigvals() işlevinin, bir matrisin özdeğerlerini açmanın başka bir yolu olduğunu unutmayın.
Seyrek matrislerle çalışırken, özdeğerleri ve özvektörleri bulmak için doğru işlevleri sağlamak üzere scipy.sparse modülüne başvurabilirsiniz:
Not: Yukarıdaki kod, alınacak özdeğer ve özvektör sayısını, yani 1’i belirtir.
Özdeğerler ve özvektörler, Boyut İndirgeme için Temel Bileşenler Analizi (PCA) ve yüz tanıma için EigenFaces gibi birçok görüntü işleme ve makine öğrenimi tekniğinde önemli kavramlardır.
Tekil Değer Ayrışımı (SVD)
Veri bilimi öğrenmek istiyorsanız sırada SVD’yi bilmeniz gerekiyor. Bir \(A\) matrisinin tekil değer ayrışımı, \(A\)’nın üç matrisin çarpımına ayrıştırılması ya da çarpanlara ayrılmasıdır: \(A = U * \Sigma * V^t\).
\(A\) matrisinin boyutunun \(M\) x \(N\) olduğunu biliyorsanız, bireysel matrislerin boyutları şu şekildedir:
\(U\) matrisi \(M\) x \(M\) boyutundadır
\(V\) matrisi \(N\) x \(N\) boyutundadır
\(\Sigma\) matrisi \(M\) x \(N\) boyutundadır
\(*\), matrislerin çarpıldığını; \(V^t\) ifadesindeki \(^t\) ise matrisin devrik (transpoz) olduğunu, yani satır ve sütunların yer değiştirdiğini ifade eder.
Basitçe söylemek gerekirse, tekil değer ayrışımı bir matrisi daha basit ve anlamlı parçalara ayırmanın bir yolunu sunar. Bu parçalar, ilgilendiğimiz bazı verileri içerebilir.
# Singular Value Decomposition
U,s,Vh = linalg.svd(myMatrix)
# Initialize `M` and `N`
M,N = myMatrix.shape
# Construct sigma matrix in SVD
Sig = linalg.diagsvd(s,M,N)
Not: Seyrek matrisler için ayrıştırmayı gerçekleştirmek üzere sparse.linalg.svds() işlevini kullanabilirsiniz.
Veri bilimine yeniyseniz, matris ayrıştırması size oldukça kapalı gelebilir: Bunu uygulayabileceğiniz kullanım alanlarını hemen göremeyebilirsiniz. Ancak SVD, veri sıkıştırma, gürültü azaltma ve veri analizi gibi birçok görevde kullanışlıdır. Aşağıda SVD’nin görselleri sıkıştırmak için nasıl kullanılabileceğini göreceksiniz:
# Import the necessary packagesimport numpy as npfrom scipy import linalgfrom skimage import dataimport matplotlib.pyplot as plt# Get an image from`skimage`img= data.camera()# Check number of singular valueslinalg.svdvals(img)# Singular Value DecompositionU, s, Vh = linalg.svd(img)# Use only 32 singular valuesA = np.dot(U[:,0:32], np.dot(np.diag(s[0:32]), Vh[0:32,:]))fig = plt.figure(figsize=(8,3))# Add a subplot to the figureax = fig.add_subplot(121)# Plot `img` on grayscaleax.imshow(img, cmap='gray')# Add a second subplot to the figureax2 = fig.add_subplot(122)# Plot `A`in the second subplotax2.imshow(A)# Add a titlefig.suptitle('Image Compression with SVD', fontsize=14, fontweight='bold')# Show the plotplt.show()Altyapı:
Bu da size aşağıdaki sonucu verecektir:
Ayrıca SVD’nin kullanıldığı şu örnekleri de göz önünde bulundurun:
SVD, boyut indirgeme için kullanılan Temel Bileşenler Analizi (PCA) ile yakından bağlantılıdır: her ikisi de verinizin özellik uzayı eksenlerinin lineer birleşimlerinden oluşturulmuş bir dizi “yeni eksen” ile sonuçlanır. Bu “yeni eksenler”, verilerdeki varyansı, her yönün verideki varyansa katkısına göre ayrıştırır. PCA’nın veriler üzerinde nasıl çalıştığına dair somut bir örnek görmek için Scikit-Learn Eğitimimize gidin.
Bir diğer bağlantı ise veri madenciliği ve doğal dil işleme (NLP) ile ilgilidir: Gizli Anlamsal Dizinleme (LSI). Bu, belge getirme ve kelime benzerliğinde kullanılan bir tekniktir. Gizli anlamsal dizinleme, belgeleri bu belgelerde bulunan farklı kelimelerden oluşan kavramlarla eşlemek için SVD’yi kullanır. Çeşitli kelimeler bir kavramda gruplanabilir. Burada da SVD, kelimeler ve belgeleri arasındaki gürültülü ilişkiyi azaltır ve orijinal verinin boyut sayısını düşürür.
Gördüğünüz gibi SVD, veri bilimi yolculuğunuzda mutlaka ele almanız gereken önemli bir kavramdır. Bu nedenle, bu eğitimin kapsadığından daha derine inmeyi düşünmelisiniz: örneğin bu matris ayrıştırması hakkında daha fazlasını okumak için bu sayfaya gidin.
Sırada Ne Var?
Eğitimin sonuna geldiniz! Buradan sonra nereye gideceğiniz tamamen size kalmış.
Ancak durun!
Lineer cebire daha derinlemesine giren kursları kaçırmayın: bu eğitim yalnızca konuya giriş niteliğindeydi ve her şeyi kapsamadı!
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Makine öğrenimine gerçekten dalmak için bilmeniz gerekenlerin önemli bir kısmı lineer cebirdir ve bu eğitim tam olarak bunu ele alıyor. Bugünkü yazı, vektörler ve matrisler düzeyine inerek, makine öğrenimi yöntemlerinin nasıl ve ne zaman çalıştığına dair sezginizi geliştirmenize yardımcı olacak lineer cebir konularını kapsıyor.
Eğitimin sonunda, umarız bir algoritmaya yakından bakma konusunda kendinizi daha özgüvenli hissedersiniz!
İçindekiler
Giriş
Veri bilimini öğrenmek istiyorsanız ustalaşmanız gereken üç temel konudan biri makine öğrenimidir. Ve makine öğrenimine gerçekten girdiğinizde, daha derine inmek ve algoritmaların nasıl çalıştığına dair sezgi ve anlayış kazanmak önemlidir.
Ve bence siz, (aday) veri bilimci, bu noktaya ulaşmanın zor olabileceği konusunda muhtemelen benimle hemfikirsiniz.
Ancak böyle olmak zorunda değil.
SciPy ve NumPy Karşılaştırması
DataCamp’in NumPy eğitiminden, bu kütüphanenin Python’da bilimsel hesaplamanın çekirdek kütüphanelerinden biri olduğunu anlamış olacaksınız. Bu kütüphane, Fen ve Mühendislikteki problemlerin matematiksel modellerini bilgisayarda çözmek için kullanılabilecek bir dizi araç ve teknik içerir. Ancak en sık kullanacağınız araç, yüksek performanslı çok boyutlu bir dizi (array) nesnesidir: diziler ve matrisleri verimli biçimde hesaplamanıza olanak veren güçlü bir veri yapısıdır.
Şimdi, SciPy temelde NumPy üzerine kuruludur.
O da matematiksel algoritmalar ve yardımcı işlevler sağlayan, bilimsel hesaplama için çekirdek paketlerden biridir; ancak Python’un NumPy uzantısı üzerinde inşa edilmiştir. Bu, SciPy ve NumPy’nin sıklıkla birlikte kullanıldığı anlamına gelir!
Bu eğitimin ilerleyen kısımlarında, bu iki kütüphane arasındaki iş birliğinin nasıl kendiliğinden geliştiğini daha net göreceksiniz.
NumPy ve SciPy ile Etkileşim
Her iki paketle de verimli biçimde etkileşim kurmak için, öncelikle bu kütüphanenin ve güçlü veri yapısının bazı temellerini bilmeniz gerekir. Bu dizilerle çalışmak için, bu matrisler ve diziler üzerinde çalışan çok sayıda üst düzey matematiksel işlev vardır.
Devamında, SciPy ile verimli çalışabilmek için hakim olmanız gereken konulara hızlı bir genel bakış elde edeceksiniz. Özünde, dizi yapısını, veri türlerini nasıl ele alacağınızı ve dizi şekillerini nasıl değiştirebileceğinizi bilmeniz gerekir. Bunlar size yabancı geliyorsa, DataCamp’in Python NumPy Eğitimini almaya ve öğrenirken NumPy kopya kağıdına göz atmayı düşünün.
Tüm bunları zaten biliyorsanız, sonraki bölümü atlayıp “SciPy ile Lineer Cebir” kısmına geçin; ancak lineer cebir için SciPy kopya kağıdınızı hazır bulundurun!
NumPy
ndarrayNesnelerinin TemelleriYapısal olarak bir dizi, işaretçilerden ibarettir. Bir bellek adresi, bir veri türü, bir şekil ve adımların (strides) birleşimidir. Ham veri hakkında, bir öğenin nasıl bulunacağı ve yorumlanacağı hakkında bilgi içerir.
Bellek adresi ve adımlar, dizilerin daha alt düzey detaylarına indiğinizde önem kazanırken, veri türü ve şekil, yeni başlayanların mutlaka bilmesi ve anlaması gereken şeylerdir. Göz önünde bulundurmak isteyebileceğiniz iki başka öznitelik de diziniz hakkında daha fazla bilgi toplamanızı sağlayan
datavesize’dır.Aşağıdaki DataCamp Light parçasında
ndarrayözniteliklerinin kullanımını tazeleyin.myArraydizisi zaten yüklendi. IPython kabuğuna yazarak ve ENTER’a basarak inceleyebilirsiniz.Yukarıdaki kod parçasında yer alan sonuçlarda
myArray’in veri türününint64olduğunu göreceksiniz. Dizilerle yoğun çalışırken,astype()yöntemiyle dizilerinizi bir veri türünden diğerine dönüştürmenin yolları olduğunu kesinlikle hatırlarsınız.Bununla birlikte, SciPy ve NumPy’yi birlikte kullanırken, özellikle karmaşık sayılarla çalışıyorsanız, aşağıdaki NumPy tür yönetimi işlevlerini de çok kullanışlı bulabilirsiniz:
Sonuçları görmek için
print()çağrıları eklemeyi deneyin. Ardından karmaşık sayıların gerçek ve sanal kısımları olduğunu göreceksiniz.np.real()venp.imag()işlevleri sırasıyla bu kısımları döndürmek üzere tasarlanmıştır.Alternatif olarak, bir dizi nesnesini farklı bir veri türüne dökmek için yukarıdaki örnekte olduğu gibi
np.castda kullanabilirsiniz.Yukarıdaki kod parçasında gerçekten zor görünen tek şey
np.real_if_close()işlevidir.myArraygibi karmaşık bir girdi verdiğinizde, karmaşık kısımlar sıfıra yakınsa gerçek bir dizi elde edersiniz. Bu son kısım, “0’a yakınlık”, işlevine iletebileceğiniztolargümanıyla kendiniz tarafından ayarlanabilir. Eşiikle oynayıp neler olduğunu görün!Dizi (Array) Oluşturma
Artık dizinizi nasıl inceleyeceğinizi ve veri türünde nasıl ayarlamalar yapacağınızı gördünüz; fakat dizileri nasıl oluşturacağınızı açıkça görmediniz. Bunu yapmak için
np.array()kullanabileceğinizi zaten biliyor olmalısınız; ancak bilmeniz gereken başka dizi oluşturma yordamları da var:np.eye()venp.identity().np.eye()işlevi, argüman olarak verdiğiniz pozitif tam sayıya eşit boyutlarda kare bir matris oluşturmanıza olanak tanır. Elemanlar genellikle sıfırlarla doldurulur, yalnızca matrisin köşegeni birlerle doldurulur.np.identity()işlevi de aynı şekilde çalışır ve birim (identity) bir dizi döndürür.Ancak, unutmayın ki
np.eye(), hangi köşegenin birlerle doldurulacağını belirtmek için belirtebileceğiniz ek birkargümanı alabilir.Lineer cebir için matrislerle çalışırken işinize kesinlikle yarayacak diğer dizi oluşturma işlevleri şunlardır:
np.arange()işlevi, iki sayı arasında eşit aralıklı değerlere sahip bir dizi oluşturur. Elemanlar arasındaki aralığı belirtebilirsiniz,np.linspace()için de geçerlidir; ancak bu işlevle dizinizde kaç eleman istediğinizi belirtirsiniz.np.logspace(), yine eşit aralıklı değerlerden oluşan diziler oluşturur; fakat bu kez logaritmik ölçekte. Bu, aralığın artık logaritmik olduğu anlamına gelir: iki sayı, bu sayıların 10 tabanındaki logaritmaları arasında eşit aralıklıdır.Bu işlevler, önce bu yazıda okuduğunuz ağ (mesh) ızgaralarını oluşturmak için kullanılabilecek ağ biçiminde diziler oluşturur.
Not: Aşağıdaki kod parçasında
numpyzatennpolarak içe aktarılmıştır!Artık hafızanızı tazelediniz ve dizilerinizin veri türlerini nasıl ele alacağınızı biliyorsunuz; şimdi indeksleme ve dilimleme konusunu da ele alma zamanı.
İndeksleme ve Dilimleme
İndeksleme ile, köşeli parantezleri
[]kullanarak dizi değerlerini indekslersiniz. Başka bir deyişle, bir dizinin seçili öğelerine (bir alt kümeye) erişmek istiyorsanız indekslemeyi kullanabilirsiniz. Verinizi dilimlemek, alt kümeye ayırmaya oldukça benzer; ancak biraz daha gelişmiş sayılabilir. Bir diziyi dilimlediğinizde yalnızca belirli değerlere odaklanmaz, “konumlar” yerine “bölgeler” ile çalışırsınız.Aşağıdaki kod örnekleriyle her iki kavramı da tazeleyin:
Artık zihin dilimleme ve indekslemeyle taze iken, SciPy ile birlikte bilimsel hesaplamaya girerken işinizi daha verimli hale getirebilecek bazı indeks hileleriyle de ilgilenebilirsiniz. Dört işlev özellikle karşınıza çıkacaktır:
np.mgrid(),np.ogrid(),np.rvenp.c.NumPy ile biraz deneyiminiz varsa son iki işleve aşina olabilirsiniz.
np.rvenp.c, sırasıyla dizileri satır veya sütun bazında yığmanız gerektiğinde sıkça kullanılır. Bu işlevlerle,np.concatenate()kullanmak yerine dizileri hızlıca inşa edebilirsiniz.Bu dört işlevin ilk ikisine bakarken neden bir ağ ızgarasına ihtiyaç duyacağınızı sorabilirsiniz. Ağ ızgaralarını, dikdörtgensel bir ızgaradaki her konumda x ve y koordinatlarını içeren iki dizi üretmek için kullanabilirsiniz.
np.meshgrid()işlevi, iki 1B diziyi alır ve iki dizideki tüm (x, y) çiftlerine karşılık gelen iki 2B matris üretir.np.mgrid()işlevi MATLAB’in meshgrid’inin bir uygulamasıdır ve aynı şekle sahip diziler döndürür. Bu, çıktı dizilerinin boyutlarının ve sayısının indeksleme boyutlarının sayısına eşit olduğu anlamına gelir.np.ogrid()açık bir ağ ızgarası verir venp.mgrid()’in verdiği sonuç kadar yoğun değildir. Yukarıdaki kod parçasında ikisi arasındaki görsel farkı görebilirsiniz.Bu iki işlev arasındaki farklar hakkında buradan da okuyabilirsiniz.
İndeksleme/dilimleme amaçları için kullanabileceğiniz bir diğer işlev
np.select()’tir. Bunu, işlevin ilk argümanında kendiniz belirleyebileceğiniz koşullara bağlı olarak bir dizi listesinden değer döndürmek için kullanabilirsiniz. İkinci argümanda ise bu seçim süreci için dikkate almak istediğiniz diziyi iletirsiniz.Şu örneğe göz atın:
Harika! Artık orijinal dizinizin doğru değerlerini seçtiğinize göre, yeni dizinizin şeklini hâlâ seçebilir ve onu manipüle edebilirsiniz.
Şekil Seçimi ve Manipülasyonu
NumPy, dizilerinizin şeklini seçmek ve manipüle etmek için pek çok yol sunar ve muhtemelen bunların çoğunu zaten biliyorsunuzdur. Aşağıdaki bölüm, işinize yarayabilecek işlevlere kısa bir genel bakış sunacak; bu nedenle yazı hepsini kapsamıyor.
Peki, SciPy ile çalışırken özellikle kullanışlı olan işlevler var mı?
Aslında en kullanışlı olanlar; dizileri düzleştirmenize, yığmanıza ve bölmenize yardımcı olanlardır.
np.concatenate()yerine sıklıkla tercih edeceğiniznp.cvenp.rişlevlerini zaten gördünüz; fakat bilmek isteyeceğiniz daha birçok işlev var!Örneğin dizilerinizi yatay olarak yığmak için
np.hstack()veya dikey olarak yığmak içinnp.vstack(). Benzer şekilde, dizilerinizi yatay ve dikey olarak bölmek içinnp.vsplit()venp.hsplit()kullanabilirsiniz. Ancak muhtemelen bütün bunları zaten biliyorsunuz.Bunu aşağıdaki kod parçasında kanıtlayın:
Unutmayın ki
np.eye()işlevi 2x2 birim bir dizi oluşturur; bu da yukarıdaki kod parçasında sizin için yüklenen 2 boyutlu diziyle yığmak için idealdir.Dizileri yığarken dikkate almanız gereken koşullar hakkında daha fazla bilgi edinmek istiyorsanız buraya gidin. Ancak, iki diziyi satır veya sütun bazında birleştirmek istiyorsanız, dizilere ve işlevlerin ne yaptığına bakarak hangi ‘kurallara’ uymanız gerektiğine dair bir sezgi de geliştirebilirsiniz.
Dizileri bölerken dikkat etmeniz gereken en önemli şey muhtemelen dizinizin şeklidir; çünkü bölmenin gerçekleşmesini istediğiniz doğru indeksi seçmek istersiniz.
Yığma ve bölme işlevlerinin yanı sıra, dizilerinizin belirli bir boyutta olmasını sağlamaya yardımcı olan işlevlerin de bilimsel hesaplamaya daha derinlemesine daldığınızda vazgeçilmez olacağını aklınızda tutun.
Şu işlevleri düşünün:
Not: Dizinizin şeklini yeniden düzenlemek (reshape) ile yeniden boyutlandırmak (resize) arasındaki farkı unutmayın. İlkinde verinin şeklini değiştirirsiniz ancak verinin kendisini değiştirmezsiniz. Yeniden boyutlandırmada ise, seçtiğiniz şekle bağlı olarak dizideki verinin değişmesi mümkündür.
Dizilerinizi daha fazla manipüle etmenizi sağlayan işlevlerin yanı sıra, dikkate almanız gereken bir de “vektörleştirme” vardır. Bir işlevi bir diziye uyguladığınızda, genellikle o işlevi dizinin her bir elemanına uygularsınız. Örneğin, bir diziye
np.cos(),np.sin()veyanp.tan()uygulamayı düşünün. İşlevin tüm dizi elemanlarında çalıştığını göreceksiniz. Bunu gördüğünüzde, işlevin vektörleştirildiğini bilirsiniz.Ancak kendi işlevlerinizi tanımladığınızda—ki bilimsel hesaplamaya girdiğinizde muhtemelen yapacaksınız—onları da vektörleştirmek isteyebilirsiniz. Bu durumlarda
np.vectorize()çağrısını kullanabilirsiniz:Bilinmesi faydalı diğer vektörleştirilmiş matematiksel işlevler arasında, karmaşık dizi elemanlarının açısını veren
np.angle()ve temel trigonometrik, üstel veya logaritmik işlevler yer alır.SciPy ile Lineer Cebir
Artık her iki paketi de lehinize nasıl kullanmanız gerektiğini bildiğinize göre, bu eğitimin konusu olan lineer cebire dalma zamanı.
Ancak Python’u nasıl kullanabileceğinize geçmeden önce, çalışma alanınızın tamamen hazır olduğundan emin olun!
SciPy Kurulumu
Elbette önce Python’un kurulu olduğundan emin olmanız gerekir. Bunu hâlâ yapmanız gerekiyorsa bu sayfaya gidin :) Windows üzerinde çalışıyorsanız, Python’u PATH ortam değişkenine eklediğinizden emin olun. Ek olarak, Python’un açık kaynak kütüphanelerini kullanabilmenizi sağlayacak bir paket yöneticisini, örneğin
pip’i kurmayı unutmayın.Python 3’ün güncel sürümlerinin pip ile geldiğini unutmayın; bu nedenle pip’iniz olup olmadığını iki kez kontrol edin; varsa, başka paketler kurmadan önce yükseltin:
Ama sadece bir paket yöneticisi kurmak yeterli değil; Kütüphane için wheel dosyasını da indirmeniz gerekir: SciPy wheel’ınızı almak için buraya gidin. İndirdikten sonra, bilgisayarınızda indirme dizininde bir terminal açın ve kurulumu yapın. Ek olarak, kurulumun başarılı olup olmadığını kontrol edebilir ve çalıştırdığınız paket sürümünü doğrulayabilirsiniz:
Bu adımlardan sonra hazırsınız!
İpucu: paketi, Anaconda Python dağıtımını indirerek kurun. Başlamak için kolay bir yoldur; çünkü Anaconda yalnızca veri bilimi için en popüler 100 Python, R ve Scala paketini içermekle kalmaz, aynı zamanda Jupyter ve Spyder gibi çeşitli açık kaynak geliştirme ortamlarını da içerir. Jupyter Notebook ile çalışmaya başlamak isterseniz, şu Jupyter notebook eğitimine göz atın.
Henüz indirmediyseniz, almak için buraya gidin.
Vektörler ve Matrisler: Temeller
Artık çalışma alanınızı hazırladığınıza göre, Python’da lineer cebire nihayet başlayabilirsiniz. Özünde bu disiplin, vektör uzaylarının ve aralarındaki lineer dönüşümlerin incelenmesiyle ilgilenir. Bu lineer dönüşümler matrislerle ifade edilebilir; bu da hesaplamayı kolaylaştırır.
Unutmayın: Bir vektör uzayı, lineer cebirde temel bir kavramdır. Vektörlerden oluşan bir koleksiyona sahip olduğunuz ve iki vektörü topladığınızda veya ölçeklendirdiğinizde, ortaya çıkan vektörün uzayın dışına çıkmadığı bir uzaydır. Ayrıca vektörlerin, bir matrisin satırları (veya sütunları) olduğunu hatırlayın.
Peki bu Python’da nasıl çalışır?
np.array()işleviyle kolayca bir vektör oluşturabilirsiniz. Benzer şekilde, her bir bir veya iki boyutlundarray’enp.matrix()veyanp.mat()komutlarıyla bir matris yapısı kazandırabilirsiniz.Aşağıdaki kod parçasında deneyin:
Yani diziler ve matrisler biçimlendirme dışında aynı şey mi?
Tam olarak değil. Bazı farklılıklar var:
nboyutludur,ndarray’in bir alt sınıfıdır,.T()’si vardır; ancak yalnızca matrislerin.H()ve.I()’si bulunur,**işleminin matrisler ve diziler için sonuçları farklıdırMatrislerle çalışırken, elemanlarının çoğu sıfır olan bazı matrislere rastlayabilirsiniz. Bu matrislere “seyrek matrisler” denir; çoğu elemanı sıfır olmayanlara ise “yoğun matrisler”.
Bu kendi başına önemsiz görünebilir; ancak SciPy ile lineer cebir çalışırken bazı şeyleri yapmak için kullanacağınız modüllerde fark yaratabilir. Daha somut olarak, yoğun matrisler için
scipy.linalgkullanabilirsiniz; seyrek matrislerle çalışırken ise kendiscipy.sparse.linalg’ını da içerenscipy.sparsemodülünü kontrol etmeyi düşünebilirsiniz.Seyrek matrisler için onları oluşturmanın bir hayli seçeneği vardır. Aşağıdaki kod parçası bazılarını listeler:
Ek olarak, seyrek matris oluşturmak için kullanabileceğiniz başka işlevler de vardır:
bsr_matrix()ile Blok Seyrek Satır matrisleri,coo_matrix()ile Koordinat formatında seyrek matrisler,dia_matrix()ile Diyagonal depolama seyrek matrisleri velil_matrix()ile satır tabanlı bağlı liste seyrek matrisleri.Gerçekten çok fazla seçenek var; peki kendi seyrek matrisinizi oluştururken hangisini seçmelisiniz?
O kadar da zor değil.
Özetle, önce nasıl başlatacağınıza bakmalısınız. Sonra, seyrek matrisinizle ne yapmak istediğinizi düşünün.
Daha somut olarak, hangi tür seyrek matrisi kullanacağınıza karar vermek için aşağıdaki kontrol listesinden geçebilirsiniz:
coo_matrix()veyadok_matrix()seçin.dia_matrix()seçin.lil_matrix()kullanın.bsr_matrix()kullanmayı düşünün.csr_matrix()vecsc_matrix()işlevlerini kullanarak dönüştürün. Bu son iki işlev, matrislerinizi başlatırken harika değildir; ancak çarparken hız farkını kesinlikle fark edeceksiniz.Çok kolay!
Vektör İşlemleri
Artık vektörler, yoğun matrisler ve seyrek matrisler arasındaki farkı öğrendiğinize veya tazelediğinize göre, vektörlere ve onlarla yapabileceğiniz matematiksel işlemlere daha yakından bakma zamanı. Eğitim burada özellikle matematiksel işlemlere odaklanıyor; böylece matrislerle benzerlikleri ve farkları göreceksiniz; ayrıca lineer cebirin büyük bir kısmı nihayetinde matrislerle çalışmaktır.
np.array()ile kolayca bir vektör oluşturabileceğinizi zaten gördünüz. Ancak artık elinizde vektörler olduğuna göre, onlara uygulanabilecek bazı temel işlemleri de bilmek isteyebilirsiniz. Aşağıdaki kod parçasındavector1vevector2sizin için zaten yüklendi:Artık bazı vektör işlemlerini başarıyla gördüğünüze göre, asıl matris işine başlama zamanı!
Matrisler: İşlemler ve Yordamlar
Önceki bölümün başında bıraktığınız yere benzer şekilde, matrisleri nasıl oluşturacağınızı biliyorsunuz; ancak bunları lehinize nasıl kullanabileceğinizi henüz bilmiyorsunuz. Bu bölüm, verimli çalışmak için kullanabileceğiniz bazı matris işlevlerine ve temel matris yordamlarına genel bir bakış sunar.
Öncelikle bazı işlevleri gözden geçirelim. Daha önce NumPy ile çalıştıysanız bunlar size oldukça kolay gelecektir; ancak henüz deneyiminiz yoksa bile, bu işlevlerin kullanıma kolay olduğunu göreceksiniz.
Bazı işlev örneklerine bakalım.
Dizileri veya matrisleri toplamak ve çıkarmak için
np.add()venp.subtract(), bölme ve çarpma içinnp.divide()venp.multiplyvardır. Bu gerçekten büyük bir gizem gibi görünmüyor, değil mi? Ayrıca, önceki bölümde skaler çarpımı hesaplamak için gördüğünüznp.dot()işlevi matrislerle de kullanılabilir. Ancak vektörler yerine iki matris verdiğinizden emin olun.Bunlar temel, değil mi?
Biraz daha az temel olana geçelim. Çarpımlara geldiğinde, düşünebileceğiniz başka işlevler de vardır; vektörlerin skaler çarpımı için
np.vdot(), dizilerin iç veya dış çarpımları içinnp.inner()veyanp.outer(),np.tensordot()ve iki dizinin Kronecker çarpımı içinnp.kron()gibi:İpucu: Yukarıdaki kod parçasına çıktı almak için print deyimleri ekleyerek tek tek çarpım sonuçlarını görün.
Bunların dışında,
linalgmodülünün bazı işlevlerini de düşünmek faydalı olabilir: matris üstel işlevlerilinalg.expm(),linalg.expm2()velinalg.expm3(). Bu üçü arasındaki fark, üstelin hesaplanma yöntemlerinde yatar. Genel bir matris üstel için ilkine bağlı kalın; ancak sonuçlardaki farkı görmek için üçünü de mutlaka deneyin!Ayrıca
linalg.cosm(),linalg.sinm()velinalg.tanm()gibi trigonometrik işlevler;linalg.coshm(),linalg.sinhm()velinalg.tanhm()gibi hiperbolik trigonometrik işlevler;linalg.signm()işaret işlevi;linalg.logm()matris logaritması velinalg.sqrtm()matris karekökü.Ek olarak,
linalg.funm()işlevinin yardımıyla bir matris işlevini de değerlendirebilirsiniz. Aşağıdaki örneğe bakın:Gördüğünüz gibi birinci argüman olarak işlev uygulamak istediğiniz matrisi, ikinci argüman olarak ise matrise uygulamak istediğiniz bir işlevi (bu örnekte bir lambda işlevi) geçiriyorsunuz.
linalg.funm()’e ilettiğiniz işlevin vektörleştirilmiş olması gerektiğini unutmayın.Şimdi bazı temel matris yordamlarına bakalım. Muhtemelen ilk bakmak isteyeceğiniz şey matris öznitelikleridir: devrik (transpoz) için
T, eşlenik devrik içinH, ters içinIve diziye dökmek içinA.Deneyin:
Bir matrisi devirdiğinizde, satırları orijinalin sütunları olan yeni bir matris elde edersiniz. Eşlenik devrik ise her matris elemanı için satır ve sütun indeksini değiştirir. Bir matrisin tersi, orijinal matrisle çarpıldığında birim matris veren matristir.
Bu özniteliklerin yanı sıra, sırasıyla devrik almak ve matris tersini hesaplamak için
np.transpose()velinalg.inv()gibi bazı temel matris yordamlarını kullanabileceğiniz işlevler de vardır.Bunların dışında, ana köşegendeki elemanların toplamını
np.trace()ile alabilirsiniz. Benzer şekilde, bir dizinin matris rütbesini (rank) veya belirli bir eşikten büyük Tekil Değer Ayrışımı tekil değerlerinin sayısını NumPy’ninlinalg.matrix_rankişleviyle elde edebilirsiniz.Matris rütbesi şu an için anlam ifade etmiyorsa endişelenmeyin; bu eğitimin ilerleyen kısımlarında bununla ilgili daha fazlasını göreceksiniz.
Şimdilik, kullanabileceğiniz iki yordam daha üzerinde duralım:
linalg.normile hesaplanabilir: matris normu, matrisin elemanları cinsinden tanımlanan bir sayıdır. Norm, elemanların ne kadar büyük olduğunu söylediği için matris hakkında önemli bilgi verebilen yararlı bir niceliktir.linalg.det()ile hesaplayabilirsiniz. Determinant, kare matrisi tek bir sayıya indirger; bu da kare matrisin tersinir olup olmadığını belirler.Son olarak, büyük doğrusal denklem sistemlerini çözmek, matrislerin en temel uygulamalarından biridir. \(Ax = b\) sisteminiz varsa; burada \(A\) kare bir matris, \(b\) genel bir matris olsun; çalıştığınız matris türüne bağlı olarak \(x\)’i bulmak için kullanabileceğiniz iki yöntem vardır:
Seyrek matrisleri çözmek için
linalg.spsolve()kullanabilirsiniz. Denklemi çözemediğinizde,linalg.lstsq()komutunun yardımıyla yaklaşık bir \(x\) elde etmek yine de mümkün olabilir.İpucu: DataCamp’in SciPy kopya kağıdını kaçırmayın.
Artık matrisleri nasıl oluşturabileceğiniz ve onları matematiksel işlemler için nasıl kullanabileceğiniz hakkında fikir sahibi olduğunuza göre, makine öğrenimine gerçekten girmeniz için gereken daha ileri konuları ele alma zamanı.
Özdeğerler ve Özvektörler
Ele alacağınız ilk konu özdeğerler ve özvektörlerdir.
Özdeğerler, bir matrisin özüne bakmanın yeni bir yoludur. Ancak daha fazla detaya inmeden önce, önce özvektörlerin ne olduğunu açıklayalım. Neredeyse tüm vektörler, bir matrisle çarpıldıklarında yön değiştirir. Ancak belirli istisnai, ortaya çıkan vektörler, çarpımın sonucu olan vektörlerle aynı yöndedir. Bunlar özvektörlerdir.
Başka bir deyişle, bir özvektörü bir matrisle çarpın; bu çarpımın sonucu, orijinal özvektörün \(\lambda\) (özdeğer) ile çarpımına eşittir: \[Ax = \lambda x. \]
Bu, özdeğerin size çok değerli bilgi verdiği anlamına gelir: bir özvektörün bir matrisle çarpıldığında gerilip gerilmediğini, küçülüp küçülmediğini, tersine dönüp dönmediğini veya değişmeden kalıp kalmadığını söyler.
Kare matrisler için olağan veya genelleştirilmiş özdeğer problemlerini çözmek üzere SciPy’nin
linalgmodülündeneig()işlevini kullanırsınız.eigvals()işlevinin, bir matrisin özdeğerlerini açmanın başka bir yolu olduğunu unutmayın.Seyrek matrislerle çalışırken, özdeğerleri ve özvektörleri bulmak için doğru işlevleri sağlamak üzere
scipy.sparsemodülüne başvurabilirsiniz:Not: Yukarıdaki kod, alınacak özdeğer ve özvektör sayısını, yani 1’i belirtir.
Özdeğerler ve özvektörler, Boyut İndirgeme için Temel Bileşenler Analizi (PCA) ve yüz tanıma için EigenFaces gibi birçok görüntü işleme ve makine öğrenimi tekniğinde önemli kavramlardır.
Tekil Değer Ayrışımı (SVD)
Veri bilimi öğrenmek istiyorsanız sırada SVD’yi bilmeniz gerekiyor. Bir \(A\) matrisinin tekil değer ayrışımı, \(A\)’nın üç matrisin çarpımına ayrıştırılması ya da çarpanlara ayrılmasıdır: \(A = U * \Sigma * V^t\).
\(A\) matrisinin boyutunun \(M\) x \(N\) olduğunu biliyorsanız, bireysel matrislerin boyutları şu şekildedir:
\(*\), matrislerin çarpıldığını; \(V^t\) ifadesindeki \(^t\) ise matrisin devrik (transpoz) olduğunu, yani satır ve sütunların yer değiştirdiğini ifade eder.
Basitçe söylemek gerekirse, tekil değer ayrışımı bir matrisi daha basit ve anlamlı parçalara ayırmanın bir yolunu sunar. Bu parçalar, ilgilendiğimiz bazı verileri içerebilir.
Not: Seyrek matrisler için ayrıştırmayı gerçekleştirmek üzere
sparse.linalg.svds()işlevini kullanabilirsiniz.Veri bilimine yeniyseniz, matris ayrıştırması size oldukça kapalı gelebilir: Bunu uygulayabileceğiniz kullanım alanlarını hemen göremeyebilirsiniz. Ancak SVD, veri sıkıştırma, gürültü azaltma ve veri analizi gibi birçok görevde kullanışlıdır. Aşağıda SVD’nin görselleri sıkıştırmak için nasıl kullanılabileceğini göreceksiniz:
Bu da size aşağıdaki sonucu verecektir:
Ayrıca SVD’nin kullanıldığı şu örnekleri de göz önünde bulundurun:
Gördüğünüz gibi SVD, veri bilimi yolculuğunuzda mutlaka ele almanız gereken önemli bir kavramdır. Bu nedenle, bu eğitimin kapsadığından daha derine inmeyi düşünmelisiniz: örneğin bu matris ayrıştırması hakkında daha fazlasını okumak için bu sayfaya gidin.
Sırada Ne Var?
Eğitimin sonuna geldiniz! Buradan sonra nereye gideceğiniz tamamen size kalmış.
Ancak durun!
Lineer cebire daha derinlemesine giren kursları kaçırmayın: bu eğitim yalnızca konuya giriş niteliğindeydi ve her şeyi kapsamadı!
Elbette, bu lineer cebir hakkındaki Scipy eğitiminden sonra öğrenim müfredatınıza kesinlikle değer katacak Makine Öğrenimi eğitimini de almayı düşünün. Ancak temellere geri dönmek isterseniz, NumPy eğitimimizi veya Intermediate Python for Data Science kursunu gözden geçirin.