Tutorial do Scikit-Learn: como instalar e exemplos do Scikit-Learn

โšก Resumo Inteligente

Scikit-learn รฉ de cรณdigo aberto. Python Biblioteca que abrange prรฉ-processamento, classificaรงรฃo, regressรฃo, agrupamento e seleรงรฃo de modelos por meio de uma รบnica interface de estimador consistente, o que mantรฉm um fluxo de trabalho completo de aprendizado de mรกquina curto, legรญvel e reproduzรญvel, desde os dados brutos atรฉ as previsรตes com pontuaรงรฃo.

  • ๐Ÿ”˜ Instalaรงรฃo: Tanto o Conda quanto o pip funcionam, e a versรฃo estรกvel atual jรก contรฉm todos os transformadores usados โ€‹โ€‹aqui.
  • โ˜‘๏ธ Conjunto de dados trabalhado: O arquivo do censo de adultos da UCI, com 32,561 linhas, serve de base para todos os exemplos deste passo a passo.
  • โœ… Oleodutos: A funรงรฃo `make_column_transformer` dimensiona as colunas numรฉricas e codifica as colunas categรณricas usando one-hot encoding em um รบnico objeto.
  • ๐Ÿงช Tuning: O GridSearchCV percorre uma grade de parรขmetros completa, enquanto o RandomizedSearchCV realiza uma amostragem e termina muito mais cedo.
  • ๐Ÿ› ๏ธ Trรชs modelos: A regressรฃo logรญstica obteve uma pontuaรงรฃo de 0.850891, o XGBoost de 0.873157 e a rede MLPClassifier de 0.821253.
  • โš ๏ธ Explicabilidade: O LIME mostra quais caracterรญsticas direcionaram uma รบnica previsรฃo para sua classe, incluindo as previsรตes incorretas.

Tutorial do Scikit-learn com etapas de instalaรงรฃo e exemplos prรกticos.

O que รฉ Scikit-learn?

Scikit-learn รฉ um open-source Python biblioteca para aprendizado de mรกquinaEle suporta algoritmos consagrados como KNN, gradient boosting, random forest e SVM, e รฉ construรญdo sobre... NumPy e SciPy. O Scikit-learn รฉ amplamente utilizado em competiรงรตes do Kaggle, bem como em importantes empresas de tecnologia. Ele abrange prรฉ-processamento, reduรงรฃo de dimensionalidade, classificaรงรฃo, regressรฃo, agrupamento e seleรงรฃo de modelos.

O Scikit-learn possui uma das melhores documentaรงรตes entre as bibliotecas de cรณdigo aberto. Ele oferece atรฉ mesmo um grรกfico de estimativa interativo. Escolher o estimador certo, que te guia desde o tamanho do seu conjunto de dados atรฉ uma lista restrita de algoritmos que valem a pena experimentar.

A figura abaixo ilustra como o Scikit-learn funciona.

Como o Scikit-learn funciona em um fluxo de trabalho de aprendizado de mรกquina

O Scikit-learn nรฃo รฉ difรญcil de usar e oferece excelentes resultados. No entanto, ele treina na CPU: o trabalho รฉ paralelizado entre os nรบcleos com o argumento `n_jobs`, em vez de na GPU. Executar um algoritmo de aprendizado profundo com ele รฉ possรญvel, mas raramente รฉ a melhor opรงรฃo, especialmente se vocรช jรก sabe como usar outras ferramentas. TensorFlow.

Como baixar e instalar o Scikit-learn

Agora neste Python Neste tutorial sobre Scikit-learn, vocรช aprenderรก como baixar e instalar o Scikit-learn:

Opรงรฃo 1: AWS

O Scikit-learn pode ser usado na AWS. Uma imagem Docker com o Scikit-learn prรฉ-instalado elimina completamente o trabalho de configuraรงรฃo.

Para instalar a versรฃo de desenvolvedor, execute o comando abaixo dentro de Jupyter:

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

Opรงรฃo 2: Mac ou Windows usando Anaconda

Para saber mais sobre a instalaรงรฃo do Anaconda, consulte Como baixar e instalar o TensorFlow.

Na รฉpoca em que este guia foi escrito, os desenvolvedores do scikit-learn haviam lanรงado uma versรฃo de desenvolvimento que corrigia problemas presentes na versรฃo entรฃo vigente. Portanto, os passos a seguir utilizam essa versรฃo de desenvolvimento. Em uma mรกquina nova, a versรฃo estรกvel atual jรก contรฉm todos os transformadores usados โ€‹โ€‹aqui. pip install -U scikit-learn basta.

