Denetimli Makine Öğrenimi Algoritmalarını Keşfetme
Yayınlanan: 2022-03-11Bu okumanın temel amacı, Python'un scikit-learn kitaplığındaki makine öğrenimi algoritmalarından yararlanabilmek için yeterli istatistiksel metodolojiyi anlamak ve ardından bu bilgiyi klasik bir makine öğrenimi problemini çözmek için uygulamaktır.
Yolculuğumuzun ilk durağı bizi kısa bir makine öğrenimi geçmişine götürecek. Sonra farklı algoritmalara dalacağız. Son durağımızda Titanik Hayatta Kalma Oranı Tahmin Problemini çözmek için öğrendiklerimizi kullanacağız.
Bazı sorumluluk reddi beyanları:
- Ben tam donanımlı bir yazılım mühendisiyim, makine öğrenimi algoritması uzmanı değilim.
- Bazı temel Python bildiğinizi varsayıyorum.
- Bu keşif amaçlıdır, bu nedenle her ayrıntı bir öğreticide olduğu gibi açıklanmaz.
Bunu not ettikten sonra, içeri girelim!
Makine Öğrenimi Algoritmalarına Hızlı Bir Giriş
Bu alana girer girmez, makine öğreniminin düşündüğünüzden daha az romantik olduğunu fark ediyorsunuz. Başlangıçta, daha fazlasını öğrendikten sonra, tüm günümü yazılım kodlamaya harcayacak ve benim için para kazanacak kendi Jarvis AI'mı oluşturabileceğime dair umutlarla doluydum, böylece bütün günümü dışarıda kitap okuyarak, motosiklet sürerek geçirebilirdim. ve kişisel Jarvis'im ceplerimi daha da derinleştirirken pervasız bir yaşam tarzının tadını çıkarmak. Ancak, kısa süre sonra, makine öğrenimi algoritmalarının temelinin, kişisel olarak sıkıcı ve ilginç bulduğum istatistikler olduğunu fark ettim. Neyse ki, "sıkıcı" istatistiklerin bazı çok etkileyici uygulamaları olduğu ortaya çıktı.
Yakında bu büyüleyici uygulamalara ulaşmak için istatistikleri çok iyi anlamanız gerektiğini keşfedeceksiniz. Makine öğrenimi algoritmalarının hedeflerinden biri, sağlanan verilerde istatistiksel bağımlılıkları bulmaktır.
Sağlanan veriler, yaşa karşı kan basıncını kontrol etmekten çeşitli piksellerin rengine dayalı el yazısı metin bulmaya kadar her şey olabilir.
Bununla birlikte, kriptografik karma işlevlerdeki (SHA, MD5, vb.) bağımlılıkları bulmak için makine öğrenimi algoritmalarını kullanıp kullanamayacağımı merak ediyordum - ancak bunu gerçekten yapamazsınız çünkü uygun kripto ilkelleri bu şekilde yapılandırılmıştır. bağımlılıkları ortadan kaldırdıklarını ve önemli ölçüde tahmin edilmesi zor çıktılar ürettiklerini. Sonsuz bir süre verildiğinde, makine öğrenimi algoritmalarının herhangi bir kripto modelini kırabileceğine inanıyorum.
Ne yazık ki, o kadar fazla zamanımız yok, bu yüzden kripto para madenciliğini verimli bir şekilde yapmanın başka bir yolunu bulmamız gerekiyor. Şimdiye kadar ne kadar ilerledik?
Makine Öğrenimi Algoritmalarının Kısa Tarihi
Makine öğrenimi algoritmalarının kökleri, 18. yüzyılda yaşamış İngiliz istatistikçi Thomas Bayes'e dayanmaktadır. Onun makalesi Şans Doktrini'nde Bir Problemi Çözmeye Yönelik Bir Deneme , istatistik alanında yaygın olarak uygulanan Bayes Teoremi'ni desteklemektedir.
19. yüzyılda, Pierre-Simon Laplace, Bayes'in çalışmalarını genişleterek ve bugün bildiklerimizi Bayes Teoremi olarak tanımlayarak Theorie analytique des olasılıkları yayınladı. Bundan kısa bir süre önce Adrien-Marie Legendre, günümüzde de denetimli öğrenmede yaygın olarak kullanılan “en küçük kareler” yöntemini tanımlamıştı.
20. yüzyıl, kamuoyunca bilinen keşiflerin büyük çoğunluğunun bu alanda yapıldığı dönemdir. Andrey Markov, şiirleri analiz etmek için kullandığı Markov zincirlerini icat etti. Alan Turing, temelde genetik algoritmaları öngören, yapay olarak akıllı hale gelebilecek bir öğrenme makinesi önerdi. Frank Rosenblatt, Perceptron'u icat etti ve medyada büyük bir heyecan ve geniş yankı uyandırdı.
Ancak 1970'ler, AI fikri etrafında çok fazla karamsarlık gördü - ve dolayısıyla fonların azalması - bu nedenle bu döneme AI kışı deniyor. 1980'lerde geri yayılımın yeniden keşfi, makine öğrenimi araştırmalarında yeniden canlanmaya neden oldu. Ve bugün, bir kez daha sıcak bir konu.
Merhum Leo Breiman, iki istatistiksel modelleme paradigması arasında ayrım yaptı: Veri modelleme ve algoritmik modelleme. “Algoritmik modelleme”, rastgele orman gibi az çok makine öğrenme algoritmaları anlamına gelir.
Makine öğrenimi ve istatistik yakından ilişkili alanlardır. Michael I. Jordan'a göre, metodolojik ilkelerden teorik araçlara kadar makine öğrenimi fikirleri, istatistikte uzun bir geçmişe sahiptir. Ayrıca, makine öğrenimi uzmanlarının ve istatistikçilerin örtük olarak üzerinde çalıştığı genel sorun için veri bilimini bir yer tutucu terim olarak önerdi.
Makine Öğrenimi Algoritmaları Kategorileri
Makine öğrenimi alanı, denetimli öğrenme ve denetimsiz öğrenme olarak adlandırılan iki ana sütun üzerinde durmaktadır. Bazı insanlar ayrıca yeni bir çalışma alanı olan derin öğrenmeyi , denetimli ve denetimsiz öğrenme sorunundan ayrı olarak düşünürler.
Denetimli öğrenme , bir bilgisayara girdi örneklerinin ve bunların istenen çıktılarının sunulmasıdır. Bilgisayarın amacı, girdileri çıktılara eşleyen genel bir formül öğrenmektir. Bu daha da ayrılabilir:
- Yarı denetimli öğrenme , bilgisayara bazı çıktıların eksik olduğu tamamlanmamış bir eğitim seti verildiğinde
- Bilgisayarın yalnızca çok sınırlı bir dizi örnek için eğitim etiketleri alabildiği aktif öğrenme . İnteraktif olarak kullanıldığında eğitim setleri kullanıcıya etiketlenmesi için sunulabilir.
- Takviyeli öğrenme , eğitim verilerinin yalnızca programın dinamik ortamdaki eylemlerine, örneğin araç sürme veya bir rakibe karşı oyun oynama gibi geri bildirim olarak verildiği zamandır.
Buna karşılık, denetimsiz öğrenme , hiçbir etiketin verilmediği ve girdisindeki yapıyı bulmanın algoritmaya bağlı olduğu zamandır. Yalnızca gizli kalıpları keşfetmemiz gerektiğinde denetimsiz öğrenme başlı başına bir hedef olabilir.
Derin öğrenme , insan beyninin yapısından ve işlevinden ilham alan ve sadece istatistiksel kavramlardan ziyade yapay sinir ağlarına dayanan yeni bir çalışma alanıdır. Derin öğrenme hem denetimli hem de denetimsiz yaklaşımlarda kullanılabilir.
Bu makalede, yalnızca daha basit denetimli makine öğrenimi algoritmalarından bazılarını inceleyeceğiz ve bunları Titanik'in trajik batması sırasında bir kişinin hayatta kalma şansını hesaplamak için kullanacağız. Ancak genel olarak, hangi algoritmayı kullanacağınızdan emin değilseniz, başlamak için güzel bir yer scikit-learn'in makine öğrenimi algoritması hile sayfasıdır.
Temel Denetimli Makine Öğrenimi Modelleri
Belki de mümkün olan en kolay algoritma lineer regresyondur. Bazen bu, grafik olarak düz bir çizgi olarak gösterilebilir, ancak ismine rağmen, bir polinom hipotezi varsa, bu çizgi bunun yerine bir eğri olabilir. Her iki durumda da, skaler bağımlı değişken $y$ ile $x$ ile gösterilen bir veya daha fazla açıklayıcı değer arasındaki ilişkileri modeller.
Meslekten olmayan kişilerin terimleriyle, bu, doğrusal regresyonun, bilinen her $x$ ve $y$ arasındaki bağımlılığı öğrenen algoritma olduğu anlamına gelir, böylece daha sonra onu bilinmeyen bir $x$ örneği için $y$'ı tahmin etmek için kullanabiliriz.
İlk denetimli öğrenme örneğimizde, bir kişinin yaşına göre kan basıncını tahmin etmek için temel bir doğrusal regresyon modeli kullanacağız. Bu, iki anlamlı özelliği olan çok basit bir veri kümesidir: Yaş ve kan basıncı.
Yukarıda belirtildiği gibi, çoğu makine öğrenimi algoritması, kendilerine sağlanan verilerde istatistiksel bir bağımlılık bularak çalışır. Bu bağımlılığa hipotez denir ve genellikle $h(\theta)$ ile gösterilir.
Hipotezi anlamak için, verileri yükleyerek ve keşfederek başlayalım.
import matplotlib.pyplot as plt from pandas import read_csv import os # Load data data_path = os.path.join(os.getcwd(), "data/blood-pressure.txt") dataset = read_csv(data_path, delim_whitespace=True) # We have 30 entries in our dataset and four features. The first feature is the ID of the entry. # The second feature is always 1. The third feature is the age and the last feature is the blood pressure. # We will now drop the ID and One feature for now, as this is not important. dataset = dataset.drop(['ID', 'One'], axis=1) # And we will display this graph %matplotlib inline dataset.plot.scatter(x='Age', y='Pressure') # Now, we will assume that we already know the hypothesis and it looks like a straight line h = lambda x: 84 + 1.24 * x # Let's add this line on the chart now ages = range(18, 85) estimated = [] for i in ages: estimated.append(h(i)) plt.plot(ages, estimated, 'b') [<matplotlib.lines.Line2D at 0x11424b828>]
Yukarıdaki grafikte, her mavi nokta veri örneğimizi temsil eder ve mavi çizgi, algoritmamızın öğrenmesi gereken hipotezdir. Peki bu hipotez tam olarak nedir?
Bu problemi çözmek için, $y = f(x)$ ile gösterilen $x$ ile $y$ arasındaki bağımlılığı öğrenmemiz gerekiyor. Bu nedenle $f(x)$ ideal hedef fonksiyondur. Makine öğrenimi algoritması, bilinmeyen $f(x)$'ın en yakın tahmini olan $h(x)$ hipotez fonksiyonunu tahmin etmeye çalışacaktır.
Doğrusal regresyon problemi için olası en basit hipotez şuna benzer: $h_\theta(x) = \theta_0 + \theta_1 * x$. Tek bir skaler değişken $y$ çıktısı veren tek bir giriş skaler değişkenimiz $x$ var, burada $\theta_0$ ve $\theta_1$ öğrenmemiz gereken parametrelerdir. Bu mavi çizgiyi verilere uydurma işlemine doğrusal regresyon denir. Yalnızca bir girdi parametremiz olduğunu anlamak önemlidir $x_1$; bununla birlikte, birçok hipotez işlevi ayrıca önyargı birimini de ($x_0$) içerecektir. Dolayısıyla ortaya çıkan hipotezimiz $h_\theta(x) = \theta_0 * x_0 + \theta_1 * x_1$ şeklindedir. Ancak $x_0$ yazmaktan kaçınabiliriz çünkü neredeyse her zaman 1'e eşittir.
Mavi çizgiye geri dönmek. Hipotezimiz $h(x) = 84 + 1.24x$ gibi görünüyor, bu da $\theta_0 = 84$ ve $\theta_1 = 1.24$ anlamına geliyor. Bu $\theta$ değerlerini otomatik olarak nasıl türetebiliriz?
Bir maliyet fonksiyonu tanımlamamız gerekiyor. Esasen, maliyet fonksiyonunun yaptığı, model tahmini ile gerçek çıktı arasındaki ortalama karekök hatasını basitçe hesaplamaktır.
\[J(\theta) = \frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})^2\ ]Örneğin, hipotezimiz 48 yaşındaki birinin kan basıncının $h(48) = 84 + 1.24 * 48 = 143mmHg$; ancak, eğitim örneğimizde 130 $ mmHg$ değerine sahibiz. Bu nedenle hata $(143 - 130)^2 = 169$'dır. Şimdi bu hatayı eğitim veri kümemizdeki her bir giriş için hesaplamamız ve ardından toplamamız gerekiyor ($\sum_{i=1}^m(h_\theta(x^{(i)})) - y^{(i )})^2$) ve bundan ortalama değeri alın.
Bu bize fonksiyonun maliyetini temsil eden tek bir skaler sayı verir. Amacımız, maliyet fonksiyonu en düşük olacak şekilde $\theta$ değerlerini bulmaktır; diğer bir deyişle, maliyet fonksiyonunu minimize etmek istiyoruz. Bu umarım sezgisel görünecektir: Küçük bir maliyet fonksiyonu değerimiz varsa, bu tahmin hatasının da küçük olduğu anlamına gelir.
import numpy as np # Let's calculate the cost for the hypothesis above h = lambda x, theta_0, theta_1: theta_0 + theta_1 * x def cost(X, y, t0, t1): m = len(X) # the number of the training samples c = np.power(np.subtract(h(X, t0, t1), y), 2) return (1 / (2 * m)) * sum(c) X = dataset.values[:, 0] y = dataset.values[:, 1] print('J(Theta) = %2.2f' % cost(X, y, 84, 1.24)) J(Theta) = 1901.95
Şimdi, maliyet fonksiyonu değerimiz minimum olacak şekilde $\theta$ gibi değerleri bulmamız gerekiyor. Ama bunu nasıl yapacağız?
\[minJ(\theta) = \frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})^2\ ]Birkaç olası algoritma vardır, ancak en popüler olanı gradyan inişidir . Gradyan iniş yönteminin arkasındaki sezgiyi anlamak için önce onu grafik üzerinde çizelim. Basitlik adına, daha basit bir hipotez $h(\theta) = \theta_1 * x$ kabul edeceğiz. Daha sonra, $x$'ın $\theta$'ın değeri ve $y$'ın bu noktada maliyet fonksiyonu olduğu basit bir 2B grafiği çizeceğiz.
import matplotlib.pyplot as plt fig = plt.figure() # Generate the data theta_1 = np.arange(-10, 14, 0.1) J_cost = [] for t1 in theta_1: J_cost += [ cost(X, y, 0, t1) ] plt.plot(theta_1, J_cost) plt.xlabel(r'$\theta_1$') plt.ylabel(r'$J(\theta)$') plt.show() Maliyet fonksiyonu dışbükeydir, yani $[a, b]$ aralığında yalnızca bir minimum vardır. Bu da en iyi $\theta$ parametrelerinin maliyet fonksiyonunun minimum olduğu noktada olduğu anlamına gelir.
Temel olarak, gradyan inişi, işlevi en aza indiren parametreler kümesini bulmaya çalışan bir algoritmadır. İlk parametre seti ile başlar ve yinelemeli olarak fonksiyon gradyanının negatif yönünde adımlar atar.
Belirli bir noktada bir hipotez fonksiyonunun türevini hesaplarsak, bu bize o noktadaki eğriye teğet olan doğrunun eğimini verir. Bu, grafiğin her noktasındaki eğimi hesaplayabileceğimiz anlamına gelir.
Algoritmanın çalışma şekli şudur:
- Rastgele bir başlangıç noktası seçiyoruz (rastgele $\theta$).
- Bu noktada maliyet fonksiyonunun türevini hesaplayın.
- $\theta_j := \theta_j - \lambda * \frac{\partial}{\partial \theta_j} * J(\theta)$ eğimine doğru küçük bir adım atın.
- Birleşene kadar 2-3 arasındaki adımları tekrarlayın.
Şimdi, yakınsama koşulu, algoritmanın uygulanmasına bağlıdır. 50 adımdan sonra, bazı eşiklerden sonra veya başka herhangi bir şeyden sonra durabiliriz.
import math # Example of the simple gradient descent algorithm taken from Wikipedia cur_x = 2.5 # The algorithm starts at point x gamma = 0.005 # Step size multiplier precision = 0.00001 previous_step_size = cur_x df = lambda x: 2 * x * math.cos(x) # Remember the learning curve and plot it while previous_step_size > precision: prev_x = cur_x cur_x += -gamma * df(prev_x) previous_step_size = abs(cur_x - prev_x) print("The local minimum occurs at %f" % cur_x) The local minimum occurs at 4.712194
Bu makalede bu algoritmaları uygulamayacağız. Bunun yerine, yaygın olarak benimsenen açık kaynaklı bir Python makine öğrenimi kitaplığı olan scikit-learn kullanacağız. Farklı veri madenciliği ve makine öğrenimi sorunları için çok sayıda çok kullanışlı API sağlar.
from sklearn.linear_model import LinearRegression # LinearRegression uses the gradient descent method # Our data X = dataset[['Age']] y = dataset[['Pressure']] regr = LinearRegression() regr.fit(X, y) # Plot outputs plt.xlabel('Age') plt.ylabel('Blood pressure') plt.scatter(X, y, color='black') plt.plot(X, regr.predict(X), color='blue') plt.show() plt.gcf().clear() <matplotlib.figure.Figure at 0x120fae1d0>
print( 'Predicted blood pressure at 25 yo = ', regr.predict(25) ) print( 'Predicted blood pressure at 45 yo = ', regr.predict(45) ) print( 'Predicted blood pressure at 27 yo = ', regr.predict(27) ) print( 'Predicted blood pressure at 34.5 yo = ', regr.predict(34.5) ) print( 'Predicted blood pressure at 78 yo = ', regr.predict(78) ) Predicted blood pressure at 25 yo = [[ 122.98647692]] Predicted blood pressure at 45 yo = [[ 142.40388395]] Predicted blood pressure at 27 yo = [[ 124.92821763]] Predicted blood pressure at 34.5 yo = [[ 132.20974526]] Predicted blood pressure at 78 yo = [[ 174.44260555]]İstatistiksel Veri Türleri
Makine öğrenimi sorunları için verilerle çalışırken, farklı veri türlerini tanımak önemlidir. Sayısal (sürekli veya ayrık), kategorik veya sıralı verilere sahip olabiliriz.
Sayısal verilerin bir ölçüm olarak anlamı vardır. Örneğin, bir kişinin yaşı, kilosu, sahip olduğu bitcoin sayısı veya kişinin ayda kaç makale yazabileceği. Sayısal veriler ayrıca ayrık ve sürekli türlere ayrılabilir.
- Ayrık veriler, örneğin bir apartmandaki oda sayısı veya yazı tura sayısı gibi tam sayılarla sayılabilen verileri temsil eder.
- Sürekli veriler mutlaka tam sayılarla temsil edilemez. Örneğin, atlayabileceğiniz mesafeyi ölçüyorsanız, 2 metre veya 1.5 metre veya 1.652245 metre olabilir.
Kategorik veriler kişinin cinsiyeti, medeni durumu, ülkesi vb. değerleri temsil eder. Bu veriler sayısal değer alabilir, ancak bu sayıların matematiksel bir anlamı yoktur. Bunları birlikte ekleyemezsiniz.
Sıralı veriler diğer iki türün bir karışımı olabilir, bu kategoriler matematiksel olarak anlamlı bir şekilde numaralandırılabilir. Yaygın bir örnek, derecelendirmelerdir: Çoğu zaman, bir ile on arasında bir ölçekte değerlendirme yapmamız istenir ve yalnızca tam sayılara izin verilir. Bunu sayısal olarak (örneğin, bir şey için ortalama bir derecelendirme bulmak için) kullanabilmemize rağmen, makine öğrenimi yöntemlerini uygulama söz konusu olduğunda, verilere genellikle kategorikmiş gibi davranırız.
Lojistik regresyon
Doğrusal regresyon, sayısal değerleri tahmin etmemize yardımcı olan harika bir algoritmadır, örneğin belirli büyüklükte ve oda sayısına sahip evin fiyatı. Ancak bazen, aşağıdaki gibi sorulara yanıt almak için kategorik verileri de tahmin etmek isteyebiliriz:
- Bu bir köpek mi yoksa bir kedi mi?
- Bu tümör kötü huylu mu yoksa iyi huylu mu?
- Bu şarap iyi mi kötü mü?
- Bu e-posta spam mı değil mi?
Ya da:
- Resimde hangi numara var?
- Bu e-posta hangi kategoriye ait?
Bütün bu sorular sınıflandırma problemine özgüdür. Ve en basit sınıflandırma algoritmasına lojistik regresyon denir ve bu, farklı bir hipoteze sahip olması dışında nihayetinde lineer regresyonla aynıdır.
Her şeyden önce, aynı doğrusal hipotezi $h_\theta(x) = \theta^TX$'ı yeniden kullanabiliriz (bu vektörleştirilmiş formdadır). Doğrusal regresyon $[a, b]$ aralığında herhangi bir sayı üretebilirken, lojistik regresyon yalnızca nesnenin belirli bir kategoriye girip girmeme olasılığı olan $[−1, 1]$ içindeki değerleri verebilir.
Bir sigmoid işlevi kullanarak, herhangi bir sayısal değeri $[−1, 1]$ aralığındaki bir değeri temsil edecek şekilde dönüştürebiliriz.
\[f(x) = \frac{1}{1 + e^x}\]Şimdi, $x$ yerine mevcut bir hipotezi geçmemiz gerekiyor ve bu nedenle şunu elde edeceğiz:
\[f(x) = \frac{1}{1 + e^{\theta_0 + \theta_1 * x_1 + ... + \theta_n * x_n}}\]Bundan sonra, hipotez sıfırdan büyükse bunun doğru bir değer olduğunu, aksi takdirde yanlış olduğunu söyleyen basit bir eşik uygulayabiliriz.
\[h_\theta(x) = \begin{durumlar} 1 & \mbox{if } \theta^TX > 0 \\ 0 & \mbox{else} \end{durumlar}\]Bu, lojistik regresyon için bir hipotez öğrenmek için aynı maliyet fonksiyonunu ve aynı gradyan iniş algoritmasını kullanabileceğimiz anlamına gelir.
Bir sonraki makine öğrenme algoritması örneğimizde, uzay mekiğinin pilotlarına otomatik mi yoksa manuel iniş kontrolünü mi kullanmaları gerektiğini tavsiye edeceğiz. Altı özellik ve temel gerçeği içeren çok küçük bir veri setimiz (15 örnek) var.
Makine öğrenimi algoritmalarında, “ temel gerçeği ” terimi, denetimli öğrenme teknikleri için eğitim setinin sınıflandırmasının doğruluğunu ifade eder.
Veri kümemiz tamamlandı, yani eksik özellik yok; ancak bazı özelliklerde kategori yerine “*” vardır, bu da bu özelliğin önemli olmadığı anlamına gelir. Tüm bu yıldız işaretlerini sıfırlarla değiştireceğiz.
from sklearn.linear_model import LogisticRegression # Data data_path = os.path.join(os.getcwd(), "data/shuttle-landing-control.csv") dataset = read_csv(data_path, header=None, names=['Auto', 'Stability', 'Error', 'Sign', 'Wind', 'Magnitude', 'Visibility'], na_values='*').fillna(0) # Prepare features X = dataset[['Stability', 'Error', 'Sign', 'Wind', 'Magnitude', 'Visibility']] y = dataset[['Auto']].values.reshape(1, -1)[0] model = LogisticRegression() model.fit(X, y) # For now, we're missing one important concept. We don't know how well our model # works, and because of that, we cannot really improve the performance of our hypothesis. # There are a lot of useful metrics, but for now, we will validate how well # our algorithm performs on the dataset it learned from. "Score of our model is %2.2f%%" % (model.score(X, y) * 100) Score of our model is 73.33%
Doğrulama?
Önceki örnekte, öğrenme verilerini kullanarak modelimizin performansını doğrulamıştık. Bununla birlikte, algoritmamızın veriyi fazla sığdırmak için yetersiz kalabileceği göz önüne alındığında, bu şimdi iyi bir seçenek mi? Bir evin büyüklüğünü temsil eden bir özelliğimiz ve fiyatını temsil eden bir özelliğimiz olduğunda daha basit bir örneğe bakalım.
from sklearn.pipeline import make_pipeline from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression from sklearn.model_selection import cross_val_score # Ground truth function ground_truth = lambda X: np.cos(15 + np.pi * X) # Generate random observations around the ground truth function n_samples = 15 degrees = [1, 4, 30] X = np.linspace(-1, 1, n_samples) y = ground_truth(X) + np.random.randn(n_samples) * 0.1 plt.figure(figsize=(14, 5)) models = {} # Plot all machine learning algorithm models for idx, degree in enumerate(degrees): ax = plt.subplot(1, len(degrees), idx + 1) plt.setp(ax, xticks=(), yticks=()) # Define the model polynomial_features = PolynomialFeatures(degree=degree) model = make_pipeline(polynomial_features, LinearRegression()) models[degree] = model # Train the model model.fit(X[:, np.newaxis], y) # Evaluate the model using cross-validation scores = cross_val_score(model, X[:, np.newaxis], y) X_test = X plt.plot(X_test, model.predict(X_test[:, np.newaxis]), label="Model") plt.scatter(X, y, edgecolor='b', s=20, label="Observations") plt.xlabel("x") plt.ylabel("y") plt.ylim((-2, 2)) plt.title("Degree {}\nMSE = {:.2e}".format( degree, -scores.mean())) plt.show() 
Ne eğitim verilerini ne de yeni gözlemleri genelleştiremiyorsa, makine öğrenimi algoritma modeli yetersiz kalıyor . Yukarıdaki örnekte, gerçek eğitim veri setini gerçekten temsil etmeyen ve çok düşük performansa sahip olacak basit bir doğrusal hipotez kullanıyoruz. İyi bir ölçü verildiğinde kolayca tespit edilebildiği için genellikle eksik takma tartışılmaz.
Algoritmamız gösterilen her bir gözlemi hatırlarsa, eğitim veri kümesi dışındaki yeni gözlemlerde düşük performansa sahip olacaktır. Buna aşırı takma denir. Örneğin, 30. dereceden bir polinom modeli, noktaların çoğundan geçer ve eğitim setinde çok iyi bir puana sahiptir, ancak bunun dışındaki herhangi bir şey kötü performans gösterecektir.
Veri kümemiz tek bir özellikten oluşur ve 2B uzayda çizilmesi kolaydır; bununla birlikte, gerçek hayatta, Öklid uzayında görsel olarak çizilmelerini imkansız kılan yüzlerce özelliğe sahip veri kümelerimiz olabilir. Modelin eksik mi yoksa fazla mı olduğunu görmek için başka hangi seçeneklerimiz var?
Size öğrenme eğrisi kavramını tanıtmanın zamanı geldi. Bu, eğitim örneklerinin sayısı üzerinden ortalama karesel hatanın grafiğini çizen basit bir grafiktir.
Öğrenme materyallerinde genellikle aşağıdakilere benzer grafikler görürsünüz:
Ancak gerçek hayatta bu kadar mükemmel bir resim elde edemeyebilirsiniz. Modellerimizin her biri için öğrenme eğrisini çizelim.
from sklearn.model_selection import learning_curve, ShuffleSplit # Plot learning curves plt.figure(figsize=(20, 5)) for idx, degree in enumerate(models): ax = plt.subplot(1, len(degrees), idx + 1) plt.title("Degree {}".format(degree)) plt.grid() plt.xlabel("Training examples") plt.ylabel("Score") train_sizes = np.linspace(.6, 1.0, 6) # Cross-validation with 100 iterations to get a smoother mean test and training # score curves, each time with 20% of the data randomly selected as a validation set. cv = ShuffleSplit(n_splits=100, test_size=0.2, random_state=0) model = models[degree] train_sizes, train_scores, test_scores = learning_curve( model, X[:, np.newaxis], y, cv=cv, train_sizes=train_sizes, n_jobs=4) train_scores_mean = np.mean(train_scores, axis=1) test_scores_mean = np.mean(test_scores, axis=1) plt.plot(train_sizes, train_scores_mean, 'o-', color="r", label="Training score") plt.plot(train_sizes, test_scores_mean, 'o-', color="g", label="Test score") plt.legend(loc = "best") plt.show() Simüle edilmiş senaryomuzda, eğitim puanını temsil eden mavi çizgi düz bir çizgi gibi görünmektedir. Gerçekte, hala biraz azalır - bunu birinci dereceden polinom grafiğinde görebilirsiniz, ancak diğerlerinde bu çözünürlükte söylemek çok zor. En azından açıkça görüyoruz ki, eğitim için öğrenme eğrileri ile “yüksek önyargılı” senaryolu test gözlemleri arasında büyük bir boşluk var.
Ortadaki “normal” öğrenme oranı grafiğinde antrenman puanı ve test puanı çizgilerinin nasıl bir araya geldiğini görebilirsiniz.
Ve “yüksek varyans” grafiğinde, az sayıda örnekle test ve eğitim puanlarının çok benzer olduğunu görebilirsiniz; ancak, örnek sayısını artırdığınızda, test puanı ondan uzaklaşırken eğitim puanı neredeyse mükemmel kalır.
Doğrusal olmayan bir hipotez kullanırsak, örneğin daha polinom özellikleri olan hipotez gibi, eksik modelleri ( yüksek önyargılı modeller olarak da adlandırılır) düzeltebiliriz.
Overfitting modelimiz ( yüksek varyans ) gösterilen her örnekten geçer; ancak, test verilerini tanıttığımızda, öğrenme eğrileri arasındaki boşluk genişler. Fazla uydurma modelleri düzeltmek için düzenlileştirme, çapraz doğrulama ve daha fazla veri örneğini kullanabiliriz.
Çapraz doğrulama
Fazla uydurmayı önlemek için yaygın uygulamalardan biri, mevcut verilerin bir kısmını tutmak ve bir test seti olarak kullanmaktır. Bununla birlikte, polinom özelliklerinin sayısı gibi farklı model ayarlarını değerlendirirken, optimum tahmin edici performansını elde etmek için parametreler ayarlanabildiğinden ve bu nedenle test seti hakkındaki bilgimiz, test setine gereğinden fazla uydurma riskiyle karşı karşıyayız. modele sızın. Bu sorunu çözmek için veri kümesinin "doğrulama kümesi" olarak adlandırılan bir parçasına daha sahip olmamız gerekir. Eğitim, eğitim seti üzerinde ilerler ve optimal model performansına ulaştığımızı düşündüğümüzde validasyon setini kullanarak son bir değerlendirme yapabiliriz.
Bununla birlikte, mevcut verileri üç kümeye bölerek, modelleri eğitmek için kullanılabilecek örnek sayısını önemli ölçüde azaltırız ve sonuçlar, eğitim-doğrulama kümeleri için belirli bir rastgele seçime bağlı olabilir.
Bu soruna bir çözüm, çapraz doğrulama adı verilen bir prosedürdür. Standart $k$-kat çapraz doğrulamada, verileri kıvrımlar adı verilen $k$ alt kümelerine böleriz. Ardından, geri kalan kıvrımı test seti olarak kullanırken (“uzatma kıvrımı” olarak adlandırılır) algoritmayı yinelemeli olarak $k-1$ kıvrımları üzerinde eğitiriz.
Çapraz doğrulama, parametreleri yalnızca orijinal eğitim setinizle ayarlamanıza olanak tanır. Bu, nihai modelinizi seçmek için test setinizi gerçekten görünmeyen bir veri seti olarak tutmanıza izin verir.
P out , stratified $k$-fold , shuffle ve split gibi çok daha fazla çapraz doğrulama tekniği vardır, ancak bunlar bu makalenin kapsamı dışındadır.
düzenlileştirme
Bu, modelin fazla takılması sorununu çözmeye yardımcı olabilecek başka bir tekniktir. Veri kümelerinin çoğu bir desene ve biraz gürültüye sahiptir. Düzenlemenin amacı, gürültünün model üzerindeki etkisini azaltmaktır.
Üç ana düzenleme tekniği vardır: Kement, Tikhonov ve elastik ağ.
L1 düzenlemesi (veya Kement düzenlemesi ), son modelde herhangi bir rol oynamamaları için sıfıra küçülecek bazı özellikleri seçecektir. L1, önemli özellikleri seçmek için bir yöntem olarak görülebilir.
L2 düzenlileştirme (veya Tikhonov düzenlileştirme ) tüm özellikleri nispeten küçük olmaya zorlayacak ve böylece model üzerinde daha az etki sağlayacaklardır.
Elastik ağ , L1 ve L2'nin birleşimidir.
Normalleştirme (Özellik Ölçeklendirme)
Özellik ölçeklendirme de verilerin ön işlenmesi sırasında önemli bir adımdır. Veri kümemiz $[-\infty, \infty]$ değerlerine sahip özelliklere ve farklı bir ölçekte diğer özelliklere sahip olabilir. Bu, bağımsız değer aralıklarını standardize etmek için bir yöntemdir.
Özellik ölçekleme, öğrenme modellerinin performansını iyileştirmek için de önemli bir süreçtir. Her şeyden önce, tüm özellikler aynı normda ölçeklenirse, gradyan inişi çok daha hızlı yakınsar. Ayrıca, birçok algoritma (örneğin, destek vektör makineleri (SVM)), iki nokta arasındaki mesafeyi hesaplayarak çalışır ve özelliklerden biri geniş değerlere sahipse, mesafe bu özellikten oldukça etkilenir.
Vektör makineleri desteklemek
SVM, sınıflandırma ve regresyon problemleri için kullanılabilecek, yaygın olarak kullanılan bir başka makine öğrenimi algoritmasıdır. SVM'de, her gözlemi $n$ boyutlu uzayda bir nokta olarak çizeriz, burada $n$ sahip olduğumuz özelliklerin sayısıdır. Her özelliğin değeri, belirli koordinatların değeridir. Ardından, iki sınıfı yeterince iyi ayıran bir hiperdüzlem bulmaya çalışırız.
En iyi hiper düzlemi belirledikten sonra, iki sınıfı daha da ayıracak kenar boşlukları eklemek istiyoruz.
SVM, öznitelik sayısının çok yüksek olduğu veya öznitelik sayısının veri örneklerinin sayısından fazla olduğu durumlarda çok etkilidir. Ancak SVM vektör bazında çalıştığı için kullanım öncesinde verilerin normalize edilmesi çok önemlidir.
Nöral ağlar
Yapay sinir ağı algoritmaları, muhtemelen makine öğrenimi çalışmalarının en heyecan verici alanıdır. Sinir ağları, beynin nöronlarının birbirine nasıl bağlandığını taklit etmeye çalışır.
Bir sinir ağı böyle görünür. Her düğümün bir dizi girdi aldığı çok sayıda düğümü birleştiririz, bunlara bazı hesaplamalar uygularız ve bir değer çıkarırız.
Hem denetimli hem de denetimsiz öğrenme için çok çeşitli sinir ağı algoritmaları vardır. Sinir ağları, otonom arabaları sürmek, oyun oynamak, uçaklara inmek, görüntüleri sınıflandırmak ve daha fazlası için kullanılabilir.
Kötü şöhretli Titanik
RMS Titanic, 15 Nisan 1912'de bir buzdağıyla çarpıştıktan sonra Kuzey Atlantik Okyanusu'nda batan bir İngiliz yolcu gemisiydi. Yaklaşık 2.224 mürettebat ve yolcu vardı ve 1.500'den fazla kişi öldü, bu da onu tüm zamanların en ölümcül ticari deniz felaketlerinden biri haline getirdi.
Şimdi, sınıflandırma problemlerinde kullanılan en temel makine öğrenimi algoritmalarının arkasındaki sezgiyi anladığımıza göre, Titanik'tekilerin hayatta kalma sonucunu tahmin etmek için bilgimizi uygulayabiliriz.
Veri kümemiz, Kaggle veri bilimi yarışmaları platformundan ödünç alınacaktır.
import os from pandas import read_csv, concat # Load data data_path = os.path.join(os.getcwd(), "data/titanic.csv") dataset = read_csv(data_path, skipinitialspace=True) dataset.head(5)| Yolcu Kimliği | hayatta kaldı | P sınıfı | İsim | Seks | Yaş | SibSp | parşömen | Bilet | Ücret | Kabin | gemiye bindi | |
| 0 | 1 | 0 | 3 | Braund, Bay Owen Harris | erkek | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
| 1 | 2 | 1 | 1 | Cumings, Bayan John Bradley (Florence Briggs T... | dişi | 38.0 | 1 | 0 | bilgisayar 17599 | 71.2833 | C85 | C |
| 2 | 3 | 1 | 3 | Heikkinen, Bayan Laina | dişi | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
| 3 | 4 | 1 | 1 | Futrelle, Bayan Jacques Heath (Lily May Peel) | dişi | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
| 4 | 5 | 0 | 3 | Allen, Bay William Henry | erkek | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
İlk adımımız verileri yüklemek ve keşfetmek olacaktır. 891 test kaydımız var; her kayıt aşağıdaki yapıya sahiptir:
- yolcu kimliği - gemideki yolcunun kimliği
- hayatta kalma – Kişinin kazadan sağ çıkıp çıkmadığı
- pclass – Bilet sınıfı, örneğin 1., 2., 3.
- cinsiyet – Yolcunun cinsiyeti: Erkek veya kadın
- isim – Başlık dahil
- yaş – Yıl olarak yaş
- sibsp – Titanik'teki kardeş/eş sayısı
- parch – Titanik'teki ebeveyn/çocuk sayısı
- bilet – Bilet numarası
- ücret – Yolcu ücreti
- kabin – Kabin numarası
- gemiye bindi - Biniş limanı
Bu veri seti hem sayısal hem de kategorik verileri içerir. Genellikle, verilere daha derinlemesine dalmak ve buna dayanarak varsayımlarda bulunmak iyi bir fikirdir. Ancak bu durumda bu adımı atlayıp doğrudan tahminlere geçeceğiz.
import pandas as pd # We need to drop some insignificant features and map the others. # Ticket number and fare should not contribute much to the performance of our models. # Name feature has titles (eg, Mr., Miss, Doctor) included. # Gender is definitely important. # Port of embarkation may contribute some value. # Using port of embarkation may sound counter-intuitive; however, there may # be a higher survival rate for passengers who boarded in the same port. dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.', expand=False) dataset = dataset.drop(['PassengerId', 'Ticket', 'Cabin', 'Name'], axis=1) pd.crosstab(dataset['Title'], dataset['Sex'])| Title \ Sex | dişi | erkek |
| Capt | 0 | 1 |
| Col | 0 | 2 |
| Countess | 1 | 0 |
| Don | 0 | 1 |
| Dr | 1 | 6 |
| Jonkheer | 0 | 1 |
| Lady | 1 | 0 |
| Major | 0 | 2 |
| Usta | 0 | 40 |
| Özlemek | 182 | 0 |
| Mlle | 2 | 0 |
| Mme | 1 | 0 |
| Mr | 0 | 517 |
| Mrs | 125 | 0 |
| Ms | 1 | 0 |
| Rev | 0 | 6 |
| Sir | 0 | 1 |
# We will replace many titles with a more common name, English equivalent, # or reclassification dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col',\ 'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Other') dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss') dataset['Title'] = dataset['Title'].replace('Ms', 'Miss') dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs') dataset[['Title', 'Survived']].groupby(['Title'], as_index=False).mean()| Başlık | Survived | |
| 0 | Usta | 0.575000 |
| 1 | Özlemek | 0.702703 |
| 2 | Mr | 0.156673 |
| 3 | Mrs | 0.793651 |
| 4 | Diğer | 0.347826 |
# Now we will map alphanumerical categories to numbers title_mapping = { 'Mr': 1, 'Miss': 2, 'Mrs': 3, 'Master': 4, 'Other': 5 } gender_mapping = { 'female': 1, 'male': 0 } port_mapping = { 'S': 0, 'C': 1, 'Q': 2 } # Map title dataset['Title'] = dataset['Title'].map(title_mapping).astype(int) # Map gender dataset['Sex'] = dataset['Sex'].map(gender_mapping).astype(int) # Map port freq_port = dataset.Embarked.dropna().mode()[0] dataset['Embarked'] = dataset['Embarked'].fillna(freq_port) dataset['Embarked'] = dataset['Embarked'].map(port_mapping).astype(int) # Fix missing age values dataset['Age'] = dataset['Age'].fillna(dataset['Age'].dropna().median()) dataset.head()| Survived | Pclass | Seks | Yaş | SibSp | Parch | Ücret | Embarked | Başlık | |
| 0 | 0 | 3 | 0 | 22.0 | 1 | 0 | 7.2500 | 0 | 1 |
| 1 | 1 | 1 | 1 | 38.0 | 1 | 0 | 71.2833 | 1 | 3 |
| 2 | 1 | 3 | 1 | 26.0 | 0 | 0 | 7.9250 | 0 | 2 |
| 3 | 1 | 1 | 1 | 35.0 | 1 | 0 | 53.1000 | 0 | 3 |
| 4 | 0 | 3 | 0 | 35.0 | 0 | 0 | 8.0500 | 0 | 1 |
At this point, we will rank different types of machine learning algorithms in Python by using scikit-learn to create a set of different models. It will then be easy to see which one performs the best.
- Logistic regression with varying numbers of polynomials
- Support vector machine with a linear kernel
- Support vector machine with a polynomial kernel
- Neural network
For every single model, we will use $k$-fold validation.
from sklearn.model_selection import KFold, train_test_split from sklearn.pipeline import make_pipeline from sklearn.preprocessing import PolynomialFeatures, StandardScaler from sklearn.neural_network import MLPClassifier from sklearn.svm import SVC # Prepare the data X = dataset.drop(['Survived'], axis = 1).values y = dataset[['Survived']].values X = StandardScaler().fit_transform(X) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = None) # Prepare cross-validation (cv) cv = KFold(n_splits = 5, random_state = None) # Performance p_score = lambda model, score: print('Performance of the %s model is %0.2f%%' % (model, score * 100)) # Classifiers names = [ "Logistic Regression", "Logistic Regression with Polynomial Hypotheses", "Linear SVM", "RBF SVM", "Neural Net", ] classifiers = [ LogisticRegression(), make_pipeline(PolynomialFeatures(3), LogisticRegression()), SVC(kernel="linear", C=0.025), SVC(gamma=2, C=1), MLPClassifier(alpha=1), ] # iterate over classifiers models = [] trained_classifiers = [] for name, clf in zip(names, classifiers): scores = [] for train_indices, test_indices in cv.split(X): clf.fit(X[train_indices], y[train_indices].ravel()) scores.append( clf.score(X_test, y_test.ravel()) ) min_score = min(scores) max_score = max(scores) avg_score = sum(scores) / len(scores) trained_classifiers.append(clf) models.append((name, min_score, max_score, avg_score)) fin_models = pd.DataFrame(models, columns = ['Name', 'Min Score', 'Max Score', 'Mean Score']) fin_models.sort_values(['Mean Score']).head()| İsim | Min Score | Max Score | Mean Score | |
| 2 | Linear SVM | 0.793296 | 0.821229 | 0.803352 |
| 0 | Logistic Regression | 0.826816 | 0.860335 | 0.846927 |
| 4 | Neural Net | 0.826816 | 0.860335 | 0.849162 |
| 1 | Logistic Regression with Polynomial Hypotheses | 0.854749 | 0.882682 | 0.869274 |
| 3 | RBF SVM | 0.843575 | 0.888268 | 0.869274 |
Ok, so our experimental research says that the SVM classifier with a radial basis function (RBF) kernel performs the best. Now, we can serialize our model and re-use it in production applications.
import pickle svm_model = trained_classifiers[3] data_path = os.path.join(os.getcwd(), "best-titanic-model.pkl") pickle.dump(svm_model, open(data_path, 'wb'))Machine learning is not complicated, but it's a very broad field of study, and it requires knowledge of math and statistics in order to grasp all of its concepts.
Right now, machine learning and deep learning are among the hottest topics of discussion in Silicon Valley, and are the bread and butter of almost every data science company, mainly because they can automate many repetitive tasks including speech recognition, driving vehicles, financial trading, caring for patients, cooking, marketing, and so on.
Now you can take this knowledge and solve challenges on Kaggle.
This was a very brief introduction to supervised machine learning algorithms. Luckily, there are a lot of online courses and information about machine learning algorithms. I personally would recommend starting with Andrew Ng's course on Coursera.
Kaynaklar
- Andrew Ng's course on Coursera
- Kaggle datasets
- A deep learning reading list
- A list of free books on machine learning algorithms, data mining, deep learning, and related topics
- Makine Öğrenimi Teorisine Giriş ve Uygulamaları: Örneklerle Görsel Bir Eğitim
