Условие
B2B SaaS с 1000 клиентами. CSM команда хочет знать, кто рискует уйти. Спроектируй health score.
Решение
Компоненты health score
| Категория | Метрики |
|---|---|
| Usage | DAU/MAU в account, % seats active, feature adoption breadth |
| Engagement | days since last login, core actions per week, time in app |
| Outcomes | success metrics клиента (revenue/savings они получают) |
| Relationship | NPS, support tickets (sentiment), exec sponsor active |
| Commercial | usage vs plan limits, contract renewal проксимити, expansion sigs |
| Red flags | churn keyword in tickets, security/compliance issues |
Композитная формула
health = w1·usage + w2·engagement + w3·outcomes + w4·relationship - w5·red_flags
Веса — калибруют на исторических churn:
import statsmodels.api as sm
# Target = churned in next 90 days
X = df[['usage_score', 'engagement_score', 'outcomes_score', 'relationship_score', 'red_flags']]
y = df['churned_90d']
model = sm.Logit(y, sm.add_constant(X)).fit()
# β дают эмпирические весаШкала
0-30 Red immediate action, executive escalation
30-60 Yellow CSM outreach, root cause analysis
60-80 Green business as usual, opportunity for upsell
80-100 Champion fanатичный клиент, advocate / case study
ML approach
Вместо линейной свёртки — gradient boosting:
from xgboost import XGBClassifier
model = XGBClassifier().fit(X_train, y_train)
prob_churn = model.predict_proba(X_test)[:, 1]
health = 100 * (1 - prob_churn)XGBoost ловит нелинейности и interactions. Минус: интерпретируемость.
Validation
Backtest: predict churn 90 дней назад, сравнить с реальным churn.
from sklearn.metrics import roc_auc_score
print(roc_auc_score(actual_churn, predicted_churn))AUC > 0.7 — рабочая модель.
Actionability
Health score без действия — бесполезен. Каждый сегмент должен иметь playbook:
| Health | Action |
|---|---|
| Red | Exec call, save plan, discount |
| Yellow | Root cause analysis, training, dedicated CSM |
| Green | Quarterly business review, identify expansion |
| Champion | Reference call, case study, referral |
Granularity
Account-level vs user-level:
- Account health для CSM.
- User health для product (кому показывать onboarding-prompts).
Aggregating user → account: weighted (по seat license, role).
Подводные камни
- Веса «по интуиции» обычно врут. Калибровать на исторических данных.
- Health score — leading indicator. Если ваша outcome — churn 90 days, training data должна включать accounts с уже истёкшим окном.
- Concept drift: health score, обученный 2 года назад, перестаёт работать. Переобучать раз в квартал.
- Single number обманывает: account с low usage может быть в очень крупной компании (политически важен), red ≠ ouster.
- Score не должен «надо смотреть на 10 цифр» — дополнительно ТОП-3 reasons за/против.
Эталонный ответ
Composite score из usage, engagement, outcomes, relationship, red flags. Веса калибровать на historical churn через logistic/XGBoost. Сегменты Red/Yellow/Green с конкретными playbook. Backtest AUC.