Como instalar o scikit-learn com ambiente Conda

Se vocรช instalou o scikit-learn com o ambiente conda, siga os passos abaixo para atualizar para a versรฃo 0.20.

Passo 1) Ative o ambiente TensorFlow.

source activate hello-tf

Passo 2) Remova o scikit-learn usando o comando conda

conda remove scikit-learn

Passo 3) Instale a versรฃo de desenvolvedor

Instale a versรฃo para desenvolvedores do scikit-learn juntamente com as bibliotecas necessรกrias.

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

OBSERVAร‡รƒO: Windows usuรกrios precisam Microsoft visual C++ 14. Vocรช pode conseguir. aqui..

Exemplo do Scikit-Learn com aprendizado de mรกquina

Este tutorial do Scikit estรก dividido em duas partes:

  1. Aprendizado de mรกquina com scikit-learn
  2. Como confiar em seu modelo com LIME

A primeira parte detalha como construir um pipeline, criar um modelo e ajustar os hiperparรขmetros, enquanto a segunda parte aborda a interpretaรงรฃo do modelo.

Etapa 1) Importe os dados

Neste tutorial do Scikit-learn, vocรช usarรก o conjunto de dados do censo de adultos.

O arquivo รฉ lido diretamente do Repositรณrio de Aprendizado de Mรกquina da UCI no cรณdigo abaixo, portanto, nenhum download manual รฉ necessรกrio. Se vocรช estiver interessado em estatรญsticas descritivas, vale a pena conferir as ferramentas Dive e Overview. Consulte Neste tutorial Para saber mais sobre Mergulho e Visรฃo Geral.

Vocรช importa o conjunto de dados com o pandas. Observe que รฉ necessรกrio converter as variรกveis โ€‹โ€‹contรญnuas para o formato float.

Este conjunto de dados inclui oito variรกveis โ€‹โ€‹categรณricas, listadas em CATE_FEATURES:

  • classe de trabalho
  • educaรงรฃo
  • marital
  • ocupaรงรฃo
  • relacionamento
  • raรงa
  • sexo
  • paรญs nativo

Inclui tambรฉm seis variรกveis โ€‹โ€‹contรญnuas, listadas em CONTI_FEATURES:

  • idade
  • fnlwgt
  • nรบmero_educaรงรฃo
  • Ganho de capital
  • perda_capital
  • horas_semana

As listas sรฃo preenchidas manualmente para que vocรช tenha uma ideia mais clara de quais colunas estรฃo em jogo. Uma maneira mais rรกpida de criar uma lista de colunas categรณricas ou contรญnuas รฉ:

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

Aqui estรก o cรณdigo para importar os dados:

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

Chamar a funรงรฃo describe() no frame retorna as estatรญsticas resumidas para as seis colunas contรญnuas:

idade fnlwgt nรบmero_educaรงรฃo Ganho de capital perda_capital horas_semana
contar 32561.000000 3.256100e + 04 32561.000000 32561.000000 32561.000000 32561.000000
significar 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
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

Vocรช pode verificar a quantidade de valores รบnicos da variรกvel `native_country`. Apenas uma famรญlia รฉ da Holanda (Paรญses Baixos). Essa famรญlia nรฃo traz nenhuma informaรงรฃo e causarรก um erro durante o treinamento.

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

Vocรช pode excluir esta linha sem informaรงรตes do conjunto de dados:

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

A seguir, vocรช armazena a posiรงรฃo dos recursos contรญnuos em uma lista. Vocรช precisarรก dele na prรณxima etapa para construir o pipeline.

O cรณdigo abaixo percorre todos os nomes de coluna em CONTI_FEATURES, lรช cada localizaรงรฃo (ou seja, seu nรบmero de coluna) e a adiciona a uma lista chamada 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]

O bloco seguinte realiza a mesma funรงรฃo para as variรกveis โ€‹โ€‹categรณricas.

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

Agora, observe o prรณprio conjunto de dados. Cada variรกvel categรณrica รฉ uma string, e um modelo nรฃo pode receber um valor de string, portanto, o conjunto de dados precisa ser transformado com variรกveis โ€‹โ€‹dummy.

df_train.head(5)

