Menjelajahi Algoritma Pembelajaran Mesin yang Diawasi

Diterbitkan: 2022-03-11

Tujuan utama dari bacaan ini adalah untuk memahami metodologi statistik yang cukup untuk dapat memanfaatkan algoritma pembelajaran mesin di perpustakaan scikit-learn Python dan kemudian menerapkan pengetahuan ini untuk memecahkan masalah pembelajaran mesin klasik.

Perhentian pertama dari perjalanan kita akan membawa kita melalui sejarah singkat pembelajaran mesin. Kemudian kita akan menyelami algoritma yang berbeda. Pada pemberhentian terakhir kami, kami akan menggunakan apa yang kami pelajari untuk memecahkan Masalah Prediksi Tingkat Kelangsungan Hidup Titanic.

Beberapa disclaimer:

  • Saya seorang insinyur perangkat lunak full-stack, bukan ahli algoritma pembelajaran mesin.
  • Saya berasumsi Anda tahu beberapa Python dasar.
  • Ini bersifat eksploratif, jadi tidak setiap detail dijelaskan seperti dalam tutorial.

Dengan catatan itu, mari selami!

Pengantar Singkat Algoritma Pembelajaran Mesin

Segera setelah Anda menjelajah ke bidang ini, Anda menyadari bahwa pembelajaran mesin kurang romantis daripada yang mungkin Anda pikirkan. Awalnya, saya penuh harapan bahwa setelah saya belajar lebih banyak, saya akan dapat membuat Jarvis AI saya sendiri, yang akan menghabiskan sepanjang hari coding software dan menghasilkan uang untuk saya, jadi saya bisa menghabiskan sepanjang hari di luar ruangan membaca buku, mengendarai sepeda motor, dan menikmati gaya hidup sembrono sementara Jarvis pribadi saya membuat kantong saya lebih dalam. Namun, saya segera menyadari bahwa dasar dari algoritma pembelajaran mesin adalah statistik, yang menurut saya pribadi membosankan dan tidak menarik. Untungnya, ternyata statistik "membosankan" memiliki beberapa aplikasi yang sangat menarik.

Anda akan segera menemukan bahwa untuk mendapatkan aplikasi yang menarik itu, Anda perlu memahami statistik dengan sangat baik. Salah satu tujuan dari algoritma pembelajaran mesin adalah untuk menemukan dependensi statistik dalam data yang disediakan.

Data yang diberikan dapat berupa apa saja mulai dari memeriksa tekanan darah terhadap usia hingga menemukan teks tulisan tangan berdasarkan warna berbagai piksel.

Karena itu, saya ingin tahu apakah saya dapat menggunakan algoritme pembelajaran mesin untuk menemukan dependensi dalam fungsi hash kriptografis (SHA, MD5, dll.)—namun, Anda tidak dapat benar-benar melakukannya karena primitif kripto yang tepat dibuat sedemikian rupa bahwa mereka menghilangkan ketergantungan dan menghasilkan keluaran yang sulit diprediksi secara signifikan. Saya percaya bahwa, dengan waktu yang tidak terbatas, algoritme pembelajaran mesin dapat memecahkan model kripto apa pun.

Sayangnya, kami tidak punya banyak waktu, jadi kami perlu mencari cara lain untuk menambang cryptocurrency secara efisien. Sudah sejauh mana kita bangkit sampai sekarang?

Sejarah Singkat Algoritma Pembelajaran Mesin

Akar dari algoritma pembelajaran mesin berasal dari Thomas Bayes, seorang ahli statistik Inggris yang hidup pada abad ke-18. Makalahnya An Essay Towards Solving a Problem in the Doctrine of Chances mendasari Teorema Bayes, yang diterapkan secara luas di bidang statistik.

Pada abad ke-19, Pierre-Simon Laplace menerbitkan Theorie analytique des probabilites , memperluas karya Bayes dan mendefinisikan apa yang kita kenal sekarang sebagai Teorema Bayes. Sesaat sebelum itu, Adrien-Marie Legendre telah menjelaskan metode “kuadrat terkecil”, yang juga banyak digunakan saat ini dalam pembelajaran terawasi.

