html
Dominando GridSearchCV para Modelos de Aprendizado de Máquina Ótimos: Um Guia Abrangente
Sumário
- Introdução ao GridSearchCV
- Compreendendo o Conjunto de Dados
- Pré-processamento de Dados
- Tratamento de Dados Ausentes
- Codificação de Variáveis Categóricas
- Seleção de Características
- Escalonamento de Características
- Implementando GridSearchCV
- Configurando Validação Cruzada com StratifiedKFold
- Parâmetros do GridSearchCV Explicados
- Construindo e Ajustando Modelos de Aprendizado de Máquina
- K-Nearest Neighbors (KNN)
- Regressão Logística
- Gaussian Naive Bayes
- Support Vector Machines (SVM)
- Árvores de Decisão
- Random Forest
- AdaBoost
- XGBoost
- Análise de Desempenho
- Otimização do GridSearchCV
- Conclusão e Próximos Passos
1. Introdução ao GridSearchCV
GridSearchCV é uma técnica em aprendizado de máquina utilizada para ajuste de hiperparâmetros. Hiperparâmetros são parâmetros cruciais que governam o processo de treinamento e a estrutura do modelo. Diferentemente dos parâmetros regulares, os hiperparâmetros são definidos antes do início da fase de treinamento e podem influenciar significativamente o desempenho do modelo.
GridSearchCV funciona pesquisando exaustivamente através de uma grade de parâmetros especificada, avaliando cada combinação usando validação cruzada e identificando a combinação que resulta no melhor desempenho com base em uma métrica escolhida (por exemplo, F1-score, acurácia).
Por que GridSearchCV?
- Busca Abrangente: Avalia todas as combinações possíveis de hiperparâmetros.
- Validação Cruzada: Garante que o desempenho do modelo seja robusto e não apenas ajustado a um subconjunto específico de dados.
- Automação: Simplifica o processo de ajuste, economizando tempo e recursos computacionais.
No entanto, é essencial observar que o GridSearchCV pode ser computacionalmente intensivo, especialmente com grandes conjuntos de dados e grades de parâmetros extensas. Este guia explora estratégias para gerenciar esses desafios de forma eficaz.
2. Compreendendo o Conjunto de Dados
Para esta demonstração, utilizamos um conjunto de dados focado na satisfação dos passageiros de companhias aéreas. O conjunto de dados originalmente compreende mais de 100.000 registros, mas foi reduzido para 5.000 registros para viabilidade neste exemplo. Cada registro abrange 23 características, incluindo informações demográficas, detalhes de voo e níveis de satisfação.
Amostra do Conjunto de Dados
Gênero
Tipo de Cliente
Idade
Tipo de Viagem
Classe
Distância do Voo
...
Satisfação
Feminino
Cliente Fiel
41
Viagem Pessoal
Eco Plus
746
...
Neutro ou Insatisfeito
Masculino
Cliente Fiel
53
Viagem de Negócios
Business
3095
...
Insatisfeito
Masculino
Cliente Desleal
21
Viagem de Negócios
Eco
125
...
Insatisfeito
...
...
...
...
...
...
...
...
A variável alvo é Satisfação, categorizada como "Satisfeito" ou "Neutro ou Insatisfeito".
3. Pré-processamento de Dados
O pré-processamento eficaz de dados é fundamental para garantir que os modelos de aprendizado de máquina tenham um desempenho ótimo. As etapas incluem o tratamento de dados ausentes, a codificação de variáveis categóricas, a seleção de características e o escalonamento de características.
Tratamento de Dados Ausentes
Dados Numéricos: Valores ausentes em colunas numéricas são tratados usando a estratégia de imputação pela média.
123456789101112
from sklearn.impute import SimpleImputerimport numpy as np # Initialize imputer for numeric dataimp_mean = SimpleImputer(missing_values=np.nan, strategy='mean') # Identify numerical columnsnumerical_cols = list(np.where((X.dtypes == np.int64) | (X.dtypes == np.float64))[0]) # Fit and transform the dataimp_mean.fit(X.iloc[:, numerical_cols])X.iloc[:, numerical_cols] = imp_mean.transform(X.iloc[:, numerical_cols])
Dados Categóricos: Para colunas baseadas em strings, a estratégia de imputação pelo valor mais frequente é empregada.
123456789
# Initialize imputer for categorical dataimp_freq = SimpleImputer(missing_values=np.nan, strategy='most_frequent') # Identify string columnsstring_cols = list(np.where((X.dtypes == object))[0]) # Fit and transform the dataimp_freq.fit(X.iloc[:, string_cols])X.iloc[:, string_cols] = imp_freq.transform(X.iloc[:, string_cols])
Codificação de Variáveis Categóricas
As variáveis categóricas são transformadas em um formato numérico usando Codificação de Rótulos e Codificação One-Hot.
123456789101112131415161718192021222324252627282930
from sklearn.preprocessing import LabelEncoder, OneHotEncoderfrom sklearn.compose import ColumnTransformer def LabelEncoderMethod(series): le = LabelEncoder() return le.fit_transform(series) def OneHotEncoderMethod(indices, data): columnTransformer = ColumnTransformer( [('encoder', OneHotEncoder(), indices)], remainder='passthrough' ) return columnTransformer.fit_transform(data) def EncodingSelection(X, threshold=10): string_cols = list(np.where((X.dtypes == object))[0]) one_hot_encoding_indices = [] for col in string_cols: unique_vals = len(pd.unique(X[X.columns[col]])) if unique_vals == 2 or unique_vals > threshold: X[X.columns[col]] = LabelEncoderMethod(X[X.columns[col]]) else: one_hot_encoding_indices.append(col) X = OneHotEncoderMethod(one_hot_encoding_indices, X) return X # Apply encodingX = EncodingSelection(X)
Seleção de Características
Para melhorar o desempenho do modelo e reduzir a complexidade computacional, SelectKBest com a estatística Qui-Quadrado (χ²) é utilizada para selecionar as 10 principais características.
123456789101112
from sklearn.feature_selection import SelectKBest, chi2from sklearn.preprocessing import MinMaxScaler # Initialize SelectKBestkbest = SelectKBest(score_func=chi2, k=10) # Scale featuresscaler = MinMaxScaler()X_scaled = scaler.fit_transform(X) # Fit SelectKBestX_selected = kbest.fit_transform(X_scaled, y)
Escalonamento de Características
O escalonamento de características garante que todas as características contribuam igualmente para o desempenho do modelo.
123456789
from sklearn.preprocessing import StandardScaler # Initialize StandardScalersc = StandardScaler(with_mean=False) # Fit and transform the training datasc.fit(X_train)X_train = sc.transform(X_train)X_test = sc.transform(X_test)
4. Implementando GridSearchCV
Com os dados pré-processados, o próximo passo envolve configurar o GridSearchCV para ajustar os hiperparâmetros de vários modelos de aprendizado de máquina.
Configurando Validação Cruzada com StratifiedKFold
StratifiedKFold garante que cada dobra da validação cruzada mantenha a mesma proporção de rótulos de classe, o que é crucial para conjuntos de dados desequilibrados.
1234
from sklearn.model_selection import StratifiedKFold # Initialize StratifiedKFoldcv = StratifiedKFold(n_splits=2)
Parâmetros do GridSearchCV Explicados
- Estimator: O modelo de aprendizado de máquina a ser ajustado.
- Param_grid: Um dicionário que define os hiperparâmetros e seus respectivos valores a serem explorados.
- Verbose: Controla a verbosidade; defina para 1 para exibir o progresso.
- Scoring: A métrica de desempenho a ser otimizada, por exemplo, 'f1'.
- n_jobs: Número de núcleos de CPU a serem utilizados; definindo para -1 utiliza todos os núcleos disponíveis.
123456789101112131415161718192021
from sklearn.model_selection import GridSearchCV # Example: Setting up GridSearchCV for KNNfrom sklearn.neighbors import KNeighborsClassifier model = KNeighborsClassifier()params = { 'n_neighbors': [4, 5, 6, 7], 'leaf_size': [1, 3, 5], 'algorithm': ['auto', 'kd_tree'], 'weights': ['uniform', 'distance']} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1)
5. Construindo e Ajustando Modelos de Aprendizado de Máquina
5.1 K-Nearest Neighbors (KNN)
O KNN é um algoritmo simples, mas eficaz, para tarefas de classificação. O GridSearchCV ajuda na seleção do número ótimo de vizinhos, tamanho de folha, algoritmo e esquema de ponderação.
123456
# Fit GridSearchCVgrid_search_cv.fit(X_train, y_train) # Best parametersprint("Best Estimator", grid_search_cv.best_estimator_)print("Best score", grid_search_cv.best_score_)
Saída:
12
Best Estimator KNeighborsClassifier(leaf_size=1)Best score 0.8774673417446253
5.2 Regressão Logística
A Regressão Logística modela a probabilidade de um resultado binário. GridSearchCV ajusta o tipo de solucionador, penalidade e força de regularização.
123456789101112131415161718192021
from sklearn.linear_model import LogisticRegression model = LogisticRegression()params = { 'solver': ['newton-cg', 'lbfgs', 'liblinear'], 'penalty': ['l1', 'l2'], 'C': [100, 10, 1.0, 0.1, 0.01]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("Best Estimator", grid_search_cv.best_estimator_)print("Best score", grid_search_cv.best_score_)
Saída:
12
Best Estimator LogisticRegression(C=0.01, solver='newton-cg')Best score 0.8295203666687819
5.3 Gaussian Naive Bayes
O Gaussian Naive Bayes assume que as características seguem uma distribuição normal. Possui menos hiperparâmetros, tornando-o menos intensivo para o GridSearchCV.
123456789
from sklearn.naive_bayes import GaussianNBfrom sklearn.metrics import accuracy_score, classification_report model_GNB = GaussianNB()model_GNB.fit(X_train, y_train)y_pred = model_GNB.predict(X_test) print(accuracy_score(y_pred, y_test))print(classification_report(y_pred, y_test))
Saída:
123456789
0.84 precision recall f1-score support 0 0.86 0.86 0.86 564 1 0.82 0.81 0.82 436 accuracy 0.84 1000 macro avg 0.84 0.84 0.84 1000weighted avg 0.84 0.84 0.84 1000
5.4 Support Vector Machines (SVM)
As SVMs são classificadores versáteis que funcionam bem para dados lineares e não lineares. O GridSearchCV ajusta o tipo de kernel, parâmetro de regularização C
, grau, coeficiente coef0
e coeficiente do kernel gamma
.
1234567891011121314151617181920212223
from sklearn.svm import SVC model = SVC()params = { 'kernel': ['linear', 'poly', 'rbf', 'sigmoid'], 'C': [1, 5, 10], 'degree': [3, 8], 'coef0': [0.01, 10, 0.5], 'gamma': ['auto', 'scale']} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("Best Estimator", grid_search_cv.best_estimator_)print("Best score", grid_search_cv.best_score_)
Saída:
12
Best Estimator SVC(C=5, coef0=0.01)Best score 0.9168629045108148
5.5 Árvores de Decisão
As Árvores de Decisão particionam os dados com base nos valores das características para fazer previsões. GridSearchCV otimiza parâmetros como o número máximo de nós folha e o número mínimo de amostras necessárias para dividir um nó interno.
1234567891011121314151617181920
from sklearn.tree import DecisionTreeClassifier model = DecisionTreeClassifier()params = { 'max_leaf_nodes': list(range(2, 100)), 'min_samples_split': [2, 3, 4]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("Best Estimator", grid_search_cv.best_estimator_)print("Best score", grid_search_cv.best_score_)
Saída:
12
Best Estimator DecisionTreeClassifier(max_leaf_nodes=29, min_samples_split=4)Best score 0.9098148654372425
5.6 Random Forest
As Random Forests agregam múltiplas árvores de decisão para melhorar o desempenho e controlar o overfitting. O GridSearchCV ajusta parâmetros como o número de estimadores, profundidade máxima, número de características e divisões de amostra.
123456789101112131415161718192021222324
from sklearn.ensemble import RandomForestClassifier model = RandomForestClassifier()params = { 'bootstrap': [True], 'max_depth': [80, 90, 100, 110], 'max_features': [2, 3], 'min_samples_leaf': [3, 4, 5], 'min_samples_split': [8, 10, 12], 'n_estimators': [100, 200, 300, 1000]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("Best Estimator", grid_search_cv.best_estimator_)print("Best score", grid_search_cv.best_score_)
Saída:
12
Best Estimator RandomForestClassifier(max_leaf_nodes=82, min_samples_split=4)Best score 0.9225835186933584
5.7 AdaBoost
AdaBoost combina múltiplos classificadores fracos para formar um classificador forte. O GridSearchCV ajusta o número de estimadores e a taxa de aprendizado.
1234567891011121314151617181920
from sklearn.ensemble import AdaBoostClassifier model = AdaBoostClassifier()params = { 'n_estimators': np.arange(10, 300, 10), 'learning_rate': [0.01, 0.05, 0.1, 1]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("Best Estimator", grid_search_cv.best_estimator_)print("Best score", grid_search_cv.best_score_)
Saída:
12
Best Estimator AdaBoostClassifier(learning_rate=1, n_estimators=30)Best score 0.8938313525749858
5.8 XGBoost
O XGBoost é uma implementação de gradient boosting altamente eficiente e escalável. Devido ao seu extenso espaço de hiperparâmetros, o GridSearchCV pode consumir muito tempo.
1234567891011121314151617181920212223242526
import xgboost as xgb model = xgb.XGBClassifier()params = { 'min_child_weight': [1, 5, 10], 'gamma': [0.5, 1, 1.5, 2, 5], 'subsample': [0.6, 0.8, 1.0], 'colsample_bytree': [0.6, 0.8, 1.0], 'max_depth': [3, 4, 5], 'n_estimators': [100, 500, 1000], 'learning_rate': [0.01, 0.3, 0.5, 0.1], 'reg_lambda': [1, 2]} grid_search_cv = GridSearchCV( estimator=model, param_grid=params, verbose=1, cv=cv, scoring='f1', n_jobs=-1) grid_search_cv.fit(X_train, y_train)print("Best Estimator", grid_search_cv.best_estimator_)print("Best score", grid_search_cv.best_score_)
Saída:
123456789
Best Estimator XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1, colsample_bynode=1, colsample_bytree=0.8, gamma=0.5, gpu_id=-1, importance_type='gain', interaction_constraints='', learning_rate=0.01, max_delta_step=0, max_depth=5, min_child_weight=1, missing=nan, monotone_constraints='()', n_estimators=500, n_jobs=12, num_parallel_tree=1, random_state=0, reg_alpha=0, reg_lambda=1, scale_pos_weight=1, subsample=1.0, tree_method='exact', validate_parameters=1, verbosity=None)Best score 0.9267223852716081
Nota: A execução do GridSearchCV para o XGBoost é notavelmente demorada devido ao vasto número de combinações de hiperparâmetros.
6. Análise de Desempenho
Após o ajuste, cada modelo apresenta níveis variados de desempenho com base nos melhores F1-scores alcançados:
- KNN: 0.877
- Regressão Logística: 0.830
- Gaussian Naive Bayes: 0.840
- SVM: 0.917
- Árvore de Decisão: 0.910
- Random Forest: 0.923
- AdaBoost: 0.894
- XGBoost: 0.927
Interpretação
- XGBoost e Random Forest exibem os maiores F1-scores, indicando desempenho superior no conjunto de dados.
- SVM também demonstra desempenho robusto.
- KNN e AdaBoost oferecem resultados competitivos com F1-scores ligeiramente inferiores.
- Regressão Logística e Gaussian Naive Bayes, embora mais simples, ainda oferecem métricas de desempenho respeitáveis.
7. Otimizando o GridSearchCV
Dada a intensidade computacional do GridSearchCV, especialmente com grandes conjuntos de dados ou grades de parâmetros extensas, é crucial explorar estratégias de otimização:
7.1 RandomizedSearchCV
Diferente do GridSearchCV, o RandomizedSearchCV amostra um número fixo de configurações de parâmetros de distribuições especificadas. Essa abordagem pode reduzir significativamente o tempo de computação enquanto ainda explora um conjunto diversificado de hiperparâmetros.
1234567891011121314151617
from sklearn.model_selection import RandomizedSearchCV # Example setup for RandomizedSearchCVrandom_search_cv = RandomizedSearchCV( estimator=model, param_distributions=params, n_iter=100, # Number of parameter settings sampled verbose=1, cv=cv, scoring='f1', n_jobs=-1, random_state=42) random_search_cv.fit(X_train, y_train)print("Best Estimator", random_search_cv.best_estimator_)print("Best score", random_search_cv.best_score_)
7.2 Reduzindo o Tamanho da Grade de Parâmetros
Concentre-se nos hiperparâmetros que impactam significativamente o desempenho do modelo. Realize análises exploratórias ou aproveite o conhecimento do domínio para priorizar certos parâmetros sobre outros.
7.3 Utilizando Processamento Paralelo
Definir n_jobs=-1
no GridSearchCV permite o uso de todos os núcleos de CPU disponíveis, acelerando o processo de computação.
7.4 Parada Antecipada
Implemente mecanismos de parada antecipada para interromper a busca uma vez que um nível de desempenho satisfatório seja alcançado, prevenindo computações desnecessárias.
8. Conclusão e Próximos Passos
O GridSearchCV é uma ferramenta indispensável para o ajuste de hiperparâmetros, oferecendo uma abordagem sistemática para melhorar o desempenho dos modelos de aprendizado de máquina. Através de um pré-processamento de dados meticuloso, formulação estratégica da grade de parâmetros e aproveitamento de otimizações computacionais, os cientistas de dados podem aproveitar todo o potencial do GridSearchCV.
Próximos Passos:
- Explore o RandomizedSearchCV para um ajuste de hiperparâmetros mais eficiente.
- Implemente as Melhores Práticas de Validação Cruzada para garantir a robustez do modelo.
- Integre Técnicas de Engenharia de Características para melhorar ainda mais o desempenho do modelo.
- Implante Modelos Otimizados em cenários do mundo real, monitorando seu desempenho ao longo do tempo.
Dominando o GridSearchCV e suas otimizações, você estará bem equipado para construir modelos de aprendizado de máquina de alto desempenho e confiáveis que resistem aos diferentes cenários de dados.