Na verdade, vocรช precisa de uma coluna para cada grupo em cada recurso. Primeiro, execute o cรณdigo abaixo para calcular o nรบmero total de colunas necessรกrias.

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

O conjunto de dados completo contรฉm 101 grupos, conforme mostrado acima. A variรกvel `workclass` sozinha possui nove grupos. Vocรช pode listar os nomes dos grupos com o cรณdigo abaixo; `unique()` retorna os valores distintos de cada variรกvel categรณrica.

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

O conjunto de dados de treinamento conterรก, portanto, 101 + 6 colunas: os grupos one-hot mais as seis caracterรญsticas contรญnuas.

O Scikit-learn pode cuidar da conversรฃo em duas etapas:

  1. Converta a string em um ID. "State-gov" torna-se ID 1, "Self-emp-not-inc" torna-se ID 2 e assim por diante. O LabelEncoder faz isso para vocรช.
  2. Transponha cada ID para uma nova coluna. O conjunto de dados possui 101 IDs de grupo, portanto haverรก 101 colunas, uma para cada grupo de caracterรญsticas categรณricas. O Scikit-learn fornece o OneHotEncoder para essa operaรงรฃo.

Etapa 2) Crie o conjunto de treinamento/teste

Agora que o conjunto de dados estรก pronto, divida-o em 80/20: 80% para o conjunto de treinamento e 20% para o conjunto de teste.