Abad ke-20 adalah periode ketika sebagian besar penemuan yang diketahui publik telah dibuat di bidang ini. Andrey Markov menemukan rantai Markov, yang ia gunakan untuk menganalisis puisi. Alan Turing mengusulkan mesin pembelajaran yang bisa menjadi kecerdasan buatan, yang pada dasarnya menunjukkan algoritma genetika. Frank Rosenblatt menemukan Perceptron , memicu kegembiraan besar dan liputan besar di media.

Tapi kemudian tahun 1970-an melihat banyak pesimisme seputar gagasan AI—dan dengan demikian, mengurangi pendanaan—jadi periode ini disebut musim dingin AI . Penemuan kembali backpropagation pada 1980-an menyebabkan kebangkitan dalam penelitian pembelajaran mesin. Dan hari ini, itu adalah topik hangat sekali lagi.

Almarhum Leo Breiman membedakan antara dua paradigma pemodelan statistik: pemodelan data dan pemodelan algoritmik. “Pemodelan algoritmik” kurang lebih berarti algoritme pembelajaran mesin seperti hutan acak .

Pembelajaran mesin dan statistik adalah bidang yang terkait erat. Menurut Michael I. Jordan, gagasan pembelajaran mesin, dari prinsip metodologis hingga alat teoretis, telah memiliki prasejarah yang panjang dalam statistik. Dia juga menyarankan ilmu data sebagai istilah pengganti untuk masalah keseluruhan yang secara implisit dikerjakan oleh spesialis pembelajaran mesin dan ahli statistik.

Kategori Algoritma Pembelajaran Mesin

Bidang pembelajaran mesin berdiri di atas dua pilar utama yang disebut pembelajaran terawasi dan pembelajaran tanpa pengawasan . Beberapa orang juga menganggap bidang studi baru— pembelajaran mendalam —terpisah dari pertanyaan pembelajaran terawasi vs. tanpa pengawasan.

Pembelajaran yang diawasi adalah ketika komputer disajikan dengan contoh input dan output yang diinginkan. Tujuan komputer adalah untuk mempelajari rumus umum yang memetakan input ke output. Ini dapat dipecah lebih lanjut menjadi:

  • Pembelajaran semi-terawat , yaitu ketika komputer diberikan set pelatihan yang tidak lengkap dengan beberapa keluaran yang hilang
  • Pembelajaran aktif , yaitu ketika komputer hanya dapat memperoleh label pelatihan untuk serangkaian instance yang sangat terbatas. Ketika digunakan secara interaktif, set pelatihan mereka dapat disajikan kepada pengguna untuk diberi label.
  • Pembelajaran penguatan , yaitu ketika data pelatihan hanya diberikan sebagai umpan balik untuk tindakan program di lingkungan yang dinamis, seperti mengemudikan kendaraan atau bermain game melawan lawan.

Sebaliknya, pembelajaran tanpa pengawasan adalah ketika tidak ada label yang diberikan sama sekali dan terserah pada algoritme untuk menemukan struktur dalam inputnya. Pembelajaran tanpa pengawasan bisa menjadi tujuan itu sendiri ketika kita hanya perlu menemukan pola tersembunyi.

Pembelajaran mendalam adalah bidang studi baru yang terinspirasi oleh struktur dan fungsi otak manusia dan didasarkan pada jaringan saraf tiruan daripada hanya konsep statistik. Pembelajaran mendalam dapat digunakan dalam pendekatan yang diawasi dan tidak diawasi.

Dalam artikel ini, kita hanya akan membahas beberapa algoritme pembelajaran mesin terawasi yang lebih sederhana dan menggunakannya untuk menghitung peluang bertahan hidup seseorang dalam tenggelamnya Titanic yang tragis. Tetapi secara umum, jika Anda tidak yakin algoritme mana yang akan digunakan, tempat yang bagus untuk memulai adalah lembar contekan algoritme pembelajaran mesin scikit-learn.

Model Pembelajaran Mesin yang Diawasi Dasar

