Classificação binária do TensorFlow: exemplo de classificador linear

⚡ Resumo Inteligente

Classificadores lineares atribuem cada observação a uma classe com base na soma ponderada de suas características. Este tutorial constrói um classificador binário em TensorFlow no conjunto de dados do censo e aumenta a precisão de 0.76 para 0.84.

  • 🔘 Definição principal: Um classificador linear prevê uma classe discreta a partir de uma combinação linear de valores de características.
  • ☑️ Etapa de probabilidade: A função logística converte a saída do modelo linear em uma probabilidade entre 0 e 1.
  • Métricas são importantes: A acurácia por si só pode induzir a erros em rótulos desbalanceados, portanto, combine-a com a matriz de confusão, a precisão e a revocação.
  • 🧪 Guia passo a passo do censo: Seis colunas contínuas e oito categóricas se transformam em tensores antes mesmo de o estimador as visualizar.
  • 🛠️ Engenharia de recursos: Elevar a idade ao quadrado, agrupá-la em categorias e, em seguida, cruzar a escolaridade com a ocupação aumenta a precisão de 0.7616 para 0.8358.
  • 📈 Regularização: Um otimizador Ftrl com L1 em ​​0.9 e L2 em 5 ajusta a precisão final para 0.8383.

Classificador Linear de Classificação Binária do TensorFlow

Os dois mais comuns aprendizagem supervisionada as tarefas são regressão linear e classificador linear. A regressão linear prevê um valor enquanto o classificador linear prevê uma classe. Este tutorial é focado em Classificadores Lineares.

O que é classificador linear?

A Classificador Linear em Machine Learning é um método para encontrar a classe de um objeto com base em suas características para classificação estatística. Toma decisões de classificação com base no valor de uma combinação linear de características de um objeto. O classificador linear é usado em problemas práticos como classificação de documentos e problemas com muitas variáveis.

Os problemas de classificação representam cerca de 80% da tarefa de aprendizado de máquina. A classificação visa prever a probabilidade de cada classe dado um conjunto de entradas. O rótulo (ou seja, a variável dependente) é um valor discreto, denominado classe.

  1. Se o rótulo tiver apenas duas classes, o algoritmo de aprendizagem é um Classificador Binário.
  2. O classificador multiclasse aborda rótulos com mais de duas classes.

Por exemplo, um problema típico de classificação binária é prever a probabilidade de um cliente fazer uma segunda compra. Prever o tipo de animal exibido em uma imagem é um problema de classificação multiclasse, uma vez que existem mais de duas variedades de animais.

A parte teórica deste tutorial coloca o foco principal na classe binária. Você aprenderá mais sobre a função de saída multiclasse em um tutorial futuro.

Com a definição estabelecida, o próximo passo é ver como o algoritmo transforma as características brutas em uma decisão de classe.

Como funciona o classificador binário?

Você aprendeu no tutorial anterior que uma função é composta por dois tipos de variáveis, uma variável dependente e um conjunto de recursos (variáveis ​​independentes). Na regressão linear, uma variável dependente é um número real sem intervalo. O objetivo principal é prever seu valor minimizando o erro quadrático médio.

Para TensorFlow Em um classificador binário, o rótulo pode ter dois valores inteiros possíveis. Na maioria dos casos, é [0,1] ou [1,2]. Por exemplo, o objetivo é prever se um cliente comprará um produto ou não. O rótulo é definido da seguinte forma:

  • Y = 1 (o cliente comprou o produto)
  • Y = 0 (o cliente não compra o produto)

O modelo utiliza as características X para classificar cada cliente na classe mais provável a que ele pertence, ou seja, potencial comprador ou não.

A probabilidade de sucesso é calculada com regressão logística. O algoritmo calculará uma probabilidade com base no recurso X e prevê um sucesso quando essa probabilidade estiver acima de 50 por cento. Mais formalmente, a probabilidade é calculada conforme mostrado no exemplo de classificação binária do TensorFlow abaixo:

Fórmula de probabilidade sigmoide usada por um classificador binário do TensorFlow

onde 0 é o conjunto de pesos, os recursos eb o viés.

A função pode ser decomposta em duas partes:

  • O modelo linear
  • A função logística

Modelo linear

Você já está familiarizado com a forma como os pesos são calculados. Os pesos são calculados usando um produto escalar:Produto escalar do vetor de pesos e do vetor de características. Y é uma função linear de todos os recursos xi. Se o modelo não possuir características, a previsão é igual ao viés, b.

Os pesos indicam a direção da correlação entre os recursos xi e o rótulo y. Uma correlação positiva aumenta a probabilidade da classe positiva, enquanto uma correlação negativa aproxima a probabilidade de 0 (ou seja, classe negativa).

O modelo linear retorna apenas números reais, o que é inconsistente com a medida de probabilidade do intervalo [0,1]. A função logística é necessária para converter a saída do modelo linear em uma probabilidade,

Função logística

A função logística, ou função sigmóide, tem formato de S e a saída desta função está sempre entre 0 e 1.

A fórmula abaixo descreve a transformação, e o gráfico que se segue mostra a curva resultante achatando-se em direção a 0 à esquerda e em direção a 1 à direita.

Fórmula da função logística que mapeia uma pontuação linear para uma probabilidade.

Curva sigmoide em forma de S limitada entre 0 e 1
Exemplo de função logística

É fácil substituir a saída da regressão linear na função sigmóide. Isso resulta em um novo número com probabilidade entre 0 e 1.

