As duas tarefas de aprendizagem supervisionada mais comuns são a regressão linear e o classificador linear. A regressão linear prevê um valor, enquanto o classificador linear prevê uma classe. Este tutorial é focado no Classificador Linear.
O que é classificador linear?
Um Classificador Linear em Aprendizado de Máquina é um método para localizar a classe de um objeto com base em suas características para classificação estatística. Ele toma a decisão 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, chamado de classe.
- Se o rótulo tiver apenas duas classes, o algoritmo de aprendizado é um classificador binário.
- O classificador multiclasse lida com 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.
Neste tutorial, você aprenderá
- O que é classificador linear?
- Como funciona o classificador binário?
- Como medir o desempenho do classificador linear?
- Precisão
- Matriz de confusão
- Precisão e Sensibilidade
- Classificador linear com TensorFlow
- Etapa 1) Importar os dados
- Etapa 2) Conversão de dados
- Etapa 3) Treine o Classificador
- Etapa 4) Melhorar o modelo
- Etapa 5) Hiperparâmetro: Lasso & Ridge
Como funciona o classificador binário?
Você aprendeu no tutorial anterior que uma função é composta de 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 o classificador binário TensorFlow, 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 os recursos X para classificar cada cliente na classe mais provável a que pertence, ou seja, comprador potencial 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:
onde 0 é o conjunto de pesos, os recursos e b 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: Y é uma função linear de todos os recursos x i . Se o modelo não possui recursos, a previsão é igual ao viés, b.
Os pesos indicam a direção da correlação entre os recursos x i e o rótulo y. Uma correlação positiva aumenta a probabilidade da classe positiva, enquanto uma correlação negativa leva a probabilidade para mais perto de 0, (ou seja, classe negativa).
O modelo linear retorna apenas o número real, o que é inconsistente com a medida de probabilidade de 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 uma forma de S e a saída dessa função está sempre entre 0 e 1.
É 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 tornam-se classe 0
- Valores entre 0,5 a 1 tornam-se classe 1
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 por cento significa que o modelo está correto em 80 por cento dos casos.
Você pode notar uma deficiência com esta 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 tenta estimar a morte de um paciente após uma doença. Nos dados, 5 por cento dos pacientes morrem. 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 prediz 0 óbito para todo o conjunto de dados, ele estará correto em 95 por cento dos casos.
Matriz de confusão
A melhor maneira de avaliar o desempenho de um classificador é examinar a matriz de confusão.
A 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 previstos 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 previstos como negativos reais
A partir da matriz de confusão, é fácil comparar a aula real e a aula 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 exatidão da classe positiva. Ele mede a probabilidade de a previsão da classe positiva estar correta.
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 é emparelhada com a métrica Recall. A recuperação também é chamada de sensibilidade ou taxa positiva verdadeira.
Sensibilidade
A sensibilidade calcula a proporção de classes positivas detectadas corretamente. Essa métrica mostra a qualidade do modelo em reconhecer uma classe positiva.
Classificador linear com TensorFlow
Para este tutorial, usaremos o conjunto de dados do censo. O objetivo é usar as variáveis no conjunto de dados do censo para prever o nível de renda. Observe que a renda é uma variável binária
- com um valor de 1 se a renda> 50k
- 0 se a renda for <50k.
Esta variável é o seu rótulo
Este conjunto de dados inclui oito variáveis categóricas:
- ambiente de trabalho
- Educação
- conjugal
- ocupação
- relação
- raça
- sexo
- país nativo
além disso, seis variáveis contínuas:
- idade
- fnlwgt
- educação_num
- Ganho de capital
- capital_loss
- horas_semana
Por meio deste exemplo de classificação do TensorFlow, você entenderá como treinar classificadores TensorFlow lineares com o estimador TensorFlow e como melhorar a métrica de precisão.
Vamos proceder da seguinte forma:
- Etapa 1) Importar os dados
- Etapa 2) Conversão de dados
- Etapa 3) Treine o classificador
- Etapa 4) Melhorar o modelo
- Etapa 5) Hiperparâmetro: Lasso & Ridge
Etapa 1) Importar os dados
Primeiro, você importa as bibliotecas usadas durante o tutorial.
import tensorflow as tfimport pandas as pd
Em seguida, você importa os dados do arquivo do UCI e define os nomes das colunas. Você usará COLUNAS para nomear as colunas em um quadro de dados do pandas.
Observe que você treinará o classificador usando um dataframe Pandas.
## Define path dataCOLUMNS = ['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 trem 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 int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel objectdtype: 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, no entanto, você precisa convertê-lo em um valor numérico. O código a seguir cria um dicionário com os valores para converter e fazer um loop sobre o item da coluna. Observe que você executa esta operação duas vezes, uma para o teste do trem, uma 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 do trem, há 24.720 rendas abaixo de 50 mil e 7.841 acima. A proporção é quase a mesma para o conjunto de teste. Consulte este tutorial sobre facetas para obter mais informações.
print(df_train["label"].value_counts())### The model will be correct in atleast 70% of the caseprint(df_test["label"].value_counts())## Unbalanced labelprint(df_train.dtypes)0 247201 7841Name: label, dtype: int640 124351 3846Name: label, dtype: int64age int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel int64dtype: object
Etapa 2) Conversão de dados
Algumas etapas são necessárias antes de treinar um classificador linear com Tensorflow. Você precisa preparar os recursos a serem incluídos no modelo. Na regressão do benchmark, você usará os dados originais sem aplicar qualquer transformação.
O estimador precisa ter uma lista de recursos para treinar o modelo. Portanto, 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, em seguida, passá-los nas 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:
- Inteiro
- Objeto
Cada recurso é listado nas próximas duas variáveis de acordo com seus tipos.
## Add features to the bucket:### Define continuous listCONTI_FEATURES = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']### Define the categorical listCATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']
O feature_column é equipado com um objeto numeric_column para ajudar na transformação das variáveis contínuas em tensores. 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 apropriado de tensor.
Abaixo, escrevemos um código para permitir que você veja o que está acontecendo por trás de feature_column.numeric_column. Iremos imprimir o valor convertido para idade. É para fins explicativos, portanto, não há necessidade de entender o código python. 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 namefeature_names = [feature]## Create dict with the datad = dict(zip(feature_names, [df_train[feature]]))## Convert ageif 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 valueinput_layer = tf.feature_column.input_layer(features=d,feature_columns=feature_columns)## Create lookup tablezero = tf.constant(0, dtype=tf.float32)where = tf.not_equal(input_layer, zero)## Return lookup tbleindices = tf.where(where)values = tf.gather_nd(input_layer, indices)## Initiate graphsess = tf.Session()## Print valueprint(sess.run(input_layer))print_transformation(feature = "age", continuous = True)[[39.][50.][38.]… [58.][22.][52.]]
Os valores são exatamente os mesmos 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 tiver muitos valores, é possível criar a coluna categórica com categorical_column_with_vocabulary_list. Ele atribuirá uma ID a todas as listas de vocabulário exclusivas.
Por exemplo, se um status de variável tiver três valores distintos:
- Esposo
- Esposa
- Solteiro
Em seguida, três IDs serão atribuídos. Por exemplo, o Marido terá o ID 1, a Esposa o ID 2 e assim por diante.
Para fins de ilustração, você pode usar este código para converter uma variável de objeto em uma coluna categórica no TensorFlow.
O recurso sexo só pode ter dois valores: masculino ou feminino. Quando convertermos o sexo do recurso, o Tensorflow criará 2 novas colunas, uma para masculino e outra para feminino. Se o sexo for igual a masculino, a nova coluna masculino será igual a 1 e feminino a 0. Este exemplo é exibido na tabela abaixo:
filas |
sexo |
depois da transformação |
Masculino |
fêmea |
1 |
Masculino |
=> |
1 |
0 |
2 |
Masculino |
=> |
1 |
0 |
3 |
fêmea |
=> |
0 |
1 |
Em tensorflow:
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 o código Python 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 com quase zero. O método cuida de tudo. Você só precisa especificar o número de baldes e a coluna-chave. O número de intervalos é 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 a seguir, 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
O TensorFlow atualmente fornece um estimador para a regressão linear e a classificação linear.
- Regressão linear: LinearRegressor
- Classificação linear: LinearClassifier
A sintaxe do classificador linear é a mesma do tutorial sobre regressão linear, exceto por um argumento, n_class. Você precisa definir a coluna do recurso, o diretório do modelo e, comparar com o regressor linear; você tem que definir o número da classe. Para uma regressão logit, se o número da classe é igual a 2.
O modelo calculará os pesos das colunas contidas em existing_features e categorical_features.
model = tf.estimator.LinearClassifier(n_classes = 2,model_dir="ongoing/train",feature_columns=categorical_features+ continuous_features)
RESULTADO:
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':, '_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. Como você usa o método Pandas para passar os dados para o modelo, é necessário definir as variáveis X como um quadro de dados do pandas. Observe que você faz um loop em 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 = 1INFO:tensorflow:global_step/sec: 65.8282INFO:tensorflow:loss = 52583.64, step = 101 (1.528 sec)INFO:tensorflow:global_step/sec: 118.386INFO:tensorflow:loss = 25203.816, step = 201 (0.837 sec)INFO:tensorflow:global_step/sec: 110.542INFO:tensorflow:loss = 54924.312, step = 301 (0.905 sec)INFO:tensorflow:global_step/sec: 199.03INFO:tensorflow:loss = 68509.31, step = 401 (0.502 sec)INFO:tensorflow:global_step/sec: 167.488INFO:tensorflow:loss = 9151.754, step = 501 (0.599 sec)INFO:tensorflow:global_step/sec: 220.155INFO:tensorflow:loss = 34576.06, step = 601 (0.453 sec)INFO:tensorflow:global_step/sec: 199.016INFO:tensorflow:loss = 36047.117, step = 701 (0.503 sec)INFO:tensorflow:global_step/sec: 197.531INFO:tensorflow:loss = 22608.148, step = 801 (0.505 sec)INFO:tensorflow:global_step/sec: 208.479INFO: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.
Observe que a perda diminuiu subsequentemente 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 teste e ver o desempenho. Para avaliar o desempenho do seu modelo, você precisa usar o objeto avaliar. Você alimenta o modelo com o conjunto de teste 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:22INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train/model.ckpt-1000INFO: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:23INFO: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 por cento. Em uma análise mais detalhada, você pode ver que a previsão e a recuperação são bastante baixas.
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 previsão com um termo de interação. Neste tutorial, você revisará essa ideia adicionando um termo polinomial à regressão.
A regressão polinomial é instrumental quando há não linearidade nos dados. Existem duas maneiras de capturar a não linearidade nos dados.
- Adicionar termo polinomial
- Bucketize 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 X variáveis com diferentes potências. Uma regressão polinomial de segundo grau tem duas variáveis, X e X ao quadrado. O terceiro grau tem três variáveis, X, X 2 e X 3
Abaixo, construímos um gráfico com duas variáveis, X e Y. É óbvio que a relação não é linear. Se adicionarmos uma regressão linear, podemos ver que o modelo é incapaz de capturar o padrão (imagem à esquerda).
Agora, olhe para a imagem à esquerda da imagem abaixo, adicionamos cinco termos à regressão (ou seja, y = x + x 2 + x 3 + x 4 + x 5. O modelo agora captura muito melhor o padrão. o poder da regressão polinomial.
Voltemos ao nosso exemplo. A idade não tem uma relação linear com a renda. A idade precoce pode ter uma renda fixa próxima de zero porque crianças ou jovens não trabalham. Em seguida, aumenta na idade produtiva e diminui durante a aposentadoria. É normalmente uma forma de U invertido. Uma maneira de capturar esse padrão é adicionando uma potência dois à regressão.
Vamos ver se 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 possui 3 argumentos:
- df_t: define o conjunto de treinamento
- df_te: define o conjunto de teste
- 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 'nova'
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 tem 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]
Observe que você alterou o diretório do Graph. Você não pode treinar modelos diferentes no mesmo diretório. Isso significa que você precisa alterar o caminho do argumento model_dir. Se você não fizer isso, 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':, '_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 = 1INFO:tensorflow:global_step/sec: 81.487INFO:tensorflow:loss = 70077.66, step = 101 (1.228 sec)INFO:tensorflow:global_step/sec: 111.169INFO:tensorflow:loss = 49522.082, step = 201 (0.899 sec)INFO:tensorflow:global_step/sec: 128.91INFO:tensorflow:loss = 107120.57, step = 301 (0.776 sec)INFO:tensorflow:global_step/sec: 132.546INFO:tensorflow:loss = 12814.152, step = 401 (0.755 sec)INFO:tensorflow:global_step/sec: 162.194INFO:tensorflow:loss = 19573.898, step = 501 (0.617 sec)INFO:tensorflow:global_step/sec: 204.852INFO:tensorflow:loss = 26381.986, step = 601 (0.488 sec)INFO:tensorflow:global_step/sec: 188.923INFO:tensorflow:loss = 23417.719, step = 701 (0.529 sec)INFO:tensorflow:global_step/sec: 192.041INFO:tensorflow:loss = 23946.049, step = 801 (0.521 sec)INFO:tensorflow:global_step/sec: 197.025INFO: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.
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:37INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train1/model.ckpt-1000INFO: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:39INFO: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ê pode fazer melhor combinando bucketization e termo de interação juntos.
Bucketização e interação
Como você viu antes, um classificador linear é incapaz de capturar o padrão de renda por idade corretamente. Isso 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 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 diferentes pesos para cada intervalo.
No TensorFlow, isso é feito com bucketized_column. Você precisa adicionar o intervalo de valores aos 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 aprimorar o modelo é por meio da interação. Na palavra do TensorFlow, é o cruzamento de recursos. O cruzamento de recursos é uma forma de criar novos recursos que são combinações dos existentes, o que pode ser útil para um classificador linear que não pode modelar interações entre recursos.
Você pode dividir a idade com outro recurso, como educação. Ou seja, é provável que alguns grupos tenham uma renda alta e outros, baixa (pense no aluno 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 feição cruzada, você usa coluna cruzada com as variáveis para cruzar em um colchete. 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 intervalo é o número máximo de grupos possível em uma variável. Aqui você o define como 1000, pois você 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)
RESULTADO
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':, '_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 = 1INFO:tensorflow:global_step/sec: 94.969INFO:tensorflow:loss = 50.334488, step = 101 (1.054 sec)INFO:tensorflow:global_step/sec: 242.342INFO:tensorflow:loss = 56.153225, step = 201 (0.414 sec)INFO:tensorflow:global_step/sec: 213.686INFO:tensorflow:loss = 45.792007, step = 301 (0.470 sec)INFO:tensorflow:global_step/sec: 174.084INFO:tensorflow:loss = 37.485672, step = 401 (0.572 sec)INFO:tensorflow:global_step/sec: 191.78INFO:tensorflow:loss = 56.48449, step = 501 (0.524 sec)INFO:tensorflow:global_step/sec: 163.436INFO:tensorflow:loss = 32.528934, step = 601 (0.612 sec)INFO:tensorflow:global_step/sec: 164.347INFO:tensorflow:loss = 37.438057, step = 701 (0.607 sec)INFO:tensorflow:global_step/sec: 154.274INFO:tensorflow:loss = 61.1075, step = 801 (0.647 sec)INFO:tensorflow:global_step/sec: 189.14INFO: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.
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:52INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train3/model.ckpt-1000INFO: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:54INFO: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 é 83,58 por cento. É quatro por cento maior do que o modelo anterior.
Finalmente, você pode adicionar um termo de regularização para evitar overfitting.
Etapa 5) Hiperparâmetro: Lasso & Ridge
Seu modelo pode sofrer de overfitting ou underfitting .
- Overfitting: o modelo é incapaz de generalizar a previsão para novos dados
- Underfitting: O modelo é incapaz de 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, ele 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, 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. Nesse caso, ele não faz uma previsão razoável de 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: Ridge
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 experimentar sozinho os diferentes valores dos hiperparâmetros e ver se consegue aumentar o nível de precisão.
Observe 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 treinado anteriormente.
Vamos ver como fica 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))
OUPUT
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':, '_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)
OUPUT
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 = 1INFO:tensorflow:global_step/sec: 77.4165INFO:tensorflow:loss = 50.38778, step = 101 (1.294 sec)INFO:tensorflow:global_step/sec: 187.889INFO:tensorflow:loss = 55.38014, step = 201 (0.535 sec)INFO:tensorflow:global_step/sec: 201.895INFO:tensorflow:loss = 46.806694, step = 301 (0.491 sec)INFO:tensorflow:global_step/sec: 217.992INFO:tensorflow:loss = 38.68271, step = 401 (0.460 sec)INFO:tensorflow:global_step/sec: 193.676INFO:tensorflow:loss = 56.99398, step = 501 (0.516 sec)INFO:tensorflow:global_step/sec: 202.195INFO:tensorflow:loss = 33.263622, step = 601 (0.497 sec)INFO:tensorflow:global_step/sec: 216.756INFO:tensorflow:loss = 37.7902, step = 701 (0.459 sec)INFO:tensorflow:global_step/sec: 240.215INFO:tensorflow:loss = 61.732605, step = 801 (0.416 sec)INFO:tensorflow:global_step/sec: 220.336INFO: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.
model_regu.evaluate(input_fn=get_input_fn(df_test_new,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
RESULTADO
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:07INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train4/model.ckpt-1000INFO: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:09INFO: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 este hiperparâmetro, você aumenta ligeiramente as métricas de precisão. No próximo tutorial, você aprenderá como melhorar um classificador linear usando um método de kernel.
Resumo
Para treinar um modelo, você precisa:
- Defina as características: Variáveis independentes: X
- Defina o rótulo: Variável dependente: y
- Construir um trem / conjunto de teste
- Defina o peso inicial
- Defina a função de perda: MSE
- Otimize o modelo: descida gradiente
- Definir:
- Taxa de Aprendizagem
- Número de época
- Tamanho do batch
- Número de aulas
Neste tutorial, você aprendeu como usar a API de alto nível para um classificador de regressão linear. Você precisa definir:
- Colunas de recursos. Se contínuo: tf.feature_column.numeric_column (). Você pode preencher uma lista com compreensão de lista python
- O estimador: tf.estimator.LinearClassifier (feature_columns, model_dir, n_classes = 2)
- Uma função para importar os dados, o tamanho do lote e a época: input_fn ()
Depois disso, você está pronto para treinar, avaliar e fazer uma previsão com treinar (), avaliar () e prever ()
Para melhorar o desempenho do modelo, você pode:
- Use regressão polinomial
- Termo de interação: tf.feature_column.crossed_column
- Adicionar parâmetro de regularização