Mungkin algoritma yang paling mudah adalah regresi linier. Kadang-kadang ini dapat direpresentasikan secara grafis sebagai garis lurus, tetapi terlepas dari namanya, jika ada hipotesis polinomial, garis ini bisa menjadi kurva. Either way, model hubungan antara variabel dependen skalar $y$ dan satu atau lebih nilai penjelas dilambangkan dengan $x$.

Dalam istilah awam, ini berarti bahwa regresi linier adalah algoritme yang mempelajari ketergantungan antara $x$ dan $y$ yang diketahui, sehingga nanti kita dapat menggunakannya untuk memprediksi $y$ untuk sampel $x$ yang tidak diketahui.

Dalam contoh pembelajaran terawasi pertama kami, kami akan menggunakan model regresi linier dasar untuk memprediksi tekanan darah seseorang berdasarkan usia mereka. Ini adalah kumpulan data yang sangat sederhana dengan dua fitur yang berarti: Usia dan tekanan darah.

Seperti yang telah disebutkan di atas, sebagian besar algoritme pembelajaran mesin bekerja dengan menemukan ketergantungan statistik pada data yang diberikan kepada mereka. Ketergantungan ini disebut hipotesis dan biasanya dilambangkan dengan $h(\theta)$.

Untuk mengetahui hipotesis, mari kita mulai dengan memuat dan menjelajahi data.

 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>]

Sebuah hipotesis linier ditampilkan pada usia vs grafik tekanan darah.

Pada bagan di atas, setiap titik biru mewakili sampel data kami dan garis biru adalah hipotesis yang perlu dipelajari oleh algoritme kami. Jadi apa sebenarnya hipotesis ini?

Untuk menyelesaikan masalah ini, kita perlu mempelajari ketergantungan antara $x$ dan $y$, yang dilambangkan dengan $y = f(x)$. Oleh karena itu $f(x)$ adalah fungsi target yang ideal. Algoritme pembelajaran mesin akan mencoba menebak fungsi hipotesis $h(x)$ yang merupakan aproksimasi terdekat dari $f(x)$ yang tidak diketahui.

Bentuk hipotesis paling sederhana yang mungkin untuk masalah regresi linier terlihat seperti ini: $h_\theta(x) = \theta_0 + \theta_1 * x$. Kami memiliki variabel skalar input tunggal $x$ yang mengeluarkan variabel skalar tunggal $y$, di mana $\theta_0$ dan $\theta_1$ adalah parameter yang perlu kita pelajari. Proses memasukkan garis biru ini ke dalam data disebut regresi linier. Penting untuk dipahami bahwa kita hanya memiliki satu parameter input $x_1$; namun, banyak fungsi hipotesis juga akan menyertakan unit bias ($x_0$). Jadi hipotesis yang dihasilkan memiliki bentuk $h_\theta(x) = \theta_0 * x_0 + \theta_1 * x_1$. Tetapi kita dapat menghindari penulisan $x_0$ karena hampir selalu sama dengan 1.

Kembali ke garis biru. Hipotesis kami terlihat seperti $h(x) = 84 + 1,24x$, yang berarti bahwa $\theta_0 = 84$ dan $\theta_1 = 1,24$. Bagaimana kita bisa menurunkan nilai $\theta$ secara otomatis?

Kita perlu mendefinisikan fungsi biaya . Pada dasarnya, apa yang dilakukan fungsi biaya hanyalah menghitung kesalahan akar rata-rata kuadrat antara prediksi model dan output aktual.

\[J(\theta) = \frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})^2\ ]

Misalnya, hipotesis kami memprediksi bahwa untuk seseorang yang berusia 48 tahun, tekanan darahnya seharusnya $h(48) = 84 + 1,24 * 48 = 143mmHg$; namun, dalam sampel pelatihan kami, kami memiliki nilai $130 mmHg$. Oleh karena itu kesalahannya adalah $(143 - 130)^2 = 169$. Sekarang kita perlu menghitung kesalahan ini untuk setiap entri dalam kumpulan data pelatihan kita, lalu menjumlahkannya ($\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i )})^2$) dan ambil nilai rata-rata dari itu.

