Модуль 17. Бизнес-аналитика в медицине (Healthcare)
Картина домена: кто есть кто и где «живут» данные
Системы:
- EMR/EHR (медкарта): пациенты, визиты (encounters), диагнозы/процедуры, назначения, выписка.
- HIS/EPM (админ/регистратура/финансы): расписания, счета, страховые планы.
- LIS (лаб): заказы, результаты.
- RIS/PACS (радиология/изображения): заявки на исследования, изображения (DICOM), отчёты.
- PDMS/ICU (реанимация): витальные параметры, скорости инфузий.
- EMPI/MPI (мастер-идентификатор пациента): дедупликация, злития/разлития записей.
- ESB/iPaaS (интеграции): шина HL7 v2, API FHIR.
- DWH/BI: сырые потоки → нормализация → витрины → семантика.
Потоки:
- HL7 v2: ADT (приём/перевод/выписка), ORM/OML (заказ), ORU (результат), SIU (расписание).
- FHIR: ресурсы Patient, Encounter, EpisodeOfCare, Appointment, Observation, Condition, Procedure, MedicationRequest, ImagingStudy, DiagnosticReport, Practitioner, Organization, Location.
Кодовые системы:
- ICD-10 — диагнозы (болезни).
- LOINC — лабораторные тесты/измерения.
- SNOMED CT — клинические концепты (семантически богаче).
- RxNorm/АТХ — лекарства.
- CPT/HCPCS — процедуры/услуги (часто для биллинга).
Задача BA: согласовать событийную модель (что считается визитом/эпизодом), словарь кодов, правила приватности и метрики; зафиксировать NFR и UAT.
Модель данных (минимально достаточная для Clinic Ops)
Факты:
-
fact_encounter — визит/госпитализация.
Поля: encounter_id, patient_id, type (ED/IP/OP), start_ts, end_ts, admit_src, discharge_disp, department_id, bed_id. -
fact_transfer — внутрибольничные переводы.
encounter_id, from_loc, to_loc, start_ts, end_ts. -
fact_appointment — расписание/явка.
appt_id, patient_id, specialty, planned_ts, status (booked/arrived/no-show/cancelled), provider_id. -
fact_observation — измерения/лабы (нормализованные по LOINC).
obs_id, patient_id, encounter_id, loinc_code, value_num, units, ref_range, status, effective_ts. -
fact_condition — диагнозы (ICD-10/SNOMED).
condition_id, encounter_id, code, coding_system, principal_flag, onset_ts. - fact_procedure — процедуры (CPT/локальная номенклатура).
-
fact_imaging — исследования (PACS/DICOM).
accession, modality, imagingstudy_id, started_ts, completed_ts, radiation_dose (опц.). - fact_readmission — флаги повторных госпитализаций (derived).
- fact_privacy_audit — обращение к данным (кто/когда/что).
Измерения:
- dim_patient (SCD2) — дата рождения/пол/адрес/страховка/EMPI id (PHI!), флаги согласий.
- dim_provider — врач/медсестра/специалист.
- dim_location — учреждение→отделение→палата→коечное место.
- dim_department — ED/ICU/OR/ward/ambulatory.
- dim_payer_plan — страховой план.
- dim_calendar — физкалендарь/рабочие смены/праздники.
Ключевые решения BA:
- Гранулярность визита: inpatient (IP) — от приёма до выписки; ED — отдельный encounter; OP — посещение амбулатории.
- Time-zones: хранить в UTC + локальная зона для отображения.
- Идентификация: единый EMPI id; хранить «историю слияний» (merge/unmerge).
- Лаги: лаборатория и PACS приходят позже ADT — учесть в Freshness/черновиках.
Метрики и определения (без двусмысленностей)
LOS (Length of Stay)
- LOS (дни) = discharge_ts − admit_ts (в днях, правило округления зафиксировать).
- ALOS — средний LOS по отделению/диагнозу.
-
ALOS excluding day cases — без дневных стационаров (опционально).
Ловушки: переводы между отделениями, технические «выписка/перевыписка» — решите, считать ли непрерывным эпизодом.
Readmission (повторная госпитализация)
- 30-дневная readmission: повторный IP-encounter того же пациента в течение 30 дней от выписки (исключая плановые).
-
Rate = # readmitted / # discharges × 100%.
Ловушки: planned vs unplanned, роддом/онкология (особые правила), переносы между учреждениями.
No-show (неявка на приём)
-
No-show rate = # (status=no-show) / # (booked) за период.
Детализация: по врачу/специальности/времени суток/каналу записи.
ED/операционные метрики (если нужно)
- Door-to-Triage/Physician — минуты; LWBS (Left Without Being Seen).
- OR utilization — занятость операционных по слотам, отмены.
Нагрузка/коечный фонд
- Bed occupancy = occupied_bed_hours / available_bed_hours.
- Bed turnover = выписки/коек за период.
- Boarding time (ED→bed) — от решения о госпитализации до размещения.
Правило: все определения — в «паспорт дашборда» и глоссарий; видимость методологии в шапке отчёта.
HL7 v2 и FHIR: что договорить в требованиях
HL7 v2 (сообщения/сегменты)
- ADT^A01/A03/A08 — приём/выписка/обновление. Сегменты: MSH, PID (пациент), PV1 (визит), Zxx (кастом).
- SIU^S12 — расписание (appointment).
- ORM/ORU — заказ/результат (лабы). Сегменты: OBR/OBX.
-
DFT^P03 — финансы (чек/услуги).
BA фиксирует: обязательные поля, словари кодов, правила дедупликации (message control id), таймштампы (TS, точность).
FHIR (ресурсы/связи)
- Patient ↔ Encounter ↔ EpisodeOfCare;
- Appointment/Schedule/Slot для расписаний;
- Observation (LOINC) и DiagnosticReport (лабы/радиология);
- ImagingStudy + ссылка на PACS/VNA;
- Condition (ICD-10/SNOMED), Procedure, MedicationRequest.
NFR/Интеграции:
- Бой — по FHIR REST/Subscriptions (near-real-time), батчи — nightly; максимальная задержка ADT ≤ 1–5 мин, лаборатория/риски ≤ 15–60 мин.
PACS/Imaging (как стыковать в BI)
- DICOM: ключ — AccessionNumber, StudyInstanceUID, Modality (CT/MR/US/XR/… ), PerformedStation, BodyPartExamined.
- RIS→PACS→EHR: заказ (RIS), снимки (PACS), заключение (EHR/RIS).
- Витрина: fact_imaging + DiagnosticReport (текст отчёта), стадийность: scheduled → started → completed → reported.
-
Метрики: время от назначения до выполнения/описания, повторные снимки, отклонения дозы (CTDIvol/DLP — если есть).
Безопасность: доступ к DICOM в BI — только по защищённым ссылкам/рендеринг без скачивания PHI.
Приватность и безопасность медданных (PHI)
Что обязательно:
- Минимизация данных: в BI — только нужные поля; персональные (ФИО/телефон/адрес) скрыты/заменены псевдонимами.
- RLS/ABAC: доступ по роли (врач отделения видит только свой сервис/пациентов), «break-glass» — по политике с аудитом.
- Маскирование: ДР — только год/возрастной диапазон; ID — хеш/токен; свободный текст — редактировать/скрывать.
- Аудит: кто видел карточку пациента/изображения/результаты.
- Согласия/правовые основания: реестр согласий на обработку/исследования.
- Риски повторной идентификации: агрегируйте малые группы (n<5 — не показывать/схлопывать).
- Экспорт: по умолчанию — запрещён PHI, только агрегаты; исключения — через защищённый канал и протокол.
SQL-фрагменты (практика и проверки)
LOS и ALOS по отделениям
SELECT d.department_name,
AVG(EXTRACT(EPOCH FROM (e.end_ts - e.start_ts))/86400.0) AS alos_days
FROM fact_encounter e
JOIN dim_department d ON e.department_id=d.department_id
WHERE e.type='IP' AND e.end_ts IS NOT NULL
GROUP BY d.department_name;
Readmission 30 дней (упрощённо)
WITH discharges AS (
SELECT patient_id, end_ts AS discharge_ts, encounter_id
FROM fact_encounter
WHERE type='IP' AND end_ts IS NOT NULL
),
readm AS (
SELECT d1.encounter_id AS index_encounter,
MIN(d2.start_ts) AS readmit_ts
FROM discharges d1
JOIN fact_encounter d2
ON d2.patient_id = d1.patient_id
AND d2.type='IP'
AND d2.start_ts > d1.discharge_ts
AND d2.start_ts <= d1.discharge_ts + INTERVAL '30 day'
AND d2.admit_src <> 'planned'
GROUP BY d1.encounter_id
)
SELECT COUNT(*)::float / (SELECT COUNT(*) FROM discharges) AS readmit_rate
FROM readm;
No-show rate по специальностям
SELECT specialty,
SUM(CASE WHEN status='no-show' THEN 1 ELSE 0 END)::float
/ NULLIF(SUM(CASE WHEN status IN ('booked','arrived','no-show') THEN 1 ELSE 0 END),0)
AS no_show_rate
FROM fact_appointment
WHERE planned_ts::date BETWEEN :d1 AND :d2
GROUP BY specialty;
Bed occupancy (по часам)
WITH bed_occupancy AS (
SELECT bed_id, ts_hour
FROM generate_series(:from_ts, :to_ts, INTERVAL '1 hour') ts(ts_hour)
JOIN fact_encounter e
ON ts.ts_hour >= e.start_ts
AND ts.ts_hour < COALESCE(e.end_ts, now())
)
SELECT l.location_name, COUNT(*) / NULLIF(SUM(capacity_hours),0) AS occupancy
FROM bed_occupancy b
JOIN dim_location l ON b.bed_id=l.bed_id
-- capacity_hours задайте по отделениям/коечным местам
GROUP BY l.location_name;
Дашборд «Clinic Ops» (нагрузка, no-show, LOS) — макет + NFR
Цели: сбалансировать расписание, снизить неявки, контролировать LOS и загрузку коек.
Зоны:
- KPI-плашки: ALOS, Readmission 30д, No-show %, Bed occupancy %, Boarding time ED→Bed.
- Расписание/нагрузка (heatmap): часы×специальность — занятость слотов, no-show% (цвет).
- Очередь госпитализаций: ожидание коек по отделениям.
- Тренды: ALOS/Readmission по месяцам, no-show по времени суток/каналу записи.
- Таблица пациентов (де-идентифицировано): возрастной диапазон, отделение, LOS, главный диагноз (ICD-10), статус выписки.
- DQ/Privacy-виджет: свежесть ADT/лабораторных/расписания; доля без LOINC; PHI-экспорт=Off; n<5 — скрыто.
Фильтры: период, отделение, тип визита (IP/ED/OP), возраст, страховой план, провайдер.
NFR: Freshness ADT ≤ 5 мин; расписание ≤ 1 мин; PACS/лабы ≤ 15–60 мин; p95 отклик ≤ 5 сек; RLS по ролям (админ/отделение/врач).
Риски и анти-паттерны
|
Риск |
Симптом |
Что делать |
|---|---|---|
|
Дубли пациентов (EMPI) |
Несовпадения LOS/readmission |
Внедрить EMPI, хранить историю merge/unmerge, правила «золотой записи» |
|
Переносы расписания |
Неверный no-show |
Лог изменений SIU, статусы «перенос» vs «отмена» |
|
Поздние лабы/ПАКС |
«Прыгают» тренды |
Freshness-порог, баннер «черновик», блок экспорта |
|
Свободный текст PHI в BI |
Утечка |
Фильтровать/красить текст, отключить drill-through на raw-отчёты |
|
Слишком малые группы |
Ре-идентификация |
Порог n<5 → capping/схлопывание категорий |
|
Непоследовательная методика LOS |
Отделения спорят |
Единая политика округления/переводов; версия методологии |
|
Слияние encounter’ов |
Потеря readmission |
Эпизод ухода (EpisodeOfCare), «сквозной» идентификатор |
|
Таймзоны |
Неверные интервалы |
UTC + локальный tz; DST-фиксация |
|
Карты DICOM внутри BI |
Тяжёлые/рисковые |
Ссылки/просмотрщик с авторизацией, без скачивания |
Теория — «ровно сколько нужно»
- Little’s Law: WIP ≈ Throughput × Lead Time — применим к очередям ожидания консультаций/коек.
- Когортный анализ повторных госпитализаций: группируйте по диагнозам, возрасту, соцфакторам; избегайте Simpson’s paradox (проверяйте ключевые срезы).
- Propensity/DiD: для оценки влияния напоминаний/изменений расписания на no-show.
- SPC для процессов ожидания: контроль вариабельности времени до приёма/до госпитализации.
Вопрос–ответ (FAQ)
Q: EMR vs EHR?
A: EMR — медкарта конкретного учреждения; EHR — объединённая электронная история (cross-org). В аналитике используйте EMPI для склейки.
Q: HL7 v2 или FHIR?
A: Оба: v2 — шина событий из «старых» систем (ADT/ORM/ORU); FHIR — API и near-real-time подписки. Витрины могут питаться из обоих.
Q: LOINC vs ICD-10?
A: LOINC — идентификация теста/измерения; ICD-10 — диагноз. Нельзя подменять одно другим.
Q: Readmission: 30 дней календарных или рабочих?
A: Календарных; зафиксируйте исключения (плановые операции, переводы).
Q: Можно ли показывать списки пациентов в BI?
A: Только де-идентифицировано и по RLS; PHI — в клинических системах с медицинским доступом.
Q: PACS/изображения в дашборде?
A: Да, как ссылки/вьюверы с авторизацией; хранение/экспорт изображений из BI — нельзя без политики и контроля.
Практика (что сдать по итогу модуля)
A. Дашборд Clinic Ops (макет + Acceptance)
- KPI/зоны/фильтры из §8; паспорт дашборда (цель, методология, владельцы, Freshness).
-
Acceptance (минимум 12):
- ALOS по отделению совпадает с эталоном (±0,1 дня).
- Readmission 30д — корректно исключает плановые.
- No-show% по специальности — как в регистратуре (±0,5 п.п.).
- Bed occupancy — корректный numerator/denominator.
- Boarding time ED→Bed — не считается для переводов внутри IP.
- Фильтры совместно — не дают пустых таблиц без объяснения.
- Freshness ADT < 5 мин — иначе баннер «черновик».
- LOINC-код обязателен для Observation (иначе «прочее»).
- PACS-линки открываются только авторизованным.
- RLS: врач видит своё отделение; HQ — всё, итоги совпадают.
- Экспорт — только агрегаты (PHI off).
- p95 отклик ≤ 5 сек при 12 мес истории.
B. Чек-лист приватности (внедрить)
- Категории данных (PHI/не-PHI), RLS/ABAC матрица, маскирование, аудит, экспорт, пороги n-малых групп, политика «break-glass».
C. Схема интеграций и словари
- Карта HL7 v2 (ADT/SIU/ORM/ORU), FHIR ресурсы и связи, кодовые системы (ICD-10/LOINC/SNOMED), таблицы соответствий.
D. DQ-правила (минимум 10)
- Доля Observation без LOINC < 2%.
- Encounter без discharge_disp = 0%.
- Appointment: booked без final status не «зависают» > 24 ч.
- Merge/unmerge лог — непротиворечив.
- Таймстемпы в UTC, локаль известна.
Чек-листы готовности
Методология
- Определения LOS/readmission/no-show/bed occupancy утверждены и версионированы.
- Паспорт дашборда содержит дату свежести и ссылку на глоссарий.
Данные
- EMPI работает, история merge/unmerge хранится.
- HL7 v2 + FHIR покрывают ADT/расписания/лабы/радиологию.
- Коды ICD-10/LOINC в норме; доля «прочее» < порога.
Приватность
- RLS/ABAC по ролям, экспорт PHI — off по умолчанию.
- Маскирование/псевдонимизация, аудит доступа включён.
- n-малых групп обрабатываются.
NFR
- Freshness: ADT ≤ 5 мин; лаб/ПАКС ≤ 15–60 мин.
- p95 ≤ 5 сек; доступность ключевых страниц ≥ 99,5%.
Вы согласуете события (ADT/Appointment/Observation/Imaging), коды (ICD-10/LOINC/SNOMED), приватность (RLS/маскирование/аудит), соберёте витрины и макет Clinic Ops с понятными метриками (LOS/readmission/no-show/коечная нагрузка), при этом формализуете NFR и DQ-правила. Это позволит клинике управлять потоком пациентов и ресурсами, не рискуя безопасностью данных.



