Scikit-Learn-tutorial: installeren en Scikit-Learn-voorbeelden

⚡ Slimme samenvatting

Scikit-learn is de open-source Python Een bibliotheek die voorbewerking, classificatie, regressie, clustering en modelselectie combineert in één consistente schatterinterface. Dit zorgt ervoor dat een complete machine learning-workflow kort, leesbaar en reproduceerbaar blijft, van ruwe data tot gescoorde voorspellingen.

  • 🔘 Installatie: Zowel Conda als pip werken, en de huidige stabiele versie bevat al alle transformatoren die hier gebruikt worden.
  • ☑️ Verwerkte dataset: Het UCI-volkstellingsbestand met 32,561 rijen vormt de basis voor elk voorbeeld in deze handleiding.
  • ✅ Pijpleidingen: make_column_transformer schaalt de numerieke kolommen en codeert de categorische kolommen met behulp van one-hot-codering in één enkel object.
  • 🧪 tuning: GridSearchCV doorloopt een volledig parameterraster, terwijl RandomizedSearchCV er steekproeven van neemt en veel sneller klaar is.
  • ️ Drie modellen: Logistische regressiescores 0.850891, XGBoost 0.873157 en het MLPClassifier-netwerk 0.821253.
  • ⚠️ Uitlegbaarheid: LIME laat zien welke kenmerken een enkele voorspelling naar die klasse hebben geduwd, inclusief de onjuiste kenmerken.

Scikit-learn-handleiding met installatiestappen en uitgewerkte voorbeelden.

Wat is Scikit-leren?

Scikit leren is een open-source Python bibliotheek voor machine learningHet ondersteunt gevestigde algoritmen zoals KNN, gradient boosting, random forest en SVM, en het is gebouwd op basis van NumPy en SciPy. Scikit-learn wordt veel gebruikt in Kaggle-competities en bij vooraanstaande technologiebedrijven. Het omvat voorbewerking, dimensionaliteitsreductie, classificatie, regressie, clustering en modelselectie.

Scikit-learn heeft een van de beste documentaties van alle open-sourcebibliotheken. Het biedt zelfs een interactieve schattingsgrafiek. De juiste taxateur kiezenDat leidt je van de grootte van je dataset naar een shortlist van algoritmen die het proberen waard zijn.

Onderstaande afbeelding illustreert hoe Scikit-learn werkt.

Hoe Scikit-learn werkt in een machine learning-workflow

Scikit-learn is niet moeilijk te gebruiken en levert uitstekende resultaten. Het traint echter wel op de CPU: het werk wordt geparallelliseerd over de cores met het argument `n_jobs` in plaats van op een GPU. Het uitvoeren van een deep learning-algoritme ermee is mogelijk, maar zelden optimaal, vooral als je al weet hoe je het moet gebruiken. TensorFlow.

Scikit-learn downloaden en installeren

Nu in dit Python In deze Scikit-learn tutorial leer je hoe je Scikit-learn kunt downloaden en installeren:

Optie 1: AWS

Scikit-learn kan via AWS worden gebruikt. Een Docker-image met vooraf geïnstalleerde scikit-learn bespaart u alle installatiewerkzaamheden.

Om de ontwikkelaarsversie te installeren, voert u de onderstaande opdracht uit in de volgende map: Jupyter:

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

Optie 2: Mac of Windows gebruik van anaconda

Voor meer informatie over de installatie van Anaconda kunt u terecht bij... Hoe download en installeer je TensorFlow?.

Toen deze handleiding werd geschreven, hadden de ontwikkelaars van scikit-learn een ontwikkelingsversie uitgebracht die problemen in de toenmalige release verhielp. De onderstaande stappen maken daarom gebruik van die ontwikkelingsversie. Op een nieuwe machine bevat de huidige stabiele release al alle transformatoren die hier worden gebruikt. pip install -U scikit-learn is genoeg.

Scikit-learn installeren met Conda Environment

Als je scikit-learn hebt geïnstalleerd met de conda-omgeving, volg dan de onderstaande stappen om bij te werken naar versie 0.20.

Stap 1) Activeer de TensorFlow-omgeving

source activate hello-tf

Stap 2) Verwijder scikit-learn met behulp van het conda-commando.

conda remove scikit-learn

Stap 3) Installeer de ontwikkelaarsversie

Installeer de ontwikkelaarsversie van scikit-learn samen met de benodigde bibliotheken.

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

NOTITIE: Windows gebruikers hebben nodig Microsoft Visual C++ 14. Je kunt het krijgen hier.

Scikit-Learn-voorbeeld met machine learning

Deze Scikit-tutorial is verdeeld in twee delen:

  1. Machine learning met scikit-learn
  2. Hoe u uw model kunt vertrouwen met LIME

Het eerste deel beschrijft hoe je een pipeline bouwt, een model creëert en de hyperparameters afstemt, terwijl het tweede deel ingaat op de interpretatie van het model.

Stap 1) Importeer de gegevens

Tijdens deze Scikit-learn-tutorial ga je de dataset van de volwassenentelling gebruiken.

Het bestand wordt in de onderstaande code rechtstreeks uit de UCI Machine Learning Repository gelezen, dus handmatig downloaden is niet nodig. Als u geïnteresseerd bent in de beschrijvende statistieken, zijn de tools Dive en Overview de moeite waard om te bekijken. Zie ook deze tutorial Om meer te weten te komen over Dive en Overview.

Je importeert de dataset met pandas. Houd er rekening mee dat je de continue variabelen moet converteren naar het float-formaat.

Deze dataset bevat acht categorische variabelen, die worden vermeld in CATE_FEATURES:

  • werkklas
  • onderwijs
  • huwelijks-
  • bezetting
  • relatie
  • race
  • geslacht
  • geboorteland

Het omvat ook zes continue variabelen, die worden vermeld in CONTI_FEATURES:

  • leeftijd
  • fnlwgt
  • onderwijs_num
  • kapitaal_winst
  • kapitaal_verlies
  • uren_week

De lijsten worden hier handmatig ingevuld, zodat u een duidelijker beeld krijgt van welke kolommen relevant zijn. Een snellere manier om een ​​lijst met categorische of continue kolommen samen te stellen is:

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

Hier is de code om de gegevens te importeren:

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

Door describe() op het frame aan te roepen, worden de samenvattende statistieken voor de zes continue kolommen geretourneerd:

leeftijd fnlwgt onderwijs_num kapitaal_winst kapitaal_verlies uren_week
tellen 32561.000000 3.256100e + 04 32561.000000 32561.000000 32561.000000 32561.000000
gemiddelde 38.581647 1.897784e + 05 10.080679 1077.648844 87.303830 40.437456
soa 13.640433 1.055500e + 05 2.572720 7385.292085 402.960219 12.347429
Min 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

Je kunt het aantal unieke waarden van de eigenschap native_country controleren. Slechts één huishouden is afkomstig uit Nederland. Dat huishouden levert geen informatie op en zal een foutmelding geven tijdens de training.

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

U kunt deze niet-informatieve rij uit de dataset verwijderen:

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

Vervolgens slaat u de positie van de doorlopende objecten op in een lijst. U hebt deze nodig bij de volgende stap om de pijplijn te bouwen.

De onderstaande code doorloopt alle kolomnamen in CONTI_FEATURES, leest elke locatie (dat wil zeggen, het kolomnummer) en voegt deze toe aan een lijst genaamd 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]

Het volgende blok doet hetzelfde voor de categorische variabelen.

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

Laten we nu eens naar de dataset zelf kijken. Elk categorisch kenmerk is een tekenreeks, en een model kan geen tekenreeks als invoer krijgen. Daarom moet de dataset worden getransformeerd met behulp van dummyvariabelen.

df_train.head(5)

Je hebt namelijk één kolom nodig voor elke groep in elk kenmerk. Voer eerst de onderstaande code uit om het totale aantal benodigde kolommen te berekenen.

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