Ini memberi kita nomor skalar tunggal yang mewakili biaya fungsi. Tujuan kami adalah menemukan nilai $\theta$ sedemikian rupa sehingga fungsi biayanya adalah yang terendah; dengan kata lain, kami ingin meminimalkan fungsi biaya. Mudah-mudahan ini akan tampak intuitif: Jika kita memiliki nilai fungsi biaya kecil, ini berarti kesalahan prediksi juga kecil.

 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

Sekarang, kita perlu mencari nilai $\theta$ sedemikian sehingga nilai fungsi biaya kita minimal. Tapi bagaimana kita melakukannya?

\[minJ(\theta) = \frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})^2\ ]

Ada beberapa kemungkinan algoritme, tetapi yang paling populer adalah gradient descent . Untuk memahami intuisi di balik metode penurunan gradien, pertama-tama mari kita plot pada grafik. Demi kesederhanaan, kita akan mengasumsikan hipotesis yang lebih sederhana $h(\theta) = \theta_1 * x$. Selanjutnya, kita akan membuat diagram 2D ​​sederhana di mana $x$ adalah nilai $\theta$ dan $y$ adalah fungsi biaya pada titik ini.

 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() 

Fungsi biaya cembung.

Fungsi biayanya cembung, artinya pada interval $[a, b]$ hanya ada satu minimum. Yang sekali lagi berarti bahwa parameter $\theta$ terbaik berada pada titik di mana fungsi biaya minimal.

Pada dasarnya, gradient descent adalah algoritma yang mencoba menemukan himpunan parameter yang meminimalkan fungsi. Ini dimulai dengan set parameter awal dan secara iteratif mengambil langkah ke arah negatif dari gradien fungsi.

Menemukan minimum untuk fungsi biaya.

Jika kita menghitung turunan dari fungsi hipotesis pada titik tertentu, ini akan memberi kita kemiringan garis singgung kurva pada titik itu. Ini berarti bahwa kita dapat menghitung kemiringan di setiap titik pada grafik.

Cara kerja algoritma ini adalah:

  1. Kami memilih titik awal acak ($\theta$ acak).
  2. Hitung turunan dari fungsi biaya pada titik ini.
  3. Ambil langkah kecil menuju lereng $\theta_j := \theta_j - \lambda * \frac{\partial}{\partial \theta_j} * J(\theta)$.
  4. Ulangi langkah 2-3 sampai kita bertemu.

Sekarang, kondisi konvergensi tergantung pada implementasi algoritma. Kami mungkin berhenti setelah 50 langkah, setelah beberapa ambang, atau apa pun.

 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

Kami tidak akan menerapkan algoritme tersebut dalam artikel ini. Sebagai gantinya, kami akan menggunakan scikit-learn yang diadopsi secara luas, perpustakaan pembelajaran mesin Python sumber terbuka. Ini menyediakan banyak API yang sangat berguna untuk berbagai masalah penambangan data dan pembelajaran mesin.

 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() 

Hipotesis linier yang dipelajari pada grafik tekanan darah vs. usia

<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]]

Jenis Data Statistik

Saat bekerja dengan data untuk masalah pembelajaran mesin, penting untuk mengenali berbagai jenis data. Kami mungkin memiliki data numerik (kontinu atau diskrit), kategoris, atau ordinal.

Data numerik memiliki arti sebagai ukuran. Misalnya, usia, berat badan, jumlah bitcoin yang dimiliki seseorang, atau berapa banyak artikel yang dapat ditulis orang tersebut per bulan. Data numerik dapat dipecah lebih lanjut menjadi tipe diskrit dan kontinu.

  • Data diskrit merupakan data yang dapat dihitung dengan bilangan bulat, misalnya jumlah kamar di apartemen atau jumlah lemparan koin.
  • Data berkelanjutan tidak selalu dapat direpresentasikan dengan bilangan bulat. Misalnya, jika Anda mengukur jarak yang dapat Anda lompati, itu mungkin 2 meter, atau 1,5 meter, atau 1,652245 meter.

Data kategoris mewakili nilai-nilai seperti jenis kelamin seseorang, status perkawinan, negara, dll. Data ini dapat mengambil nilai numerik, tetapi angka-angka itu tidak memiliki arti matematis. Anda tidak dapat menambahkannya bersama-sama.

