YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

Attrition Prediction β€” Model B (XGBoost + Feature Engineering)

A binary classifier that predicts employee attrition risk using XGBoost trained on 14 engineered features derived from 8 raw HR signals.


Model at a Glance

Property Value
Algorithm XGBoost + StandardScaler (sklearn Pipeline)
Feature Set 14 (8 raw + 6 engineered)
Cross-Val F1 0.9834 Β± 0.0008
Cross-Val AUC 0.9996 Β± 0.0000
Cross-Val Recall 0.9800 Β± 0.0008
Cross-Val Precision 0.9869 Β± 0.0010
Test AUC 0.9997
Bundle file attrition_model_bundle_XGB_FE.pkl

Features

Raw Inputs (8)

Feature Range Description
EngagementScore 0–10 Employee engagement level
TenureMonths 1–120 Months of employment
StressScore 0–10 Workplace stress level
PromotionDelay 0–120 Months since last promotion
EngagementTrend βˆ’1 – +1 Direction of recent engagement change
SentimentScore βˆ’1 – +1 Survey/text-derived sentiment
PerformanceScore 0–10 Manager-rated performance
ConflictScore 0–10 Frequency/severity of workplace conflicts

Engineered Features (6)

Feature Formula Rationale
stress_per_tenure StressScore / (TenureMonths + 1) Stress normalised by tenure; newer employees under high stress are highest-risk
engagement_drop EngagementScore * (1 - EngagementTrend) Combines current engagement level with rate of decline
burnout_index (StressScore * ConflictScore) / (EngagementScore + 1) Non-linear burnout composite; amplifies when stress and conflict are high and engagement is low
stress_log log1p(StressScore) Log-transforms stress to compress the tail and improve split quality
tenure_sqrt sqrt(TenureMonths) Captures diminishing tenure effect on attrition risk
fe_risk_score 0.4 * Stress + 0.3 * Conflict - 0.3 * Engagement Domain-expert weighted composite; directly interpretable by HR teams

Hyperparameters

XGBClassifier(
    n_estimators=400,
    max_depth=5,
    learning_rate=0.05,
    subsample=0.85,
    colsample_bytree=0.85,
    eval_metric="logloss",
    random_state=42
)

Pipeline: StandardScaler β†’ XGBClassifier


Installation

pip install xgboost scikit-learn joblib pandas numpy

Usage

Load the bundle

import joblib
import pandas as pd
import numpy as np

bundle = joblib.load("attrition_model_bundle_XGB_FE.pkl")
pipeline   = bundle["pipeline"]
features   = bundle["features"]          # 14-element list
add_features = bundle["feature_engineering"]  # callable
thresholds = bundle["risk_thresholds"]   # {"high": 0.60, "medium": 0.35}

Feature engineering function

def add_features(df: pd.DataFrame) -> pd.DataFrame:
    df = df.copy()
    df["stress_per_tenure"] = df["StressScore"] / (df["TenureMonths"] + 1)
    df["engagement_drop"]   = df["EngagementScore"] * (1 - df["EngagementTrend"])
    df["burnout_index"]     = (df["StressScore"] * df["ConflictScore"]) / (df["EngagementScore"] + 1)
    df["stress_log"]        = np.log1p(df["StressScore"])
    df["tenure_sqrt"]       = np.sqrt(df["TenureMonths"])
    df["fe_risk_score"]     = (
        0.4 * df["StressScore"]
        + 0.3 * df["ConflictScore"]
        - 0.3 * df["EngagementScore"]
    )
    return df

Predict a single employee

RAW_FEATURES = [
    "EngagementScore", "TenureMonths", "StressScore", "PromotionDelay",
    "EngagementTrend", "SentimentScore", "PerformanceScore", "ConflictScore"
]

def predict(raw_input: dict) -> dict:
    row = pd.DataFrame([raw_input])[RAW_FEATURES]
    row = add_features(row)[features]

    prob = pipeline.predict_proba(row)[0, 1]
    prob = np.clip(prob, 0.05, 0.95)

    tier = "High" if prob >= 0.60 else "Medium" if prob >= 0.35 else "Low"

    return {
        "resign_pct": round(prob * 100, 2),
        "stay_pct":   round((1 - prob) * 100, 2),
        "risk_tier":  tier,
        "probability": round(prob, 4),
    }

# Example
result = predict({
    "EngagementScore": 3.2,
    "TenureMonths": 28,
    "StressScore": 8.7,
    "PromotionDelay": 28,
    "EngagementTrend": -0.62,
    "SentimentScore": -0.30,
    "PerformanceScore": 6.8,
    "ConflictScore": 6.2,
})
print(result)
# {'resign_pct': 95.0, 'stay_pct': 5.0, 'risk_tier': 'High', 'probability': 0.95}

Batch prediction

df_raw = pd.read_csv("employees.csv")
df_fe  = add_features(df_raw)[features]

probs = pipeline.predict_proba(df_fe)[:, 1]
probs = np.clip(probs, 0.05, 0.95)

df_raw["resign_pct"] = (probs * 100).round(2)
df_raw["risk_tier"]  = pd.cut(
    probs,
    bins=[0, 0.35, 0.60, 1.0],
    labels=["Low", "Medium", "High"]
)

Risk Tiers

Tier Probability Threshold Recommended Action
πŸ”΄ High β‰₯ 60% Immediate manager intervention + retention package
🟑 Medium 35% – 59% Scheduled 1:1 check-in + engagement survey
🟒 Low < 35% Standard monitoring cadence

SHAP Explainability

import shap

scaler    = pipeline.named_steps["scaler"]
xgb_model = pipeline.named_steps["xgb"]

# Scale with feature names preserved β€” required for correct SHAP labels
X_scaled = pd.DataFrame(
    scaler.transform(X_sample),
    columns=X_sample.columns
)

# Background sample for interventional perturbation
background = pd.DataFrame(
    scaler.transform(X_train.sample(100, random_state=42)),
    columns=X_train.columns
)

explainer   = shap.TreeExplainer(xgb_model, background, feature_perturbation="interventional")
shap_values = explainer(X_scaled)

shap.plots.beeswarm(shap_values, max_display=14)

Important: always pass the scaled feature matrix to TreeExplainer, not raw values. Wrap the scaled array in a named DataFrame to preserve feature labels in plots.


Bundle Contents

{
    "pipeline":            <sklearn Pipeline>,  # StandardScaler + XGBClassifier
    "features":            [...],               # ordered list of 14 feature names
    "feature_engineering": <callable>,          # add_features() function
    "model_type":          "stack_xgb_fe",
    "risk_thresholds":     {"high": 0.60, "medium": 0.35},
    "shap_note":           "Scale before SHAP; wrap in named DataFrame"
}

Notes

  • Probabilities are clipped to [0.05, 0.95] to prevent degenerate 0% / 100% outputs on edge-case inputs.
  • The fe_risk_score feature is a useful standalone KPI for HR dashboards β€” it requires no model inference.
  • For highest accuracy at the cost of inference speed, use Model C (stacking ensemble). Model B is recommended for real-time API deployments.
  • Re-train quarterly on updated HR data to account for organisational changes.
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support