Hutan Acak dengan Python

Contoh Pembelajaran Mesin End-to-End yang Praktis

Saat ini adalah saat yang paling tepat untuk mempelajari pembelajaran mesin. Dengan sumber daya pembelajaran yang “tersedia online”, “alat sumber terbuka” gratis dengan implementasi algoritme apa pun, dan ketersediaan daya komputasi yang murah melalui layanan cloud seperti AWS, pembelajaran mesin benar-benar merupakan bidang yang telah didemokratisasi oleh internet. . Siapa pun yang memiliki akses ke laptop dan kemauan untuk belajar dapat mencoba algoritma canggih dalam hitungan menit. Dengan sedikit waktu lebih banyak, Anda dapat mengembangkan model praktis untuk membantu kehidupan sehari-hari atau di tempat kerja (atau bahkan beralih ke bidang pembelajaran mesin dan memperoleh manfaat ekonomi). Postingan ini akan memandu Anda melalui implementasi menyeluruh dari model pembelajaran mesin hutan acak yang kuat. Hal ini dimaksudkan sebagai pelengkap dari penjelasan konseptual tentang hutan acak saya, namun dapat dibaca seluruhnya selama Anda memiliki gagasan dasar tentang pohon keputusan dan hutan acak. Sebuah postingan tindak lanjut merinci bagaimana kami dapat meningkatkan model yang dibangun di sini.

Tentu saja akan ada kode Python di sini, namun ini tidak dimaksudkan untuk mengenal siapa pun, melainkan untuk menunjukkan betapa pembelajaran mesin dapat diakses dengan sumber daya yang tersedia saat ini! Proyek lengkap dengan data tersedia di "GitHub", dan "file data" serta "Jupyter Notebook" juga dapat diunduh dari Google Drive. Yang Anda perlukan hanyalah laptop dengan Python terinstal dan kemampuan untuk memulai Notebook Jupyter dan Anda dapat mengikutinya. (Untuk menginstal Python dan menjalankan notebook Jupyter, lihat panduan ini). Akan ada beberapa topik pembelajaran mesin penting yang dibahas di sini, tetapi saya akan mencoba memperjelasnya dan menyediakan sumber daya untuk mempelajari lebih lanjut bagi mereka yang tertarik.

Pengenalan Masalah

Masalah yang akan kami atasi adalah memprediksi suhu maksimum untuk besok di kota kami menggunakan data cuaca satu tahun yang lalu. Saya menggunakan Seattle, WA tetapi jangan ragu untuk mencari data untuk kota Anda sendiri menggunakan alat Online Data Iklim NOAA. Kita akan bertindak seolah-olah kita tidak mempunyai akses terhadap prakiraan cuaca apa pun (selain itu, lebih menyenangkan membuat prediksi sendiri daripada bergantung pada orang lain). Yang kami punya akses adalah riwayat suhu maksimum selama satu tahun, suhu selama dua hari sebelumnya, dan perkiraan dari seorang teman yang selalu mengaku mengetahui segalanya tentang cuaca. Ini adalah “masalah pembelajaran mesin regresi yang diawasi”. Ini diawasi karena kami memiliki fitur (data kota) dan target (suhu) yang ingin kami prediksi. Selama pelatihan, kami memberikan fitur dan target kepada hutan acak dan hutan tersebut harus mempelajari cara memetakan data ke dalam prediksi. Selain itu, ini adalah tugas regresi karena nilai targetnya kontinu (berlawanan dengan kelas diskrit dalam klasifikasi). Itu saja latar belakang yang kita butuhkan, jadi mari kita mulai!

Peta jalan

Sebelum kita terjun langsung ke pemrograman, kita harus memberikan panduan singkat agar kita tetap pada jalurnya. Langkah-langkah berikut menjadi dasar alur kerja pembelajaran mesin apa pun setelah kita memikirkan masalah dan model:

  1. Nyatakan pertanyaannya dan tentukan data yang diperlukan
  2. Dapatkan data dalam format yang dapat diakses
  3. Identifikasi dan perbaiki titik data/anomali yang hilang sesuai kebutuhan
  4. Siapkan data untuk model pembelajaran mesin
  5. Tetapkan model dasar yang ingin Anda lampaui
  6. Latih model pada data pelatihan
  7. Buatlah prediksi pada data pengujian
  8. Bandingkan prediksi dengan target set pengujian yang diketahui dan hitung metrik kinerja
  9. Jika kinerjanya tidak memuaskan, sesuaikan model, peroleh lebih banyak data, atau coba teknik pemodelan lain
  10. Interpretasikan model dan laporkan hasilnya secara visual dan numerik