Data ordinal dapat merupakan campuran dari dua jenis lainnya, dalam kategori tersebut dapat diberi nomor dengan cara yang bermakna secara matematis. Contoh umum adalah penilaian: Seringkali kita diminta untuk menilai sesuatu dalam skala satu sampai sepuluh, dan hanya bilangan bulat yang diperbolehkan. Meskipun kita dapat menggunakan ini secara numerik—misalnya, untuk menemukan peringkat rata-rata untuk sesuatu—kita sering memperlakukan data seolah-olah itu kategoris ketika harus menerapkan metode pembelajaran mesin padanya.

Regresi logistik

Regresi linier adalah algoritma luar biasa yang membantu kita memprediksi nilai numerik, misalnya, harga rumah dengan ukuran dan jumlah kamar tertentu. Namun, terkadang, kami mungkin juga ingin memprediksi data kategoris, untuk mendapatkan jawaban atas pertanyaan seperti:

  • Ini anjing atau kucing?
  • Apakah tumor ini ganas atau jinak?
  • Apakah anggur ini baik atau buruk?
  • Apakah email ini spam atau bukan?

Atau bahkan:

  • Nomor berapa yang ada di gambar?
  • Termasuk kategori mana email ini?

Semua pertanyaan ini khusus untuk masalah klasifikasi . Dan algoritma klasifikasi yang paling sederhana disebut regresi logistik , yang pada akhirnya sama dengan regresi linier kecuali memiliki hipotesis yang berbeda.

Pertama-tama, kita dapat menggunakan kembali hipotesis linier yang sama $h_\theta(x) = \theta^TX$ (ini dalam bentuk vektor). Sedangkan regresi linier dapat menghasilkan angka apa pun dalam interval $[a, b]$, regresi logistik hanya dapat menghasilkan nilai dalam $[−1, 1]$, yang merupakan probabilitas objek yang termasuk dalam kategori tertentu atau tidak.

Menggunakan fungsi sigmoid , kita dapat mengonversi nilai numerik apa pun untuk mewakili nilai pada interval $[−1, 1]$.

\[f(x) = \frac{1}{1 + e^x}\]

Sekarang, alih-alih $x$, kita harus melewati hipotesis yang ada dan oleh karena itu kita akan mendapatkan:

\[f(x) = \frac{1}{1 + e^{\theta_0 + \theta_1 * x_1 + ... + \theta_n * x_n}}\]

Setelah itu, kita dapat menerapkan ambang sederhana yang mengatakan bahwa jika hipotesis lebih besar dari nol, ini adalah nilai benar, jika tidak salah.

\[h_\theta(x) = \begin{cases} 1 & \mbox{if } \theta^TX > 0 \\ 0 & \mbox{else} \end{cases}\]

Ini berarti bahwa kita dapat menggunakan fungsi biaya yang sama dan algoritma penurunan gradien yang sama untuk mempelajari hipotesis untuk regresi logistik.

Dalam contoh algoritme pembelajaran mesin kami berikutnya, kami akan memberi tahu pilot pesawat ulang-alik apakah mereka harus menggunakan kontrol pendaratan otomatis atau manual. Kami memiliki kumpulan data yang sangat kecil—15 sampel—yang terdiri dari enam fitur dan kebenaran dasar .

Dalam algoritme pembelajaran mesin, istilah " kebenaran dasar " mengacu pada keakuratan klasifikasi set pelatihan untuk teknik pembelajaran terawasi.

Dataset kami sudah lengkap, artinya tidak ada fitur yang hilang; namun, beberapa fitur memiliki “*” alih-alih kategori, yang berarti fitur ini tidak menjadi masalah. Kami akan mengganti semua tanda bintang tersebut dengan nol.

 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%

Validasi?

Pada contoh sebelumnya, kami memvalidasi kinerja model kami menggunakan data pembelajaran. Namun, apakah ini sekarang pilihan yang baik, mengingat algoritme kami dapat kurang cocok atau terlalu cocok dengan data? Mari kita lihat contoh yang lebih sederhana ketika kita memiliki satu fitur yang mewakili ukuran rumah dan fitur lainnya yang mewakili harganya.

 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() 