De volledige dataset bevat 101 groepen, zoals hierboven weergegeven. Alleen al de feature 'workclass' heeft negen groepen. Je kunt de namen van de groepen weergeven met de onderstaande code; de ​​functie `unique()` retourneert de unieke waarden van elke categorische feature.

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

De trainingsdataset zal daarom 101 + 6 kolommen bevatten: de one-hot-groepen plus de zes continue kenmerken.

Scikit-learn kan de conversie in twee stappen voor u uitvoeren:

  1. Converteer de tekenreeks naar een ID. State-gov wordt ID 1, Self-emp-not-inc wordt ID 2, enzovoort. LabelEncoder doet dit automatisch voor u.
  2. Zet elke ID om naar een nieuwe kolom. De dataset bevat 101 groeps-ID's, dus er zullen 101 kolommen zijn die elke categorische kenmerkgroep vastleggen. Scikit-learn biedt OneHotEncoder voor deze bewerking.

Stap 2) Maak de trein-/testset aan

Nu de dataset klaar is, verdeel je deze in een verhouding van 80/20: 80 procent voor de trainingsset en 20 procent voor de testset.

Je kunt train_test_split gebruiken. Het eerste argument is de dataframe met kenmerken en het tweede is het label. Je stelt de grootte van de testset in met 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)

Stap 3) Bouw de pijpleiding

De pipeline maakt het eenvoudiger om het model te voeden met consistente data. Het idee is om de ruwe data door één object te leiden dat alle bewerkingen in de juiste volgorde uitvoert.

Met deze dataset moet je de continue variabelen standaardiseren en de categorische variabelen converteren. Elke bewerking kan binnen een pipeline plaatsvinden: ontbrekende waarden kunnen worden vervangen door het gemiddelde of de mediaan, en er kunnen nieuwe variabelen worden aangemaakt.

Je hebt twee opties: de twee processen hardcoderen of een pipeline bouwen. Hardcoderen kan testdata in de berekende statistieken laten lekken en na verloop van tijd inconsistenties veroorzaken, dus een pipeline is de betere optie.

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

De pipeline voert twee bewerkingen uit voordat de gegevens aan de logistieke classifier worden aangeleverd:

  1. Standaardiseer de variabele: StandardScaler()
  2. Converteer de categorische kenmerken: OneHotEncoder(sparse=False)

Je voert beide stappen uit met make_column_transformer. Toen deze handleiding werd geschreven, was de functie nog niet opgenomen in de uitgebrachte versie van scikit-learn (0.19), daarom werd de ontwikkelaarsversie gebruikt; deze is sinds versie 0.20 in elke stabiele release opgenomen.

make_column_transformer is eenvoudig: je geeft aan welke kolommen je wilt transformeren en welke transformatie je wilt toepassen. Om de continue kenmerken te standaardiseren, geef je het volgende door:

  • conti_features, StandardScaler() binnen make_column_transformer
    • conti_features: de lijst met continue kolommen
    • StandardScaler: standaardiseert die kolommen

Het OneHotEncoder-object in make_column_transformer codeert de labels automatisch.

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

Versie-opmerking: Twee argumenten in het bovenstaande blok zijn gewijzigd. De huidige versies verwachten eerst de transformator en daarna de kolommen, en dun werd hernoemd sparse_output was aanwezig in scikit-learn 1.2 en verwijderd in 1.4, dus de nieuwere code leest als volgt: OneHotEncoder(sparse_output=False).

Je kunt testen of de pipeline werkt met fit_transform. De uitvoer moet de vorm 26048, 107 hebben.

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

De datatransformator is klaar. Je maakt de pipeline aan met make_pipeline, en zodra de data is getransformeerd, voer je deze in de logistische regressie.

model = make_pipeline(
    preprocess,
    LogisticRegression())

Het trainen van een model met scikit-learn is dan heel eenvoudig: roep de `fit`-methode aan in de pipeline. Je kunt de nauwkeurigheid afdrukken met de `score`-methode.

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