Langkah 1 sudah dicentang! Kami mempunyai pertanyaan: “dapatkah kami memprediksi suhu maksimum besok untuk kota kami?” dan kami tahu bahwa kami memiliki akses terhadap riwayat suhu maksimum selama setahun terakhir di Seattle, WA.

Akuisisi Data

Pertama, kita memerlukan beberapa data. Untuk menggunakan contoh realistis, saya mengambil data cuaca untuk Seattle, WA dari tahun 2016 menggunakan alat NOAA Climate Data Online. Umumnya, sekitar 80% waktu yang dihabiskan dalam analisis data adalah membersihkan dan mengambil data, namun beban kerja ini dapat dikurangi dengan mencari sumber data berkualitas tinggi. Alat NOAA ternyata mudah digunakan dan data suhu dapat diunduh sebagai file csv bersih yang dapat diurai dalam bahasa seperti Python atau R. File data lengkap tersedia untuk diunduh bagi mereka yang ingin mengikutinya.

Kode Python berikut dimuat dalam data csv dan menampilkan struktur data:

# Pandas is used for data manipulation
import pandas as pd
# Read in data and display first 5 rows
features = pd.read_csv('temps.csv')
features.head(5)

Informasinya dalam format “data rapi” dengan setiap baris membentuk satu observasi, dengan nilai variabel di kolomnya.

Berikut penjelasan kolom-kolom tersebut:

tahun:2016 untuk semua titik data

bulan: nomor bulan dalam setahun

hari: nomor hari dalam setahun

minggu: hari dalam seminggu sebagai string karakter

temp_2: suhu maksimal 2 hari sebelumnya

temp_1: suhu maksimal 1 hari sebelumnya

rata-rata: suhu maksimum rata-rata historis

aktual: pengukuran suhu maksimal

teman: prediksi teman Anda, angka acak antara 20 di bawah rata-rata dan 20 di atas rata-rata

Identifikasi Anomali/Data yang Hilang

Jika kita melihat dimensi datanya, kita melihat hanya ada 348 baris, yang tidak sesuai dengan 366 hari yang kita ketahui pada tahun 2016. Melihat data dari NOAA, saya melihat beberapa hari hilang, yang merupakan pengingat bahwa data yang dikumpulkan di dunia nyata tidak akan pernah sempurna. "Data yang hilang" dapat memengaruhi analisis, begitu juga dengan data yang salah atau outlier. Dalam hal ini, data yang hilang tidak akan berpengaruh besar, dan kualitas datanya bagus karena sumbernya. Kita juga bisa melihat ada sembilan kolom yang mewakili delapan fitur dan satu target ('aktual').

print('The shape of our features is:', features.shape)
The shape of our features is: (348, 9)

Untuk mengidentifikasi anomali, kita dapat dengan cepat menghitung statistik ringkasan.

# Descriptive statistics for each column
features.describe()

Tidak ada titik data yang langsung tampak anomali dan tidak ada angka nol di kolom pengukuran mana pun. Cara lain untuk memverifikasi kualitas data adalah dengan membuat plot dasar. Seringkali lebih mudah untuk menemukan anomali dalam grafik daripada angka. Saya tidak mencantumkan kode sebenarnya di sini, karena pembuatan plot dengan Python tidak intuitif tetapi silakan merujuk ke buku catatan untuk implementasi lengkap (seperti data scientist yang baik, saya cukup banyak menyalin dan menempelkan kode pembuatan plot dari Stack Overflow ).

Dengan memeriksa statistik kuantitatif dan grafiknya, kami dapat merasa yakin dengan kualitas tinggi data kami. Tidak ada outlier yang jelas, dan meskipun ada beberapa poin yang hilang, hal tersebut tidak akan mengurangi analisis.

Persiapan data

Sayangnya, kami belum sampai pada titik di mana Anda bisa memasukkan data mentah ke dalam model dan membuatnya memberikan jawaban (walaupun orang-orang sedang mengerjakannya)! Kami perlu melakukan sedikit modifikasi untuk memasukkan data kami ke dalam istilah yang dapat dimengerti mesin. Kami akan menggunakan perpustakaan Python Pandas untuk manipulasi data kami dengan mengandalkan struktur yang dikenal sebagai kerangka data, yang pada dasarnya adalah spreadsheet excel dengan baris dan kolom.

Langkah-langkah yang tepat untuk menyiapkan data akan bergantung pada model yang digunakan dan data yang dikumpulkan, namun sejumlah manipulasi data akan diperlukan untuk aplikasi pembelajaran mesin apa pun.

Enkode Satu-Panas

Langkah pertama bagi kami dikenal sebagai "one-hot coding" data. Proses ini mengambil variabel kategori, seperti hari dalam seminggu dan mengubahnya menjadi representasi numerik tanpa urutan sembarangan. Hari-hari dalam seminggu bersifat intuitif bagi kami karena kami menggunakannya sepanjang waktu. Anda (mudah-mudahan) tidak akan pernah menemukan orang yang tidak mengetahui bahwa 'Senin' mengacu pada hari pertama minggu kerja, namun mesin tidak memiliki pengetahuan intuitif apa pun. Yang diketahui komputer adalah angka dan untuk pembelajaran mesin kita harus mengakomodasinya. Kita dapat dengan mudah memetakan hari dalam seminggu ke angka 1–7, namun hal ini mungkin menyebabkan algoritme lebih mementingkan hari Minggu karena memiliki nilai numerik yang lebih tinggi. Sebagai gantinya, kami mengubah satu kolom hari kerja menjadi tujuh kolom data biner. Hal ini paling baik diilustrasikan secara bergambar. Satu pengkodean panas mengambil ini:

dan mengubahnya menjadi

Jadi, jika suatu titik data adalah hari Rabu, maka akan ada angka 1 di kolom Rabu dan 0 di semua kolom lainnya. Proses ini dapat dilakukan di panda dalam satu baris!

# One-hot encode the data using pandas get_dummies
features = pd.get_dummies(features)
# Display the first 5 rows of the last 12 columns
features.iloc[:,5:].head(5)

Cuplikan data setelah enkode one-hot:

Bentuk data kita sekarang 349 x 15 dan semua kolomnya berupa angka, sesuai algoritma yang menyukainya!

Fitur dan Target serta Konversi Data menjadi Array

Sekarang, kita perlu memisahkan data menjadi fitur dan target. Target, disebut juga label, adalah nilai yang ingin kita prediksi, dalam hal ini suhu maksimal aktual dan fitur-fiturnya adalah semua kolom yang digunakan model untuk membuat prediksi. Kami juga akan mengonversi kerangka data Pandas menjadi array Numpy karena itulah cara kerja algoritme. (Saya menyimpan tajuk kolom, yang merupakan nama fitur, ke daftar untuk digunakan untuk visualisasi nanti).

# Use numpy to convert to arrays
import numpy as np
# Labels are the values we want to predict
labels = np.array(features['actual'])
# Remove the labels from the features
# axis 1 refers to the columns
features= features.drop('actual', axis = 1)
# Saving feature names for later use
feature_list = list(features.columns)
# Convert to numpy array
features = np.array(features)

Perangkat Pelatihan dan Pengujian

Ada satu langkah terakhir dalam persiapan data: membagi data menjadi set pelatihan dan pengujian. Selama pelatihan, kami membiarkan model 'melihat' jawabannya, dalam hal ini suhu sebenarnya, sehingga model dapat mempelajari cara memprediksi suhu dari fitur-fiturnya. Kami berharap ada hubungan antara semua fitur dan nilai target, dan tugas model adalah mempelajari hubungan ini selama pelatihan. Kemudian, ketika tiba waktunya untuk mengevaluasi model, kami memintanya untuk membuat prediksi pada set pengujian yang hanya memiliki akses ke fitur (bukan jawabannya)! Karena kami memiliki jawaban sebenarnya untuk rangkaian pengujian, kami dapat membandingkan prediksi ini dengan nilai sebenarnya untuk menilai seberapa akurat model tersebut. Secara umum, saat melatih sebuah model, kami membagi data secara acak menjadi “kumpulan pelatihan dan pengujian” untuk mendapatkan representasi dari semua titik data (jika kami melatih pada sembilan bulan pertama tahun ini dan kemudian menggunakan tiga bulan terakhir untuk prediksi, kami algoritma tidak akan bekerja dengan baik karena belum melihat data apa pun dari tiga bulan terakhir.) Saya menyetel status acak ke 42 yang berarti hasilnya akan sama setiap kali saya menjalankan pemisahan untuk hasil yang dapat direproduksi.

Kode berikut membagi kumpulan data dengan satu baris lainnya:

# Using Skicit-learn to split data into training and testing sets
from sklearn.model_selection import train_test_split
# Split the data into training and testing sets
train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size = 0.25, random_state = 42)

Kita bisa melihat bentuk semua data untuk memastikan kita melakukan semuanya dengan benar. Kami mengharapkan jumlah kolom fitur pelatihan cocok dengan jumlah kolom fitur pengujian dan jumlah baris yang cocok untuk masing-masing fitur pelatihan dan pengujian serta labelnya :

