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.

Kako Scikit Learn radi
Kako Scikit Learn funkcionira

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:

  1. Strojno učenje sa scikit-learnom
  2. 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:

  1. Standardizirajte varijablu: `StandardScaler()“
  2. 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)

Priprema podataka

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)

Priprema podataka

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