Introduction
Machine learning (ML) is transforming industries, but building effective models requires more than just knowing algorithms—it demands systematic workflows. Whether you are a data scientist fine-tuning a gradient booster or a ML engineer debugging a pipeline, the right prompts can guide your thinking and code. This article collects 15 practical prompts for ML tasks using three of the most popular libraries: Scikit-learn, XGBoost, and CatBoost. Each prompt is a complete, actionable template you can adapt to your own data.
These prompts cover the full ML lifecycle: data preprocessing, feature engineering, model training, hyperparameter tuning, and evaluation. They are designed for both beginners—who need clear explanations—and experts looking for concise references. By the end, you will have a reusable toolkit for faster, more reliable ML workflows.
Why These Libraries?
- Scikit-learn (Pedregosa et al., 2011) is the industry standard for classical ML algorithms, preprocessing, and pipelines. Its API is consistent and well-documented at scikit-learn.org.
- XGBoost (Chen & Guestrin, 2016) is a gradient boosting framework optimized for speed and performance, widely used in Kaggle competitions. Official docs: xgboost.readthedocs.io.
- CatBoost (Dorogush et al., 2018) handles categorical features natively and reduces overfitting with ordered boosting. Learn more at catboost.ai.
Prompt 1: Automated Missing Value Imputation
Task: Write a function that detects missing values in a DataFrame and imputes them using Scikit-learn's SimpleImputer with a strategy based on column data type.
Prompt:
"Create a Python function
smart_impute(df)using Scikit-learn'sSimpleImputer. For numeric columns, use median imputation; for categorical columns, use most_frequent. Return the imputed DataFrame and a dictionary of imputers per column."
Example Result:
import pandas as pd
from sklearn.impute import SimpleImputer
def smart_impute(df):
imputers = {}
df_imp = df.copy()
for col in df.columns:
if df[col].dtype in ['int64', 'float64']:
imputer = SimpleImputer(strategy='median')
else:
imputer = SimpleImputer(strategy='most_frequent')
df_imp[col] = imputer.fit_transform(df[[col]]).ravel()
imputers[col] = imputer
return df_imp, imputers
Explanation: This prompt ensures you handle missing data robustly. Using median for numerics avoids outlier sensitivity, while most_frequent preserves categorical distributions. Always fit imputers on training data only, then transform test data—this function can be extended with a transform_only mode.
Prompt 2: Custom One-Hot Encoding with Fallback
Task: Encode categorical features with OneHotEncoder, but automatically handle unseen categories during inference by ignoring them.
Prompt:
"Using Scikit-learn's
OneHotEncoder, configure it to handle unknown categories by ignoring them. Show code that fits on training data and transforms test data with a new category."
Example Result:
from sklearn.preprocessing import OneHotEncoder
import pandas as pd
train = pd.DataFrame({'color': ['red', 'blue', 'green']})
test = pd.DataFrame({'color': ['red', 'yellow']}) # 'yellow' unseen
encoder = OneHotEncoder(handle_unknown='ignore', sparse_output=False)
train_encoded = encoder.fit_transform(train)
test_encoded = encoder.transform(test)
print(test_encoded.shape) # (1, 3) because 'yellow' ignored
Explanation: The handle_unknown='ignore' parameter creates a zero vector for unseen categories, preventing pipeline crashes. This is critical for production systems where new categories appear over time.
Prompt 3: Feature Scaling Pipeline
Task: Build a Scikit-learn Pipeline that standardizes numeric features and leaves others unchanged.
Prompt:
"Construct a pipeline using
ColumnTransformerandStandardScaler. Numeric columns should be scaled, categorical columns should be passed through unchanged. Use theirisdataset as an example."
Example Result:
from sklearn.datasets import load_iris
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
import pandas as pd
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['species'] = iris.target_names[iris.target]
numeric_features = iris.feature_names
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features)
],
remainder='passthrough' # keep species column as-is
)
pipeline = Pipeline(steps=[('preprocessor', preprocessor)])
df_scaled = pipeline.fit_transform(df)
print(df_scaled.shape) # (150, 5)
Explanation: ColumnTransformer lets you apply different preprocessing steps to different columns. remainder='passthrough' ensures non-numeric columns (like species) are kept, avoiding data loss.
Prompt 4: Train-Test Split with Stratification
Task: Split a dataset into training and test sets while preserving the class distribution.
Prompt:
"Write code using
train_test_splitfrom Scikit-learn to perform a stratified split on a classification dataset. Use 80% training, 20% test, and set a random seed for reproducibility."
Example Result:
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
print(f"Train size: {X_train.shape[0]}, Test size: {X_test.shape[0]}")
Explanation: Stratification ensures each class is proportionally represented in both splits. This prevents biased evaluation when classes are imbalanced. Always set random_state for reproducibility.
Prompt 5: XGBoost Model with Early Stopping
Task: Train an XGBoost classifier using early stopping to avoid overfitting, with a validation set.
Prompt:
"Using XGBoost's
XGBClassifier, train a model witheval_set,early_stopping_rounds=10, andeval_metric='logloss'. Show how to retrieve the best iteration."
Example Result:
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X, y = load_breast_cancer(return_X_y=True)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
model = xgb.XGBClassifier(
n_estimators=1000,
learning_rate=0.1,
early_stopping_rounds=10,
eval_metric='logloss',
random_state=42
)
model.fit(
X_train, y_train,
eval_set=[(X_val, y_val)],
verbose=False
)
print(f"Best iteration: {model.best_iteration}")
Explanation: Early stopping monitors validation loss and halts training when no improvement occurs for early_stopping_rounds consecutive rounds. This saves time and reduces overfitting. The best_iteration attribute shows the optimal number of trees.
Prompt 6: CatBoost with Categorical Features
Task: Train a CatBoost classifier that automatically handles categorical features without manual encoding.
Prompt:
"Using CatBoost's
CatBoostClassifier, specify which columns are categorical using thecat_featuresparameter. Train on a dataset with mixed types and evaluate accuracy."
Example Result:
from catboost import CatBoostClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
df = pd.DataFrame({
'age': [25, 30, 35],
'city': ['NYC', 'LA', 'NYC'],
'income': [50000, 60000, 70000],
'target': [0, 1, 0]
})
X = df.drop('target', axis=1)
y = df['target']
cat_features = ['city']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
model = CatBoostClassifier(iterations=10, verbose=0, random_seed=42)
model.fit(X_train, y_train, cat_features=cat_features)
y_pred = model.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.2f}")
Explanation: CatBoost's native categorical support uses ordered target encoding to reduce overfitting. You only need to pass column indices or names—no OneHotEncoder required. This simplifies pipelines and often improves performance.
Prompt 7: Hyperparameter Tuning with GridSearchCV
Task: Perform grid search over XGBoost hyperparameters using Scikit-learn's GridSearchCV.
Prompt:
"Set up a
GridSearchCVforXGBClassifierwith parameter grid:max_depth[3,5,7],learning_rate[0.01, 0.1], andn_estimators[50, 100]. Use 5-fold cross-validation and return the best parameters."
Example Result:
from sklearn.model_selection import GridSearchCV
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True)
model = xgb.XGBClassifier(random_state=42, use_label_encoder=False, eval_metric='logloss')
param_grid = {
'max_depth': [3, 5, 7],
'learning_rate': [0.01, 0.1],
'n_estimators': [50, 100]
}
grid = GridSearchCV(model, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid.fit(X, y)
print(f"Best params: {grid.best_params_}")
Explanation: GridSearchCV exhaustively searches all combinations—here 3×2×2=12 fits, each with 5-fold CV, totaling 60 model trainings. Use n_jobs=-1 to parallelize. For larger grids, consider RandomizedSearchCV.
Prompt 8: Randomized Search for CatBoost
Task: Use RandomizedSearchCV to tune CatBoost parameters more efficiently than grid search.
Prompt:
"Implement a randomized search for
CatBoostClassifierwithiterations(10, 50),depth(4, 6, 8), andlearning_rate(0.01, 0.1, 0.3). Sample 10 random combinations with 3-fold CV."
Example Result:
from sklearn.model_selection import RandomizedSearchCV
from catboost import CatBoostClassifier
from sklearn.datasets import load_breast_cancer
import numpy as np
X, y = load_breast_cancer(return_X_y=True)
model = CatBoostClassifier(verbose=0, random_seed=42)
param_dist = {
'iterations': [10, 50],
'depth': [4, 6, 8],
'learning_rate': [0.01, 0.1, 0.3]
}
random_search = RandomizedSearchCV(
model, param_dist, n_iter=10, cv=3, scoring='accuracy', random_state=42, n_jobs=-1
)
random_search.fit(X, y)
print(f"Best params: {random_search.best_params_}")
Explanation: Randomized search samples a fixed number of combinations (n_iter), making it faster for large spaces. It's often more effective than grid search because it explores more values per hyperparameter.
Prompt 9: Feature Importance Visualization
Task: Plot feature importance from a trained XGBoost or CatBoost model.
Prompt:
"After training an XGBoost classifier, extract feature importances using
model.feature_importances_and plot a horizontal bar chart of the top 10 features using Matplotlib."
Example Result:
import matplotlib.pyplot as plt
import pandas as pd
import xgboost as xgb
from sklearn.datasets import load_iris
iris = load_iris()
X, y = iris.data, iris.target
model = xgb.XGBClassifier(random_state=42, eval_metric='mlogloss')
model.fit(X, y)
importances = model.feature_importances_
features = iris.feature_names
imp_df = pd.DataFrame({'feature': features, 'importance': importances})
imp_df = imp_df.sort_values('importance', ascending=False).head(10)
plt.figure(figsize=(8, 5))
plt.barh(imp_df['feature'], imp_df['importance'])
plt.xlabel('Importance')
plt.title('XGBoost Feature Importances')
plt.gca().invert_yaxis()
plt.show()
Explanation: Feature importance helps interpret which variables drive predictions. XGBoost's importance is based on how often a feature is used for splitting. For CatBoost, use get_feature_importance().
Prompt 10: Cross-Validation with Pipeline
Task: Integrate preprocessing and model training in a single pipeline, then cross-validate.
Prompt:
"Build a pipeline with
StandardScalerandLogisticRegression, then evaluate it usingcross_val_scorewith 5-fold CV on the wine dataset."
Example Result:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_wine
X, y = load_wine(return_X_y=True)
pipeline = Pipeline([
('scaler', StandardScaler()),
('clf', LogisticRegression(max_iter=1000, random_state=42))
])
scores = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy')
print(f"Accuracies: {scores}")
print(f"Mean: {scores.mean():.3f} (+/- {scores.std():.3f})")
Explanation: Pipelines ensure that preprocessing (scaling) is applied inside each fold, preventing data leakage. This is a best practice for honest evaluation.
Prompt 11: Handling Imbalanced Data with Class Weights
Task: Train a Scikit-learn classifier with class weights to handle imbalanced datasets.
Prompt:
"Use
RandomForestClassifierwithclass_weight='balanced'on the breast cancer dataset. Compare accuracy and recall with a model without class weights."
Example Result:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Without class weights
rf_default = RandomForestClassifier(random_state=42)
rf_default.fit(X_train, y_train)
y_pred_default = rf_default.predict(X_test)
print("Default:")
print(classification_report(y_test, y_pred_default))
# With balanced class weights
rf_balanced = RandomForestClassifier(class_weight='balanced', random_state=42)
rf_balanced.fit(X_train, y_train)
y_pred_balanced = rf_balanced.predict(X_test)
print("Balanced:")
print(classification_report(y_test, y_pred_balanced))
Explanation: class_weight='balanced' automatically adjusts weights inversely proportional to class frequencies. This improves recall for minority classes, often at a slight cost to precision.
Prompt 12: Saving and Loading Models
Task: Save a trained XGBoost model to a file and load it later for inference.
Prompt:
"Using
joblib, save a trained XGBoost model to 'model.pkl', then load it and make predictions on new data."
Example Result:
import joblib
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X, y = load_breast_cancer(return_X_y=True)
X_train, _, y_train, _ = train_test_split(X, y, test_size=0.2, random_state=42)
model = xgb.XGBClassifier(random_state=42, eval_metric='logloss')
model.fit(X_train, y_train)
# Save
joblib.dump(model, 'model.pkl')
# Load
loaded_model = joblib.load('model.pkl')
preds = loaded_model.predict(X[:5])
print(preds)
Explanation: joblib is efficient for large NumPy arrays. For XGBoost, you can also use model.save_model('model.json') and xgb.Booster(model_file='model.json') for cross-language compatibility.
Prompt 13: Model Evaluation with Multiple Metrics
Task: Compute precision, recall, F1-score, and ROC-AUC for a binary classifier.
Prompt:
"After training a CatBoost classifier, evaluate it on test data using
precision_score,recall_score,f1_score, androc_auc_score. Print all metrics."
Example Result:
from catboost import CatBoostClassifier
from sklearn.metrics import precision_score, recall_score, f1_score, roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = CatBoostClassifier(iterations=50, verbose=0, random_seed=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
y_proba = model.predict_proba(X_test)[:, 1]
print(f"Precision: {precision_score(y_test, y_pred):.3f}")
print(f"Recall: {recall_score(y_test, y_pred):.3f}")
print(f"F1: {f1_score(y_test, y_pred):.3f}")
print(f"ROC-AUC: {roc_auc_score(y_test, y_proba):.3f}")
Explanation: Relying solely on accuracy can be misleading for imbalanced data. A combination of precision, recall, F1, and AUC provides a fuller picture of model performance.
Prompt 14: Gradient Boosting with Custom Objective
Task: Implement a custom objective function for XGBoost (e.g., weighted squared error).
Prompt:
"Write a custom squared error objective with sample weights for XGBoost. The objective should return gradient and hessian. Train the model using
xgb.train."
Example Result:
import xgboost as xgb
import numpy as np
def weighted_squared_error(predt, dtrain):
y = dtrain.get_label()
w = dtrain.get_weight() if dtrain.get_weight() is not None else np.ones_like(y)
grad = 2 * (predt - y) * w
hess = 2 * w
return grad, hess
# Dummy data
X = np.random.rand(100, 5)
y = np.random.rand(100)
weights = np.random.rand(100)
dtrain = xgb.DMatrix(X, label=y, weight=weights)
params = {'objective': weighted_squared_error, 'eval_metric': 'rmse'}
model = xgb.train(params, dtrain, num_boost_round=10)
Explanation: Custom objectives give you full control over the loss function. The gradient (first derivative) and hessian (second derivative) are required for XGBoost's Newton boosting.
Prompt 15: CatBoost Multiclass with Custom Loss
Task: Train a CatBoost multiclass classifier and evaluate per-class metrics.
Prompt:
"Using the iris dataset, train a CatBoost classifier for multiclass classification. After training, compute the confusion matrix and per-class F1-score."
Example Result:
from catboost import CatBoostClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, f1_score
import seaborn as sns
import matplotlib.pyplot as plt
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = CatBoostClassifier(iterations=50, verbose=0, random_seed=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
cm = confusion_matrix(y_test, y_pred)
print("Confusion matrix:")
print(cm)
f1 = f1_score(y_test, y_pred, average=None)
print(f"Per-class F1: {f1}")
# Plot
sns.heatmap(cm, annot=True, fmt='d')
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.show()
Explanation: Multiclass evaluation requires per-class metrics. The confusion matrix reveals which classes are confused; low F1 for a class suggests the model struggles to distinguish it.
Conclusion
These 15 prompts cover the essential tasks in any ML project: data cleaning, feature engineering, model training, tuning, and evaluation. By mastering them with Scikit-learn, XGBoost, and CatBoost, you can build robust pipelines that handle real-world data challenges. Start by adapting the code snippets to your own datasets—each prompt is a reusable template. For further learning, consult the official documentation of each library. What prompt would you add to this list? Share your thoughts in the comments.
Comments