Собесов

Mains Lab — драйверы изменения средней стоимости лечения по ДМС

Кейсы и метрикиDecomposition / hypothesis testingСложнаяMiddle

Условие

Дан реестр медицинских услуг (ДМС, одна клиника, 2021–2022). Поля: record_id, service_date, service_name, service_amount, service_number, insured (id пациента), sex_id, age_for_service_date.

Определения:

  • Кейс — последовательность услуг одного застрахованного в одной клинике, между соседними услугами не более 14 дней.
  • Визит — уникальный (date × insured).
  • Обратившийся в месяц — уникальный (month × insured).

Нужно проанализировать изменение средней стоимости лечения 2022 vs 2021 и определить ключевые драйверы. Гипотезы (минимум 3, максимум 6):

  1. Изменилась цена на услуги.
  2. Изменилась интенсивность лечения.
  3. Изменилась полу-возрастная структура пациентов.
  4. Изменилась структура услуг (доли дорогих/дешёвых).
  5. Изменилось среднее число услуг на кейс.
  6. Свои гипотезы.

Решение

Главный показатель

Введём:

  • cost_per_patient_month = Σ amount / unique(insured × month).

Это показатель «средняя стоимость обслуживания одного пациента за месяц».

Декомпозиция:

cost_per_patient_month=services_per_patientинтенсивность×avg_price_per_serviceцена\text{cost\_per\_patient\_month} = \underbrace{\text{services\_per\_patient}}_{\text{интенсивность}} \times \underbrace{\text{avg\_price\_per\_service}}_{\text{цена}}

Дальше avg_price_per_service = Σ amount / Σ service_number.

Гипотезы и проверки

H1. Цена услуг. Берём пересечение service_name, которое есть в обоих годах. Считаем weighted-average цену в 2021 и 2022, веса = service_number_2021 (фиксируем структуру). Если wavg_price_2022 > wavg_price_2021 — есть рост цен.

# Лазпейрес-индекс цен (фикс. структура 2021)
laspeyres = (df22.merge(df21[['service_name', 'qty21']], on='service_name')
                  .assign(p22q21=lambda d: d['price22'] * d['qty21'])
                  ['p22q21'].sum() / df21['amount'].sum())

H2. Интенсивность лечения. services_per_visit_per_patient или services_per_case.

  • Считаем кейсы (см. ниже), число услуг в кейсе. Сравниваем средние и медианы.

H3. Полу-возрастная структура. Для каждого пациента берём (sex, age_bucket). Сравниваем доли в 2021/2022. Если структура смещается в сторону пожилых/мужчин/итп с дороже-средним лечением — это драйвер.

Standardization (decomposition vs structure): пересчитайте 2022 cost при 2021-структуре пациентов:

cost_2022_at_2021_struct=segwseg(21)cost_per_patient_2022_in_seg\text{cost\_2022\_at\_2021\_struct} = \sum_{seg} w^{(21)}_{seg} \cdot \text{cost\_per\_patient\_2022\_in\_seg}

Дельта между real 2022 и 2022_at_2021_struct = вклад «структуры пациентов».

H4. Структура услуг. Считаем долю каждой service_name от total amount. Если в 2022 выросли дорогие услуги (например, КТ, МРТ) — это драйвер. Можно через индекс Пааше (фикс. цена 2022, веса меняются) или просто сравнить распределения.

H5. Услуги на кейс. Сначала строим кейсы:

df = df.sort_values(['insured', 'service_date'])
df['gap_days'] = (df.groupby('insured')['service_date'].diff().dt.days)
df['new_case'] = (df['gap_days'] > 14) | df['gap_days'].isna()
df['case_id']  = df.groupby('insured')['new_case'].cumsum()
df['case_id']  = df['insured'].astype(str) + '_' + df['case_id'].astype(str)

Дальше services_per_case = mean(count(*) per case_id) сравниваем 2021 vs 2022.

H6 (свои):

  • Сезонность визитов (доля Q1, Q2 ...) — могла сдвинуться.
  • Доля «новых пациентов» vs «возвращающихся» — могла поменяться.
  • COVID-эффект: в 2021 — много тестов на covid; в 2022 — лечение последствий, неврология. Резкое изменение структуры услуг.

Финальная декомпозиция

Через logarithmic decomposition:

ΔlnCΔln(services/patient)+Δln(price/service)\Delta \ln C \approx \Delta \ln(\text{services/patient}) + \Delta \ln(\text{price/service})

Можно дальше разложить через Shapley values или structural standardization: посчитать «что было бы», если фиксировать одну компоненту, и так последовательно для каждой гипотезы.

Реализация в Python (скелет)

import pandas as pd
df = pd.read_excel('data.xlsx')
df['year'] = pd.to_datetime(df['service_date']).dt.year
df['month'] = pd.to_datetime(df['service_date']).dt.to_period('M')
 
# 1. Базовый показатель
agg = df.groupby('year').agg(
    revenue=('service_amount', 'sum'),
    services=('service_number', 'sum'),
    visits=(['insured', 'service_date'], 'nunique'),  # сложная агрегация — переписать
    pat_months=([('insured', 'month')], 'nunique')
)
 
# 2. Декомпозиция
# cost_per_patient_month = (services_per_pm) * (price_per_service)
# Сравнить

Подводные камни

  1. Инфляция: цены 2022 в номинале выше из-за инфляции; нужно индексировать (CPI или медицинский индекс) перед сравнением.
  2. service_number ≠ 1: одна строка может быть «5 шт. процедуры» — учитывайте.
  3. Кейсы пересекаются с границей года: кейс начался в декабре 2021, закончился в январе 2022 — куда отнести? Делю по году первого визита.
  4. Сезонность: 2021 vs 2022 на одинаковом отрезке (январь–декабрь) — иначе сезонные пики искажают.
  5. Двойная атрибуция: гипотезы H1+H4 пересекаются (рост цены и рост доли дорогих). Используйте Shapley или последовательную standardization, а не сумму отдельных эффектов.
  6. Структурный shift в данных: новый сегмент услуг (например, телемедицина) появился только в 2022 — нельзя сравнивать price напрямую, считаем contribution отдельно.

Эталонный ответ

Метрика: cost per patient-month. Декомпозиция: services_per_pm × price_per_service. Гипотезы: цена (Лазпейрес), интенсивность, демография (стандартизация), структура услуг, услуги на кейс, COVID-эффект. Финал — Shapley-decomposition или последовательная стандартизация для аддитивного вклада факторов.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти