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.

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:
- Maskinlรฆring med scikit-learn
- 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:
- Standardiser variabelen: `StandardScaler()โ
- 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)
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)
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 |