print('Training Features Shape:', train_features.shape)
print('Training Labels Shape:', train_labels.shape)
print('Testing Features Shape:', test_features.shape)
print('Testing Labels Shape:', test_labels.shape)
Training Features Shape: (261, 14)
Training Labels Shape: (261,)
Testing Features Shape: (87, 14)
Testing Labels Shape: (87,)

Sepertinya semuanya beres! Singkatnya, untuk membuat data menjadi bentuk yang dapat diterima untuk pembelajaran mesin, kami:

  1. Variabel kategori yang dikodekan satu-panas
  2. Pisahkan data menjadi fitur dan label
  3. Dikonversi menjadi array
  4. Pisahkan data menjadi set pelatihan dan pengujian

Tergantung pada kumpulan data awal, mungkin ada pekerjaan tambahan yang harus dilakukan seperti menghilangkan outlier, “menghitung nilai yang hilang”, atau “mengubah variabel temporal menjadi representasi siklus”. Langkah-langkah ini mungkin tampak sewenang-wenang pada awalnya, tetapi setelah Anda memahami alur kerja dasarnya, secara umum akan sama untuk masalah pembelajaran mesin apa pun. Ini semua tentang mengambil data yang dapat dibaca manusia dan memasukkannya ke dalam bentuk yang dapat dipahami oleh model pembelajaran mesin.

Tetapkan Garis Dasar

Sebelum kita dapat membuat dan mengevaluasi prediksi, kita perlu menetapkan dasar, yaitu ukuran yang masuk akal yang kita harap dapat diatasi dengan model kita. Jika model kita tidak dapat memperbaiki model dasar, maka model tersebut akan gagal dan kita harus mencoba model lain atau mengakui bahwa pembelajaran mesin tidak tepat untuk masalah kita. Prediksi dasar untuk kasus kami dapat berupa rata-rata suhu maksimal historis. Dengan kata lain, garis dasar kita adalah kesalahan yang akan kita peroleh jika kita memperkirakan rata-rata suhu maksimal untuk semua hari.

# The baseline predictions are the historical averages
baseline_preds = test_features[:, feature_list.index('average')]
# Baseline errors, and display average baseline error
baseline_errors = abs(baseline_preds - test_labels)
print('Average baseline error: ', round(np.mean(baseline_errors), 2))
Average baseline error:  5.06 degrees.

Kami sekarang memiliki tujuan kami! Jika kita tidak dapat mengatasi kesalahan rata-rata 5 derajat, maka kita perlu memikirkan kembali pendekatan kita.

Model Kereta

Setelah semua pekerjaan persiapan data, pembuatan dan pelatihan model cukup sederhana “menggunakan Scikit-learn”. Kami mengimpor model regresi hutan acak dari skicit-learn, membuat instance model, dan menyesuaikan (nama pelatihan scikit-learn) model pada data pelatihan. (Sekali lagi mengatur keadaan acak untuk hasil yang dapat direproduksi). Keseluruhan proses ini hanya 3 baris di scikit-learn!

# Import the model we are using
from sklearn.ensemble import RandomForestRegressor
# Instantiate model with 1000 decision trees
rf = RandomForestRegressor(n_estimators = 1000, random_state = 42)
# Train the model on training data
rf.fit(train_features, train_labels);

Buat Prediksi pada Set Tes

Model kami kini telah dilatih untuk mempelajari hubungan antara fitur dan target. Langkah selanjutnya adalah mencari tahu seberapa bagus modelnya! Untuk melakukan hal ini, kami membuat prediksi pada fitur pengujian (model tidak pernah diizinkan untuk melihat jawaban pengujian). Kami kemudian membandingkan prediksi tersebut dengan jawaban yang diketahui. Saat melakukan regresi, kita perlu memastikan untuk menggunakan kesalahan absolut karena kita memperkirakan sebagian jawaban kita rendah dan sebagian lagi tinggi. Kami tertarik pada seberapa jauh rata-rata prediksi kami dari nilai sebenarnya sehingga kami mengambil nilai absolutnya (seperti yang juga kami lakukan saat menetapkan garis dasar).

Membuat prediksi tanpa model adalah perintah 1 baris lainnya di Skicit-learn.

# Use the forest's predict method on the test data
predictions = rf.predict(test_features)
# Calculate the absolute errors
errors = abs(predictions - test_labels)
# Print out the mean absolute error (mae)
print('Mean Absolute Error:', round(np.mean(errors), 2), 'degrees.')
Mean Absolute Error: 3.83 degrees.