Vocรช pode usar a funรงรฃo `train_test_split`. O primeiro argumento รฉ o dataframe de recursos e o segundo รฉ o rรณtulo. Vocรช define o tamanho do conjunto de teste com `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)

Etapa 3) Construir o pipeline

O pipeline facilita a alimentaรงรฃo do modelo com dados consistentes. A ideia รฉ processar os dados brutos atravรฉs de um objeto que executa todas as operaรงรตes em sequรชncia.

Com esse conjunto de dados, vocรช precisa padronizar as variรกveis โ€‹โ€‹contรญnuas e converter as categรณricas. Qualquer operaรงรฃo pode ser realizada dentro de um pipeline: valores ausentes podem ser substituรญdos pela mรฉdia ou mediana, e novas variรกveis โ€‹โ€‹podem ser criadas.

Vocรช tem uma escolha: codificar os dois processos diretamente no cรณdigo ou criar um pipeline. A codificaรงรฃo direta pode vazar dados de teste para as estatรญsticas ajustadas e criar inconsistรชncias ao longo do tempo, portanto, o pipeline รฉ a melhor opรงรฃo.

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

O pipeline executa duas operaรงรตes antes de alimentar o classificador logรญstico:

  1. Padronizar a variรกvel: StandardScaler()
  2. Converta os recursos categรณricos: OneHotEncoder(sparse=False)

Vocรช executa ambas as etapas com `make_column_transformer`. Quando este guia foi escrito, a funรงรฃo nรฃo estava presente na versรฃo lanรงada do scikit-learn (0.19), motivo pelo qual foi utilizada a versรฃo de desenvolvimento; ela estรก incluรญda em todas as versรตes estรกveis โ€‹โ€‹desde a 0.20.

A funรงรฃo `make_column_transformer` รฉ simples: vocรช declara quais colunas transformar e qual transformaรงรฃo aplicar. Para padronizar as feiรงรตes contรญnuas, vocรช passa:

  • conti_features, StandardScaler() dentro de make_column_transformer
    • conti_features: a lista de colunas contรญnuas
    • StandardScaler: padroniza essas colunas

O objeto OneHotEncoder dentro de make_column_transformer codifica os rรณtulos automaticamente.

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

Nota de versรฃo: Dois argumentos no bloco acima foram movidos. As versรตes atuais esperam o transformador primeiro e as colunas em segundo lugar, e escasso foi renomeado saรญda esparsa presente no scikit-learn 1.2 e removido na versรฃo 1.4, portanto o cรณdigo mais recente lรช OneHotEncoder(sparse_output=False).

Vocรช pode testar se o pipeline funciona com fit_transform. A saรญda deve ter o formato 26048, 107.

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

O transformador de dados estรก pronto. Vocรช cria o pipeline com make_pipeline e, uma vez que os dados estejam transformados, alimenta a regressรฃo logรญstica.

model = make_pipeline(
    preprocess,
    LogisticRegression())

Treinar um modelo com scikit-learn รฉ trivial: basta chamar o mรฉtodo `fit` no pipeline. Vocรช pode imprimir a acurรกcia com o mรฉtodo `score`.

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

Por fim, vocรช pode prever as classes com `predict_proba`, que retorna a probabilidade de cada classe. Observe que a soma das duas probabilidades รฉ igual a um.

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

Etapa 4) Usando nosso pipeline em uma pesquisa em grade

Ajustar os hiperparรขmetros, os valores que definem a estrutura do modelo, pode ser tedioso e exaustivo.

Uma forma de avaliar o modelo seria alterar o tamanho do conjunto de treinamento e medir o desempenho, repetindo o exercรญcio dez vezes para observar a dispersรฃo da pontuaรงรฃo. Isso requer muito trabalho manual.

Em vez disso, o scikit-learn fornece funรงรตes que realizam o ajuste de parรขmetros e a validaรงรฃo cruzada para vocรช.

Validaรงรฃo cruzada

A validaรงรฃo cruzada significa que, durante o treinamento, o conjunto de treinamento รฉ dividido n vezes em partes (folds) e o modelo รฉ avaliado n vezes. Se `cv` for definido como 10, o modelo serรก treinado e avaliado dez vezes. Em cada rodada, o classificador รฉ treinado em nove partes escolhidas aleatoriamente e a dรฉcima parte รฉ mantida para avaliaรงรฃo.

Pesquisa de grade

Todo classificador possui hiperparรขmetros que podem ser ajustados. Vocรช pode testar valores individualmente ou definir uma grade de parรขmetros. A documentaรงรฃo do scikit-learn lista todos os parรขmetros aceitos pelo classificador logรญstico. Para manter o treinamento rรกpido, este exemplo ajusta apenas o parรขmetro C, que controla a regularizaรงรฃo. Ele deve ser positivo, e um valor pequeno dรก mais peso ao regularizador.

Vocรช usa o objeto GridSearchCV, que recebe um dicionรกrio com os hiperparรขmetros a serem ajustados. Liste cada hiperparรขmetro seguido pelos valores que deseja testar. Para ajustar C, vocรช escreve:

  • 'logisticregression__C': [0.001, 0.01, 0.1, 1.0] โ€” o nome do parรขmetro รฉ precedido pelo nome do classificador em minรบsculas e dois sublinhados.

O modelo testarรก quatro valores diferentes: 0.001, 0.01, 0.1 e 1. Ele รฉ treinado com 10 folds, ou seja, cv=10.

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

Agora vocรช pode treinar o modelo usando o GridSearchCV com os parรขmetros grid e cv.

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

Saรญda:

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)

Nota de versรฃo: da Eu iria O argumento visรญvel nesta saรญda foi descontinuado no scikit-learn 0.22 e removido na versรฃo 0.24, portanto, deve ser simplesmente removido da chamada GridSearchCV nas versรตes atuais.

Para acessar os melhores parรขmetros, vocรช usa best_params_.

grid_clf.best_params_

Saรญda:

{'logisticregression__C': 1.0}

Apรณs treinar o modelo com quatro valores de regularizaรงรฃo diferentes, o parรขmetro ideal รฉ:

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

melhor regressรฃo logรญstica da pesquisa em grade: 0.850891

Para acessar as probabilidades previstas:

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

Modelo XGBoost com scikit-learn

Agora, experimente um dos classificadores mais poderosos do mercado. O XGBoost รฉ um aprimoramento do Random Forest baseado em gradient boosting. Seus fundamentos teรณricos estรฃo fora do escopo deste texto. Python Tutorial do Scikit-learn, mas lembre-se de que o XGBoost jรก ganhou diversas competiรงรตes no Kaggle. Em um conjunto de dados de tamanho mรฉdio, ele pode ter um desempenho tรฃo bom quanto, ou atรฉ melhor, do que um algoritmo de aprendizado profundo.

O classificador รฉ difรญcil de treinar porque expรตe um grande nรบmero de parรขmetros. Vocรช pode, รฉ claro, usar o GridSearchCV para escolhรช-los para vocรช.

Uma opรงรฃo melhor aqui รฉ o RandomizedSearchCV. O GridSearchCV fica lento quando a grade รฉ grande, porque o espaรงo de busca cresce a cada parรขmetro adicionado. O RandomizedSearchCV, por sua vez, amostra os valores de cada hiperparรขmetro aleatoriamente em cada iteraรงรฃo, de modo que 1,000 iteraรงรตes avaliam 1,000 combinaรงรตes. Fora isso, funciona de maneira muito semelhante ao GridSearchCV.

Vocรช precisa importar o xgboost. Se a biblioteca nรฃo estiver instalada, execute `pip3 install xgboost` ou instale-a a partir de um arquivo de configuraรงรฃo. Jupyter caderno com:

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

Em seguida, importe o classificador e os dois auxiliares de pesquisa:

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

A prรณxima etapa neste Scikit Python O objetivo deste tutorial รฉ especificar os parรขmetros a serem ajustados. A documentaรงรฃo oficial do XGBoost lista todos eles. Para os fins deste tutorial, vamos nos concentrar em... Python No tutorial do Sklearn, vocรช escolhe apenas dois hiperparรขmetros com dois valores cada, porque o XGBoost leva muito tempo para treinar e cada ponto extra na grade aumenta o tempo de espera.

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

Em seguida, vocรช constrรณi um novo pipeline com o classificador XGBoost e 600 estimadores. O parรขmetro `n_estimators` รฉ ajustรกvel e um valor alto pode levar a sobreajuste (overfitting). Vocรช pode experimentar outros valores, mas esteja ciente de que isso pode levar horas. Todos os outros parรขmetros mantรชm seus valores padrรฃo.

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

Vocรช pode aprimorar a validaรงรฃo cruzada com o validador cruzado Stratified K-Folds. Aqui, apenas trรชs folds sรฃo usados โ€‹โ€‹para acelerar o cรกlculo, com alguma perda de qualidade; aumente esse nรบmero para 5 ou 10 em sua mรกquina para obter melhores resultados. O modelo รฉ treinado em quatro iteraรงรตes.

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)

A busca aleatรณria estรก pronta, entรฃo vocรช pode treinar o modelo.

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

Como vocรช pode ver, o XGBoost obteve uma pontuaรงรฃo melhor do que a regressรฃo logรญstica anterior.

print("Melhor parameter", random_search.best_params_)
print("best logistic regression from grid search: %f" % random_search.best_estimator_.score(X_test, y_test))
Melhor 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)

Crie DNN com MLPClassifier no scikit-learn

Por fim, vocรช pode treinar uma rede neural com o prรณprio scikit-learn. O mรฉtodo รฉ o mesmo que para qualquer outro classificador, e o estimador รฉ o MLPClassifier.

from sklearn.neural_network import MLPClassifier

A rede abaixo รฉ definida por:

  • Solucionador de Adam
  • funรงรฃo de ativaรงรฃo ReLU
  • Alfa = 0.0001
  • Tamanho do lote: 150
  • Duas camadas ocultas com 200 e 100 neurรดnios respectivamente
model_dnn = make_pipeline(
    preprocess,
    MLPClassifier(solver='adam',
                  alpha=0.0001,
                  activation='relu',
                    batch_size=150,
                    hidden_layer_sizes=(200, 100),
                    random_state=1))

Vocรช pode alterar o nรบmero de camadas para melhorar o modelo.

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

Pontuaรงรฃo de regressรฃo DNN: 0.821253

LIME: Confie no seu modelo

Agora que vocรช tem um bom modelo, precisa de uma maneira de confiar nele. Os algoritmos de aprendizado de mรกquina, especialmente florestas aleatรณrias e redes neurais, sรฃo conhecidos como modelos de caixa preta: eles funcionam, mas ninguรฉm consegue entender o porquรช.

Trรชs pesquisadores desenvolveram uma ferramenta que mostra como o computador chega a uma previsรฃo. O artigo deles รฉ โ€œPor que eu deveria confiar em vocรช?โ€E o algoritmo que eles publicaram se chama Local Interpretable Model-Agnostic Explanations (LIME).

Vejamos um exemplo. ร€s vezes, nรฃo sabemos se uma previsรฃo de aprendizado de mรกquina รฉ confiรกvel. Um mรฉdico nรฃo pode aceitar um diagnรณstico simplesmente porque foi produzido por um computador, e รฉ preciso saber se um modelo รฉ confiรกvel antes de colocรก-lo em produรงรฃo.

Imagine poder ver por que qualquer classificador fez uma previsรฃo, mesmo para modelos tรฃo complexos quanto redes neurais, florestas aleatรณrias ou SVMs com um kernel arbitrรกrio. Fica muito mais fรกcil confiar em uma previsรฃo quando os motivos por trรกs dela sรฃo visรญveis, e igualmente mais fรกcil decidir quando um modelo nรฃo รฉ confiรกvel. O LIME mostra quais recursos influenciaram a decisรฃo do classificador.

Preparaรงรฃo de dados

Hรก algumas coisas que vocรช precisa alterar para executar o LIME com PythonPrimeiro, instale o lime no terminal com o comando `pip install lime`.

O Lime utiliza um objeto LimeTabularExplainer para aproximar o modelo localmente. Este objeto requer:

  • um conjunto de dados em NumPy formato
  • O nome dos recursos: feature_names
  • O nome das classes: class_names
  • O รญndice da coluna dos recursos categรณricos: categorical_features
  • O nome do grupo para cada caracterรญstica categรณrica: nomes_categoriais

Crie o conjunto de treinamento NumPy.

Vocรช pode copiar e converter df_train do pandas para NumPy com muita facilidade.

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

Obtenha o nome da classe

O rรณtulo pode ser acessado atravรฉs de unique(). Vocรช deverรก ver:

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

Indexe as colunas de caracterรญsticas categรณricas.

Utilize o mรฉtodo que vocรช aprendeu anteriormente para obter o nome de cada grupo. Vocรช codifica o rรณtulo com LabelEncoder e repete a operaรงรฃo em cada atributo categรณrico.

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

Agora que o conjunto de dados estรก pronto, vocรช pode criar os diferentes conjuntos de dados mostrados nos exemplos do Scikit-learn abaixo. Os dados sรฃo transformados fora do pipeline para evitar erros com o LIME: o conjunto de treinamento passado para o LimeTabularExplainer deve ser um array NumPy sem strings, e o mรฉtodo acima jรก produziu um.

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)

Vocรช pode criar o pipeline com os parรขmetros ideais encontrados pelo 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))])

Vocรช receberรก um aviso. Ele explica que nรฃo รฉ necessรกrio criar um codificador de rรณtulos antes do pipeline. Se vocรช nรฃo estiver usando o LIME, o mรฉtodo da primeira parte deste tutorial de Machine Learning com Scikit-learn funciona bem. Caso contrรกrio, mantenha esta abordagem: primeiro crie um conjunto de dados codificado e, em seguida, aplique o codificador one-hot dentro do 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)

Antes de usar o LIME, crie um array NumPy contendo as caracterรญsticas das linhas classificadas incorretamente. Vocรช poderรก usar essa lista posteriormente para entender o que levou o classificador ao erro.

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)

Em seguida, vocรช cria uma funรงรฃo lambda que recupera a previsรฃo do modelo para novos dados. Vocรช precisarรก dela em breve.

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

Vocรช converte o dataframe do pandas em um array NumPy.

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)

Agora, escolha uma famรญlia aleatรณria do conjunto de teste e veja tanto a previsรฃo quanto o processo pelo qual o computador chegou a ela.

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

Vocรช pode usar o recurso de explicaรงรฃo com `explain_instance` para inspecionar o raciocรญnio por trรกs do modelo. O grรกfico gerado รฉ mostrado abaixo.

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

Grรกfico explicativo do LIME mostrando as contribuiรงรตes das caracterรญsticas para uma famรญlia prevista corretamente.

O classificador previu corretamente a situaรงรฃo desta famรญlia: a renda รฉ de fato superior a 50 mil.

O primeiro ponto a observar รฉ que o classificador nรฃo tem muita certeza de si mesmo. Ele prevรช uma renda acima de 50 mil com 64% de probabilidade, e esses 64% sรฃo influenciados por ganhos de capital e estado civil. A cor azul contribui negativamente para a classe positiva e a linha laranja, positivamente.

O classificador estรก hesitante porque o ganho de capital dessa famรญlia รฉ zero, enquanto o ganho de capital geralmente รฉ um bom indicador de riqueza. A famรญlia tambรฉm trabalha menos de 40 horas por semana. Idade, ocupaรงรฃo e sexo contribuem positivamente.

Se o estado civil fosse solteiro, o classificador teria previsto uma renda inferior a 50 mil (0.64 โ€“ 0.18 = 0.46).

Agora tente outra residรชncia, uma que foi classificada incorretamente. A tabela explicativa correspondente segue o cรณdigo.

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)

Quadro explicativo LIME para a famรญlia que o classificador rotulou incorretamente.

O classificador previu uma renda inferior a 50 mil, o que estรก errado. Essa famรญlia รฉ atรญpica: nรฃo teve ganho nem perda de capital, a pessoa รฉ divorciada, tem quase 60 anos e possui nรญvel de escolaridade superior a 12. Seguindo o padrรฃo geral, o classificador posicionou a renda familiar abaixo de 50 mil.

Experimente o LIME vocรช mesmo e perceberรก diversos erros grosseiros do classificador. O repositรณrio GitHub do autor da biblioteca contรฉm documentaรงรฃo adicional para classificaรงรฃo de imagens e textos.

Referรชncia de comandos do Scikit-learn

A seguir, uma lista de comandos รบteis que se aplicam ao scikit-learn versรฃo 0.20 e posteriores.

Tarefa Funรงรฃo ou classe
Crie o conjunto de dados de treino/teste. treinar_teste_split
Construir um pipeline
Selecione as colunas e aplique a transformaรงรฃo. make_column_transformer
Tipo de transformaรงรฃo
Padronizar StandardScaler
Escala mรญn-mรกx MinMax Scaler
Normalizar Normalizador
Imputar valores ausentes SimplesImputador
Converter categรณrico OneHotEncoder
Ajuste e transforme os dados ajuste_transform
Faรงa o pipeline make_pipeline
Modelo bรกsico
Regressรฃo logรญstica LogรญsticaRegressรฃo
XGBoostName Classificador XGB
Rede neural Classificador MLP
Pesquisa de grade GradeSearchCV
Pesquisa aleatรณria CV de pesquisa randomizado

Perguntas Frequentes

Instale a versรฃo estรกvel atual com `pip install -U scikit-learn` ou `conda install -c conda-forge scikit-learn`. A versรฃo de desenvolvimento usada nas etapas acima sรณ era necessรกria em 2018, quando `make_column_transformer` ainda nรฃo havia sido lanรงada; agora ela รฉ distribuรญda em todas as versรตes estรกveis.

A funรงรฃo `fit` aprende parรขmetros como a mรฉdia e o desvio padrรฃo de uma coluna. A funรงรฃo `transform` aplica esses parรขmetros aos dados. A funรงรฃo `fit_transform` realiza ambas as aรงรตes em uma รบnica chamada e deve sempre modificar o conjunto de treinamento, nunca o conjunto de teste reservado.

Ajustar um scaler ou encoder ao conjunto de dados completo permite que as estatรญsticas do conjunto de teste cheguem ao modelo. Um pipeline reajusta cada transformer dentro de cada dobra de validaรงรฃo cruzada, de modo que as linhas reservadas permaneรงam invisรญveis atรฉ o momento em que sรฃo pontuadas.

Ele completa automaticamente formas familiares: blocos ColumnTransformer, grades de parรขmetros e os nomes com sublinhado duplo que o GridSearchCV espera. RevVeja qualquer coisa que seja sensรญvel ร  versรฃo, porque as sugestรตes geralmente reproduzem nomes de argumentos antigos, como sparse em vez de sparse_output.

Nรฃo totalmente. As ferramentas de busca automatizadas exploram uma grade mais rapidamente e descartam candidatos fracos, mas vocรช ainda escolhe o espaรงo de busca, a mรฉtrica de pontuaรงรฃo e o esquema de validaรงรฃo cruzada. Essas decisรตes importam mais do que o prรณprio algoritmo de busca.

Nรฃo. O treinamento รฉ executado na CPU e paralelizado entre os nรบcleos por meio de n_jobs. Uma camada experimental da API Array permite que um conjunto limitado de estimadores aceite arrays de GPU, mas TensorFlow e estruturas semelhantes continuam sendo a opรงรฃo de GPU.

Sim. Chame `set_output(transform=โ€pandasโ€)` em um transformador ou em um pipeline inteiro e o resultado manterรก os nomes das colunas em vez de retornar um objeto vazio. NumPy matriz, o que torna a inspeรงรฃo da saรญda do ColumnTransformer muito mais fรกcil.

Passe `class_weight=โ€balancedโ€` para os estimadores que o aceitam, faรงa a reamostragem com uma biblioteca complementar como `balanced-learn` e pontue com precisรฃo, recall ou a mรฉtrica F1 em vez de apenas acurรกcia.

Resuma esta postagem com: