Tutorial Scikit-Learn: Cara Install & Contoh Scikit-Learn
Apa itu Scikit-belajar?
Scikit-belajar adalah sumber terbuka Python pustaka untuk pembelajaran mesin. Mendukung algoritme canggih seperti KNN, XGBoost, random forest, dan SVM. Dibangun di atas NumPy. Scikit-learn banyak digunakan dalam kompetisi Kaggle serta perusahaan teknologi terkemuka. Membantu dalam praproses, reduksi dimensionalitas (pemilihan parameter), klasifikasi, regresi, pengelompokan, dan pemilihan model.
Scikit-learn memiliki dokumentasi terbaik dari semua perpustakaan sumber terbuka. Ini memberi Anda grafik interaktif di https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html.

Scikit-learn tidak terlalu sulit untuk digunakan dan memberikan hasil yang sangat baik. Namun, scikit learn tidak mendukung komputasi paralel. Algoritme pembelajaran mendalam dapat dijalankan dengannya, tetapi ini bukan solusi optimal, terutama jika Anda tahu cara menggunakan TensorFlow.
Cara Mengunduh dan Menginstal Scikit-learn
Sekarang dalam hal ini Python Tutorial Scikit-learn, kita akan belajar cara mendownload dan menginstal Scikit-learn:
Opsi 1: AWS
scikit-learn dapat digunakan melalui AWS. Silakan lihat Gambar buruh pelabuhan yang telah menginstal scikit-learn.
Untuk menggunakan versi pengembang gunakan perintah di Jupyter
import sys !{sys.executable} -m pip install git+git://github.com/scikit-learn/scikit-learn.git
Opsi 2: Mac atau Windows menggunakan Anaconda
Untuk mempelajari tentang instalasi Anaconda, lihat https://www.guru99.com/download-install-tensorflow.html
Baru-baru ini, pengembang scikit telah merilis versi pengembangan yang mengatasi masalah umum yang dihadapi pada versi saat ini. Kami merasa lebih nyaman menggunakan versi pengembang daripada versi saat ini.
Cara Menginstal scikit-learn dengan Conda Environment
Jika Anda menginstal scikit-learn dengan lingkungan conda, ikuti langkah untuk memperbarui ke versi 0.20
Langkah 1) Aktifkan lingkungan tensorflow
source activate hello-tf
Langkah 2) Hapus scikit lean menggunakan perintah conda
conda remove scikit-learn
Langkah 3) Instal versi pengembang.
Instal scikit learn versi pengembang bersama dengan perpustakaan yang diperlukan.
conda install -c anaconda git pip install Cython pip install h5py pip install git+git://github.com/scikit-learn/scikit-learn.git
CATATAN: Windows pengguna perlu menginstal Microsoft visual C++ 14. Anda bisa mendapatkannya dari di sini
Contoh Scikit-Learn dengan Machine Learning
Tutorial Scikit ini dibagi menjadi dua bagian:
- Pembelajaran mesin dengan scikit-learn
- Bagaimana memercayai model Anda dengan LIME
Bagian pertama merinci cara membangun jalur pipa, membuat model dan menyetel hiperparameter, sedangkan bagian kedua menyediakan keadaan terkini dalam hal pemilihan model.
Langkah 1) Impor data
Selama tutorial pembelajaran Scikit ini, Anda akan menggunakan kumpulan data dewasa.
Untuk latar belakang kumpulan data ini, lihat Jika Anda tertarik untuk mengetahui lebih banyak tentang statistik deskriptif, silakan gunakan alat Penyelaman dan Ikhtisar.
Lihat tutorial ini pelajari lebih lanjut tentang Penyelaman dan Ikhtisar
Anda mengimpor kumpulan data dengan Pandas. Perhatikan bahwa Anda perlu mengonversi jenis variabel kontinu dalam format float.
Kumpulan data ini mencakup delapan variabel kategori:
Variabel kategori tercantum di CATE_FEATURES
- kelas kerja
- pendidikan
- perkawinan
- pekerjaan
- hubungan
- ras
- seks
- negara Asal
apalagi, enam variabel kontinu:
Variabel kontinu tercantum di CONTI_FEATURES
- usia
- fnlwgt
- pendidikan_num
- keuntungan dalam bentuk uang
- modal_rugi
- jam_minggu
Perhatikan bahwa kami mengisi daftar dengan tangan sehingga Anda memiliki gambaran yang lebih baik tentang kolom apa yang kami gunakan. Cara yang lebih cepat untuk membuat daftar kategorikal atau berkelanjutan adalah dengan menggunakan:
## List Categorical CATE_FEATURES = df_train.iloc[:,:-1].select_dtypes('object').columns print(CATE_FEATURES) ## List continuous CONTI_FEATURES = df_train._get_numeric_data() print(CONTI_FEATURES)
Berikut kode untuk mengimpor data:
# Import dataset import pandas as pd ## Define path data COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country', 'label'] ### Define continuous list CONTI_FEATURES = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week'] ### Define categorical list CATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country'] ## Prepare the data features = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country'] PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data" df_train = pd.read_csv(PATH, skipinitialspace=True, names = COLUMNS, index_col=False) df_train[CONTI_FEATURES] =df_train[CONTI_FEATURES].astype('float64') df_train.describe()
usia | fnlwgt | pendidikan_num | keuntungan dalam bentuk uang | modal_rugi | jam_minggu | |
---|---|---|---|---|---|---|
menghitung | 32561.000000 | 3.256100e + 04 | 32561.000000 | 32561.000000 | 32561.000000 | 32561.000000 |
berarti | 38.581647 | 1.897784e + 05 | 10.080679 | 1077.648844 | 87.303830 | 40.437456 |
std | 13.640433 | 1.055500e + 05 | 2.572720 | 7385.292085 | 402.960219 | 12.347429 |
menit | 17.000000 | 1.228500e + 04 | 1.000000 | 0.000000 | 0.000000 | 1.000000 |
25% | 28.000000 | 1.178270e + 05 | 9.000000 | 0.000000 | 0.000000 | 40.000000 |
50% | 37.000000 | 1.783560e + 05 | 10.000000 | 0.000000 | 0.000000 | 40.000000 |
75% | 48.000000 | 2.370510e + 05 | 12.000000 | 0.000000 | 0.000000 | 45.000000 |
max | 90.000000 | 1.484705e + 06 | 16.000000 | 99999.000000 | 4356.000000 | 99.000000 |
Anda dapat memeriksa jumlah nilai unik fitur negara_asli. Terlihat hanya satu rumah tangga yang berasal dari Belanda-Belanda. Rumah tangga ini tidak akan memberi kami informasi apa pun, tetapi akan mengalami kesalahan selama pelatihan.
df_train.native_country.value_counts()
United-States 29170 Mexico 643 ? 583 Philippines 198 Germany 137 Canada 121 Puerto-Rico 114 El-Salvador 106 India 100 Cuba 95 England 90 Jamaica 81 South 80 China 75 Italy 73 Dominican-Republic 70 Vietnam 67 Guatemala 64 Japan 62 Poland 60 Columbia 59 Taiwan 51 Haiti 44 Iran 43 Portugal 37 Nicaragua 34 Peru 31 France 29 Greece 29 Ecuador 28 Ireland 24 Hong 20 Cambodia 19 Trinadad&Tobago 19 Thailand 18 Laos 18 Yugoslavia 16 Outlying-US(Guam-USVI-etc) 14 Honduras 13 Hungary 13 Scotland 12 Holand-Netherlands 1 Name: native_country, dtype: int64
Anda dapat mengecualikan baris tidak informatif ini dari kumpulan data
## Drop Netherland, because only one row df_train = df_train[df_train.native_country != "Holand-Netherlands"]
Selanjutnya, Anda menyimpan posisi fitur berkelanjutan dalam daftar. Anda akan membutuhkannya pada langkah berikutnya untuk membangun saluran pipa.
Kode di bawah ini akan mengulang semua nama kolom di CONTI_FEATURES dan mendapatkan lokasinya (yaitu nomornya) dan kemudian menambahkannya ke daftar yang disebut conti_features
## Get the column index of the categorical features conti_features = [] for i in CONTI_FEATURES: position = df_train.columns.get_loc(i) conti_features.append(position) print(conti_features)
[0, 2, 10, 4, 11, 12]
Kode di bawah melakukan pekerjaan yang sama seperti di atas tetapi untuk variabel kategori. Kode di bawah ini mengulangi apa yang telah Anda lakukan sebelumnya, kecuali dengan fitur kategorikal.
## Get the column index of the categorical features categorical_features = [] for i in CATE_FEATURES: position = df_train.columns.get_loc(i) categorical_features.append(position) print(categorical_features)
[1, 3, 5, 6, 7, 8, 9, 13]
Anda dapat melihat kumpulan datanya. Perhatikan bahwa, setiap fitur kategorikal adalah sebuah string. Anda tidak dapat memberi makan model dengan nilai string. Anda perlu mengubah kumpulan data menggunakan variabel dummy.
df_train.head(5)
Faktanya, Anda perlu membuat satu kolom untuk setiap grup di fitur tersebut. Pertama, Anda dapat menjalankan kode di bawah ini untuk menghitung jumlah total kolom yang dibutuhkan.
print(df_train[CATE_FEATURES].nunique(), 'There are',sum(df_train[CATE_FEATURES].nunique()), 'groups in the whole dataset')
workclass 9 education 16 marital 7 occupation 15 relationship 6 race 5 sex 2 native_country 41 dtype: int64 There are 101 groups in the whole dataset
Seluruh dataset berisi 101 grup seperti yang ditunjukkan di atas. Misalnya, fitur workclass memiliki sembilan grup. Anda dapat memvisualisasikan nama grup dengan kode berikut
unik() mengembalikan nilai unik dari fitur kategorikal.
for i in CATE_FEATURES: print(df_train[i].unique())
['State-gov' 'Self-emp-not-inc' 'Private' 'Federal-gov' 'Local-gov' '?' 'Self-emp-inc' 'Without-pay' 'Never-worked'] ['Bachelors' 'HS-grad' '11th' 'Masters' '9th' 'Some-college' 'Assoc-acdm' 'Assoc-voc' '7th-8th' 'Doctorate' 'Prof-school' '5th-6th' '10th' '1st-4th' 'Preschool' '12th'] ['Never-married' 'Married-civ-spouse' 'Divorced' 'Married-spouse-absent' 'Separated' 'Married-AF-spouse' 'Widowed'] ['Adm-clerical' 'Exec-managerial' 'Handlers-cleaners' 'Prof-specialty' 'Other-service' 'Sales' 'Craft-repair' 'Transport-moving' 'Farming-fishing' 'Machine-op-inspct' 'Tech-support' '?' 'Protective-serv' 'Armed-Forces' 'Priv-house-serv'] ['Not-in-family' 'Husband' 'Wife' 'Own-child' 'Unmarried' 'Other-relative'] ['White' 'Black' 'Asian-Pac-Islander' 'Amer-Indian-Eskimo' 'Other'] ['Male' 'Female'] ['United-States' 'Cuba' 'Jamaica' 'India' '?' 'Mexico' 'South' 'Puerto-Rico' 'Honduras' 'England' 'Canada' 'Germany' 'Iran' 'Philippines' 'Italy' 'Poland' 'Columbia' 'Cambodia' 'Thailand' 'Ecuador' 'Laos' 'Taiwan' 'Haiti' 'Portugal' 'Dominican-Republic' 'El-Salvador' 'France' 'Guatemala' 'China' 'Japan' 'Yugoslavia' 'Peru' 'Outlying-US(Guam-USVI-etc)' 'Scotland' 'Trinadad&Tobago' 'Greece' 'Nicaragua' 'Vietnam' 'Hong' 'Ireland' 'Hungary']
Oleh karena itu, dataset pelatihan akan berisi 101 + 7 kolom. Tujuh kolom terakhir adalah fitur berkelanjutan.
Scikit-learn dapat menangani konversi. Hal ini dilakukan dalam dua langkah:
- Pertama, Anda perlu mengonversi string menjadi ID. Misalnya, Pemerintah Negara Bagian akan memiliki ID 1, Self-emp-not-inc ID 2 dan seterusnya. Fungsi LabelEncoder melakukan ini untuk Anda
- Ubah urutan setiap ID ke kolom baru. Seperti disebutkan sebelumnya, kumpulan data memiliki 101 ID grup. Oleh karena itu akan ada 101 kolom yang menangkap semua grup fitur kategorikal. Scikit-learn memiliki fungsi bernama OneHotEncoder yang melakukan operasi ini
Langkah 2) Buat set pelatihan/pengujian
Sekarang dataset sudah siap, kita dapat membaginya 80/20.
80 persen untuk set pelatihan dan 20 persen untuk set tes.
Anda dapat menggunakan train_test_split. Argumen pertama adalah kerangka data adalah fitur dan argumen kedua adalah kerangka data label. Anda dapat menentukan ukuran set pengujian dengan test_size.
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(df_train[features], df_train.label, test_size = 0.2, random_state=0) X_train.head(5) print(X_train.shape, X_test.shape)
(26048, 14) (6512, 14)
Langkah 3) Bangun saluran pipa
Pipeline memudahkan pemberian data yang konsisten ke model.
Ide di baliknya adalah memasukkan data mentah ke dalam 'saluran pipa' untuk melakukan operasi.
Misalnya, dengan kumpulan data saat ini, Anda perlu menstandarkan variabel kontinu dan mengonversi data kategorikal. Perhatikan bahwa Anda dapat melakukan operasi apa pun di dalam alur. Misalnya, jika Anda memiliki 'NA' di kumpulan data, Anda dapat menggantinya dengan mean atau median. Anda juga dapat membuat variabel baru.
Anda punya pilihan; kode keras kedua proses atau buat saluran pipa. Pilihan pertama dapat menyebabkan kebocoran data dan menimbulkan inkonsistensi seiring berjalannya waktu. Pilihan yang lebih baik adalah menggunakan jalur pipa.
from sklearn.preprocessing import StandardScaler, OneHotEncoder, LabelEncoder from sklearn.compose import ColumnTransformer, make_column_transformer from sklearn.pipeline import make_pipeline from sklearn.linear_model import LogisticRegression
Pipeline akan melakukan dua operasi sebelum memasukkan pengklasifikasi logistik:
- Standarisasi variabel: `StandardScaler()“
- Konversikan fitur kategorikal: OneHotEncoder(sparse=False)
Anda dapat melakukan dua langkah tersebut menggunakan make_column_transformer. Fungsi ini tidak tersedia di versi scikit-learn saat ini (0.19). Versi saat ini tidak dapat menjalankan pembuat enkode label dan satu pembuat enkode panas dalam pipeline. Ini adalah salah satu alasan kami memutuskan untuk menggunakan versi pengembang.
make_column_transformer mudah digunakan. Anda perlu menentukan kolom mana yang akan menerapkan transformasi dan transformasi apa yang akan dioperasikan. Misalnya, untuk menstandarkan fitur berkelanjutan, Anda dapat melakukan:
- conti_features, StandardScaler() di dalam make_column_transformer.
- conti_features: daftar dengan variabel kontinu
- StandardScaler: membakukan variabel
Objek OneHotEncoder di dalam make_column_transformer secara otomatis mengkodekan label.
preprocess = make_column_transformer( (conti_features, StandardScaler()), ### Need to be numeric not string to specify columns name (categorical_features, OneHotEncoder(sparse=False)) )
Anda dapat menguji apakah alur kerja berfungsi dengan fit_transform. Kumpulan data harus memiliki bentuk berikut: 26048, 107
preprocess.fit_transform(X_train).shape
(26048, 107)
Trafo data siap digunakan. Anda dapat membuat alur dengan make_pipeline. Setelah data diubah, Anda dapat memasukkan regresi logistik.
model = make_pipeline( preprocess, LogisticRegression())
Melatih model dengan scikit-learn adalah hal yang sepele. Anda perlu menggunakan kecocokan objek yang didahului oleh pipeline, yaitu model. Anda dapat mencetak akurasi dengan objek skor dari perpustakaan scikit-learn
model.fit(X_train, y_train) print("logistic regression score: %f" % model.score(X_test, y_test))
logistic regression score: 0.850891
Terakhir, Anda dapat memprediksi kelas dengan prediktor_proba. Ini mengembalikan probabilitas untuk setiap kelas. Perhatikan bahwa jumlahnya menjadi satu.
model.predict_proba(X_test)
array([[0.83576663, 0.16423337], [0.94582765, 0.05417235], [0.64760587, 0.35239413], ..., [0.99639252, 0.00360748], [0.02072181, 0.97927819], [0.56781353, 0.43218647]])
Langkah 4) Menggunakan saluran pipa kami dalam pencarian grid
Menyesuaikan hyperparameter (variabel yang menentukan struktur jaringan seperti unit tersembunyi) bisa jadi membosankan dan melelahkan.
Salah satu cara untuk mengevaluasi model adalah dengan mengubah ukuran set pelatihan dan mengevaluasi kinerjanya.
Anda dapat mengulangi metode ini sepuluh kali untuk melihat metrik skor. Namun, ini terlalu banyak pekerjaan.
Sebaliknya, scikit-learn menyediakan fungsi untuk melakukan penyetelan parameter dan validasi silang.
Validasi silang
Validasi Silang berarti selama pelatihan, set pelatihan diselipkan n beberapa kali lipat dan kemudian mengevaluasi model n waktu. Misalnya, jika cv disetel ke 10, set pelatihan akan dilatih dan dievaluasi sepuluh kali. Pada setiap putaran, pengklasifikasi memilih sembilan lipatan secara acak untuk melatih model, dan lipatan ke-10 dimaksudkan untuk evaluasi.
Pencarian kotak
Setiap pengklasifikasi memiliki hyperparameter untuk disesuaikan. Anda dapat mencoba nilai yang berbeda, atau Anda dapat mengatur kisi parameter. Jika Anda mengunjungi situs web resmi scikit-learn, Anda dapat melihat pengklasifikasi logistik memiliki parameter berbeda untuk disesuaikan. Untuk mempercepat pelatihan, Anda memilih untuk menyetel parameter C. Ini mengontrol parameter regularisasi. Itu harusnya positif. Nilai yang kecil memberi bobot lebih pada pengatur.
Anda dapat menggunakan objek GridSearchCV. Anda perlu membuat kamus yang berisi hyperparameter untuk disesuaikan.
Anda mencantumkan hyperparameter diikuti dengan nilai yang ingin Anda coba. Misalnya, untuk menyetel parameter C, Anda menggunakan:
- 'logisticregression__C': [0.1, 1.0, 1.0]: Parameter diawali dengan nama, dalam huruf kecil, pengklasifikasi dan dua garis bawah.
Model akan mencoba empat nilai berbeda: 0.001, 0.01, 0.1, dan 1.
Anda melatih model menggunakan 10 lipatan: cv=10
from sklearn.model_selection import GridSearchCV # Construct the parameter grid param_grid = { 'logisticregression__C': [0.001, 0.01,0.1, 1.0], }
Anda dapat melatih model menggunakan GridSearchCV dengan parameter gri dan cv.
# Train the model grid_clf = GridSearchCV(model, param_grid, cv=10, iid=False) grid_clf.fit(X_train, y_train)
KELUARAN
GridSearchCV(cv=10, error_score='raise-deprecating', estimator=Pipeline(memory=None, steps=[('columntransformer', ColumnTransformer(n_jobs=1, remainder='drop', transformer_weights=None, transformers=[('standardscaler', StandardScaler(copy=True, with_mean=True, with_std=True), [0, 2, 10, 4, 11, 12]), ('onehotencoder', OneHotEncoder(categorical_features=None, categories=None,...ty='l2', random_state=None, solver='liblinear', tol=0.0001, verbose=0, warm_start=False))]), fit_params=None, iid=False, n_jobs=1, param_grid={'logisticregression__C': [0.001, 0.01, 0.1, 1.0]}, pre_dispatch='2*n_jobs', refit=True, return_train_score='warn', scoring=None, verbose=0)
Untuk mengakses parameter terbaik, Anda menggunakan best_params_
grid_clf.best_params_
KELUARAN
{'logisticregression__C': 1.0}
Setelah melatih model dengan empat nilai regularisasi yang berbeda, diperoleh parameter optimalnya
print("best logistic regression from grid search: %f" % grid_clf.best_estimator_.score(X_test, y_test))
regresi logistik terbaik dari pencarian grid: 0.850891
Untuk mengakses probabilitas yang diprediksi:
grid_clf.best_estimator_.predict_proba(X_test)
array([[0.83576677, 0.16423323], [0.9458291 , 0.0541709 ], [0.64760416, 0.35239584], ..., [0.99639224, 0.00360776], [0.02072033, 0.97927967], [0.56782222, 0.43217778]])
Model XGBoost dengan scikit-learn
Mari kita coba contoh Scikit-learn untuk melatih salah satu pengklasifikasi terbaik di pasar. XGBoost adalah peningkatan dari hutan acak. Latar belakang teoritis pengklasifikasi di luar cakupan ini Python tutorial scikit. Perlu diingat, XGBoost telah memenangkan banyak kompetisi kaggle. Dengan ukuran kumpulan data rata-rata, performanya bisa sama baiknya dengan algoritme pembelajaran mendalam atau bahkan lebih baik.
Pengklasifikasi ini sulit untuk dilatih karena memiliki banyak parameter yang harus disesuaikan. Anda tentu saja dapat menggunakan GridSearchCV untuk memilih parameter untuk Anda.
Sebagai gantinya, mari kita lihat cara menggunakan cara yang lebih baik untuk menemukan parameter optimal. GridSearchCV bisa membosankan dan sangat lama untuk dilatih jika Anda meneruskan banyak nilai. Ruang pencarian bertambah seiring dengan jumlah parameter. Solusi yang lebih baik adalah dengan menggunakan RandomizedSearchCV. Metode ini terdiri dari pemilihan nilai setiap hyperparameter setelah setiap iterasi secara acak. Misalnya, jika pengklasifikasi dilatih lebih dari 1000 iterasi, maka 1000 kombinasi akan dievaluasi. Ini bekerja kurang lebih seperti itu. GridSearchCV
Anda perlu mengimpor xgboost. Jika perpustakaan tidak diinstal, silakan gunakan pip3 install xgboost atau
use import sys !{sys.executable} -m pip install xgboost
In Jupyter lingkungan Hidup
Selanjutnya,
import xgboost from sklearn.model_selection import RandomizedSearchCV from sklearn.model_selection import StratifiedKFold
Langkah selanjutnya dalam Scikit ini Python tutorial termasuk menentukan parameter yang akan disetel. Anda dapat merujuk ke dokumentasi resmi untuk melihat semua parameter yang akan disetel. Demi Python Tutorial Sklearn, Anda hanya memilih dua hyperparameter dengan masing-masing dua nilai. XGBoost membutuhkan banyak waktu untuk berlatih, semakin banyak hyperparameter di grid, semakin lama waktu yang Anda perlukan untuk menunggu.
params = { 'xgbclassifier__gamma': [0.5, 1], 'xgbclassifier__max_depth': [3, 4] }
Anda membangun alur kerja baru dengan pengklasifikasi XGBoost. Anda memilih untuk menentukan 600 estimator. Perhatikan bahwa n_estimator adalah parameter yang dapat Anda sesuaikan. Nilai yang tinggi dapat menyebabkan overfitting. Anda dapat mencoba sendiri nilai yang berbeda, tetapi perlu diingat bahwa hal itu dapat memakan waktu berjam-jam. Anda menggunakan nilai default untuk parameter lainnya
model_xgb = make_pipeline( preprocess, xgboost.XGBClassifier( n_estimators=600, objective='binary:logistic', silent=True, nthread=1) )
Anda dapat meningkatkan validasi silang dengan validator silang Stratified K-Folds. Anda hanya membuat tiga lipatan di sini untuk mempercepat komputasi tetapi menurunkan kualitas. Tingkatkan nilai ini menjadi 5 atau 10 di rumah untuk meningkatkan hasilnya.
Anda memilih untuk melatih model dalam empat iterasi.
skf = StratifiedKFold(n_splits=3, shuffle = True, random_state = 1001) random_search = RandomizedSearchCV(model_xgb, param_distributions=params, n_iter=4, scoring='accuracy', n_jobs=4, cv=skf.split(X_train, y_train), verbose=3, random_state=1001)
Pencarian acak siap digunakan, Anda dapat melatih modelnya
#grid_xgb = GridSearchCV(model_xgb, params, cv=10, iid=False) random_search.fit(X_train, y_train)
Fitting 3 folds for each of 4 candidates, totalling 12 fits [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5 ............ [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5 ............ [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5 ............ [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5 ............ [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5, score=0.8759645283888057, total= 1.0min [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5 ............ [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5, score=0.8729701715996775, total= 1.0min [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=0.5, score=0.8706519235199263, total= 1.0min [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5 ............ [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1 .............. [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5, score=0.8735460094437406, total= 1.3min [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1 .............. [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1, score=0.8722791661868018, total= 57.7s [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1 .............. [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1, score=0.8753886905447426, total= 1.0min [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1 .............. [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5, score=0.8697304768486523, total= 1.3min [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1 .............. [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=0.5, score=0.8740066797189912, total= 1.4min [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1 .............. [CV] xgbclassifier__max_depth=3, xgbclassifier__gamma=1, score=0.8707671043538355, total= 1.0min [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1, score=0.8729701715996775, total= 1.2min [Parallel(n_jobs=4)]: Done 10 out of 12 | elapsed: 3.6min remaining: 43.5s [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1, score=0.8736611770125533, total= 1.2min [CV] xgbclassifier__max_depth=4, xgbclassifier__gamma=1, score=0.8692697535130154, total= 1.2min
[Parallel(n_jobs=4)]: Done 12 out of 12 | elapsed: 3.6min finished /Users/Thomas/anaconda3/envs/hello-tf/lib/python3.6/site-packages/sklearn/model_selection/_search.py:737: DeprecationWarning: The default of the `iid` parameter will change from True to False in version 0.22 and will be removed in 0.24. This will change numeric results when test-set sizes are unequal. DeprecationWarning)
RandomizedSearchCV(cv=<generator object _BaseKFold.split at 0x1101eb830>, error_score='raise-deprecating', estimator=Pipeline(memory=None, steps=[('columntransformer', ColumnTransformer(n_jobs=1, remainder='drop', transformer_weights=None, transformers=[('standardscaler', StandardScaler(copy=True, with_mean=True, with_std=True), [0, 2, 10, 4, 11, 12]), ('onehotencoder', OneHotEncoder(categorical_features=None, categories=None,... reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None, silent=True, subsample=1))]), fit_params=None, iid='warn', n_iter=4, n_jobs=4, param_distributions={'xgbclassifier__gamma': [0.5, 1], 'xgbclassifier__max_depth': [3, 4]}, pre_dispatch='2*n_jobs', random_state=1001, refit=True, return_train_score='warn', scoring='accuracy', verbose=3)
Seperti yang Anda lihat, XGBoost memiliki skor yang lebih baik dibandingkan regresi logistik sebelumnya.
print("Best parameter", random_search.best_params_) print("best logistic regression from grid search: %f" % random_search.best_estimator_.score(X_test, y_test))
Best parameter {'xgbclassifier__max_depth': 3, 'xgbclassifier__gamma': 0.5} best logistic regression from grid search: 0.873157
random_search.best_estimator_.predict(X_test)
array(['<=50K', '<=50K', '<=50K', ..., '<=50K', '>50K', '<=50K'], dtype=object)
Buat DNN dengan MLPClassifier di scikit-learn
Terakhir, Anda dapat melatih algoritme pembelajaran mendalam dengan scikit-learn. Caranya sama dengan classifier lainnya. Pengklasifikasi tersedia di MLPClassifier.
from sklearn.neural_network import MLPClassifier
Anda mendefinisikan algoritma pembelajaran mendalam berikut:
- pemecah Adam
- Fungsi aktivasi Relu
- Alfa = 0.0001
- ukuran batch 150
- Dua lapisan tersembunyi dengan masing-masing 100 dan 50 neuron
model_dnn = make_pipeline( preprocess, MLPClassifier(solver='adam', alpha=0.0001, activation='relu', batch_size=150, hidden_layer_sizes=(200, 100), random_state=1))
Anda dapat mengubah jumlah lapisan untuk menyempurnakan model
model_dnn.fit(X_train, y_train) print("DNN regression score: %f" % model_dnn.score(X_test, y_test))
Skor regresi DNN: 0.821253
LIME: Percayai Model Anda
Sekarang setelah Anda memiliki model yang bagus, Anda memerlukan alat untuk memercayainya. Pembelajaran mesin Algoritma, khususnya random forest dan neural network, dikenal sebagai algoritma black-box. Dengan kata lain, ia berfungsi tetapi tidak seorang pun tahu mengapa.
Tiga peneliti telah menemukan alat hebat untuk melihat bagaimana komputer membuat prediksi. Makalahnya berjudul Mengapa Saya Harus Mempercayai Anda?
Mereka mengembangkan algoritma bernama Penjelasan Model-Agnostik Lokal yang Dapat Ditafsirkan (LIME).
Ambil contoh:
terkadang Anda tidak tahu apakah Anda dapat mempercayai prediksi pembelajaran mesin:
Seorang dokter, misalnya, tidak dapat mempercayai suatu diagnosis hanya karena komputer menyatakan demikian. Anda juga perlu mengetahui apakah Anda dapat mempercayai model tersebut sebelum memasukkannya ke dalam produksi.
Bayangkan kita dapat memahami mengapa pengklasifikasi mana pun membuat prediksi bahkan model yang sangat rumit seperti jaringan saraf, hutan acak, atau svms dengan kernel apa pun
akan lebih mudah untuk memercayai suatu prediksi jika kita dapat memahami alasan di baliknya. Dari contoh dokter, jika model memberi tahu dia gejala mana yang penting, Anda akan memercayainya, dan akan lebih mudah untuk mengetahui apakah Anda sebaiknya tidak memercayai model tersebut.
Lime dapat memberi tahu Anda fitur apa saja yang memengaruhi keputusan pengklasifikasi
Persiapan data
Itu adalah beberapa hal yang perlu Anda ubah untuk menjalankan LIME ular sanca. Pertama-tama, Anda perlu memasang kapur di terminal. Anda dapat menggunakan pip install lime
Lime menggunakan objek LimeTabularExplainer untuk memperkirakan model secara lokal. Objek ini memerlukan:
- kumpulan data dalam format numpy
- Nama fitur: nama_fitur
- Nama kelas: nama_kelas
- Indeks kolom fitur kategorikal: fitur_kategoris
- Nama grup untuk setiap fitur kategorikal: nama_kategori
Buat set kereta numpy
Anda dapat menyalin dan mengonversi df_train dari pandas ke mati rasa sangat mudah
df_train.head(5) # Create numpy data df_lime = df_train df_lime.head(3)
Dapatkan nama kelasnya Label dapat diakses dengan objek unik(). Anda akan melihat:
- '<= 50K'
- '> 50K'
# Get the class name class_names = df_lime.label.unique() class_names
array(['<=50K', '>50K'], dtype=object)
indeks kolom fitur kategorikal
Anda dapat menggunakan metode yang Anda pelajari sebelumnya untuk mendapatkan nama grup. Anda menyandikan label dengan LabelEncoder. Anda mengulangi operasi pada semua fitur kategorikal.
## import sklearn.preprocessing as preprocessing categorical_names = {} for feature in CATE_FEATURES: le = preprocessing.LabelEncoder() le.fit(df_lime[feature]) df_lime[feature] = le.transform(df_lime[feature]) categorical_names[feature] = le.classes_ print(categorical_names)
{'workclass': array(['?', 'Federal-gov', 'Local-gov', 'Never-worked', 'Private', 'Self-emp-inc', 'Self-emp-not-inc', 'State-gov', 'Without-pay'], dtype=object), 'education': array(['10th', '11th', '12th', '1st-4th', '5th-6th', '7th-8th', '9th', 'Assoc-acdm', 'Assoc-voc', 'Bachelors', 'Doctorate', 'HS-grad', 'Masters', 'Preschool', 'Prof-school', 'Some-college'], dtype=object), 'marital': array(['Divorced', 'Married-AF-spouse', 'Married-civ-spouse', 'Married-spouse-absent', 'Never-married', 'Separated', 'Widowed'], dtype=object), 'occupation': array(['?', 'Adm-clerical', 'Armed-Forces', 'Craft-repair', 'Exec-managerial', 'Farming-fishing', 'Handlers-cleaners', 'Machine-op-inspct', 'Other-service', 'Priv-house-serv', 'Prof-specialty', 'Protective-serv', 'Sales', 'Tech-support', 'Transport-moving'], dtype=object), 'relationship': array(['Husband', 'Not-in-family', 'Other-relative', 'Own-child', 'Unmarried', 'Wife'], dtype=object), 'race': array(['Amer-Indian-Eskimo', 'Asian-Pac-Islander', 'Black', 'Other', 'White'], dtype=object), 'sex': array(['Female', 'Male'], dtype=object), 'native_country': array(['?', 'Cambodia', 'Canada', 'China', 'Columbia', 'Cuba', 'Dominican-Republic', 'Ecuador', 'El-Salvador', 'England', 'France', 'Germany', 'Greece', 'Guatemala', 'Haiti', 'Honduras', 'Hong', 'Hungary', 'India', 'Iran', 'Ireland', 'Italy', 'Jamaica', 'Japan', 'Laos', 'Mexico', 'Nicaragua', 'Outlying-US(Guam-USVI-etc)', 'Peru', 'Philippines', 'Poland', 'Portugal', 'Puerto-Rico', 'Scotland', 'South', 'Taiwan', 'Thailand', 'Trinadad&Tobago', 'United-States', 'Vietnam', 'Yugoslavia'], dtype=object)} df_lime.dtypes
age float64 workclass int64 fnlwgt float64 education int64 education_num float64 marital int64 occupation int64 relationship int64 race int64 sex int64 capital_gain float64 capital_loss float64 hours_week float64 native_country int64 label object dtype: object
Sekarang setelah kumpulan data siap, Anda dapat membuat kumpulan data yang berbeda seperti yang ditunjukkan pada contoh pembelajaran Scikit di bawah ini. Anda sebenarnya mengubah data di luar pipeline untuk menghindari kesalahan dengan LIME. Set pelatihan di LimeTabularExplainer harus berupa array numpy tanpa string. Dengan metode di atas, Anda sudah memiliki dataset pelatihan yang dikonversi.
from sklearn.model_selection import train_test_split X_train_lime, X_test_lime, y_train_lime, y_test_lime = train_test_split(df_lime[features], df_lime.label, test_size = 0.2, random_state=0) X_train_lime.head(5)
Anda dapat membuat pipeline dengan parameter optimal dari XGBoost
model_xgb = make_pipeline( preprocess, xgboost.XGBClassifier(max_depth = 3, gamma = 0.5, n_estimators=600, objective='binary:logistic', silent=True, nthread=1)) model_xgb.fit(X_train_lime, y_train_lime)
/Users/Thomas/anaconda3/envs/hello-tf/lib/python3.6/site-packages/sklearn/preprocessing/_encoders.py:351: FutureWarning: The handling of integer data will change in version 0.22. Currently, the categories are determined based on the range [0, max(values)], while in the future they will be determined based on the unique values. If you want the future behavior and silence this warning, you can specify "categories='auto'."In case you used a LabelEncoder before this OneHotEncoder to convert the categories to integers, then you can now use the OneHotEncoder directly. warnings.warn(msg, FutureWarning)
Pipeline(memory=None, steps=[('columntransformer', ColumnTransformer(n_jobs=1, remainder='drop', transformer_weights=None, transformers=[('standardscaler', StandardScaler(copy=True, with_mean=True, with_std=True), [0, 2, 10, 4, 11, 12]), ('onehotencoder', OneHotEncoder(categorical_features=None, categories=None,... reg_alpha=0, reg_lambda=1, scale_pos_weight=1, seed=None, silent=True, subsample=1))])
Anda mendapat peringatan. Peringatan tersebut menjelaskan bahwa Anda tidak perlu membuat encoder label sebelum alur kerja. Jika Anda tidak ingin menggunakan LIME, Anda dapat menggunakan metode dari bagian pertama tutorial Machine Learning dengan Scikit-learn. Jika tidak, Anda dapat tetap menggunakan metode ini, pertama-tama buat set data yang dikodekan, atur untuk mendapatkan encoder hot one dalam alur kerja.
print("best logistic regression from grid search: %f" % model_xgb.score(X_test_lime, y_test_lime))
best logistic regression from grid search: 0.873157
model_xgb.predict_proba(X_test_lime)
array([[7.9646105e-01, 2.0353897e-01], [9.5173013e-01, 4.8269872e-02], [7.9344827e-01, 2.0655173e-01], ..., [9.9031430e-01, 9.6856682e-03], [6.4581633e-04, 9.9935418e-01], [9.7104281e-01, 2.8957171e-02]], dtype=float32)
Sebelum menggunakan LIME, mari buat array numpy dengan fitur klasifikasi yang salah. Anda dapat menggunakan daftar itu nanti untuk mendapatkan gambaran tentang apa yang menyesatkan pengklasifikasi.
temp = pd.concat([X_test_lime, y_test_lime], axis= 1) temp['predicted'] = model_xgb.predict(X_test_lime) temp['wrong']= temp['label'] != temp['predicted'] temp = temp.query('wrong==True').drop('wrong', axis=1) temp= temp.sort_values(by=['label']) temp.shape
(826, 16)
Anda membuat fungsi lambda untuk mengambil prediksi dari model dengan data baru. Anda akan membutuhkannya segera.
predict_fn = lambda x: model_xgb.predict_proba(x).astype(float) X_test_lime.dtypes
age float64 workclass int64 fnlwgt float64 education int64 education_num float64 marital int64 occupation int64 relationship int64 race int64 sex int64 capital_gain float64 capital_loss float64 hours_week float64 native_country int64 dtype: object
predict_fn(X_test_lime)
array([[7.96461046e-01, 2.03538969e-01], [9.51730132e-01, 4.82698716e-02], [7.93448269e-01, 2.06551731e-01], ..., [9.90314305e-01, 9.68566816e-03], [6.45816326e-04, 9.99354184e-01], [9.71042812e-01, 2.89571714e-02]])
Anda mengonversi kerangka data pandas menjadi array numpy
X_train_lime = X_train_lime.values X_test_lime = X_test_lime.values X_test_lime
array([[4.00000e+01, 5.00000e+00, 1.93524e+05, ..., 0.00000e+00, 4.00000e+01, 3.80000e+01], [2.70000e+01, 4.00000e+00, 2.16481e+05, ..., 0.00000e+00, 4.00000e+01, 3.80000e+01], [2.50000e+01, 4.00000e+00, 2.56263e+05, ..., 0.00000e+00, 4.00000e+01, 3.80000e+01], ..., [2.80000e+01, 6.00000e+00, 2.11032e+05, ..., 0.00000e+00, 4.00000e+01, 2.50000e+01], [4.40000e+01, 4.00000e+00, 1.67005e+05, ..., 0.00000e+00, 6.00000e+01, 3.80000e+01], [5.30000e+01, 4.00000e+00, 2.57940e+05, ..., 0.00000e+00, 4.00000e+01, 3.80000e+01]])
model_xgb.predict_proba(X_test_lime)
array([[7.9646105e-01, 2.0353897e-01], [9.5173013e-01, 4.8269872e-02], [7.9344827e-01, 2.0655173e-01], ..., [9.9031430e-01, 9.6856682e-03], [6.4581633e-04, 9.9935418e-01], [9.7104281e-01, 2.8957171e-02]], dtype=float32)
print(features, class_names, categorical_features, categorical_names)
['age', 'workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country'] ['<=50K' '>50K'] [1, 3, 5, 6, 7, 8, 9, 13] {'workclass': array(['?', 'Federal-gov', 'Local-gov', 'Never-worked', 'Private', 'Self-emp-inc', 'Self-emp-not-inc', 'State-gov', 'Without-pay'], dtype=object), 'education': array(['10th', '11th', '12th', '1st-4th', '5th-6th', '7th-8th', '9th', 'Assoc-acdm', 'Assoc-voc', 'Bachelors', 'Doctorate', 'HS-grad', 'Masters', 'Preschool', 'Prof-school', 'Some-college'], dtype=object), 'marital': array(['Divorced', 'Married-AF-spouse', 'Married-civ-spouse', 'Married-spouse-absent', 'Never-married', 'Separated', 'Widowed'], dtype=object), 'occupation': array(['?', 'Adm-clerical', 'Armed-Forces', 'Craft-repair', 'Exec-managerial', 'Farming-fishing', 'Handlers-cleaners', 'Machine-op-inspct', 'Other-service', 'Priv-house-serv', 'Prof-specialty', 'Protective-serv', 'Sales', 'Tech-support', 'Transport-moving'], dtype=object), 'relationship': array(['Husband', 'Not-in-family', 'Other-relative', 'Own-child', 'Unmarried', 'Wife'], dtype=object), 'race': array(['Amer-Indian-Eskimo', 'Asian-Pac-Islander', 'Black', 'Other', 'White'], dtype=object), 'sex': array(['Female', 'Male'], dtype=object), 'native_country': array(['?', 'Cambodia', 'Canada', 'China', 'Columbia', 'Cuba', 'Dominican-Republic', 'Ecuador', 'El-Salvador', 'England', 'France', 'Germany', 'Greece', 'Guatemala', 'Haiti', 'Honduras', 'Hong', 'Hungary', 'India', 'Iran', 'Ireland', 'Italy', 'Jamaica', 'Japan', 'Laos', 'Mexico', 'Nicaragua', 'Outlying-US(Guam-USVI-etc)', 'Peru', 'Philippines', 'Poland', 'Portugal', 'Puerto-Rico', 'Scotland', 'South', 'Taiwan', 'Thailand', 'Trinadad&Tobago', 'United-States', 'Vietnam', 'Yugoslavia'], dtype=object)}
import lime import lime.lime_tabular ### Train should be label encoded not one hot encoded explainer = lime.lime_tabular.LimeTabularExplainer(X_train_lime , feature_names = features, class_names=class_names, categorical_features=categorical_features, categorical_names=categorical_names, kernel_width=3)
Mari pilih rumah tangga secara acak dari set pengujian dan lihat prediksi model dan bagaimana komputer menentukan pilihannya.
import numpy as np np.random.seed(1) i = 100 print(y_test_lime.iloc[i]) >50K
X_test_lime[i]
array([4.20000e+01, 4.00000e+00, 1.76286e+05, 7.00000e+00, 1.20000e+01, 2.00000e+00, 4.00000e+00, 0.00000e+00, 4.00000e+00, 1.00000e+00, 0.00000e+00, 0.00000e+00, 4.00000e+01, 3.80000e+01])
Anda dapat menggunakan penjelasan denganexplain_instance untuk memeriksa penjelasan di balik model
exp = explainer.explain_instance(X_test_lime[i], predict_fn, num_features=6) exp.show_in_notebook(show_all=False)
Kita dapat melihat bahwa pengklasifikasi memperkirakan rumah tangga dengan benar. Penghasilannya memang di atas 50k.
Hal pertama yang dapat kami katakan adalah pengklasifikasi tidak begitu yakin dengan probabilitas yang diprediksi. Mesin tersebut memperkirakan rumah tangga tersebut memiliki pendapatan di atas 50k dengan probabilitas 64%. 64% ini terdiri dari Capital gain dan perkawinan. Warna biru memberikan kontribusi negatif terhadap kelas positif dan garis oranye memberikan kontribusi positif.
Klasifikasi ini membingungkan karena keuntungan modal rumah tangga ini nol, sedangkan keuntungan modal biasanya merupakan prediktor kekayaan yang baik. Selain itu, rumah tangga ini bekerja kurang dari 40 jam per minggu. Usia, pekerjaan, dan jenis kelamin berkontribusi positif terhadap klasifikasi ini.
Jika status perkawinannya lajang, pengklasifikasi memperkirakan pendapatan di bawah 50rb (0.64-0.18 = 0.46)
Kita dapat mencoba dengan rumah tangga lain yang klasifikasinya salah
temp.head(3) temp.iloc[1,:-2]
age 58 workclass 4 fnlwgt 68624 education 11 education_num 9 marital 2 occupation 4 relationship 0 race 4 sex 1 capital_gain 0 capital_loss 0 hours_week 45 native_country 38 Name: 20931, dtype: object
i = 1 print('This observation is', temp.iloc[i,-2:])
This observation is label <=50K predicted >50K Name: 20931, dtype: object
exp = explainer.explain_instance(temp.iloc[1,:-2], predict_fn, num_features=6) exp.show_in_notebook(show_all=False)
Pengklasifikasi memperkirakan pendapatan di bawah 50k padahal itu tidak benar. Rumah tangga ini sepertinya aneh. Itu tidak memiliki keuntungan modal, atau kerugian modal. Ia sudah bercerai dan berusia 60 tahun, dan merupakan masyarakat terpelajar, yaitu pendidikan_num > 12. Menurut pola keseluruhan, rumah tangga ini, seperti dijelaskan oleh pengklasifikasi, seharusnya memperoleh pendapatan di bawah 50k.
Anda mencoba bermain-main dengan LIME. Anda akan melihat kesalahan besar dari pengklasifikasi.
Anda dapat memeriksa GitHub pemilik perpustakaan. Mereka menyediakan dokumentasi tambahan untuk klasifikasi gambar dan teks.
Ringkasan
Di bawah ini adalah daftar beberapa perintah berguna dengan versi scikit learn >=0.20
membuat kumpulan data kereta/pengujian | peserta pelatihan berpisah |
Bangun saluran pipa | |
pilih kolom dan terapkan transformasi | makecolumntransformator |
jenis transformasi | |
membakukan | Penskala Standar |
min maks | MinMaxScaler |
Normalisasi | Normalisasi |
Hitung nilai yang hilang | Penipu |
Konversi kategorikal | OneHotEncoder |
Cocokkan dan ubah data | fit_transform |
Buatlah saluran pipa | make_pipeline |
Model dasar | |
regresi logistik | Regresi logistik |
XGBoost | Pengklasifikasi XGB |
Jaringan saraf | Pengklasifikasi MLP |
Pencarian kotak | GridSearchCV |
Pencarian acak | PencarianAcakCV |