Perkiraan rata-rata kami meleset sebesar 3,83 derajat. Itu berarti peningkatan rata-rata lebih dari 1 derajat dibandingkan baseline. Meskipun hal ini mungkin tidak terlihat signifikan, namun angka ini hampir 25% lebih baik dibandingkan dengan data dasar, yang tergantung pada bidang dan masalahnya, dapat menghasilkan jutaan dolar bagi sebuah perusahaan.

Tentukan Metrik Kinerja

Untuk menempatkan prediksi kita dalam perspektif, kita dapat menghitung akurasi menggunakan rata-rata persentase kesalahan yang dikurangi dari 100%.

# Calculate mean absolute percentage error (MAPE)
mape = 100 * (errors / test_labels)
# Calculate and display accuracy
accuracy = 100 - np.mean(mape)
print('Accuracy:', round(accuracy, 2), '%.')
Accuracy: 93.99 %.

Kelihatannya cukup bagus! Model kami telah mempelajari cara memprediksi suhu maksimum untuk hari berikutnya di Seattle dengan akurasi 94%.

Tingkatkan Model jika Diperlukan

Dalam alur kerja pembelajaran mesin biasa, ini adalah saat memulai penyetelan hyperparameter. Ini adalah frasa rumit yang berarti “menyesuaikan pengaturan untuk meningkatkan kinerja” (Pengaturan ini dikenal sebagai “hiperparameter” untuk membedakannya dari parameter model yang dipelajari selama pelatihan). Cara paling umum untuk melakukan ini adalah dengan membuat sekumpulan model dengan pengaturan berbeda, mengevaluasi semuanya pada set validasi yang sama, dan melihat model mana yang memiliki kinerja terbaik. Tentu saja, ini akan menjadi proses yang membosankan jika dilakukan secara manual, dan ada"metode otomatis" untuk melakukan proses ini di Skicit-learn. Penyetelan hyperparameter seringkali “lebih bersifat rekayasa” daripada berdasarkan teori, dan saya akan mendorong siapa pun yang tertarik untuk melihat “dokumentasi” dan mulai bermain-main! Akurasi 94% cukup memuaskan untuk masalah ini, namun perlu diingat bahwa model pertama yang dibuat hampir tidak pernah menjadi model yang berhasil diproduksi.

Menafsirkan Model dan Melaporkan Hasil

Pada titik ini, kami mengetahui bahwa model kami bagus, namun sebenarnya model tersebut hanyalah sebuah "kotak hitam". Kami memasukkan beberapa array Numpy untuk pelatihan, memintanya untuk membuat prediksi, mengevaluasi prediksi, dan memastikan bahwa prediksi tersebut masuk akal. Pertanyaannya adalah: bagaimana model ini sampai pada nilai-nilai tersebut? Ada dua pendekatan untuk memahami hutan acak: pertama, kita dapat melihat satu pohon di hutan, dan kedua, kita dapat melihat pentingnya fitur dari variabel penjelas kita.

Memvisualisasikan Pohon Keputusan Tunggal

Salah satu bagian paling keren dari implementasi Random Forest di Skicit-learn adalah kita dapat memeriksa pohon mana pun di hutan. Kami akan memilih satu pohon, dan menyimpan keseluruhan pohon sebagai gambar.

Kode berikut mengambil satu pohon dari hutan dan menyimpannya sebagai gambar.

# Import tools needed for visualization
from sklearn.tree import export_graphviz
import pydot
# Pull out one tree from the forest
tree = rf.estimators_[5]
# Import tools needed for visualization
from sklearn.tree import export_graphviz
import pydot
# Pull out one tree from the forest
tree = rf.estimators_[5]
# Export the image to a dot file
export_graphviz(tree, out_file = 'tree.dot', feature_names = feature_list, rounded = True, precision = 1)
# Use dot file to create a graph
(graph, ) = pydot.graph_from_dot_file('tree.dot')
# Write graph to a png file
graph.write_png('tree.png')

Mari lihat:

Wow! Kelihatannya seperti pohon yang cukup besar dengan 15 lapisan (pada kenyataannya ini adalah pohon yang cukup kecil dibandingkan dengan beberapa pohon yang pernah saya lihat). Anda dapat "mengunduh gambar ini" sendiri dan memeriksanya lebih detail, tetapi untuk mempermudah, saya akan membatasi kedalaman pepohonan di hutan untuk menghasilkan gambar yang dapat dimengerti.

# Limit depth of tree to 3 levels
rf_small = RandomForestRegressor(n_estimators=10, max_depth = 3)
rf_small.fit(train_features, train_labels)
# Extract the small tree
tree_small = rf_small.estimators_[5]
# Save the tree as a png image
export_graphviz(tree_small, out_file = 'small_tree.dot', feature_names = feature_list, rounded = True, precision = 1)
(graph, ) = pydot.graph_from_dot_file('small_tree.dot')
graph.write_png('small_tree.png');