O classificador pode transformar a probabilidade em uma classe

  • Valores entre 0 e 0.49 passam a ser classe 0
  • Valores entre 0.5 e 1 passam a ser classe 1

Uma vez que o modelo produza classes, você precisa de uma maneira de avaliar se essas classes são boas.

Como medir o desempenho do classificador linear?

Precisão

O desempenho geral de um classificador é medido com a métrica de precisão. A precisão coleta todos os valores corretos divididos pelo número total de observações. Por exemplo, um valor de precisão de 80% significa que o modelo está correto em 80% dos casos.

A fórmula de precisão contabiliza as previsões corretas em relação ao total de observações.

Meça o desempenho do Classificador Linear usando a métrica de Precisão

Você pode notar uma deficiência nessa métrica, especialmente para a classe de desequilíbrio. Um conjunto de dados de desequilíbrio ocorre quando o número de observações por grupo não é igual. Digamos; você tenta classificar um evento raro com uma função logística. Imagine que o classificador tente estimar a morte de um paciente após uma doença. Nos dados, 5% dos pacientes falecem. Você pode treinar um classificador para prever o número de mortes e usar a métrica de precisão para avaliar o desempenho. Se o classificador prever 0 morte para todo o conjunto de dados, estará correto em 95% dos casos.

Matriz de confusão

A melhor maneira de avaliar o desempenho de um classificador é observar a matriz de confusão.

Matriz de confusão binária mostrando os quadrados TP, FP, FN e TN.

Meça o desempenho do Classificador Linear usando a matriz de confusão

O matriz de confusão visualiza a precisão de um classificador comparando as classes reais e previstas, conforme mostrado no exemplo do Classificador Linear acima. A matriz de confusão binária é composta por quadrados:

  • TP: Verdadeiro Positivo: Valores previstos corretamente como positivos reais
  • FP: Os valores previstos previram incorretamente um positivo real. ou seja, valores negativos previstos como positivos
  • FN: Falso Negativo: Valores positivos previstos como negativos
  • TN: Verdadeiro Negativo: Valores previstos corretamente como negativos reais

A partir da matriz de confusão, é fácil comparar a classe real e a classe prevista.

Precisão e Sensibilidade

A matriz de confusão fornece uma boa visão do verdadeiro positivo e do falso positivo. Em alguns casos, é preferível ter uma métrica mais concisa.

Precisão

A métrica de precisão mostra a precisão da classe positiva. Ele mede a probabilidade de a previsão da classe positiva estar correta.

Fórmula de precisão: verdadeiros positivos em relação aos positivos previstos.

A pontuação máxima é 1 quando o classificador classifica perfeitamente todos os valores positivos. A precisão por si só não é muito útil porque ignora a classe negativa. A métrica geralmente é combinada com a métrica Recall. A recuperação também é chamada de sensibilidade ou taxa de verdadeiro positivo.

à Taxa de juros

A sensibilidade calcula a proporção de classes positivas detectadas corretamente. Essa métrica mostra o quão bom o modelo é para reconhecer uma classe positiva.

Fórmula de sensibilidade: verdadeiros positivos em relação aos positivos reais.

A teoria já está estabelecida, então o restante deste passo a passo a aplica de ponta a ponta no código.

Classificador Linear com TensorFlow

Para este tutorial, usaremos o conjunto de dados do censo. O objetivo é usar as variáveis ​​do conjunto de dados do censo para prever o nível de renda. Observe que a renda é uma variável binária

  • com valor 1 se a renda > 50k
  • 0 se renda < 50k.

Esta variável é o seu rótulo

Este conjunto de dados inclui oito variáveis ​​categóricas:

  • local de trabalho
  • educação
  • marital
  • ocupação
  • relacionamento
  • raça
  • sexo
  • país nativo

além disso, seis variáveis ​​contínuas:

  • idade
  • fnlwgt
  • número_educação
  • Ganho de capital
  • perda_capital
  • horas_semana

Por meio deste exemplo de classificação do TensorFlow, você entenderá como treinar classificadores lineares do TensorFlow com o estimador do TensorFlow e como melhorar a métrica de precisão.

Nota de versão: O código abaixo utiliza a API Estimator do TensorFlow 1.x. tf-estimator O pacote foi lançado em sua versão final com o TensorFlow 2.15 e não está disponível no TensorFlow 2.16 ou posterior. Portanto, execute esses trechos de código no TensorFlow 1.x ou utilize a versão oficial. guia de migração de estimador pré-definidoOs conceitos, a engenharia de funcionalidades e as métricas permanecem os mesmos.

Procederemos da seguinte forma:

  • Etapa 1) Importe os dados
  • Etapa 2) Conversão de dados
  • Etapa 3) Treine o classificador
  • Etapa 4) Melhorar o modelo
  • Etapa 5) Hiperparâmetro: Lasso e Ridge

Etapa 1) Importe os dados

Primeiro você importa as bibliotecas usadas durante o tutorial.

import tensorflow as tf
import pandas as pd

A seguir, você importa os dados do arquivo UCI e define os nomes das colunas. Você usará COLUMNS para nomear as colunas em um quadro de dados do pandas.

Observe que você treinará o classificador usando um dataframe do Pandas.

## Define path data
COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital',
           'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
           'hours_week', 'native_country', 'label']
PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"
PATH_test = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test"

Os dados armazenados online já estão divididos entre um conjunto de treinamento e um conjunto de teste.

