Код: Выделить всё
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 и правильно настроить параметры классификатора для настройки?