Data yang sama dimodelkan oleh polinomial derajat pertama, keempat, dan 30, untuk menunjukkan underfitting dan overfitting.

Model algoritme pembelajaran mesin tidak sesuai jika tidak dapat menggeneralisasi baik data pelatihan maupun pengamatan baru. Dalam contoh di atas, kami menggunakan hipotesis linier sederhana yang tidak benar-benar mewakili kumpulan data pelatihan yang sebenarnya dan akan memiliki kinerja yang sangat buruk. Biasanya, underfitting tidak dibahas karena dapat dengan mudah dideteksi dengan metrik yang bagus.

Jika algoritme kami mengingat setiap pengamatan yang ditampilkan, maka kinerjanya akan buruk pada pengamatan baru di luar kumpulan data pelatihan. Ini disebut overfitting . Misalnya, model polinomial derajat 30 melewati sebagian besar poin dan memiliki skor yang sangat baik pada set pelatihan, tetapi apa pun di luar itu akan berkinerja buruk.

Dataset kami terdiri dari satu fitur dan mudah diplot dalam ruang 2D; namun, dalam kehidupan nyata, kita mungkin memiliki kumpulan data dengan ratusan fitur, yang membuatnya mustahil untuk diplot secara visual dalam ruang Euclidean. Pilihan lain apa yang kita miliki untuk melihat apakah modelnya kurang pas atau terlalu pas?

Saatnya memperkenalkan Anda pada konsep kurva belajar . Ini adalah grafik sederhana yang memplot kesalahan kuadrat rata-rata atas jumlah sampel pelatihan.

Dalam materi pembelajaran biasanya Anda akan melihat grafik yang mirip dengan ini:

Variasi kurva belajar teoritis berdasarkan derajat polinomial.

Namun, dalam kehidupan nyata, Anda mungkin tidak mendapatkan gambaran yang sempurna. Mari kita plot kurva belajar untuk masing-masing model kita.

 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() 

Skor pelatihan vs skor tes untuk tiga grafik dengan data yang dimodelkan oleh polinomial tingkat pertama, keempat, dan ke-30.

Dalam skenario simulasi kami, garis biru, yang mewakili skor pelatihan, tampak seperti garis lurus. Pada kenyataannya, ini masih sedikit menurun—Anda sebenarnya dapat melihat ini di grafik polinomial tingkat pertama, tetapi di grafik lain terlalu halus untuk mengatakannya pada resolusi ini. Kami setidaknya melihat dengan jelas bahwa ada kesenjangan besar antara kurva pembelajaran untuk pelatihan dan pengamatan pengujian dengan skenario "bias tinggi".

Pada grafik tingkat pembelajaran "normal" di tengah, Anda dapat melihat bagaimana skor pelatihan dan garis skor tes bersatu.

Dan pada grafik “varian tinggi”, Anda dapat melihat bahwa dengan jumlah sampel yang sedikit, nilai tes dan pelatihan sangat mirip; namun, saat Anda menambah jumlah sampel, skor pelatihan tetap hampir sempurna sementara skor tes bertambah jauh darinya.


Kita dapat memperbaiki model yang kurang pas (juga disebut model dengan bias tinggi ) jika kita menggunakan hipotesis non-linier, misalnya hipotesis dengan lebih banyak fitur polinomial.

Model overfitting kami ( varian tinggi ) melewati setiap contoh yang ditampilkan; namun, ketika kami memperkenalkan data uji, kesenjangan antara kurva pembelajaran melebar. Kami dapat menggunakan regularisasi, validasi silang, dan lebih banyak sampel data untuk memperbaiki model overfitting.

Validasi silang

Salah satu praktik umum untuk menghindari overfitting adalah mempertahankan sebagian dari data yang tersedia dan menggunakannya sebagai set pengujian. Namun, ketika mengevaluasi pengaturan model yang berbeda, seperti jumlah fitur polinomial, kami masih berisiko overfitting set pengujian karena parameter dapat diubah untuk mencapai kinerja estimator yang optimal dan, karena itu, pengetahuan kami tentang set pengujian dapat bocor ke dalam model. Untuk mengatasi masalah ini, kita perlu memegang satu bagian lagi dari dataset, yang disebut "set validasi." Pelatihan dilanjutkan pada set pelatihan dan, ketika kami berpikir bahwa kami telah mencapai kinerja model yang optimal, kami dapat membuat evaluasi akhir menggunakan set validasi.