df_train = pd.read_csv(PATH, skipinitialspace=True, names = COLUMNS, index_col=False)
df_test = pd.read_csv(PATH_test,skiprows = 1, skipinitialspace=True, names = COLUMNS, index_col=False)

O conjunto de trem contém 32,561 observações e o conjunto de teste 16,281

print(df_train.shape, df_test.shape)
print(df_train.dtypes)
(32561, 15) (16281, 15)
age                int64
workclass         object
fnlwgt             int64
education         object
education_num      int64
marital           object
occupation        object
relationship      object
race              object
sex               object
capital_gain       int64
capital_loss       int64
hours_week         int64
native_country    object
label             object
dtype: object

O TensorFlow requer um valor booleano para treinar o classificador. Você precisa converter os valores de string para inteiro. O rótulo é armazenado como um objeto, porém, você precisa convertê-lo em um valor numérico. O código abaixo cria um dicionário com os valores a serem convertidos e itera sobre o item da coluna. Observe que você realiza essa operação duas vezes, uma para o conjunto de treinamento e outra para o conjunto de teste.

label = {'<=50K': 0,'>50K': 1}
df_train.label = [label[item] for item in df_train.label]
label_t = {'<=50K.': 0,'>50K.': 1}
df_test.label = [label_t[item] for item in df_test.label]

Nos dados de treinamento, há 24,720 rendimentos inferiores a 50 mil e 7841 superiores. A proporção é quase a mesma no conjunto de teste, portanto, aproximadamente 76% de ambas as divisões pertencem à classe negativa.

print(df_train["label"].value_counts())
### The model will be correct in atleast 70% of the case
print(df_test["label"].value_counts())
## Unbalanced label
print(df_train.dtypes)
0    24720
1     7841
Name: label, dtype: int64
0    12435
1     3846
Name: label, dtype: int64
age                int64
workclass         object
fnlwgt             int64
education         object
education_num      int64
marital           object
occupation        object
relationship      object
race              object
sex               object
capital_gain       int64
capital_loss       int64
hours_week         int64
native_country    object
label              int64
dtype: object

Etapa 2) Conversão de dados

Algumas etapas são necessárias antes de treinar um classificador linear com o TensorFlow. Você precisa preparar os recursos que serão incluídos no modelo. Na regressão de referência, você usará os dados originais sem aplicar nenhuma transformação, exatamente como um modelo. scikit-learn O pipeline começaria a partir de colunas brutas.

O estimador precisa ter uma lista de recursos para treinar o modelo. Conseqüentemente, os dados da coluna precisam ser convertidos em um tensor.

Uma boa prática é definir duas listas de recursos com base em seu tipo e depois passá-las em feature_columns do estimador.

Você começará convertendo recursos contínuos e, em seguida, definirá um intervalo com os dados categóricos.

Os recursos do conjunto de dados têm dois formatos:

  • Número inteiro
  • objeto

Cada recurso é listado nas próximas duas variáveis ​​de acordo com seus tipos.

## Add features to the bucket: 
### Define continuous list
CONTI_FEATURES  = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']
### Define the categorical list
CATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']

O feature_column é equipado com um objeto numeric_column para auxiliar na transformação das variáveis ​​​​contínuas em tensor. No código abaixo, você converte todas as variáveis ​​​​de CONTI_FEATURES em um tensor com valor numérico. Isso é obrigatório para construir o modelo. Todas as variáveis ​​independentes precisam ser convertidas no tipo adequado de tensor.

A seguir, apresentamos um código para que você possa ver o que está acontecendo por trás de `feature_column.numeric_column`. Imprimiremos o valor convertido para `age`. Isso é apenas para fins explicativos; portanto, não é necessário entender o código. Python código. Você pode consultar a documentação oficial para entender os códigos.

def print_transformation(feature = "age", continuous = True, size = 2): 
    #X = fc.numeric_column(feature)
    ## Create feature name
    feature_names = [
    feature]

    ## Create dict with the data
    d = dict(zip(feature_names, [df_train[feature]]))

    ## Convert age
    if continuous == True:
        c = tf.feature_column.numeric_column(feature)
        feature_columns = [c]
    else: 
        c = tf.feature_column.categorical_column_with_hash_bucket(feature, hash_bucket_size=size) 
        c_indicator = tf.feature_column.indicator_column(c)
        feature_columns = [c_indicator]
    
## Use input_layer to print the value
    input_layer = tf.feature_column.input_layer(
        features=d,
        feature_columns=feature_columns
        )
    ## Create lookup table
    zero = tf.constant(0, dtype=tf.float32)
    where = tf.not_equal(input_layer, zero)
    ## Return lookup tble
    indices = tf.where(where)
    values = tf.gather_nd(input_layer, indices)
    ## Initiate graph
    sess = tf.Session()
    ## Print value
    print(sess.run(input_layer))
print_transformation(feature = "age", continuous = True) 
[[39.]
 [50.]
 [38.]
 ...
 [58.]
 [22.]
 [52.]]

Os valores são exatamente iguais aos de df_train

continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]

De acordo com a documentação do TensorFlow, existem diferentes maneiras de converter dados categóricos. Se a lista de vocabulário de um recurso for conhecida e não possuir muitos valores, é possível criar a coluna categórica com categorical_column_with_vocabulary_list. Ele atribuirá um ID a todas as listas de vocabulário exclusivas.

Por exemplo, se um status de variável tiver três valores distintos:

  • Marido
  • Esposa
  • Individual