Berikut adalah pohon berukuran kecil yang diberi label

Hanya berdasarkan pohon ini, kita dapat membuat prediksi untuk setiap titik data baru. Mari kita ambil contoh membuat prediksi untuk hari Rabu, 27 Desember 2017. Variabel (sebenarnya) adalah: temp_2 = 39, temp_1 = 35, average = 44, dan friends = 30. Kita mulai dari root node dan jawaban pertama Benar karena temp_1 ≤ 59,5. Kita bergerak ke kiri dan menemukan pertanyaan kedua, yang juga Benar karena rata-rata ≤ 46,8. Pindah ke kiri dan ke pertanyaan ketiga dan terakhir yang juga Benar karena temp_1 ≤ 44.5. Oleh karena itu, kami menyimpulkan bahwa perkiraan kami untuk suhu maksimum adalah 41,0 derajat seperti yang ditunjukkan oleh nilai pada simpul daun. Pengamatan yang menarik adalah pada root node hanya terdapat 162 sampel padahal terdapat 261 titik data latih. Hal ini karena setiap pohon di hutan dilatih pada subset titik data acak dengan penggantian (disebut bagging, kependekan dari bootstrap aggregating). (Kita dapat mematikan pengambilan sampel dengan penggantian dan menggunakan semua titik data dengan menyetel bootstrap = False saat membuat hutan). Pengambilan sampel titik data secara acak, dikombinasikan dengan pengambilan sampel acak dari subset fitur di setiap node pohon, adalah alasan mengapa model ini disebut hutan ‘acak’.

Selanjutnya, perhatikan bahwa di pohon kita, hanya ada 2 variabel yang sebenarnya kita gunakan untuk membuat prediksi! Menurut pohon keputusan khusus ini, fitur lainnya tidak penting untuk membuat prediksi. Bulan dalam setahun, hari dalam sebulan, dan prediksi teman kita sama sekali tidak berguna untuk memprediksi suhu maksimum besok! Satu-satunya informasi penting menurut pohon sederhana kami adalah suhu 1 hari sebelumnya dan rata-rata historis. Memvisualisasikan pohon telah meningkatkan pengetahuan domain kita tentang masalah tersebut, dan sekarang kita mengetahui data apa yang harus dicari jika kita diminta membuat prediksi!

Variabel Pentingnya

Untuk mengukur kegunaan semua variabel di seluruh hutan acak, kita dapat melihat kepentingan relatif dari variabel-variabel tersebut. Kepentingan yang dikembalikan dalam Skicit-learn menunjukkan seberapa besar penyertaan variabel tertentu meningkatkan prediksi. Perhitungan tingkat kepentingan sebenarnya berada di luar cakupan postingan ini, namun kita dapat menggunakan angka-angka tersebut untuk membuat perbandingan relatif antar variabel.

Kode di sini memanfaatkan sejumlah trik dalam bahasa Python, yaitu “daftar komprehensif”, “zip”, “penyortiran”, dan “pembongkaran argumen”. Saat ini tidak terlalu penting untuk memahami hal ini, tetapi jika Anda ingin menjadi ahli dalam Python, ini adalah alat yang harus Anda miliki!

# Get numerical feature importances
importances = list(rf.feature_importances_)
# List of tuples with variable and importance
feature_importances = [(feature, round(importance, 2)) for feature, importance in zip(feature_list, importances)]
# Sort the feature importances by most important first
feature_importances = sorted(feature_importances, key = lambda x: x[1], reverse = True)
# Print out the feature and importances 
[print('Variable: {:20} Importance: {}'.format(*pair)) for pair in feature_importances];
Variable: temp_1               Importance: 0.7
Variable: average              Importance: 0.19
Variable: day                  Importance: 0.03
Variable: temp_2               Importance: 0.02
Variable: friend               Importance: 0.02
Variable: month                Importance: 0.01
Variable: year                 Importance: 0.0
Variable: week_Fri             Importance: 0.0
Variable: week_Mon             Importance: 0.0
Variable: week_Sat             Importance: 0.0
Variable: week_Sun             Importance: 0.0
Variable: week_Thurs           Importance: 0.0
Variable: week_Tues            Importance: 0.0
Variable: week_Wed             Importance: 0.0

