Anonymous
Общий шаблон Sklearn
Сообщение
Anonymous » 30 мар 2026, 00:10
Я создаю многократно используемый конвейер scikit-learn для табличных данных с числовыми и категориальными столбцами.
Я хочу:
Вменять отсутствующие числовые значения с помощью медианы
Масштабировать числовые столбцы
Вменять категориальные значения с наибольшим количеством частое значение
Горячее кодирование категориальных столбцов
Вот мой текущий код:
Код: Выделить всё
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 как для задач классификации, так и для задач регрессии?
Если нет, что мне следует изменить?>
1774818646
Anonymous
Я создаю многократно используемый конвейер scikit-learn для табличных данных с числовыми и категориальными столбцами. Я хочу: [list] [*]Вменять отсутствующие числовые значения с помощью медианы [*]Масштабировать числовые столбцы [*]Вменять категориальные значения с наибольшим количеством частое значение [*]Горячее кодирование категориальных столбцов [/list] Вот мой текущий код: [code]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}") [/code] Мой вопрос: Правильно ли это построить общий конвейер предварительной обработки в scikit-learn как для задач классификации, так и для задач регрессии? Если нет, что мне следует изменить?>