Então três ID serão atribuídos. Por exemplo, o Marido terá o ID 1, a Esposa o ID 2 e assim por diante.

Para fins ilustrativos, você pode usar este código para converter uma variável de objeto em uma coluna categórica no TensorFlow.

A variável `sex` pode ter apenas dois valores: masculino ou feminino. Ao converter a variável `sex`, o TensorFlow criará duas novas colunas, uma para masculino e outra para feminino. Se o valor de `sex` for igual a masculino, a nova coluna `male` terá o valor 1 e a coluna `female` terá o valor 0. Este exemplo é mostrado na tabela abaixo:

linhas sexo depois da transformação masculina feminina
1 masculina => 1 0
2 masculina => 1 0
3 feminina => 0 1

No fluxo tensor:

print_transformation(feature = "sex", continuous = False, size = 2)
[[1. 0.]
 [1. 0.]
 [1. 0.]
 ...
 [0. 1.]
 [1. 0.]
 [0. 1.]]

relationship = tf.feature_column.categorical_column_with_vocabulary_list(
    'relationship', [
        'Husband', 'Not-in-family', 'Wife', 'Own-child', 'Unmarried',
        'Other-relative'])

Abaixo, adicionamos Python código para imprimir a codificação. Novamente, você não precisa entender o código, o objetivo é ver a transformação

No entanto, uma maneira mais rápida de transformar os dados é usar o método `categorical_column_with_hash_bucket`. Alterar variáveis ​​de string em uma matriz esparsa será útil. Uma matriz esparsa é uma matriz composta principalmente por zeros. O método cuida de tudo. Você só precisa especificar o número de buckets e a coluna chave. O número de buckets é a quantidade máxima de grupos que o TensorFlow pode criar. A coluna chave é simplesmente o nome da coluna a ser convertida.

No código abaixo, você cria um loop sobre todos os recursos categóricos.

categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]

Etapa 3) Treine o Classificador

Atualmente, o TensorFlow fornece um estimador para regressão linear e classificação linear.

  • Regressão linear: LinearRegressor
  • Classificação linear: LinearClassifier

A sintaxe do classificador linear é a mesma do tutorial em regressão linear exceto por um argumento, n_class. Você precisa definir a coluna de recursos, o diretório do modelo e comparar com o regressor linear; você tem que definir o número da aula. Para uma regressão logit, o número de turmas é igual a 2.

O modelo calculará os pesos das colunas contidas em Continuous_features e categorical_features.

model = tf.estimator.LinearClassifier(
    n_classes = 2,
    model_dir="ongoing/train", 
    feature_columns=categorical_features+ continuous_features)

saída

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': 
<tensorflow.python.training.server_lib.ClusterSpec object at 0x181f24c898>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

Agora que o classificador está definido, você pode criar a função de entrada. O método é o mesmo do tutorial do regressor linear. Aqui, você usa um tamanho de lote de 128 e embaralha os dados.

FEATURES = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country']
LABEL= 'label'
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)

Você cria uma função com os argumentos exigidos pelo estimador linear, ou seja, número de épocas, número de lotes e embaralha o conjunto de dados ou nota. Já que você usa o Pandas método para passar os dados para o modelo, você precisa definir as variáveis ​​X como um quadro de dados do pandas. Observe que você percorre todos os dados armazenados em FEATURES.

Vamos treinar o modelo com o objeto model.train. Você usa a função definida anteriormente para alimentar o modelo com os valores apropriados. Observe que você definiu o tamanho do lote como 128 e o número de épocas como Nenhum. O modelo será treinado em mil etapas.