Namun, dengan mempartisi data yang tersedia menjadi tiga set, kami secara dramatis mengurangi jumlah sampel yang dapat digunakan untuk melatih model, dan hasilnya dapat bergantung pada pilihan acak tertentu untuk pasangan set validasi pelatihan.

Salah satu solusi untuk masalah ini adalah prosedur yang disebut validasi silang. Dalam validasi silang $k$-fold standar, kami mempartisi data menjadi subset $k$, yang disebut folds. Kemudian, kami melatih algoritme secara iteratif pada fold $k-1$ sambil menggunakan fold yang tersisa sebagai set pengujian (disebut “holdout fold”).

Kotak yang menunjukkan posisi lipatan holdout dalam validasi silang k-fold.

Validasi silang memungkinkan Anda menyetel parameter hanya dengan set latihan asli Anda. Ini memungkinkan Anda untuk menyimpan set pengujian Anda sebagai set data yang benar-benar tidak terlihat untuk memilih model akhir Anda.

Ada lebih banyak lagi teknik validasi silang, seperti leave P out , stratified $k$-fold , shuffle and split , dll. tetapi semuanya berada di luar cakupan artikel ini.

Regularisasi

Ini adalah teknik lain yang dapat membantu memecahkan masalah model overfitting. Sebagian besar dataset memiliki pola dan beberapa noise. Tujuan dari regularisasi adalah untuk mengurangi pengaruh noise pada model.

Grafik yang menyandingkan fungsi asli dan pasangannya yang teratur.

Ada tiga teknik regularisasi utama: Lasso, Tikhonov, dan jaring elastis.

Regularisasi L1 (atau regularisasi Lasso ) akan memilih beberapa fitur untuk diciutkan menjadi nol, sehingga fitur tersebut tidak akan memainkan peran apa pun dalam model akhir. L1 dapat dilihat sebagai metode untuk memilih fitur penting.

Regularisasi L2 (atau regularisasi Tikhonov ) akan memaksa semua fitur menjadi relatif kecil, sehingga mereka akan memberikan pengaruh yang lebih kecil pada model.

Jaring elastis adalah kombinasi dari L1 dan L2.

Normalisasi (Penskalaan Fitur)

Penskalaan fitur juga merupakan langkah penting saat melakukan pra-pemrosesan data. Dataset kami mungkin memiliki fitur dengan nilai $[-\infty, \infty]$ dan fitur lainnya dengan skala yang berbeda. Ini adalah metode untuk membakukan rentang nilai independen.

Penskalaan fitur juga merupakan proses penting untuk meningkatkan kinerja model pembelajaran. Pertama-tama, penurunan gradien akan menyatu lebih cepat jika semua fitur diskalakan ke norma yang sama. Selain itu, banyak algoritme—misalnya, mesin vektor pendukung (SVM)—bekerja dengan menghitung jarak antara dua titik dan jika salah satu fitur memiliki nilai luas, maka jarak akan sangat dipengaruhi oleh fitur ini.

Mendukung Mesin Vektor

SVM adalah algoritma pembelajaran mesin populer lainnya yang dapat digunakan untuk masalah klasifikasi dan regresi. Dalam SVM, kami memplot setiap pengamatan sebagai titik dalam ruang berdimensi $n$ di mana $n$ adalah jumlah fitur yang kami miliki. Nilai setiap fitur adalah nilai koordinat tertentu. Kemudian, kami mencoba menemukan hyperplane yang memisahkan dua kelas dengan cukup baik.

Grafik yang menunjukkan hyperplane yang memisahkan dua kelas titik data, dengan beberapa vektor pendukungnya juga diilustrasikan.

Setelah kami mengidentifikasi hyperplane terbaik, kami ingin menambahkan margin, yang akan memisahkan kedua kelas lebih jauh.

Grafik yang menunjukkan hyperplane dengan margin.

