Scikit-Learn Tutorial: Hvordan installere og Scikit-Learn eksempler

Hva er Scikit-learn?

Scikit lรฆre er en รฅpen kildekode Python bibliotek for maskinlรฆring. Den stรธtter state-of-the-art algoritmer som KNN, XGBoost, random forest og SVM. Den er bygget pรฅ toppen av NumPy. Scikit-learn er mye brukt i Kaggle-konkurranse sรฅ vel som fremtredende teknologiselskaper. Det hjelper med forbehandling, dimensjonalitetsreduksjon (parametervalg), klassifisering, regresjon, gruppering og modellvalg.

Scikit-learn har den beste dokumentasjonen av alle รฅpen kildekode-biblioteker. Det gir deg et interaktivt diagram pรฅ https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html.

Hvordan Scikit Learn fungerer
Hvordan Scikit Learn fungerer

Scikit-learn er ikke veldig vanskelig รฅ bruke og gir utmerkede resultater. Scikit learning stรธtter imidlertid ikke parallelle beregninger. Det er mulig รฅ kjรธre en dyp lรฆringsalgoritme med det, men det er ikke en optimal lรธsning, spesielt hvis du vet hvordan du bruker TensorFlow.

Hvordan laste ned og installere Scikit-learn

Nรฅ i dette Python Scikit-learn tutorial, vi vil lรฆre hvordan du laster ned og installerer Scikit-learn:

Alternativ 1: AWS

scikit-learn kan brukes over AWS. Vennligst referere Docker-bildet som har scikit-learn forhรฅndsinstallert.

For รฅ bruke utviklerversjonen, bruk kommandoen i Jupyter

import sys
!{sys.executable} -m pip install git+git://github.com/scikit-learn/scikit-learn.git

Alternativ 2: Mac eller Windows bruker Anaconda

For รฅ lรฆre om Anaconda-installasjon, se https://www.guru99.com/download-install-tensorflow.html

Nylig har utviklerne av scikit gitt ut en utviklingsversjon som takler vanlige problemer med den nรฅvรฆrende versjonen. Vi fant det mer praktisk รฅ bruke utviklerversjonen i stedet for den nรฅvรฆrende versjonen.

Hvordan installere scikit-learn med Conda Environment

Hvis du installerte scikit-learn med conda-miljรธet, fรธlg trinnet for รฅ oppdatere til versjon 0.20

Trinn 1) Aktiver tensorflow-miljรธet

source activate hello-tf

Trinn 2) Fjern scikit lean ved รฅ bruke conda-kommandoen

conda remove scikit-learn

Trinn 3) Installer utviklerversjon.
Installer scikit learn utviklerversjon sammen med nรธdvendige biblioteker.

conda install -c anaconda git
pip install Cython
pip install h5py
pip install git+git://github.com/scikit-learn/scikit-learn.git

NOTAT: Windows brukeren mรฅ installere Microsoft Visual C++ 14. Du kan fรฅ det fra her.

Scikit-Learn-eksempel med maskinlรฆring

Denne Scikit-opplรฆringen er delt inn i to deler:

  1. Maskinlรฆring med scikit-learn
  2. Hvordan stole pรฅ modellen din med LIME

Den fรธrste delen beskriver hvordan du bygger en rรธrledning, lager en modell og justerer hyperparametrene, mens den andre delen gir toppmoderne nรฅr det gjelder modellvalg.

Trinn 1) Importer dataene

I lรธpet av denne Scikit-lรฆringsopplรฆringen vil du bruke voksendatasettet.

For en bakgrunn i dette datasettet, se Hvis du er interessert i รฅ vite mer om den beskrivende statistikken, vennligst bruk Dive og Overview-verktรธy.

Henvis denne opplรฆringen lรฆr mer om dykk og oversikt

Du importerer datasettet med Pandas. Merk at du mรฅ konvertere typen av de kontinuerlige variablene i flyteformat.

Dette datasettet inkluderer รฅtte kategoriske variabler:

De kategoriske variablene er oppfรธrt i CATE_FEATURES

  • arbeidsklasse
  • utdanning
  • ekteskapelig
  • okkupasjon
  • forholdet
  • rase
  • kjรธnn
  • native_country

dessuten seks kontinuerlige variabler:

De kontinuerlige variablene er oppfรธrt i CONTI_FEATURES

  • alder
  • fnlwgt
  • utdanning_nummer
  • kapitalgevinst
  • kapitaltap
  • timer_uke

Merk at vi fyller listen for hรฅnd slik at du har en bedre oversikt over hvilke kolonner vi bruker. En raskere mรฅte รฅ konstruere en liste over kategoriske eller kontinuerlige er รฅ bruke:

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

Her er koden for รฅ importere dataene:

# 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()
alder fnlwgt utdanning_nummer kapitalgevinst kapitaltap timer_uke
telle 32561.000000 3.256100e + 04 32561.000000 32561.000000 32561.000000 32561.000000
bety 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
minutter 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

Du kan sjekke antallet unike verdier for native_country-funksjonene. Du kan se at kun รฉn husstand kommer fra Holand-Nederland. Denne husstanden vil ikke gi oss noen informasjon, men vil gjennom en feil under treningen.

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

Du kan ekskludere denne uinformative raden fra datasettet

## Drop Netherland, because only one row
df_train = df_train[df_train.native_country != "Holand-Netherlands"]

Deretter lagrer du posisjonen til de kontinuerlige funksjonene i en liste. Du trenger det i neste trinn for รฅ bygge rรธrledningen.

Koden nedenfor vil gรฅ over alle kolonnenavnene i CONTI_FEATURES og hente plasseringen (dvs. nummeret) og deretter legge den til en liste kalt 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]

Koden nedenfor gjรธr samme jobb som ovenfor, men for den kategoriske variabelen. Koden nedenfor gjentar det du har gjort tidligere, bortsett fra med de kategoriske funksjonene.

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

Du kan ta en titt pรฅ datasettet. Merk at hvert kategorisk trekk er en streng. Du kan ikke mate en modell med en strengverdi. Du mรฅ transformere datasettet ved รฅ bruke en dummy-variabel.

df_train.head(5)

Faktisk mรฅ du opprette รฉn kolonne for hver gruppe i funksjonen. Fรธrst kan du kjรธre koden nedenfor for รฅ beregne det totale antallet kolonner som trengs.

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

Hele datasettet inneholder 101 grupper som vist ovenfor. For eksempel har arbeidsklassens funksjoner ni grupper. Du kan visualisere navnet pรฅ gruppene med fรธlgende koder

unique() returnerer de unike verdiene til de kategoriske funksjonene.

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

Derfor vil opplรฆringsdatasettet inneholde 101 + 7 kolonner. De siste syv kolonnene er de kontinuerlige funksjonene.

Scikit-learn kan ta seg av konverteringen. Det gjรธres i to trinn:

  • Fรธrst mรฅ du konvertere strengen til ID. For eksempel vil State-gov ha ID 1, Self-emp-not-inc ID 2 og sรฅ videre. Funksjonen LabelEncoder gjรธr dette for deg
  • Transponer hver ID til en ny kolonne. Som nevnt tidligere har datasettet 101-gruppens ID. Derfor vil det vรฆre 101 kolonner som fanger opp alle kategoriske funksjoners grupper. Scikit-learn har en funksjon kalt OneHotEncoder som utfรธrer denne operasjonen

Trinn 2) Lag toget/testsettet

Nรฅ som datasettet er klart, kan vi dele det 80/20.

80 prosent for treningssettet og 20 prosent for testsettet.

Du kan bruke train_test_split. Det fรธrste argumentet er datarammen er funksjonene og det andre argumentet er etiketten datarammen. Du kan spesifisere stรธrrelsen pรฅ testsettet med 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)

Trinn 3) Bygg rรธrledningen

Rรธrledningen gjรธr det enklere รฅ mate modellen med konsistente data.

Tanken bak er รฅ sette rรฅdataene inn i en "pipeline" for รฅ utfรธre operasjoner.

For eksempel, med det gjeldende datasettet, mรฅ du standardisere de kontinuerlige variablene og konvertere de kategoriske dataene. Merk at du kan utfรธre alle operasjoner inne i rรธrledningen. For eksempel, hvis du har 'NA'er' i datasettet, kan du erstatte dem med gjennomsnittet eller medianen. Du kan ogsรฅ opprette nye variabler.

Du har valget; hardkode de to prosessene eller lag en pipeline. Fรธrstevalget kan fรธre til datalekkasje og skape inkonsekvenser over tid. Et bedre alternativ er รฅ bruke rรธrledningen.

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

Rรธrledningen vil utfรธre to operasjoner fรธr den mater den logistiske klassifisereren:

  1. Standardiser variabelen: `StandardScaler()โ€œ
  2. Konverter de kategoriske funksjonene: OneHotEncoder(sparse=False)

Du kan utfรธre de to trinnene ved รฅ bruke make_column_transformer. Denne funksjonen er ikke tilgjengelig i gjeldende versjon av scikit-learn (0.19). Det er ikke mulig med gjeldende versjon รฅ utfรธre etikettkoderen og รฉn varmkoder i rรธrledningen. Det er en grunn til at vi bestemte oss for รฅ bruke utviklerversjonen.

make_column_transformer er enkel รฅ bruke. Du mรฅ definere hvilke kolonner som skal brukes transformasjonen og hvilken transformasjon som skal brukes. For รฅ standardisere den kontinuerlige funksjonen kan du for eksempel gjรธre:

  • conti_features, StandardScaler() inne i make_column_transformer.
    • conti_features: liste med den kontinuerlige variabelen
    • StandardScaler: standardiser variabelen

Objektet OneHotEncoder inne i make_column_transformer koder automatisk etiketten.

preprocess = make_column_transformer(
    (conti_features, StandardScaler()),
    ### Need to be numeric not string to specify columns name 
    (categorical_features, OneHotEncoder(sparse=False))
)

Du kan teste om rรธrledningen fungerer med fit_transform. Datasettet skal ha fรธlgende form: 26048, 107

preprocess.fit_transform(X_train).shape
(26048, 107)

Datatransformatoren er klar til bruk. Du kan lage pipeline med make_pipeline. Nรฅr dataene er transformert, kan du mate den logistiske regresjonen.

model = make_pipeline(
    preprocess,
    LogisticRegression())

ร… trene en modell med scikit-learn er trivielt. Du mรฅ bruke objekttilpasningen innledet av rรธrledningen, dvs. modellen. Du kan skrive ut nรธyaktigheten med partiturobjektet fra scikit-learn-biblioteket

model.fit(X_train, y_train)
print("logistic regression score: %f" % model.score(X_test, y_test))
logistic regression score: 0.850891

Til slutt kan du forutsi klassene med predict_proba. Den returnerer sannsynligheten for hver klasse. Merk at det summerer til รฉn.

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

Trinn 4) Bruk av rรธrledningen vรฅr i et rutenettsรธk

Justering av hyperparameteren (variabler som bestemmer nettverksstruktur som skjulte enheter) kan vรฆre kjedelig og utmattende.

En mรฅte รฅ evaluere modellen pรฅ kan vรฆre รฅ endre stรธrrelsen pรฅ treningssettet og evaluere prestasjonene.

Du kan gjenta denne metoden ti ganger for รฅ se poengsummene. Det er imidlertid for mye arbeid.

I stedet gir scikit-learn en funksjon for รฅ utfรธre parameterinnstilling og kryssvalidering.

Kryssvalidering

Cross-Validation betyr under treningen, treningssettet er slip n antall ganger i folder og deretter evaluerer modellen n gang. For eksempel, hvis cv er satt til 10, trenes treningssettet og evalueres ti ganger. Ved hver runde velger klassifisereren tilfeldig ni fold for รฅ trene modellen, og den 10. folden er ment for evaluering.

Rutenettsรธk

Hver klassifikator har hyperparametre for รฅ stille inn. Du kan prรธve forskjellige verdier, eller du kan angi et parameterrutenett. Hvis du gรฅr til det offisielle nettstedet for scikit-learn, kan du se at den logistiske klassifikatoren har forskjellige parametere รฅ justere. For รฅ gjรธre treningen raskere velger du รฅ stille inn C-parameteren. Den kontrollerer for regulariseringsparameteren. Det skal vรฆre positivt. En liten verdi gir mer vekt til regularizeren.

Du kan bruke objektet GridSearchCV. Du mรฅ lage en ordbok som inneholder hyperparametrene for รฅ stille inn.

Du lister opp hyperparametrene etterfulgt av verdiene du vil prรธve. For รฅ stille inn C-parameteren bruker du for eksempel:

  • 'logisticregression__C': [0.1, 1.0, 1.0]: Parameteren innledes med navnet, med smรฅ bokstaver, pรฅ klassifikatoren og to understrekinger.

Modellen vil prรธve fire forskjellige verdier: 0.001, 0.01, 0.1 og 1.

Du trener modellen ved รฅ bruke 10 folder: cv=10

from sklearn.model_selection import GridSearchCV
# Construct the parameter grid
param_grid = {
    'logisticregression__C': [0.001, 0.01,0.1, 1.0],
    }

Du kan trene modellen ved รฅ bruke GridSearchCV med parameterne gri og cv.

# Train the model
grid_clf = GridSearchCV(model,
                        param_grid,
                        cv=10,
                        iid=False)
grid_clf.fit(X_train, y_train)

UTGANG

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)

For รฅ fรฅ tilgang til de beste parameterne bruker du best_params_

grid_clf.best_params_

UTGANG

{'logisticregression__C': 1.0}

Etter รฅ ha trent modellen med fire forskjellige regulariseringsverdier, er den optimale parameteren

print("best logistic regression from grid search: %f" % grid_clf.best_estimator_.score(X_test, y_test))

beste logistiske regresjon fra rutenettsรธk: 0.850891

For รฅ fรฅ tilgang til de anslรฅtte sannsynlighetene:

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-modell med scikit-learn

La oss prรธve Scikit-learn-eksempler for รฅ trene en av de beste klassifisere pรฅ markedet. XGBoost er en forbedring i forhold til den tilfeldige skogen. Klassifisererens teoretiske bakgrunn utenfor rammen av dette Python Scikit opplรฆring. Husk at XGBoost har vunnet mange kaggle-konkurranser. Med en gjennomsnittlig datasettstรธrrelse kan den yte like bra som en dyplรฆringsalgoritme eller enda bedre.

Klassifisereren er utfordrende รฅ trene fordi den har et stort antall parametere รฅ stille inn. Du kan selvfรธlgelig bruke GridSearchCV til รฅ velge parameteren for deg.

La oss i stedet se hvordan du bruker en bedre mรฅte รฅ finne de optimale parameterne pรฅ. GridSearchCV kan vรฆre kjedelig og veldig lang รฅ trene hvis du passerer mange verdier. Sรธkeomrรฅdet vokser sammen med antall parametere. En foretrukket lรธsning er รฅ bruke RandomizedSearchCV. Denne metoden bestรฅr i รฅ velge verdiene til hver hyperparameter etter hver iterasjon tilfeldig. For eksempel, hvis klassifisereren trenes over 1000 iterasjoner, blir 1000 kombinasjoner evaluert. Det fungerer mer eller mindre som. GridSearchCV

Du mรฅ importere xgboost. Hvis biblioteket ikke er installert, vennligst bruk pip3 install xgboost eller

use import sys
!{sys.executable} -m pip install xgboost

In Jupyter miljรธ

Neste,

import xgboost
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import StratifiedKFold

Det neste trinnet i denne Scikit Python opplรฆringen inkluderer รฅ spesifisere parametrene som skal stilles inn. Du kan referere til den offisielle dokumentasjonen for รฅ se alle parameterne som skal justeres. Av hensyn til Python Sklearn tutorial, du velger bare to hyperparametre med to verdier hver. XGBoost tar mye tid รฅ trene, jo flere hyperparametre i rutenettet, jo lengre tid trenger du รฅ vente.

params = {
        'xgbclassifier__gamma': [0.5, 1],
        'xgbclassifier__max_depth': [3, 4]
        }

Du konstruerer en ny pipeline med XGBoost-klassifiserer. Du velger รฅ definere 600 estimatorer. Merk at n_estimators er en parameter du kan justere. En hรธy verdi kan fรธre til overmontering. Du kan prรธve forskjellige verdier selv, men vรฆr oppmerksom pรฅ at det kan ta timer. Du bruker standardverdien for de andre parameterne

model_xgb = make_pipeline(
    preprocess,
    xgboost.XGBClassifier(
                          n_estimators=600,
                          objective='binary:logistic',
                          silent=True,
                          nthread=1)
)

Du kan forbedre kryssvalideringen med den Stratified K-Folds kryssvalidatoren. Du konstruerer bare tre folder her for รฅ raskere beregningen, men redusere kvaliteten. ร˜k denne verdien til 5 eller 10 hjemme for รฅ forbedre resultatene.

Du velger รฅ trene modellen over fire iterasjoner.

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)

Det randomiserte sรธket er klart til bruk, du kan trene modellen

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

Som du kan se, har XGBoost en bedre poengsum enn den forrige logistiske regresjonen.

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)

Lag DNN med MLPClassifier i scikit-learn

Til slutt kan du trene en dyp lรฆringsalgoritme med scikit-learn. Metoden er den samme som den andre klassifisereren. Klassifisereren er tilgjengelig pรฅ MLPClassifier.

from sklearn.neural_network import MLPClassifier

Du definerer fรธlgende dyplรฆringsalgoritme:

  • Adam lรธser
  • Relu aktiveringsfunksjon
  • Alfa = 0.0001
  • batchstรธrrelse pรฅ 150
  • To skjulte lag med henholdsvis 100 og 50 nevroner
model_dnn = make_pipeline(
    preprocess,
    MLPClassifier(solver='adam',
                  alpha=0.0001,
                  activation='relu',
                    batch_size=150,
                    hidden_layer_sizes=(200, 100),
                    random_state=1))

Du kan endre antall lag for รฅ forbedre modellen

model_dnn.fit(X_train, y_train)
  print("DNN regression score: %f" % model_dnn.score(X_test, y_test))

DNN regresjonsscore: 0.821253

LIME: Stol pรฅ modellen din

Nรฅ som du har en god modell, trenger du et verktรธy for รฅ stole pรฅ den. Maskinlรฆring algoritmer, spesielt tilfeldig skog og nevrale nettverk, er kjent for รฅ vรฆre black-box-algoritme. Si annerledes, det fungerer, men ingen vet hvorfor.

Tre forskere har kommet opp med et flott verktรธy for รฅ se hvordan datamaskinen gir en spรฅdom. Avisen heter Why Should I Trust You?

De utviklet en algoritme kalt Lokale tolkbare modell-agnostiske forklaringer (LIME).

Ta et eksempel:

noen ganger vet du ikke om du kan stole pรฅ en maskinlรฆringsprediksjon:

En lege kan for eksempel ikke stole pรฅ en diagnose bare fordi en datamaskin sa det. Du mรฅ ogsรฅ vite om du kan stole pรฅ modellen fรธr du setter den i produksjon.

Tenk deg at vi kan forstรฅ hvorfor en klassifikator lager en prediksjon selv utrolig kompliserte modeller som nevrale nettverk, tilfeldige skoger eller svms med hvilken som helst kjerne

vil bli mer tilgjengelig for รฅ stole pรฅ en prediksjon hvis vi kan forstรฅ รฅrsakene bak den. Fra eksemplet med legen, hvis modellen fortalte ham hvilke symptomer som er viktige du ville stole pรฅ, er det ogsรฅ lettere รฅ finne ut om du ikke bรธr stole pรฅ modellen.

Lime kan fortelle deg hvilke funksjoner som pรฅvirker avgjรธrelsene til klassifisereren

Dataklargjรธring

De er et par ting du mรฅ endre for รฅ kjรธre LIME med python. Fรธrst av alt mรฅ du installere kalk i terminalen. Du kan bruke pip install lime

Lime bruker LimeTabularExplainer-objektet for รฅ tilnรฆrme modellen lokalt. Dette objektet krever:

  • et datasett i numpy-format
  • Navnet pรฅ funksjonene: funksjonsnavn
  • Navnet pรฅ klassene: klassenavn
  • Indeksen til kolonnen med kategoriske funksjoner: categorical_features
  • Navnet pรฅ gruppen for hver kategoriske funksjoner: categorical_names

Lag numpy togsett

Du kan kopiere og konvertere df_train fra pandaer til fรธlelseslรธs veldig lett

df_train.head(5)
# Create numpy data
df_lime = df_train
df_lime.head(3)

Fรฅ klassenavnet Etiketten er tilgjengelig med objektet unique(). Du bรธr se:

  • '<= 50 XNUMX'
  • '> 50K'
# Get the class name
class_names = df_lime.label.unique()
class_names
array(['<=50K', '>50K'], dtype=object)

indeks av kolonnen med kategoriske funksjoner

Du kan bruke metoden du lener deg fรธr for รฅ fรฅ navnet pรฅ gruppen. Du koder etiketten med LabelEncoder. Du gjentar operasjonen pรฅ alle de kategoriske funksjonene.

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

Nรฅ som datasettet er klart, kan du konstruere det forskjellige datasettet som vist i Scikit learn-eksempler nedenfor. Du transformerer faktisk dataene utenfor rรธrledningen for รฅ unngรฅ feil med LIME. Opplรฆringssettet i LimeTabularExplainer skal vรฆre en numpy array uten streng. Med metoden ovenfor har du allerede konvertert et treningsdatasett.

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)

Du kan lage rรธrledningen med de optimale parameterne fra 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))])

Du fรฅr en advarsel. Advarselen forklarer at du ikke trenger รฅ opprette en etikettkoder fรธr rรธrledningen. Hvis du ikke vil bruke LIME, kan du fint bruke metoden fra fรธrste del av Machine Learning with Scikit-learn-opplรฆringen. Ellers kan du fortsette med denne metoden, fรธrst opprette et kodet datasett, sett fรฅ den varme enkoderen i rรธrledningen.

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)

Fรธr vi bruker LIME i aksjon, la oss lage en numpy matrise med funksjonene til feil klassifisering. Du kan bruke den listen senere for รฅ fรฅ en idรฉ om hva som villeder klassifisereren.

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)

Du lager en lambda-funksjon for รฅ hente prediksjonen fra modellen med de nye dataene. Du trenger det snart.

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

Du konverterer pandas dataramme til numpy array

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)

La oss velge en tilfeldig husholdning fra testsettet og se modellprediksjonen og hvordan datamaskinen gjorde sitt valg.

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

Du kan bruke forklaringen med explain_instance for รฅ sjekke forklaringen bak modellen

exp = explainer.explain_instance(X_test_lime[i], predict_fn, num_features=6)
exp.show_in_notebook(show_all=False)

Dataklargjรธring

Vi kan se at klassifikatoren spรฅdde husholdningen riktig. Inntekten er faktisk over 50k.

Det fรธrste vi kan si er at klassifisereren ikke er sรฅ sikker pรฅ de forutsagte sannsynlighetene. Maskinen spรฅr at husholdningen har en inntekt over 50k med en sannsynlighet pรฅ 64%. Disse 64 % bestรฅr av kapitalgevinst og ekteskap. Den blรฅ fargen bidrar negativt til den positive klassen og den oransje linjen, positivt.

Klassifisereren er forvirret fordi kapitalgevinsten til denne husholdningen er null, mens kapitalgevinsten vanligvis er en god prediktor for formue. Dessuten jobber husholdningen mindre enn 40 timer i uken. Alder, yrke og kjรธnn bidrar positivt til klassifisereren.

Hvis sivilstatusen var singel, ville klassifikatoren ha spรฅdd en inntekt under 50k (0.64-0.18 = 0.46)

Vi kan prรธve med en annen husstand som har blitt feilklassifisert

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)

Dataklargjรธring

Klassifisereren spรฅdde en inntekt under 50k mens det er usant. Denne husholdningen virker rar. Den har ikke kapitalgevinst, og heller ikke kapitaltap. Han er skilt og er 60 รฅr gammel, og det er et utdannet folk, dvs. utdanning_num > 12. I fรธlge det overordnede mรธnsteret skal denne husstanden, som klassifisereren forklarer, fรฅ en inntekt under 50k.

Du prรธver รฅ leke med LIME. Du vil legge merke til grove feil fra klassifisereren.

Du kan sjekke GitHub til eieren av biblioteket. De gir ekstra dokumentasjon for bilde- og tekstklassifisering.

Sammendrag

Nedenfor er en liste over noen nyttige kommandoer med scikit learning-versjon >=0.20

lage tog-/testdatasett traineer splittes
Bygg en rรธrledning
velg kolonnen og bruk transformasjonen lage kolonnetransformator
type transformasjon
standardisere Standard Scaler
min maks MinMaxScaler
normal~~POS=TRUNC Normalisering
Beregn manglende verdi tilregne
Konverter kategorisk OneHotEncoder
Tilpass og transformer dataene passe_transform
Lag rรธrledningen make_pipeline
Grunnmodell
logistisk regresjon Logistisk regresjon
Xgboost XGBClassifier
Nevralt nett MLPClassifier
Rutenettsรธk GridSearchCV
Randomisert sรธk RandomizedSearchCV

Oppsummer dette innlegget med: