Как правильно настроить вложенный конвейер Scikit-Learn (ColumnTransformer + Classifier) ​​с помощью RandomizedSearchCV?Python

Программы на Python
Ответить
Anonymous
 Как правильно настроить вложенный конвейер Scikit-Learn (ColumnTransformer + Classifier) ​​с помощью RandomizedSearchCV?

Сообщение Anonymous »

Я пытаюсь создать в Scikit-Learn сквозной рабочий процесс машинного обучения для набора классификационных данных. Моя цель — передать DataFrame Pandas через ColumnTransformer (для обработки масштабирования и горячего кодирования), поместить его в классификатор (например, HistGradientBoostingClassifier), а затем настроить все это с помощью RandomizedSearchCV.

Код: Выделить всё

import pandas as pd
import numpy as np
import sklearn
from sklearn.model_selection import train_test_split, RandomizedSearchCV
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.metrics import classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

# ==========================================
# 0. GLOBAL CONFIGURATION
# ==========================================
# Force Scikit-Learn to output Pandas DataFrames instead of Numpy arrays!
sklearn.set_config(transform_output="pandas")

# df = pd.read_csv("train.csv")
# X = df.drop(columns=['TargetColumn'])
# y = df['TargetColumn']
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)

def engineer_features(df):
"""Put all your custom Pandas string splitting and math here."""
df_clean = df.copy()

# Example: Splitting a messy string column if it exists
# if 'Cabin' in df_clean.columns:
#     df_clean[['Deck', 'Num', 'Side']] = df_clean['Cabin'].str.split('/', expand=True)
#     df_clean['Num'] = pd.to_numeric(df_clean['Num'], errors='coerce')
#     df_clean = df_clean.drop(columns=['Cabin'])

return df_clean

# Apply engineering immediately
X_train = engineer_features(X_train)
X_test = engineer_features(X_test)

# Define columns that need special treatment (so they don't get swept up in the auto-sort)
drop_features = ['PassengerId', 'Name'] # Columns to completely ignore

# Automatically grab categorical and numerical columns
all_cats = X_train.select_dtypes(include=['object', 'category']).columns.tolist()
all_nums = X_train.select_dtypes(include=['number']).columns.tolist()

# Filter out the drop_features
cat_features = [col for col in all_cats if col not in drop_features]
num_features = [col for col in all_nums if col not in drop_features]

numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])

categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore', sparse_output=False))
])

preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, num_features),
('cat', categorical_transformer, cat_features)
],
remainder='drop' # Automatically drops anything not in the lists above (like PassengerId)
)

# Snap the preprocessor and the classifier together
master_pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', HistGradientBoostingClassifier(random_state=42, class_weight="balanced"))
])

# Define the tuning grid (Notice the 'classifier__' prefix!)
param_grid = {
'classifier__max_iter': [100, 200, 300],
'classifier__max_depth': [None, 10, 20],
'classifier__learning_rate': [0.01, 0.1, 0.2]
}

# Build the Tuner
tuner = RandomizedSearchCV(
estimator=master_pipeline,
param_distributions=param_grid,
n_iter=10,       # Test 10 random combinations
cv=3,            # 3-Fold Cross Validation
scoring='f1',    # Optimize for F1-Score instead of accuracy!
random_state=42,
n_jobs=-1
)

print("Tuning and training model... ")
tuner.fit(X_train, y_train)

print(f"🏆 Best Parameters Found: {tuner.best_params_}")

# Predict on the test set
y_pred = tuner.predict(X_test)

print("\n--- 📊 CLASSIFICATION REPORT ---")
print(classification_report(y_test, y_pred))
Однако при настройке этой архитектуры я постоянно сталкиваюсь с двумя основными препятствиями:
1. **Проблема вывода Pandas:** ColumnTransformer удаляет все имена столбцов Pandas и превращает мои данные в общие массивы Numpy, что делает отладку невозможной.
2. **Сбой при настройке:** Когда я передаю свой конвейер в RandomizedSearchCV, он выдает ValueError: Invalid параметр, приводящий к сбою тюнера, поскольку он не может найти параметры для классификатора.
Как я могу в этом вложенном конвейере сохранить кадры данных Pandas и правильно настроить параметры классификатора для настройки?
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»