<jupyter_start><jupyter_text>Feature Selection: Variáveis constantes e quase-constantesNeste artigo, você encontra uma breve explicação sobre feature selection e um tutorial de como lidar com variáveis constantes e quase-constantes.  Um conjunto de dados geralmente começa com um grande número de features (variáveis), porém podemos empregar uma variedade de métodos com o objetivo de determinar quais dessas features são realmente importantes para realizar as previsões. Esse procedimento é conhecido como feature selection ou seleção de variáveis.Feature selection pode ser definido como o processo na qual você seleciona automaticamente ou manualmente aquelas features que mais contribuem para a predição da variável target (variável de previsão). Em outras palavras, é o processo de selecionar um subconjunto de features relevantes do seu conjunto total de dados, com o objetivo de construir um algoritmo de machine learning. As features que são utilizadas para treinar seu modelo de machine learning, posuem uma grande influência no resultado que seu modelo pode alcançar. Quais os benefícios de aplicar feature selection? Abaixo indico alguns benefícios, porém existem outros.- Redução do overfitting - Melhora da acurácia- Redução do tempo de treinamento do modelo- Modelos com menor propensão a erros Vários métodos foram desenvolvidos para selecionar aquelas features ideais para a construção de um algoritmo de machine learning. As técnicas utilizadas podem ser divididas em três categorias principais:1. **Filter Methods**: Métodos de seleção que utilizam medidas estatísticas para atribuir um score para cada feature. As features são classificadas pelo score para serem mantidas ou removidas do modelo. Normalmente se usam testes univariados que consideram a independência da feature com a variável alvo.2. **Wrapper Methods** : Métodos de seleção que selecionam um conjunto de features, onde diferentes combinações são preparadas, avaliadas e comparadas. Um modelo preditivo é usado para avaliar a combinação de features a atribuir um score baseado em uma acurácia de modelo. 3. **Embedded Methods**: Métodos Embedded aprendem quais features melhor contribuiem para a acurácia do modelo no momento de construção do modelo. Neste artigo, estarei concentrado nos filter methods, mais precisamente em um método básico e simples, porém bastante eficiente, utilizado para selecionar variáveis constantes e quase-constantes. Esse método baseia-se apenas na variância de cada feature. Sendo as features com variância igual a 0, consideradas como constantes, uma vez que seus valores são o mesmo para todos os registros. Já as features quase-constantes, possuem uma variância muito pequena, ou seja, seu valor é quase sempre o mesmo em todo o dataset, por isso são chamadas de quase-constantes. Quando trabalhamos com um conjunto de dados muito extenso, com muitas features, pode ser complicado e até mesmo inviável determinar quais features possuem valores constantes ou quase-constantes. Dessa forma, é importante que o trabalho seja automatizado, fazendo com que todo o processo ocorra de maneira mais rápida, além de manter a qualidade da análise. Para que isso seja possível, podemos utilizar o método VarianceThreshold pertencente a biblioteca sklearn,da linguagem de programação Python. O método é bastante simples e consiste em atribuir um threshold, ou seja, um limiar, um valor na qual servirá como um filtro, removendo as features que apresentarem limite inferior a variância informada. Todo o processo será feito através da linguagem Python e o conjunto de dados utilizado pode ser encontrado através do link https://www.kaggle.com/c/santander-customer-satisfaction. Esse dataset, refere-se a dados bancários de clientes do banco Santander, sendo as features anônimas. Sem mais delongas, vamos para a parte prática. Para dar início ao trabalho, vamos importar as três bibliotecas a serem utilizadas e carregar os dados de treino e de teste.<jupyter_code># Importando as bibliotecas
import pandas as pd
import numpy as np
from sklearn.feature_selection import VarianceThreshold

