Я хочу:
- Вменять отсутствующие числовые значения с помощью медианы
- Масштабировать числовые столбцы
- Вменять категориальные значения с наибольшим количеством частое значение
- Горячее кодирование категориальных столбцов
Код: Выделить всё
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor
from sklearn.linear_model import LogisticRegression, LinearRegression, Ridge
def build_preprocessor(X):
numeric_features = X.select_dtypes(include=['int64', 'float64']).columns
categorical_features = X.select_dtypes(include=['object', 'category', 'bool']).columns
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('encoder', OneHotEncoder(handle_unknown='ignore'))
])
preprocessor = ColumnTransformer(transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)
])
return preprocessor
def train_classification_model(X, y):
preprocessor = build_preprocessor(X)
models = {
'logreg': LogisticRegression(max_iter=1000),
'dt': DecisionTreeClassifier(random_state=42),
'rf': RandomForestClassifier(random_state=42),
'knn': KNeighborsClassifier()
}
best_model = None
best_score = -1
best_name = None
for name, model in models.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
score = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy').mean()
print(f"{name}: {score:.4f}")
if score > best_score:
best_score = score
best_model = pipeline
best_name = name
print("Best model:", best_name, best_score)
best_model.fit(X, y)
return best_model
def train_regression_model(X, y):
preprocessor = build_preprocessor(X)
models = {
'linreg': LinearRegression(),
'ridge': Ridge(),
'dt': DecisionTreeRegressor(random_state=42),
'rf': RandomForestRegressor(random_state=42),
'knn': KNeighborsRegressor()
}
best_model = None
best_score = float('-inf')
best_name = None
for name, model in models.items():
pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('model', model)
])
score = cross_val_score(pipeline, X, y, cv=5, scoring='r2').mean()
print(f"{name}: {score:.4f}")
if score > best_score:
best_score = score
best_model = pipeline
best_name = name
print("Best model:", best_name, best_score)
best_model.fit(X, y)
return best_model
def predict_and_save(model, X_test, output_file='submission.csv'):
preds = model.predict(X_test)
submission = pd.DataFrame({'Prediction': preds})
submission.to_csv(output_file, index=False)
print(f"Saved to {output_file}")
Правильно ли это построить общий конвейер предварительной обработки в scikit-learn как для задач классификации, так и для задач регрессии?
Если нет, что мне следует изменить?>