Ten slotte kun je de klassen voorspellen met predict_proba, die de waarschijnlijkheid van elke klasse retourneert. Merk op dat de twee waarschijnlijkheden bij elkaar opgeteld één zijn.

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

Stap 4) Onze pijplijn gebruiken bij een rasterzoekopdracht

Het afstellen van de hyperparameters, de waarden die de structuur van het model bepalen, kan een moeizaam en uitputtend proces zijn.

Een manier om het model te evalueren zou zijn om de grootte van de trainingsset te veranderen en de prestaties te meten, waarbij de oefening tien keer wordt herhaald om de spreiding van de scores te zien. Dat is veel handmatig werk.

Scikit-learn biedt daarentegen functies die parameteroptimalisatie en kruisvalidatie voor je uitvoeren.

Kruisvalidatie

Kruisvalidatie houdt in dat tijdens de training de trainingsset n keer wordt opgesplitst in vouwen (folds) en het model n keer wordt geëvalueerd. Als cv is ingesteld op 10, wordt het model tien keer getraind en geëvalueerd. In elke ronde traint de classifier op negen willekeurig gekozen vouwen en wordt de tiende vouw gebruikt voor evaluatie.

Raster zoeken

Elke classificator heeft hyperparameters die afgesteld moeten worden. Je kunt waarden één voor één uitproberen, of een parametergrid instellen. De scikit-learn-documentatie geeft een overzicht van alle parameters die de logistische classificator accepteert. Om de training snel te houden, wordt in dit voorbeeld alleen de parameter C afgesteld, die de regularisatie regelt. Deze moet positief zijn, en een kleine waarde geeft meer gewicht aan de regularisator.

Je gebruikt het GridSearchCV-object, dat een woordenboek met de te optimaliseren hyperparameters als argument accepteert. Geef elke hyperparameter op, gevolgd door de waarden die je wilt uitproberen. Om C te optimaliseren, schrijf je:

  • 'logisticregression__C': [0.001, 0.01, 0.1, 1.0] — de parameternaam wordt voorafgegaan door de naam van de classifier in kleine letters en twee underscores.

Het model zal vier verschillende waarden proberen: 0.001, 0.01, 0.1 en 1. Het wordt getraind met 10 vouwen, oftewel cv=10.

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

Je kunt het model nu trainen met GridSearchCV met de parameters grid en cv.

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

Output:

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)

Versie-opmerking: the iid Het argument dat in deze uitvoer zichtbaar is, is afgekeurd in scikit-learn 0.22 en verwijderd in 0.24. Het zou daarom in de huidige versies gewoonweg uit de GridSearchCV-aanroep moeten worden verwijderd.

Om de beste parameters te vinden, gebruik je best_params_.

grid_clf.best_params_

Output:

{'logisticregression__C': 1.0}

Na het trainen van het model met vier verschillende regularisatiewaarden, levert de optimale parameter het volgende op:

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

beste logistische regressie uit rasterzoekopdracht: 0.850891

Om toegang te krijgen tot de voorspelde kansen:

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 met scikit-learn

Probeer nu eens een van de krachtigste classificatiemodellen op de markt. XGBoost is een gradient-boosting verbetering op het random forest-model. De theoretische achtergrond ervan valt buiten het bestek van dit artikel. Python Bekijk de Scikit-tutorial, maar houd er rekening mee dat XGBoost al heel wat Kaggle-competities heeft gewonnen. Op een dataset van gemiddelde grootte kan het net zo goed, of zelfs beter, presteren als een deep learning-algoritme.

Het trainen van de classifier is een uitdaging omdat deze een groot aantal parameters bevat. Je kunt natuurlijk GridSearchCV gebruiken om deze parameters voor je te selecteren.

Een betere optie is RandomizedSearchCV. GridSearchCV wordt traag bij grote rasters, omdat de zoekruimte groeit met elke toegevoegde parameter. RandomizedSearchCV daarentegen bemonstert de waarden van elke hyperparameter willekeurig bij elke iteratie, waardoor 1,000 iteraties 1,000 combinaties evalueren. Voor de rest werkt het grotendeels hetzelfde als GridSearchCV.

