Vodič za Scikit-Learn: Kako instalirati i Scikit-Learn primjeri
Što je Scikit-learn?
Scikit-nauči je open source Python knjižnica za strojno učenje. Podržava najsuvremenije algoritme kao što su KNN, XGBoost, slučajna šuma i SVM. Izgrađen je na temelju NumPya. Scikit-learn naširoko se koristi u konkurenciji Kagglea, kao iu istaknutim tehnološkim tvrtkama. Pomaže u pretprocesiranju, smanjenju dimenzionalnosti (odabir parametra), klasifikaciji, regresiji, klasteriranju i odabiru modela.
Scikit-learn ima najbolju dokumentaciju od svih biblioteka otvorenog koda. Omogućuje vam interaktivni grafikon na https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html.
Scikit-learn nije jako težak za korištenje i daje izvrsne rezultate. Međutim, scikit learn ne podržava paralelna izračunavanja. S njim je moguće pokrenuti algoritam dubokog učenja, ali to nije optimalno rješenje, pogotovo ako znate koristiti TensorFlow.
Kako preuzeti i instalirati Scikit-learn
Sada u ovome Python Scikit-learn vodič, naučit ćemo kako preuzeti i instalirati Scikit-learn:
Opcija 1: AWS
scikit-learn se može koristiti preko AWS-a. Molim uputiti Docker slika koja ima unaprijed instaliran scikit-learn.
Za korištenje verzije za razvojne programere koristite naredbu in Jupyter
import sys !{sys.executable} -m pip install git+git://github.com/scikit-learn/scikit-learn.git
Opcija 2: Mac ili Windows pomoću Anaconde
Da biste saznali više o instalaciji Anaconde, pogledajte https://www.guru99.com/download-install-tensorflow.html
Nedavno su programeri scikita izdali razvojnu verziju koja se bavi uobičajenim problemom s kojim se suočava trenutna verzija. Utvrdili smo da je praktičnije koristiti verziju za razvojne programere umjesto trenutne verzije.
Kako instalirati scikit-learn s Conda okruženjem
Ako ste instalirali scikit-learn s okruženjem conda, slijedite korak za ažuriranje na verziju 0.20
Korak 1) Aktivirajte tensorflow okruženje
source activate hello-tf
Korak 2) Uklonite scikit lean pomoću naredbe conda
conda remove scikit-learn
Korak 3) Instalirajte razvojnu verziju.
Instalirajte scikit learn verziju za razvojne programere zajedno s potrebnim bibliotekama.
conda install -c anaconda git pip install Cython pip install h5py pip install git+git://github.com/scikit-learn/scikit-learn.git
NAPOMENA: Windows korisnik će morati instalirati Microsoft Visual C++ 14. Možete ga dobiti od ovdje
Scikit-Learn primjer sa strojnim učenjem
Ovaj vodič za Scikit podijeljen je u dva dijela:
- Strojno učenje sa scikit-learnom
- Kako vjerovati svom modelu uz LIME
Prvi dio detaljno opisuje kako izgraditi cjevovod, kreirati model i podesiti hiperparametre, dok drugi dio pruža najsuvremenije informacije o odabiru modela.
Korak 1) Uvezite podatke
Tijekom ovog vodiča za učenje Scikita, koristit ćete skup podataka za odrasle.
Za pozadinu ovog skupa podataka pogledajte Ako ste zainteresirani saznati više o deskriptivnoj statistici, koristite alate Dive i Overview.
Uputiti Ovaj vodič saznajte više o Dive i Pregledu
Skup podataka uvozite s Pandas. Imajte na umu da morate pretvoriti vrstu kontinuiranih varijabli u float format.
Ovaj skup podataka uključuje osam kategoričkih varijabli:
Kategoričke varijable navedene su u CATE_FEATURES
- radna klasa
- obrazovanje
- bračni
- okupacija
- odnos
- utrka
- seks
- rodna_zemlja
osim toga, šest kontinuiranih varijabli:
Kontinuirane varijable navedene su u CONTI_FEATURES
- starost
- fnlwgt
- obrazovanje_br
- kapitalni dobitak
- gubitak_kapitala
- sati_tjedan
Imajte na umu da popis ispunjavamo ručno kako biste imali bolju predodžbu o tome koje stupce koristimo. Brži način za izradu popisa kategoričkih ili kontinuiranih je upotreba:
## 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)
Evo koda za uvoz podataka:
# 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()
starost | fnlwgt | obrazovanje_br | kapitalni dobitak | gubitak_kapitala | sati_tjedan | |
---|---|---|---|---|---|---|
računati | 32561.000000 | 3.256100e + 04 | 32561.000000 | 32561.000000 | 32561.000000 | 32561.000000 |
značiti | 38.581647 | 1.897784e + 05 | 10.080679 | 1077.648844 | 87.303830 | 40.437456 |
sati | 13.640433 | 1.055500e + 05 | 2.572720 | 7385.292085 | 402.960219 | 12.347429 |
minuta | 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 |
Možete provjeriti broj jedinstvenih vrijednosti značajki native_country. Možete vidjeti da samo jedno domaćinstvo dolazi iz Nizozemske-Holandije. Ovo kućanstvo nam neće donijeti nikakve informacije, ali hoće kroz grešku tijekom treninga.
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
Ovaj neinformativni red možete isključiti iz skupa podataka
## Drop Netherland, because only one row df_train = df_train[df_train.native_country != "Holand-Netherlands"]
Zatim pohranjujete položaj kontinuiranih značajki na popisu. Trebat će vam u sljedećem koraku za izgradnju cjevovoda.
Kod u nastavku će proći kroz sve nazive stupaca u CONTI_FEATURES i dobiti njegovu lokaciju (tj. broj), a zatim ga dodati na popis pod nazivom 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]
Kod u nastavku radi isti posao kao i gore, ali za kategoričku varijablu. Kod u nastavku ponavlja ono što ste prethodno radili, osim s kategoričkim značajkama.
## 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]
Možete pogledati skup podataka. Imajte na umu da je svaka kategorička značajka niz. Ne možete hraniti model s vrijednošću niza. Trebate transformirati skup podataka pomoću lažne varijable.
df_train.head(5)
Zapravo, morate stvoriti jedan stupac za svaku grupu u značajci. Prvo, možete pokrenuti kod u nastavku da biste izračunali ukupnu količinu potrebnih stupaca.
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
Cijeli skup podataka sadrži 101 grupu kao što je prikazano gore. Na primjer, značajke radne klase imaju devet grupa. Nazive grupa možete vizualizirati pomoću sljedećih kodova
unique() vraća jedinstvene vrijednosti kategoričkih značajki.
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']
Stoga će skup podataka za obuku sadržavati 101 + 7 stupaca. Zadnjih sedam stupaca su kontinuirane značajke.
Scikit-learn može se pobrinuti za konverziju. Radi se u dva koraka:
- Prvo morate pretvoriti niz u ID. Na primjer, State-gov će imati ID 1, Self-emp-not-inc ID 2 i tako dalje. Funkcija LabelEncoder to radi umjesto vas
- Transponirajte svaki ID u novi stupac. Kao što je prije spomenuto, skup podataka ima 101 ID grupe. Stoga će postojati 101 stupac koji obuhvaća sve grupe kategoričkih obilježja. Scikit-learn ima funkciju OneHotEncoder koja izvodi ovu operaciju
Korak 2) Kreirajte set za treniranje/testiranje
Sada kada je skup podataka spreman, možemo ga podijeliti 80/20.
80 posto za set za obuku i 20 posto za set za testiranje.
Možete koristiti train_test_split. Prvi argument je okvir podataka značajke, a drugi argument je okvir podataka oznake. Možete odrediti veličinu skupa testova s 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)
Korak 3) Izgradite cjevovod
Cjevovod olakšava punjenje modela dosljednim podacima.
Ideja koja stoji iza je staviti neobrađene podatke u 'cjevovod' za izvođenje operacija.
Na primjer, s trenutnim skupom podataka morate standardizirati kontinuirane varijable i pretvoriti kategoričke podatke. Imajte na umu da možete izvesti bilo koju operaciju unutar cjevovoda. Na primjer, ako imate 'NA' u skupu podataka, možete ih zamijeniti srednjom ili medijanom. Također možete kreirati nove varijable.
Imate izbor; tvrdo kodirajte dva procesa ili stvorite cjevovod. Prvi izbor može dovesti do curenja podataka i stvoriti nedosljednosti tijekom vremena. Bolja opcija je korištenje cjevovoda.
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
Cjevovod će obaviti dvije operacije prije ubacivanja u logistički klasifikator:
- Standardizirajte varijablu: `StandardScaler()“
- Pretvorite kategoričke značajke: OneHotEncoder(sparse=False)
Možete izvršiti dva koraka koristeći make_column_transformer. Ova funkcija nije dostupna u trenutnoj verziji scikit-learn (0.19). S trenutnom verzijom nije moguće izvesti koder naljepnica i jedan vrući koder u cjevovodu. To je jedan od razloga zašto smo odlučili koristiti verziju za razvojne programere.
make_column_transformer je jednostavan za korištenje. Morate definirati koje stupce primijeniti transformaciju i kojom transformacijom raditi. Na primjer, da biste standardizirali kontinuiranu značajku, možete učiniti sljedeće:
- conti_features, StandardScaler() unutar make_column_transformera.
- conti_features: popis s kontinuiranom varijablom
- StandardScaler: standardizirajte varijablu
Objekt OneHotEncoder unutar make_column_transformer automatski kodira oznaku.
preprocess = make_column_transformer( (conti_features, StandardScaler()), ### Need to be numeric not string to specify columns name (categorical_features, OneHotEncoder(sparse=False)) )
Možete testirati radi li cjevovod pomoću fit_transform. Skup podataka treba imati sljedeći oblik: 26048, 107
preprocess.fit_transform(X_train).shape
(26048, 107)
Transformator podataka je spreman za korištenje. Cjevovod možete stvoriti pomoću make_pipeline. Nakon što se podaci transformiraju, možete unijeti logističku regresiju.
model = make_pipeline( preprocess, LogisticRegression())
Obuka modela sa scikit-learn je trivijalna. Morate koristiti fit objekta kojemu prethodi cjevovod, tj. model. Možete ispisati točnost s rezultatskim objektom iz knjižnice scikit-learn
model.fit(X_train, y_train) print("logistic regression score: %f" % model.score(X_test, y_test))
logistic regression score: 0.850891
Konačno, možete predvidjeti klase pomoću predict_proba. Vraća vjerojatnost za svaku klasu. Imajte na umu da je zbroj jedan.
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]])
Korak 4) Korištenje našeg cjevovoda u pretraživanju mreže
Podešavanje hiperparametara (varijabli koje određuju mrežnu strukturu poput skrivenih jedinica) može biti zamorno i iscrpljujuće.
Jedan od načina za procjenu modela može biti promjena veličine skupa za vježbanje i procjena izvedbe.
Ovu metodu možete ponoviti deset puta da biste vidjeli metriku rezultata. Međutim, to je previše posla.
Umjesto toga, scikit-learn pruža funkciju za provođenje podešavanja parametara i unakrsne provjere.
Križna validacija
Unakrsna provjera znači da se tijekom obuke set za obuku preklopi n broj puta, a zatim n puta procjenjuje model. Na primjer, ako je cv postavljen na 10, skup za obuku se trenira i procjenjuje deset puta. U svakom krugu, klasifikator nasumično odabire devet savijanja za obuku modela, a 10. savijanje je namijenjeno evaluaciji.
Pretraživanje mreže
Svaki klasifikator ima hiperparametre za podešavanje. Možete isprobati različite vrijednosti ili možete postaviti rešetku parametara. Ako odete na službenu web stranicu scikit-learn, možete vidjeti da logistički klasifikator ima različite parametre za podešavanje. Da bi trening bio brži, odabirete podešavanje C parametra. Kontrolira parametar regularizacije. Trebalo bi biti pozitivno. Mala vrijednost daje veću težinu regulatoru.
Možete koristiti objekt GridSearchCV. Morate stvoriti rječnik koji sadrži hiperparametre za podešavanje.
Navodite hiperparametre nakon kojih slijede vrijednosti koje želite isprobati. Na primjer, za podešavanje C parametra koristite:
- 'logisticregression__C': [0.1, 1.0, 1.0]: Parametru prethodi naziv klasifikatora, malim slovima, i dvije podvlake.
Model će isprobati četiri različite vrijednosti: 0.001, 0.01, 0.1 i 1.
Model trenirate koristeći 10 presavijanja: cv=10
from sklearn.model_selection import GridSearchCV # Construct the parameter grid param_grid = { 'logisticregression__C': [0.001, 0.01,0.1, 1.0], }
Možete trenirati model koristeći GridSearchCV s parametrima gri i cv.
# Train the model grid_clf = GridSearchCV(model, param_grid, cv=10, iid=False) grid_clf.fit(X_train, y_train)
PROIZVODNJA
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)
Za pristup najboljim parametrima koristite best_params_
grid_clf.best_params_
PROIZVODNJA
{'logisticregression__C': 1.0}
Nakon treniranja modela s četiri različite vrijednosti regulacije, optimalni parametar je
print("best logistic regression from grid search: %f" % grid_clf.best_estimator_.score(X_test, y_test))
najbolja logistička regresija iz pretraživanja mreže: 0.850891
Za pristup predviđenim vjerojatnostima:
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]])
XGBoost model sa scikit-learn
Isprobajmo Scikit-learn primjere za obuku jednog od najboljih klasifikatora na tržištu. XGBoost je poboljšanje u odnosu na slučajnu šumu. Teorijska pozadina klasifikatora je izvan dosega ovoga Python Scikit tutorial. Imajte na umu da je XGBoost osvojio mnoga natjecanja u kaggleu. Uz prosječnu veličinu skupa podataka, može raditi jednako dobro kao algoritam dubokog učenja ili čak i bolje.
Klasifikator je izazovan za treniranje jer ima veliki broj parametara za podešavanje. Možete, naravno, koristiti GridSearchCV za odabir parametra za vas.
Umjesto toga, pogledajmo kako na bolji način pronaći optimalne parametre. GridSearchCV može biti zamoran i vrlo dug za treniranje ako proslijedite mnogo vrijednosti. Prostor za pretraživanje raste zajedno s brojem parametara. Poželjno rješenje je korištenje RandomizedSearchCV. Ova se metoda sastoji od odabira vrijednosti svakog hiperparametra nasumično nakon svake iteracije. Na primjer, ako je klasifikator uvježban tijekom 1000 ponavljanja, tada se procjenjuje 1000 kombinacija. Radi manje-više slično. GridSearchCV
Morate uvesti xgboost. Ako biblioteka nije instalirana, koristite pip3 install xgboost ili
use import sys !{sys.executable} -m pip install xgboost
In Jupyter okolina
Dalje,
import xgboost from sklearn.model_selection import RandomizedSearchCV from sklearn.model_selection import StratifiedKFold
Sljedeći korak u ovom Scikitu Python tutorijal uključuje određivanje parametara za podešavanje. Možete pogledati službenu dokumentaciju kako biste vidjeli sve parametre za podešavanje. Za dobrobit Python Sklearn vodič, birate samo dva hiperparametra sa po dvije vrijednosti. XGBoost-u je potrebno puno vremena za treniranje, što je više hiperparametara u mreži, duže ćete morati čekati.
params = { 'xgbclassifier__gamma': [0.5, 1], 'xgbclassifier__max_depth': [3, 4] }
Konstruirate novi cjevovod pomoću XGBoost klasifikatora. Odabrali ste definirati 600 procjenitelja. Imajte na umu da je n_estimators parametar koji možete podešavati. Visoka vrijednost može dovesti do pretjeranog opremanja. Možete sami isprobati različite vrijednosti, ali imajte na umu da to može potrajati satima. Za ostale parametre koristite zadanu vrijednost
model_xgb = make_pipeline( preprocess, xgboost.XGBClassifier( n_estimators=600, objective='binary:logistic', silent=True, nthread=1) )
Unakrsnu provjeru možete poboljšati s unakrsnom provjerom Stratified K-Folds. Ovdje konstruirate samo tri nabora kako biste ubrzali računanje, ali smanjili kvalitetu. Povećajte ovu vrijednost na 5 ili 10 kod kuće kako biste poboljšali rezultate.
Odabrali ste trenirati model kroz četiri iteracije.
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)
Nasumično pretraživanje je spremno za upotrebu, možete trenirati model
#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)
Kao što vidite, XGBoost ima bolji rezultat od prethodne logičke regresije.
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)
Stvorite DNN s MLPClassifierom u scikit-learn
Konačno, možete istrenirati algoritam dubokog učenja sa scikit-learn. Metoda je ista kao kod drugog klasifikatora. Klasifikator je dostupan na MLPClassifier.
from sklearn.neural_network import MLPClassifier
Vi definirate sljedeći algoritam dubokog učenja:
- Adam rješavač
- Relu funkcija aktiviranja
- Alfa = 0.0001
- veličina serije 150
- Dva skrivena sloja sa 100 odnosno 50 neurona
model_dnn = make_pipeline( preprocess, MLPClassifier(solver='adam', alpha=0.0001, activation='relu', batch_size=150, hidden_layer_sizes=(200, 100), random_state=1))
Možete promijeniti broj slojeva kako biste poboljšali model
model_dnn.fit(X_train, y_train) print("DNN regression score: %f" % model_dnn.score(X_test, y_test))
DNN regresijski rezultat: 0.821253
LIME: Vjerujte svom modelu
Sada kada imate dobar model, potreban vam je alat kojim ćete mu vjerovati. Strojno učenje algoritam, posebno slučajna šuma i neuronska mreža, poznati su kao algoritam crne kutije. Recimo drugačije, radi, ali nitko ne zna zašto.
Trojica istraživača smislila su sjajan alat da vide kako računalo predviđa. Rad se zove Zašto bih ti trebao vjerovati?
Razvili su algoritam pod nazivom Lokalno interpretabilna modela-agnostička objašnjenja (LIME).
Uzmimo primjer:
ponekad ne znate možete li vjerovati predviđanju strojnog učenja:
Liječnik, na primjer, ne može vjerovati dijagnozi samo zato što je računalo tako reklo. Također morate znati možete li vjerovati modelu prije nego što ga stavite u proizvodnju.
Zamislite da možemo razumjeti zašto bilo koji klasifikator predviđa čak i nevjerojatno komplicirane modele kao što su neuronske mreže, nasumične šume ili svms s bilo kojim kernelom
postat će pristupačniji za vjerovanje predviđanju ako možemo razumjeti razloge iza toga. Iz primjera s doktorom, da mu je model rekao koji su simptomi bitni, vjerovao bi mu, također je lakše dokučiti ne treba li vjerovati modelu.
Lime vam može reći koje značajke utječu na odluke klasifikatora
Priprema podataka
To je nekoliko stvari koje trebate promijeniti da biste s njima mogli pokretati LIME piton. Prije svega, potrebno je ugraditi vapno u terminal. Možete koristiti pip install vapno
Lime koristi objekt LimeTabularExplainer za lokalnu aproksimaciju modela. Ovaj objekt zahtijeva:
- skup podataka u numpy formatu
- Naziv značajki: naziv_značajki
- Naziv klasa: class_names
- Indeks stupca kategoričkih obilježja: kategorička obilježja
- Naziv grupe za svaku kategoričku značajku: kategorička_imena
Stvorite numpy skup vlakova
Možete kopirati i pretvoriti df_train iz pandas u kvrgav vrlo lako
df_train.head(5) # Create numpy data df_lime = df_train df_lime.head(3)
Nabavite naziv klase Oznaka je dostupna s objektom unique(). Trebali biste vidjeti:
- '<=50K'
- '>50K'
# Get the class name class_names = df_lime.label.unique() class_names
array(['<=50K', '>50K'], dtype=object)
indeks stupca kategoričkih obilježja
Možete upotrijebiti metodu koju ste prije koristili da biste dobili naziv grupe. Oznaku kodirate pomoću LabelEncoder. Ponovite operaciju na svim kategoričkim značajkama.
## 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
Sada kada je skup podataka spreman, možete konstruirati različiti skup podataka kao što je prikazano u donjim primjerima učenja Scikita. Vi zapravo transformirate podatke izvan cjevovoda kako biste izbjegli pogreške s LIME-om. Skup za obuku u LimeTabularExplaineru trebao bi biti numpy niz bez stringa. S gornjom metodom imate već konvertirani skup podataka za obuku.
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)
Možete napraviti cjevovod s optimalnim parametrima iz XGBoost-a
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))])
Dobivate upozorenje. Upozorenje objašnjava da ne morate kreirati koder oznake prije cjevovoda. Ako ne želite koristiti LIME, možete koristiti metodu iz prvog dijela Strojno učenje sa Scikit-learn vodičem. U suprotnom, možete nastaviti s ovom metodom, prvo izradite kodirani skup podataka, postavite vrući koder unutar cjevovoda.
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)
Prije korištenja LIME-a u akciji, kreirajmo numpy niz sa značajkama pogrešne klasifikacije. Kasnije možete upotrijebiti taj popis kako biste dobili ideju o tome što je klasifikatora dovelo u zabludu.
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)
Izradite lambda funkciju za dohvaćanje predviđanja iz modela s novim podacima. Trebat će vam uskoro.
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]])
Pretvarate pandas dataframe u numpy polje
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)
Odaberimo nasumično kućanstvo iz skupa testova i vidimo predviđanje modela i kako je računalo odabralo.
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])
Možete upotrijebiti objašnjenje uz expand_instance da provjerite objašnjenje iza modela
exp = explainer.explain_instance(X_test_lime[i], predict_fn, num_features=6) exp.show_in_notebook(show_all=False)
Vidimo da je klasifikator točno predvidio kućanstvo. Zarada je, zaista, iznad 50k.
Prvo što možemo reći jest da klasifikator nije toliko siguran u pogledu predviđenih vjerojatnosti. Stroj predviđa da kućanstvo ima prihod veći od 50 tisuća s vjerojatnošću od 64%. Tih 64% sastoji se od kapitalne dobiti i bračne dobiti. Plava boja negativno pridonosi pozitivnoj klasi, a narančasta linija pozitivno.
Klasifikator je zbunjen jer je kapitalni dobitak ovog kućanstva jednak nuli, dok je kapitalni dobitak obično dobar pokazatelj bogatstva. Osim toga, kućanstvo radi manje od 40 sati tjedno. Dob, zanimanje i spol pozitivno pridonose klasifikatoru.
Da je bračni status samac, klasifikator bi predvidio prihod ispod 50 tisuća (0.64-0.18 = 0.46)
Možemo pokušati s drugim kućanstvom koje je pogrešno klasificirano
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)
Klasifikator je predvidio prihod ispod 50k dok je to neistinito. Ovo kućanstvo djeluje čudno. Nema kapitalni dobitak, niti kapitalni gubitak. On je razveden i ima 60 godina, a radi se o obrazovanoj osobi, tj. broj obrazovanja > 12. Prema ukupnom obrascu, ovo bi kućanstvo trebalo, kako objašnjava klasifikator, imati prihod ispod 50k.
Pokušavate se igrati s LIME-om. Primijetit ćete grube pogreške iz klasifikatora.
Možete provjeriti GitHub vlasnika biblioteke. Oni pružaju dodatnu dokumentaciju za klasifikaciju slika i teksta.
rezime
Ispod je popis nekih korisnih naredbi s scikit learn verzijom >=0.20
stvoriti vlak/test skup podataka | pripravnici su se podijelili |
Izgradite cjevovod | |
odaberite stupac i primijenite transformaciju | makecolumntransformer |
vrsta transformacije | |
standardizirati | StandardScaler |
min maks | MinMaxScaler |
Normalizacija | Normalizator |
Imputirajte vrijednost koja nedostaje | imputirati |
Pretvori kategorički | OneHotEncoder |
Prilagodite i transformirajte podatke | fit_transformacija |
Napravite cjevovod | napraviti_cjevovod |
Osnovni model | |
logistička regresija | Logistička regresija |
XGBoost | XGBClassifier |
Neuronska mreža | MLPC klasifikator |
Pretraživanje mreže | GridSearchCV |
Nasumično pretraživanje | RandomizedSearchCV |