SVM sangat efektif dimana jumlah fitur sangat tinggi atau jika jumlah fitur lebih banyak maka jumlah sampel data. Namun, karena SVM beroperasi pada basis vektor, sangat penting untuk menormalkan data sebelum digunakan.

Jaringan Saraf

Algoritme jaringan saraf mungkin merupakan bidang studi pembelajaran mesin yang paling menarik. Jaringan saraf mencoba untuk meniru bagaimana neuron otak terhubung bersama.

Ilustrasi jaringan saraf, menunjukkan berbagai masukan yang dipetakan ke nilai sementara, yang pada gilirannya dipetakan ke satu keluaran.

Beginilah tampilan jaringan saraf. Kami menggabungkan banyak node bersama-sama di mana setiap node mengambil satu set input, menerapkan beberapa perhitungan pada mereka, dan menghasilkan nilai.

Ada berbagai macam algoritma jaringan saraf untuk pembelajaran yang diawasi dan tidak diawasi. Jaringan saraf dapat digunakan untuk mengemudikan mobil otonom, bermain game, mendaratkan pesawat, mengklasifikasikan gambar, dan banyak lagi.

Titanic yang Terkenal

RMS Titanic adalah kapal penumpang Inggris yang tenggelam di Samudra Atlantik Utara pada 15 April 1912 setelah bertabrakan dengan gunung es. Ada sekitar 2.224 awak dan penumpang, dan lebih dari 1.500 tewas, menjadikannya salah satu bencana maritim komersial paling mematikan sepanjang masa.

Sekarang, karena kami memahami intuisi di balik algoritme pembelajaran mesin paling dasar yang digunakan untuk masalah klasifikasi, kami dapat menerapkan pengetahuan kami untuk memprediksi hasil kelangsungan hidup bagi mereka yang berada di kapal Titanic.

Dataset kami akan dipinjam dari platform kompetisi ilmu data Kaggle.

 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)
ID Penumpang selamat Kelas P Nama Seks Usia saudaraSp Memanggang Tiket Tarif Kabin Memulai
0 1 0 3 Braund, Tuan Owen Harris pria 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... Perempuan 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Nona Laina Perempuan 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) Perempuan 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Tuan William Henry pria 35.0 0 0 373450 8.0500 NaN S

Langkah pertama kami adalah memuat dan menjelajahi data. Kami memiliki 891 catatan pengujian; setiap record memiliki struktur sebagai berikut:

  • penumpangId – ID penumpang di pesawat
  • kelangsungan hidup – Apakah orang tersebut selamat dari kecelakaan atau tidak
  • pclass – Kelas tiket, mis., 1, 2, 3
  • gender – Gender penumpang: Pria atau wanita
  • nama – Judul disertakan
  • usia – Usia dalam tahun
  • sibsp – Jumlah saudara/pasangan di kapal Titanic
  • parch – Jumlah orang tua/anak di kapal Titanic
  • tiket – Nomor tiket
  • tarif – Tarif penumpang
  • kabin – Nomor kabin
  • berangkat – Pelabuhan embarkasi

Dataset ini berisi data numerik dan kategorikal. Biasanya, adalah ide yang baik untuk menyelami data lebih dalam dan, berdasarkan itu, membuat asumsi. Namun, dalam hal ini, kami akan melewatkan langkah ini dan langsung menuju prediksi.

 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 Perempuan pria
Capt 0 1
Col 0 2
Countess 1 0
mengenakan 0 1
dr 1 6
Jonkheer 0 1
Wanita 1 0
Besar 0 2
Menguasai 0 40
Merindukan 182 0
Mlle 2 0
Mme 1 0
Pak 0 517
Nyonya 125 0
MS 1 0
Rev 0 6
Pak 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()
Judul Survived
0 Menguasai 0.575000
1 Merindukan 0.702703
2 Pak 0.156673
3 Nyonya 0.793651
4 Lainnya 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 Usia SibSp Parch Fare Embarked Judul
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
  • Jaringan syaraf

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()
Nama 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.

Sumber daya

  • 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
  • Pengantar Teori Pembelajaran Mesin dan Aplikasinya: Tutorial Visual dengan Contoh
Related: Machines and Trust: How to Mitigate AI Bias