model.train(input_fn=get_input_fn(df_train, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
									 
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow: Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into ongoing/train/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 65.8282
INFO:tensorflow:loss = 52583.64, step = 101 (1.528 sec)
INFO:tensorflow:global_step/sec: 118.386
INFO:tensorflow:loss = 25203.816, step = 201 (0.837 sec)
INFO:tensorflow:global_step/sec: 110.542
INFO:tensorflow:loss = 54924.312, step = 301 (0.905 sec)
INFO:tensorflow:global_step/sec: 199.03
INFO:tensorflow:loss = 68509.31, step = 401 (0.502 sec)
INFO:tensorflow:global_step/sec: 167.488
INFO:tensorflow:loss = 9151.754, step = 501 (0.599 sec)
INFO:tensorflow:global_step/sec: 220.155
INFO:tensorflow:loss = 34576.06, step = 601 (0.453 sec)
INFO:tensorflow:global_step/sec: 199.016
INFO:tensorflow:loss = 36047.117, step = 701 (0.503 sec)
INFO:tensorflow:global_step/sec: 197.531
INFO:tensorflow:loss = 22608.148, step = 801 (0.505 sec)
INFO:tensorflow:global_step/sec: 208.479
INFO:tensorflow:loss = 22201.918, step = 901 (0.479 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train/model.ckpt.
INFO:tensorflow:Loss for final step: 5444.363.

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0x181f223630>

Observe que a perda diminuiu posteriormente durante as últimas 100 etapas, ou seja, de 901 para 1000.

A perda final após mil iterações é 5444. Você pode estimar seu modelo no conjunto de testes e ver o desempenho. Para avaliar o desempenho do seu modelo, você precisa usar o objetoavaliar. Você alimenta o modelo com o conjunto de testes e define o número de épocas como 1, ou seja, os dados irão para o modelo apenas uma vez.

model.evaluate(input_fn=get_input_fn(df_test, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
									  
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:22
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:23
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7615626, accuracy_baseline = 0.76377374, auc = 0.63300294, auc_precision_recall = 0.50891197, average_loss = 47.12155, global_step = 1000, label/mean = 0.23622628, loss = 5993.6406, precision = 0.49401596, prediction/mean = 0.18454961, recall = 0.38637546

{'accuracy': 0.7615626,
 'accuracy_baseline': 0.76377374,
 'auc': 0.63300294,
 'auc_precision_recall': 0.50891197,
 'average_loss': 47.12155,
 'global_step': 1000,
 'label/mean': 0.23622628,
 'loss': 5993.6406,
 'precision': 0.49401596,
 'prediction/mean': 0.18454961,
 'recall': 0.38637546}

O TensorFlow retorna todas as métricas que você aprendeu na parte teórica. Sem surpresa, a precisão é grande devido ao rótulo desequilibrado. Na verdade, o modelo tem um desempenho ligeiramente melhor do que uma estimativa aleatória. Imagine que o modelo preveja todas as famílias com renda inferior a 50 mil, então o modelo tem uma precisão de 70%. Em uma análise mais detalhada, você pode ver que a previsão e o recall são bastante baixos.

Etapa 4) Melhorar o modelo

Agora que você tem um modelo de benchmark, pode tentar melhorá-lo, ou seja, aumentar a precisão. No tutorial anterior, você aprendeu como melhorar o poder de predição com um termo de interação. Neste tutorial, você revisitará essa ideia adicionando um termo polinomial à regressão.

A regressão polinomial é fundamental quando há não linearidade nos dados. Existem duas maneiras de capturar a não linearidade nos dados.

  • Adicionar termo polinomial
  • Divida a variável contínua em uma variável categórica

Termo polinomial

Na imagem abaixo você pode ver o que é uma regressão polinomial. É uma equação com variáveis ​​X com potências diferentes. Uma regressão polinomial de segundo grau tem duas variáveis, X e X ao quadrado. Terceiro grau tem três variáveis, X, X2e X3

Equações de regressão polinomial de segundo e terceiro grau

O que é regressão polinomial

O gráfico acima mostra uma curva de segundo grau em função da equação subjacente. Abaixo, construímos um gráfico com duas variáveis, X e Y. É evidente que a relação não é linear. Se adicionarmos uma regressão linear, podemos ver que o modelo não consegue capturar o padrão (imagem à esquerda).

Agora, olhe para a imagem à esquerda da imagem abaixo, adicionamos cinco termos à regressão (ou seja, y=x+x2+x3+x4+x5. O modelo agora captura muito melhor o padrão. Este é o poder da regressão polinomial.

Ajuste linear versus ajuste polinomial de cinco termos no mesmo gráfico de dispersão

Voltemos ao nosso exemplo. A idade não está numa relação linear com a renda. A idade precoce pode ter um rendimento fixo próximo de zero porque as crianças ou os jovens não trabalham. Depois aumenta na idade activa e diminui durante a reforma. Normalmente é uma forma de U invertido. Uma maneira de capturar esse padrão é adicionar uma potência dois à regressão.

Vamos ver se isso aumenta a precisão.

Você precisa adicionar este novo recurso ao conjunto de dados e na lista de recursos contínuos.

Você adiciona a nova variável no conjunto de dados de treinamento e teste, por isso é mais conveniente escrever uma função.

def square_var(df_t, df_te, var_name = 'age'):
    df_t['new'] = df_t[var_name].pow(2) 
    df_te['new'] = df_te[var_name].pow(2) 
    return df_t, df_te

A função tem 3 argumentos:

  • df_t: define o conjunto de treinamento
  • df_te: define o conjunto de testes
  • var_name = 'age': Defina a variável a ser transformada

Você pode usar o objeto pow(2) para elevar ao quadrado a variável idade. Observe que a nova variável é chamada de 'new'

Agora que a função square_var foi escrita, você pode criar os novos conjuntos de dados.

df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')

Como você pode ver, o novo conjunto de dados possui mais um recurso.

print(df_train_new.shape, df_test_new.shape)			
(32561, 16) (16281, 16)

A variável quadrada é chamada de nova no conjunto de dados. Você precisa adicioná-lo à lista de recursos contínuos.

CONTI_FEATURES_NEW  = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week', 'new']
continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW]

Observação que você alterou o diretório do Gráfico. Você não pode treinar modelos diferentes no mesmo diretório. Isso significa que você precisa alterar o caminho do argumento model_dir. Caso contrário, o TensorFlow gerará um erro.

model_1 = tf.estimator.LinearClassifier(
    model_dir="ongoing/train1", 
    feature_columns=categorical_features+ continuous_features_new)
INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': 
<tensorflow.python.training.server_lib.ClusterSpec object at 0x1820f04b70>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
FEATURES_NEW = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country', 'new']
def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES_NEW}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)

Agora que o classificador foi projetado com o novo conjunto de dados, você pode treinar e avaliar o modelo.

model_1.train(input_fn=get_input_fn(df_train, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into ongoing/train1/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 81.487
INFO:tensorflow:loss = 70077.66, step = 101 (1.228 sec)
INFO:tensorflow:global_step/sec: 111.169
INFO:tensorflow:loss = 49522.082, step = 201 (0.899 sec)
INFO:tensorflow:global_step/sec: 128.91
INFO:tensorflow:loss = 107120.57, step = 301 (0.776 sec)
INFO:tensorflow:global_step/sec: 132.546
INFO:tensorflow:loss = 12814.152, step = 401 (0.755 sec)
INFO:tensorflow:global_step/sec: 162.194
INFO:tensorflow:loss = 19573.898, step = 501 (0.617 sec)
INFO:tensorflow:global_step/sec: 204.852
INFO:tensorflow:loss = 26381.986, step = 601 (0.488 sec)
INFO:tensorflow:global_step/sec: 188.923
INFO:tensorflow:loss = 23417.719, step = 701 (0.529 sec)
INFO:tensorflow:global_step/sec: 192.041
INFO:tensorflow:loss = 23946.049, step = 801 (0.521 sec)
INFO:tensorflow:global_step/sec: 197.025
INFO:tensorflow:loss = 3309.5786, step = 901 (0.507 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train1/model.ckpt.
INFO:tensorflow:Loss for final step: 28861.898.

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0x1820f04c88>
model_1.evaluate(input_fn=get_input_fn(df_test_new, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:37
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train1/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:39
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7944229, accuracy_baseline = 0.76377374, auc = 0.6093755, auc_precision_recall = 0.54885805, average_loss = 111.0046, global_step = 1000, label/mean = 0.23622628, loss = 14119.265, precision = 0.6682401, prediction/mean = 0.09116262, recall = 0.2576703

{'accuracy': 0.7944229,
 'accuracy_baseline': 0.76377374,
 'auc': 0.6093755,
 'auc_precision_recall': 0.54885805,
 'average_loss': 111.0046,
 'global_step': 1000,
 'label/mean': 0.23622628,
 'loss': 14119.265,
 'precision': 0.6682401,
 'prediction/mean': 0.09116262,
 'recall': 0.2576703}

A variável quadrada melhorou a precisão de 0.76 para 0.79. Vamos ver se você consegue fazer melhor combinando bucketização e termo de interação.

Bucketização e interação

Como você viu antes, um classificador linear é incapaz de capturar corretamente o padrão idade-renda. Isso ocorre porque ele aprende um único peso para cada recurso. Para tornar mais fácil para o classificador, uma coisa que você pode fazer é agrupar o recurso. O agrupamento transforma um recurso numérico em vários determinados com base no intervalo em que ele se enquadra, e cada um desses novos recursos indica se a idade de uma pessoa está dentro desse intervalo.

Com esses novos recursos, o modelo linear pode capturar o relacionamento aprendendo pesos diferentes para cada intervalo.

No TensorFlow, isso é feito com bucketized_column. Você precisa adicionar o intervalo de valores nos limites.

age = tf.feature_column.numeric_column('age')
age_buckets = tf.feature_column.bucketized_column(
    age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65])

Você já sabe que a idade não é linear com a renda. Outra forma de melhorar o modelo é por meio da interação. Nas palavras do TensorFlow, é cruzamento de recursos. O cruzamento de recursos é uma forma de criar novos recursos que são combinações de recursos existentes, o que pode ser útil para um classificador linear que não consegue modelar interações entre recursos.

Você pode dividir a idade com outro recurso, como a educação. Ou seja, alguns grupos provavelmente terão renda alta e outros baixa (pense no estudante de doutorado).

education_x_occupation = [tf.feature_column.crossed_column(
    ['education', 'occupation'], hash_bucket_size=1000)]
age_buckets_x_education_x_occupation = [tf.feature_column.crossed_column(
    [age_buckets, 'education', 'occupation'], hash_bucket_size=1000)]

Para criar uma coluna de características cruzadas, você usa cross_column com as variáveis ​​a serem cruzadas entre colchetes. O hash_bucket_size indica as possibilidades máximas de cruzamento. Para criar interação entre variáveis ​​(pelo menos uma variável precisa ser categórica), você pode usar tf.feature_column.crossed_column. Para usar este objeto, você precisa adicionar entre colchetes a variável para interagir e um segundo argumento, o tamanho do balde. O tamanho do bucket é o número máximo de grupos possível dentro de uma variável. Aqui você define como 1000 porque não sabe o número exato de grupos

age_buckets precisa ser elevado ao quadrado antes de adicioná-lo às colunas de recursos. Você também adiciona os novos recursos às colunas de recursos e prepara o estimador

base_columns = [
    age_buckets,
]

model_imp = tf.estimator.LinearClassifier(
    model_dir="ongoing/train3", 
    feature_columns=categorical_features+base_columns+education_x_occupation+age_buckets_x_education_x_occupation)

saída

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train3', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1823021be0>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
FEATURES_imp = ['age','workclass', 'education', 'education_num', 'marital',
                'occupation', 'relationship', 'race', 'sex', 'native_country', 'new']

def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):
    return tf.estimator.inputs.pandas_input_fn(
       x=pd.DataFrame({k: data_set[k].values for k in FEATURES_imp}),
       y = pd.Series(data_set[LABEL].values),
       batch_size=n_batch,   
       num_epochs=num_epochs,
       shuffle=shuffle)

Você está pronto para estimar o novo modelo e ver se ele melhora a precisão.

model_imp.train(input_fn=get_input_fn(df_train_new, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
									  
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into ongoing/train3/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 94.969
INFO:tensorflow:loss = 50.334488, step = 101 (1.054 sec)
INFO:tensorflow:global_step/sec: 242.342
INFO:tensorflow:loss = 56.153225, step = 201 (0.414 sec)
INFO:tensorflow:global_step/sec: 213.686
INFO:tensorflow:loss = 45.792007, step = 301 (0.470 sec)
INFO:tensorflow:global_step/sec: 174.084
INFO:tensorflow:loss = 37.485672, step = 401 (0.572 sec)
INFO:tensorflow:global_step/sec: 191.78
INFO:tensorflow:loss = 56.48449, step = 501 (0.524 sec)
INFO:tensorflow:global_step/sec: 163.436
INFO:tensorflow:loss = 32.528934, step = 601 (0.612 sec)
INFO:tensorflow:global_step/sec: 164.347
INFO:tensorflow:loss = 37.438057, step = 701 (0.607 sec)
INFO:tensorflow:global_step/sec: 154.274
INFO:tensorflow:loss = 61.1075, step = 801 (0.647 sec)
INFO:tensorflow:global_step/sec: 189.14
INFO:tensorflow:loss = 44.69645, step = 901 (0.531 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train3/model.ckpt.
INFO:tensorflow:Loss for final step: 44.18133.

<tensorflow.python.estimator.canned.linear.LinearClassifier at 0x1823021cf8>
model_imp.evaluate(input_fn=get_input_fn(df_test_new, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)
									  
INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:52
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train3/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:54
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.8358209, accuracy_baseline = 0.76377374, auc = 0.88401634, auc_precision_recall = 0.69599575, average_loss = 0.35122654, global_step = 1000, label/mean = 0.23622628, loss = 44.67437, precision = 0.68986726, prediction/mean = 0.23320661, recall = 0.55408216


{'accuracy': 0.8358209,
 'accuracy_baseline': 0.76377374,
 'auc': 0.88401634,
 'auc_precision_recall': 0.69599575,
 'average_loss': 0.35122654,
 'global_step': 1000,
 'label/mean': 0.23622628,
 'loss': 44.67437,
 'precision': 0.68986726,
 'prediction/mean': 0.23320661,
 'recall': 0.55408216}

O novo nível de precisão é de 83.58%. É quatro por cento maior que o modelo anterior.

Finalmente, você pode adicionar um termo de regularização para evitar overfitting.

Etapa 5) Hiperparâmetro: Lasso e Ridge

Seu modelo pode sofrer sobreajuste or insuficiente.

  • Overfitting: o modelo é incapaz de generalizar a previsão para novos dados
  • Underfitting: O modelo não consegue capturar o padrão dos dados. ou seja, regressão linear quando os dados são não lineares

Quando um modelo tem muitos parâmetros e uma quantidade relativamente baixa de dados, isso leva a previsões ruins. Imagine, um grupo tem apenas três observações; o modelo calculará um peso para este grupo. O peso é usado para fazer uma previsão; se as observações do conjunto de teste para este grupo específico forem totalmente diferentes do conjunto de treinamento, então o modelo fará uma previsão errada. Durante a avaliação com o conjunto de treinamento, a precisão é boa, mas não boa com o conjunto de teste porque os pesos calculados não são os verdadeiros para generalizar o padrão. Neste caso, não faz uma previsão razoável sobre dados não vistos.

Para evitar overfitting, a regularização oferece a possibilidade de controlar essa complexidade e torná-la mais generalizável. Existem duas técnicas de regularização:

  • L1: Laço
  • L2: Cume

No TensorFlow, você pode adicionar esses dois hiperparâmetros no otimizador. Por exemplo, quanto maior o hiperparâmetro L2, o peso tende a ser muito baixo e próximo de zero. A linha ajustada será muito plana, enquanto um L2 próximo de zero implica que os pesos estão próximos da regressão linear regular.

Você pode tentar sozinho os diferentes valores dos hiperparâmetros e ver se consegue aumentar o nível de precisão.

Observação que se você alterar o hiperparâmetro, será necessário excluir a pasta em andamento/train4 caso contrário o modelo iniciará com o modelo previamente treinado.

Vamos ver como está a precisão com o hype

model_regu = tf.estimator.LinearClassifier(
    model_dir="ongoing/train4", feature_columns=categorical_features+base_columns+education_x_occupation+age_buckets_x_education_x_occupation,
    optimizer=tf.train.FtrlOptimizer(
        learning_rate=0.1,
        l1_regularization_strength=0.9,
        l2_regularization_strength=5))

saída

INFO:tensorflow:Using default config.
INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train4', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec': <tensorflow.python.training.server_lib.ClusterSpec object at 0x1820d9c128>, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
model_regu.train(input_fn=get_input_fn(df_train_new, 
                                      num_epochs=None,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

saída

INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Create CheckpointSaverHook.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Saving checkpoints for 1 into ongoing/train4/model.ckpt.
INFO:tensorflow:loss = 88.722855, step = 1
INFO:tensorflow:global_step/sec: 77.4165
INFO:tensorflow:loss = 50.38778, step = 101 (1.294 sec)
INFO:tensorflow:global_step/sec: 187.889
INFO:tensorflow:loss = 55.38014, step = 201 (0.535 sec)
INFO:tensorflow:global_step/sec: 201.895
INFO:tensorflow:loss = 46.806694, step = 301 (0.491 sec)
INFO:tensorflow:global_step/sec: 217.992
INFO:tensorflow:loss = 38.68271, step = 401 (0.460 sec)
INFO:tensorflow:global_step/sec: 193.676
INFO:tensorflow:loss = 56.99398, step = 501 (0.516 sec)
INFO:tensorflow:global_step/sec: 202.195
INFO:tensorflow:loss = 33.263622, step = 601 (0.497 sec)
INFO:tensorflow:global_step/sec: 216.756
INFO:tensorflow:loss = 37.7902, step = 701 (0.459 sec)
INFO:tensorflow:global_step/sec: 240.215
INFO:tensorflow:loss = 61.732605, step = 801 (0.416 sec)
INFO:tensorflow:global_step/sec: 220.336
INFO:tensorflow:loss = 46.938225, step = 901 (0.456 sec)
INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train4/model.ckpt.
INFO:tensorflow:Loss for final step: 43.4942.


<tensorflow.python.estimator.canned.linear.LinearClassifier at 0x181ff39e48>
model_regu.evaluate(input_fn=get_input_fn(df_test_new, 
                                      num_epochs=1,
                                      n_batch = 128,
                                      shuffle=False),
                                      steps=1000)

saída

INFO:tensorflow:Calling model_fn.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Starting evaluation at 2018-06-02-08:29:07
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from ongoing/train4/model.ckpt-1000
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
INFO:tensorflow:Evaluation [100/1000]
INFO:tensorflow:Finished evaluation at 2018-06-02-08:29:09
INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.83833915, accuracy_baseline = 0.76377374, auc = 0.8869794, auc_precision_recall = 0.7014905, average_loss = 0.34691378, global_step = 1000, label/mean = 0.23622628, loss = 44.12581, precision = 0.69720596, prediction/mean = 0.23662092, recall = 0.5579823





{'accuracy': 0.83833915,
 'accuracy_baseline': 0.76377374,
 'auc': 0.8869794,
 'auc_precision_recall': 0.7014905,
 'average_loss': 0.34691378,
 'global_step': 1000,
 'label/mean': 0.23622628,
 'loss': 44.12581,
 'precision': 0.69720596,
 'prediction/mean': 0.23662092,
 'recall': 0.5579823}

Com esse hiperparâmetro, você aumenta ligeiramente as métricas de precisão. A tabela abaixo reúne todas as métricas relatadas pelas quatro chamadas de avaliação neste tutorial.

Modelo Conjunto de características Precisão AUC Precisão Recordar
modelo Linha de base contínua + categórica 0.7615626 0.63300294 0.49401596 0.38637546
modelo_1 Idade basal mais o quadrado 0.7944229 0.6093755 0.6682401 0.2576703
modelo_impac Idade categorizada em grupos mais colunas cruzadas 0.8358209 0.88401634 0.68986726 0.55408216
modelo_regu Colunas cruzadas mais L1 e L2 0.83833915 0.8869794 0.69720596 0.5579823

Note que a precisão básica de um modelo que sempre prevê a classe majoritária é de 0.76377374, portanto, apenas os dois últimos modelos superam uma estimativa trivial por uma margem útil.

No próximo tutorial, você aprenderá como aprimorar um classificador linear usando um método kernel.

Perguntas Frequentes

A regressão logística é um tipo de classificador linear. Ela ajusta uma pontuação linear e, em seguida, a comprime por meio de uma função sigmoide para retornar probabilidades calibradas. Outros classificadores lineares, como SVM linear ou perceptron, compartilham a mesma fronteira linear, mas otimizam uma função de perda diferente.

Uma SVM linear otimiza a perda de dobradiça e apenas os pontos de margem influenciam o limite, o que é útil em conjuntos de dados pequenos e ruidosos. A regressão logística treina mais rapidamente em conjuntos de dados muito grandes e retorna estimativas de probabilidade, que são importantes quando você precisa de um limiar de decisão ajustável.

Não. O pacote tf-estimator foi lançado em sua última versão junto com o TensorFlow 2.15 e está ausente a partir do TensorFlow 2.16. Execute este tutorial no TensorFlow 1.x ou migre o estimador padrão para um modelo linear do Keras usando o guia de migração oficial.

Bibliotecas de busca automatizada tratam L1, L2, a taxa de aprendizado e os limites dos buckets como um espaço de busca e, em seguida, usam otimização Bayesiana ou métodos de bandit para eliminar tentativas fracas logo no início. Isso substitui a varredura manual sugerida neste tutorial e geralmente encontra um par de regularização melhor.

O Copilot gera rapidamente código repetitivo para a coluna `feature_column`, incluindo compreensões de lista em colunas contínuas e blocos que cruzam colunas. Considere a saída como um primeiro rascunho — verifique cada nome de API em relação à versão que você está executando, pois o Copilot mistura as abordagens do TensorFlow 1.x e 2.x.

Define o número de categorias em que uma coluna categórica é agrupada por hash. Um valor muito pequeno força a colisão de categorias não relacionadas, fazendo com que compartilhem o mesmo peso; um valor muito grande desperdiça memória. Defina-o com um valor consideravelmente maior que a contagem de valores distintos, como este tutorial faz com 1000.

A inclusão do termo quadrático faz com que o modelo preveja a classe majoritária com mais confiança. A precisão sobe para 0.6682, enquanto a revocação cai para 0.2577, o que é a relação usual entre precisão e revocação em um conjunto de rótulos desbalanceados, e não devido a um erro de codificação.

Use um kernel quando não houver uma fronteira linear separando as classes, mesmo após o agrupamento e o cruzamento de características. Os kernels mapeiam os dados implicitamente para um espaço de dimensão superior, ao custo de um treinamento mais lento e uma interpretabilidade inferior à dos pesos lineares mostrados aqui.

Resuma esta postagem com: