Я пытаюсь создать в 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 и правильно настроить параметры классификатора для настройки?
Я пытаюсь создать в Scikit-Learn сквозной рабочий процесс машинного обучения для набора классификационных данных. Моя цель — передать DataFrame Pandas через ColumnTransformer (для обработки масштабирования и горячего кодирования), поместить его в классификатор (например, HistGradientBoostingClassifier), а затем настроить все это с помощью RandomizedSearchCV. [code]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'])
# 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
# 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]
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")) ])
# 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)) [/code] Однако при настройке этой архитектуры я постоянно сталкиваюсь с двумя основными препятствиями: 1. **Проблема вывода Pandas:** ColumnTransformer удаляет все имена столбцов Pandas и превращает мои данные в общие массивы Numpy, что делает отладку невозможной. 2. **Сбой при настройке:** Когда я передаю свой конвейер в RandomizedSearchCV, он выдает ValueError: Invalid параметр, приводящий к сбою тюнера, поскольку он не может найти параметры для классификатора. Как я могу в этом вложенном конвейере сохранить кадры данных Pandas и правильно настроить параметры классификатора для настройки?