# Dados de treino e teste
treino = pd.read_csv('C:/Users/otavio/Mundo/medium/data/santander-train.csv', index_col = 0)
teste  = pd.read_csv('C:/Users/otavio/Mundo/medium/data/santander-test.csv', index_col = 0)<jupyter_output><empty_output><jupyter_text>Vamos remover a coluna target dos dados de treino e analisar o formato dos dados.<jupyter_code># Removendo coluna TARGET dos dados de treino
treino.drop(labels = ['TARGET'], axis = 1, inplace = True)
# Shape dos dados de treino e teste
print('Dados de treino:', treino.shape)
print('Dados de teste :', teste.shape)<jupyter_output>Dados de treino: (76020, 369)
Dados de teste : (75818, 369)<jupyter_text>Através do código acima, podemos observar que os datasets apresentam 369 features.  Primeiramente, vamos analisar se o conjunto de dados apresenta **features constantes**, além de determinar quantas e quais são essas features. Para isso, será aplicado o método VarianceThreshold, aplicando um threshold igual a 0, ou seja, iremos mapear aquelas features que possuem variância igual a zero através do fit.<jupyter_code>vt = VarianceThreshold(threshold = 0)
vt.fit(treino)<jupyter_output><empty_output><jupyter_text>O método get_support é um vetor booleano que indica quais features são retidas. Se somarmos get_support, obtemos quantas features NÃO são constantes. De todas as 369 features, 335 apresentaram variância diferente de 0.<jupyter_code>sum(vt.get_support())<jupyter_output><empty_output><jupyter_text>Com poucas linhas de código, foi possível determinar que 34 features apresentaram variância igual a 0 e criar uma lista de quais as features que serão excluídas dos datasets de treino e teste.<jupyter_code># Features constantes
features_constantes = [feature for feature in treino.columns if feature not in treino.columns[vt.get_support()]]
print('Número de features constantes: ', len(features_constantes))
features_constantes<jupyter_output>Número de features constantes:  34<jupyter_text>Uma vez determinada quais as features são constantes, podemos remove-las dos nossos dados utilizando o método transform.<jupyter_code># Removendo as features constantes dos datasets
treino = vt.transform(treino)
teste  = vt.transform(teste)
# Shapes dos datasets
print('Dados de treino:', treino.shape)
print('Dados de teste :', teste.shape)<jupyter_output>Dados de treino: (76020, 335)
Dados de teste : (75818, 335)<jupyter_text>Pronto! Os dadasets de treino e de teste estão sem as features constantes. Realmente é muito simples fazer e remoção e podemos notar a grande eficácia que o método traz para a análise, reduzindo o dataset consideravelmente. Agora vamos focar nossa análise nas **features quase-constantes**. A metodologia empregada é a mesma que foi desenvolvida anteriormente, com uma única diferença. Dessa vez, o threshold terá o valor igual a 0,01, ou seja, queremos remover as variáveis que apresentarem inferior a este limite. Portanto, irei apenas apresentar o código, uma vez que a explicação é a mesma.<jupyter_code># Carregando novamente os dados de treino e teste
treino = pd.read_csv('C:/Users/otavio/Mundo/medium/data/santander-train.csv', index_col = 0)
teste  = pd.read_csv('C:/Users/otavio/Mundo/medium/data/santander-test.csv', index_col = 0)
# Removendo coluna TARGET dos dados de treino
treino.drop(labels = ['TARGET'], axis = 1, inplace = True)
# Utilizando sklearn VarianceThreshold para encontrar as features quase-constantes
vt = VarianceThreshold(threshold = 0.01) # 
vt.fit(treino) # fit encontra as features com baixa variância
# get_support é um vetor booleano que indica quais features são retidas
# se somarmos get_support, obtemos quantas features NÃO são quase-constantes
sum(vt.get_support())
# Features quase-constantes
features_quaseConstantes = [feature for feature in treino.columns if feature not in treino.columns[vt.get_support()]]
print('Número de features quase-constantes: ', len(features_quaseConstantes))
features_quaseConstantes<jupyter_output>Número de features quase-constantes:  97<jupyter_text>Como resultado obtemos que 97 features podem ser consideradas como quase-constantes. Lembrando que os datasets possuem 369 features.<jupyter_code># Porcentagem de observação mostrando cada um dos diferentes valores
treino['ind_var1'].value_counts() / np.float(len(treino)) * 100
# Removendo as features quase-constantes dos datasets
treino = vt.transform(treino)
teste  = vt.transform(teste)
# Shapes dos datasets
print('Dados de treino:', treino.shape)
print('Dados de teste :', teste.shape)<jupyter_output>Dados de treino: (76020, 272)
Dados de teste : (75818, 272)
{'fraction_non_alphanumeric': 0.056010141754062465, 'fraction_numerical': 0.010602742883485075, 'mean_word_length': 5.727131782945737, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 28, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '374687', 'license': 'MIT', 'n_tokens_mistral': 2796, 'n_tokens_neox': 2673, 'n_words': 1094, 'path': 'Features-Constantes-QuaseConstantes/01-features-constants-quasiConstants.ipynb', 'repo_name': 'otaviosanluz/medium', 'size': '8677'}