Je moet xgboost importeren. Als de bibliotheek niet is geïnstalleerd, voer dan `pip3 install xgboost` uit, of installeer deze vanuit een `pip`-bestand. Jupyter notitieboek met:

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

Importeer vervolgens de classifier en de twee zoekhulpmiddelen:

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

De volgende stap in deze Scikit Python Het doel van deze handleiding is om de parameters te specificeren die moeten worden afgestemd. De officiële XGBoost-documentatie bevat een lijst van al deze parameters. Voor dit doel Python In de Sklearn-tutorial kies je slechts twee hyperparameters met elk twee waarden, omdat XGBoost lang duurt om te trainen en elk extra rasterpunt de wachttijd verlengt.

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

Vervolgens bouw je een nieuwe pipeline met de XGBoost-classificator en 600 estimators. n_estimators is zelf instelbaar, en een hoge waarde kan leiden tot overfitting. Je kunt andere waarden proberen, maar houd er rekening mee dat dit uren kan duren. Alle andere parameters behouden hun standaardwaarde.

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

Je kunt de kruisvalidatie verbeteren met de Stratified K-Folds kruisvalidator. Hier worden slechts drie vouwen gebruikt om de berekening te versnellen, ten koste van de kwaliteit; verhoog dit naar 5 of 10 op je eigen computer voor betere resultaten. Het model wordt getraind over vier iteraties.

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)

De gerandomiseerde zoekopdracht is klaar, dus je kunt het model trainen.

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

Zoals u kunt zien, scoort XGBoost beter dan de eerdere logistische regressie.

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)

Maak DNN met MLPClassifier in scikit-learn

Tot slot kun je een neuraal netwerk trainen met scikit-learn zelf. De methode is hetzelfde als voor elke andere classifier, en de estimator is MLPClassifier.

from sklearn.neural_network import MLPClassifier

Het onderstaande netwerk is als volgt gedefinieerd:

  • Adam-oplosser
  • ReLU activeringsfunctie
  • Alfa = 0.0001
  • Batchgrootte van 150
  • Twee verborgen lagen met respectievelijk 200 en 100 neuronen
model_dnn = make_pipeline(
    preprocess,
    MLPClassifier(solver='adam',
                  alpha=0.0001,
                  activation='relu',
                    batch_size=150,
                    hidden_layer_sizes=(200, 100),
                    random_state=1))

Je kunt het aantal lagen aanpassen om het model te verbeteren.

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

DNN-regressiescore: 0.821253

LIME: Vertrouw op je model

Nu je een goed model hebt, moet je het kunnen vertrouwen. Machine learning-algoritmen, met name random forests en neurale netwerken, staan ​​bekend als black-box-modellen: ze werken, maar niemand kan zien waarom.

Drie onderzoekers hebben een tool ontwikkeld die laat zien hoe een computer tot een voorspelling komt. Hun artikel is... “Waarom zou ik je vertrouwen?”en het algoritme dat ze publiceerden heet Local Interpretable Model-Agnostic Explanations (LIME).

Neem bijvoorbeeld het volgende. Soms weet je niet of een voorspelling van een machine learning-model te vertrouwen is. Een arts kan een diagnose niet zomaar accepteren omdat die door een computer is gesteld, en je moet weten of een model betrouwbaar is voordat je het in gebruik neemt.

Stel je voor dat je kunt zien waarom een ​​classificator een voorspelling heeft gedaan, zelfs voor complexe modellen zoals neurale netwerken, random forests of SVM's met een willekeurige kernel. Het wordt veel gemakkelijker om een ​​voorspelling te vertrouwen wanneer de redenen erachter zichtbaar zijn, en even gemakkelijk om te bepalen wanneer een model niet te vertrouwen is. LIME laat je zien welke kenmerken de beslissing van de classificator hebben beïnvloed.