Di bagian atas daftar adalah temp_1, suhu maksimal sehari sebelumnya. Hal ini memberi tahu kita bahwa prediktor terbaik untuk suhu maksimum pada suatu hari adalah suhu maksimum pada hari sebelumnya, sebuah temuan yang cukup intuitif. Faktor terpenting kedua adalah suhu maksimum rata-rata historis, yang juga tidak terlalu mengejutkan. Teman anda ternyata tidak terlalu membantu, seiring dengan hari dalam seminggu, tahun, bulan, dan suhu 2 hari sebelumnya. Semua hal penting ini masuk akal karena kita tidak mengharapkan hari dalam seminggu menjadi prediktor suhu maksimum karena tidak ada hubungannya dengan cuaca. Selain itu, tahun yang sama untuk semua titik data sehingga tidak memberi kita informasi untuk memprediksi suhu maksimal.

Dalam implementasi model di masa depan, kita dapat menghapus variabel-variabel yang tidak penting dan kinerjanya tidak akan terganggu. Selain itu, jika kita menggunakan model yang berbeda, misalnya mesin vektor dukungan, kita dapat menggunakan kepentingan fitur hutan acak sebagai semacam metode pemilihan fitur. Mari segera buat hutan acak hanya dengan dua variabel terpenting, suhu maksimal 1 hari sebelumnya dan rata-rata historis, lalu lihat perbandingan performanya.

# New random forest with only the two most important variables
rf_most_important = RandomForestRegressor(n_estimators= 1000, random_state=42)
# Extract the two most important features
important_indices = [feature_list.index('temp_1'), feature_list.index('average')]
train_important = train_features[:, important_indices]
test_important = test_features[:, important_indices]
# Train the random forest
rf_most_important.fit(train_important, train_labels)
# Make predictions and determine the error
predictions = rf_most_important.predict(test_important)
errors = abs(predictions - test_labels)
# Display the performance metrics
print('Mean Absolute Error:', round(np.mean(errors), 2), 'degrees.')
mape = np.mean(100 * (errors / test_labels))
accuracy = 100 - mape
print('Accuracy:', round(accuracy, 2), '%.')
Mean Absolute Error: 3.9 degrees.
Accuracy: 93.8 %.

Hal ini memberi tahu kita bahwa sebenarnya kita tidak memerlukan semua data yang telah kita kumpulkan untuk membuat prediksi yang akurat! Jika kami terus menggunakan model ini, kami hanya dapat mengumpulkan dua variabel dan mencapai kinerja yang hampir sama. Dalam lingkungan produksi, kita perlu mempertimbangkan penurunan akurasi versus waktu tambahan yang diperlukan untuk memperoleh lebih banyak informasi. Mengetahui cara menemukan keseimbangan yang tepat antara kinerja dan biaya merupakan keterampilan penting bagi seorang insinyur pembelajaran mesin dan pada akhirnya akan bergantung pada masalahnya!

Pada titik ini kita telah membahas hampir semua hal yang perlu diketahui untuk implementasi dasar hutan acak untuk masalah regresi terawasi. Kami yakin bahwa model kami dapat memprediksi suhu maksimum besok dengan akurasi 94% berdasarkan data historis satu tahun. Dari sini, silakan bermain-main dengan contoh ini, atau gunakan model pada kumpulan data pilihan Anda. Saya akan mengakhiri postingan ini dengan membuat beberapa visualisasi. Dua bagian favorit saya dalam ilmu data adalah grafik dan pemodelan, jadi tentu saja saya harus membuat beberapa bagan! Selain menyenangkan untuk dilihat, bagan dapat membantu kita mendiagnosis model karena bagan tersebut memampatkan banyak angka menjadi sebuah gambar yang dapat kita periksa dengan cepat.

Visualisasi

Bagan pertama yang akan saya buat adalah diagram batang sederhana tentang pentingnya fitur untuk menggambarkan perbedaan signifikansi relatif dari variabel-variabel tersebut. Membuat plot dengan Python agak tidak intuitif, dan saya akhirnya mencari hampir semua hal di Stack Overflow ketika saya membuat grafik. Jangan khawatir jika kode di sini kurang masuk akal, terkadang memahami kode sepenuhnya tidak diperlukan untuk mendapatkan hasil akhir yang Anda inginkan!

# Import matplotlib for plotting and use magic command for Jupyter Notebooks
import matplotlib.pyplot as plt
%matplotlib inline
# Set the style
plt.style.use('fivethirtyeight')
# list of x locations for plotting
x_values = list(range(len(importances)))
# Make a bar chart
plt.bar(x_values, importances, orientation = 'vertical')
# Tick labels for x axis
plt.xticks(x_values, feature_list, rotation='vertical')
# Axis labels and title
plt.ylabel('Importance'); plt.xlabel('Variable'); plt.title('Variable Importances');

Selanjutnya, kita dapat memplot seluruh kumpulan data dengan prediksi yang disorot. Ini memerlukan sedikit manipulasi data, namun tidak terlalu sulit. Kita dapat menggunakan plot ini untuk menentukan apakah ada outlier baik dalam data maupun prediksi kita.

# Use datetime for creating date objects for plotting
import datetime
# Dates of training values
months = features[:, feature_list.index('month')]
days = features[:, feature_list.index('day')]
years = features[:, feature_list.index('year')]
# List and then convert to datetime object
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]
# Dataframe with true values and dates
true_data = pd.DataFrame(data = {'date': dates, 'actual': labels})
# Dates of predictions
months = test_features[:, feature_list.index('month')]
days = test_features[:, feature_list.index('day')]
years = test_features[:, feature_list.index('year')]
# Column of dates
test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
# Convert to datetime objects
test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates]
# Dataframe with predictions and dates
predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predictions})
# Plot the actual values
plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual')
# Plot the predicted values
plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction')
plt.xticks(rotation = '60'); 
plt.legend()
# Graph labels
plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values');

Sedikit kerja keras untuk mendapatkan grafik yang terlihat bagus! Sepertinya kita tidak memiliki kelainan yang perlu diperbaiki. Untuk mendiagnosis model lebih lanjut, kita dapat memplot residu (kesalahan) untuk melihat apakah model kita cenderung over-predict atau under-predict, dan kita juga dapat melihat apakah residu berdistribusi normal. Namun, saya hanya akan membuat satu grafik terakhir yang menunjukkan nilai sebenarnya, suhu satu hari sebelumnya, rata-rata historis, dan prediksi teman kita. Ini akan memungkinkan kita melihat perbedaan antara variabel berguna dan variabel yang tidak terlalu membantu.

# Make the data accessible for plotting
true_data['temp_1'] = features[:, feature_list.index('temp_1')]
true_data['average'] = features[:, feature_list.index('average')]
true_data['friend'] = features[:, feature_list.index('friend')]
# Plot all the data as lines
plt.plot(true_data['date'], true_data['actual'], 'b-', label  = 'actual', alpha = 1.0)
plt.plot(true_data['date'], true_data['temp_1'], 'y-', label  = 'temp_1', alpha = 1.0)
plt.plot(true_data['date'], true_data['average'], 'k-', label = 'average', alpha = 0.8)
plt.plot(true_data['date'], true_data['friend'], 'r-', label = 'friend', alpha = 0.3)
# Formatting plot
plt.legend(); plt.xticks(rotation = '60');
# Lables and title
plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual Max Temp and Variables');

Agak sulit untuk melihat semua garisnya, tetapi kita dapat melihat mengapa suhu maksimal satu hari sebelumnya dan riwayat suhu maksimal berguna untuk memprediksi suhu maksimal sedangkan teman kita tidak (jangan menyerah dulu sobat, tapi mungkin juga tidak terlalu membebani perkiraan mereka!). Grafik seperti ini sering kali berguna untuk dibuat sebelumnya sehingga kita dapat memilih variabel yang akan disertakan, namun juga dapat digunakan untuk diagnosis. Seperti halnya “kuartet Anscombe”, grafik seringkali lebih mengungkapkan dibandingkan angka kuantitatif dan harus menjadi bagian dari alur kerja pembelajaran mesin.

Kesimpulan

Dengan grafik tersebut, kami telah menyelesaikan seluruh contoh pembelajaran mesin end-to-end! Pada titik ini, jika kita ingin meningkatkan model kita, kita dapat mencoba hyperparameter (pengaturan) yang berbeda, mencoba algoritma yang berbeda, atau pendekatan terbaik dari semuanya, mengumpulkan lebih banyak data! Kinerja model apa pun berbanding lurus dengan jumlah data valid yang dapat dipelajari, dan kami menggunakan informasi dalam jumlah yang sangat terbatas untuk pelatihan. Saya akan mendorong siapa pun untuk mencoba dan meningkatkan model ini dan membagikan hasilnya. Dari sini Anda dapat menggali lebih dalam tentang teori hutan acak dan penerapannya menggunakan berbagai sumber daya online (gratis). Bagi mereka yang mencari satu buku yang membahas teori dan implementasi model pembelajaran mesin dengan Python, saya sangat merekomendasikan Pembelajaran Mesin Praktis dengan Scikit-Learn dan Tensorflow. Selain itu, saya berharap semua orang yang berhasil lolos telah melihat betapa mudahnya pembelajaran mesin dan siap untuk bergabung dengan komunitas pembelajaran mesin yang ramah dan membantu.

Seperti biasa, saya menyambut masukan dan kritik yang membangun! Email saya adalah [email protected].