Data voorbereiding

Je moet een paar dingen aanpassen om LIME te kunnen gebruiken. PythonInstalleer eerst kalk in de terminal met behulp van een kalkaanvoerbuis.

Lime gebruikt een LimeTabularExplainer-object om het model lokaal te benaderen. Dit object vereist het volgende:

  • een dataset in NumPy formaat
  • De naam van de features: feature_names
  • De naam van de klassen: class_names
  • De index van de kolom met categorische kenmerken: categorical_features
  • De naam van de groep voor elk categorisch kenmerk: categorical_names

Maak de NumPy-trainingsset aan.

Je kunt de `df_train` dataset van pandas heel gemakkelijk kopiëren en converteren naar NumPy.

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

Haal de klassenaam op

Het label is toegankelijk via unique(). Je zou het volgende moeten zien:

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

Indexeer de kolommen met categorische kenmerken

Gebruik de eerder geleerde methode om de naam van elke groep te verkrijgen. Codeer het label met LabelEncoder en herhaal de bewerking voor elk categorisch kenmerk.

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

Nu de dataset gereed is, kunt u de verschillende datasets bouwen die in de onderstaande Scikit-learn-voorbeelden worden getoond. De data wordt hier buiten de pipeline getransformeerd om fouten met LIME te voorkomen: de trainingsset die aan LimeTabularExplainer wordt doorgegeven, moet een NumPy-array zonder strings zijn, en de bovenstaande methode heeft er al een geproduceerd.

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)

Je kunt de pipeline maken met de optimale parameters die XGBoost heeft gevonden.

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

Je krijgt een waarschuwing. Daarin wordt uitgelegd dat je geen label-encoder hoeft te maken vóór de pipeline. Als je geen LIME gebruikt, is de methode uit het eerste deel van deze tutorial over machine learning met Scikit-learn prima. Anders kun je deze aanpak aanhouden: maak eerst een gecodeerde dataset aan en pas vervolgens de one-hot-encoder toe in de pipeline.

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)

Voordat je LIME aan de slag laat gaan, maak je een NumPy-array aan met de kenmerken van de rijen die verkeerd geclassificeerd zijn. Je kunt die lijst later gebruiken om te achterhalen waardoor de classifier op het verkeerde spoor is geraakt.

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)

Vervolgens maak je een lambda-functie aan die de voorspelling van het model voor nieuwe gegevens ophaalt. Die heb je straks nodig.

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

Je converteert het pandas-dataframe naar een 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)

Kies nu een willekeurig huishouden uit de testset en bekijk zowel de voorspelling als de manier waarop de computer tot die voorspelling is gekomen.

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

Je kunt de explainer met explain_instance gebruiken om de redenering achter het model te inspecteren. De grafiek die wordt gegenereerd, zie je hieronder.

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

LIME-uitleggrafiek die de bijdragen van de kenmerken voor een correct voorspeld huishouden weergeeft

De classificatiesoftware voorspelde dit huishouden correct: het inkomen ligt inderdaad boven de 50.

Het eerste wat opvalt, is dat de classificator niet erg zeker van zichzelf is. Hij voorspelt een inkomen van meer dan 50 euro met een waarschijnlijkheid van 64%, en die 64% wordt bepaald door vermogenswinst en burgerlijke staat. De blauwe kleur draagt ​​negatief bij aan de positieve klasse en de oranje lijn positief.

De classificator aarzelt omdat de vermogenswinst van dit huishouden nul is, terwijl vermogenswinst doorgaans een goede voorspeller van vermogen is. Het huishouden werkt bovendien minder dan 40 uur per week. Leeftijd, beroep en geslacht dragen allemaal positief bij.

Als de burgerlijke staat 'ongehuwd' was, zou de classificator een inkomen onder de 50 euro hebben voorspeld (0.64 – 0.18 = 0.46).

Probeer nu een ander huishouden, een dat verkeerd is geclassificeerd. De verklarende tabel hiervoor volgt na de code.

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)

LIME-uitleggrafiek voor het huishouden dat door de classificatie onjuist is gelabeld.

De classificator voorspelde een inkomen onder de 50 euro, wat onjuist is. Dit huishouden is ongebruikelijk: er is geen sprake van vermogenswinst of -verlies, de persoon is gescheiden, bijna 60 jaar oud en hoogopgeleid (opleidingsniveau > 12). Volgens het algemene patroon plaatste de classificator het huishouden onder de 50 euro.

Speel zelf met LIME en je zult talloze grove fouten van de classifier tegenkomen. De GitHub-repository van de auteur van de bibliotheek bevat aanvullende documentatie voor beeld- en tekstclassificatie.

Scikit-learn Command Reference

Hieronder vindt u een lijst met nuttige commando's die van toepassing zijn op scikit-learn versie 0.20 en later.

Taak Functie of klasse
Maak de trainings-/testdataset aan. train_test_split
Bouw een pijplijn
Selecteer de kolommen en pas de transformatie toe. maak_kolom_transformer
Soort transformatie
Standaardiseren Standaardscaler
Min-max schaling MinMaxScaler
Normaliseren Normalizer
Ontbrekende waarden invullen SimpleImputer
Converteer categorisch OneHotEncoder
Pas de gegevens aan en transformeer ze fit_transform
Maak de pijpleiding make_pipeline
Basismodel
Logistische regressie Logistische regressie
XGBoost XGBClassifier
neuraal net MLP-classificatie
Raster zoeken RasterZoekenCV
Gerandomiseerde zoekopdracht GerandomiseerdZoekenCV

Veelgestelde vragen

Installeer de huidige stabiele versie met `pip install -U scikit-learn` of `conda install -c conda-forge scikit-learn`. De ontwikkelaarsversie die in de bovenstaande stappen werd gebruikt, was alleen nodig in 2018, toen `make_column_transformer` nog niet was uitgebracht; deze is nu in elke stabiele versie opgenomen.

`fit` leert parameters zoals het gemiddelde en de standaarddeviatie van een kolom. `transform` past deze toe op de data. `fit_transform` doet beide in één aanroep en zou alleen de trainingsset moeten aanraken, nooit de testset.

Door een scaler of encoder toe te passen op de volledige dataset, kunnen statistieken van de testset het model bereiken. Een pipeline past elke transformer binnen elke cross-validatiefold opnieuw aan, zodat de rijen die buiten beschouwing worden gelaten onzichtbaar blijven tot het moment dat ze worden beoordeeld.

Het vult bekende vormen automatisch aan: ColumnTransformer-blokken, parametergrids en de namen met dubbele underscores die GridSearchCV verwacht. RevBekijk alles wat versiegevoelig is, omdat suggesties vaak oudere argumentnamen weergeven, zoals 'sparse' in plaats van 'sparse_output'.

Niet helemaal. Geautomatiseerde zoektools verkennen een raster sneller en filteren zwakke kandidaten eruit, maar je kiest nog steeds de zoekruimte, de scoremethode en het kruisvalidatieschema. Die beslissingen zijn belangrijker dan het zoekalgoritme zelf.

Nee. De training vindt plaats op de CPU en wordt parallel uitgevoerd over de cores via n_jobs. Een experimentele Array API-laag maakt het mogelijk dat een beperkte set estimators GPU-arrays accepteert, maar TensorFlow En vergelijkbare frameworks blijven de GPU-optie.

Ja. Roep `set_output(transform=”pandas”)` aan op een transformer of een hele pipeline en het resultaat behoudt de kolomnamen in plaats van een kale uitvoer te retourneren. NumPy array, waardoor de uitvoer van ColumnTransformer veel gemakkelijker te inspecteren is.

Geef class_weight=”balanced” door aan de schatters die dit accepteren, voer een resampling uit met een bijbehorende bibliotheek zoals imbalanced-learn, en beoordeel op basis van precisie, recall of de F1-score in plaats van alleen nauwkeurigheid.

Vat dit bericht samen met: