- 29.11.2025
- 02.12.2025
- заметки
О чем это
Цензурированные данные - данные, доступные нам не полностью.
Например, мы лечили 100 больных, трое умерли к концу эксперимента, остальные, к счастью, остались живы. Они, конечно, умрут - но непонятно когда. Мы знаем лишь то, что они дожили до конца эксперимента. Как повлияло лечение на продолжительность жизни?
Или мы продавали сахар. И время от времени он кончался у нас на складе. Продажи в этот день были меньше, чем могли бы быть. Но насколько меньше - мы не знаем.
Или мы измеряли, сколько человек вышло на вакансию. Если нам нужно было десять человек, а вышло двое - мы понимаем, что у нас было всего два готовых к работе кандидата. А если нам было нужно десять и десять вышло? Сколько вышло бы, если вакансий было больше?
Цензурированные и усеченные
Прежде всего, данные бывают цензурированными (censored) и усеченными (truncated).
Пусть у нас есть границы измерения (например, от 0 до 100).
Усеченные данные, выходящие за границу, либо не собираются, либо собираются и отбрасываются при анализе.
Предположим, у нас есть мишень и в ней есть пробоины от пуль. Часть пуль пролетела мимо мишени, пробоин от них нет. Мы не знаем, как далеко они пролетели от центра мишени. Иногда даже не знаем, сколько их было. Где средняя точка попадания? Какова срединная ошибка стрелка?
Цензурированные данные при выходе за границу обрезаются по этой границе. Например, мои наручные часы измеряют скорость движения от 0 до примерно 324 км/час. Когда я взлетаю на самолете, они показывают скорость - и останавливаются на 324 км/час, потому что быстрее не бывает. Скорость полета примерно 900 км.час, но часы так не умеют.
Далее мы будем говорить про цензурированные данные.
Цензурированные справа, слева, на интервале
Цензурированные справа данные ограничены сверху (например, спидометр показывает 260 км для любой скорости выше 259)
Цензурированные слева данные ограничены снизу (например, на складе не может быть меньше 0 мешков сахару).
Данные, цензурированные и слева и справа, называются цензурированными на интервале. Например, мы чистили данные медосмотра. Заметили странные значения пульса 15 и 400. Волевым решением привели все записи о пульсе к интервалу от 45 до 240 ударов в минуту - это цензурированные на интервале данные.
Цензурированные справа данные можно представить как цензурированные на интервале [a, +∞), где a - граница интервала.
Цензурированные слева данные можно представить как цензурированные на интервале (-∞, b], где b - граница интервала.
Часто у нас есть оценка лучше чем плюс бесконечность. Например, если мы продавали два билета в группе из 100 человек, максимально возможный спрос - 100, а не +∞, но не все методы умеют это использовать.
Кстати
В клинических испытаниях выделяют типы цензурирования:
- I типа - цензурирование по времени (копаем отсюда и до обеда)
- II типа - по событиям (не более 5 штук в одни руки)
- III типа - случайное (как повезет)
В данной заметке эти полезные различия мы полностью игнорируем (на полях этой рукописи мне не хватило места).
Еще, в работе с пропущеными значеними, различают:
- MCAR пропущеные совершенно случайно (врач иногда не измерял вес пациентов)
- MAR пропущеные случайно, т.е. будет ли значение пропущено, не зависит от самой пропущеной величины, но глядя в другие признаки, мы можем предсказать пропуски (врач иногда не измерял вес пожилых пациентов)
- MNAR пропущеные не случайно (те врач иногда не измерял вес стройных пациентов, чтобы не тратить время)
Цензурирование тоже бывает чем-то обусловлено, но мы и об этом промолчим.
Подходы
Обычно цензурированными данными занимается Анализ выживаемости (Survival analysis).
1. Наивный подход - игнорируем цензурирование Мы можем проигнорировать цензурирование и просто обучить модель на всех доступных данных. Получим смещенные оценки - но если после цензурирования у данных все еще большая вариабельность, а данных много, нам может повезти - и все будет хорошо. Или не будет. Обычно так можно делать, если данные цензурированы полностью случайно (MCAR). Стоит провести анализ чувствительности - т.е. отрезать еще немножко данных по краям интервала цензурирования и посмотреть, как это повлияет на оценки.
2. Наивный подход - учимся только на нецензурированных данных. Например, исключим из анализа всех пациентов, которым повезло дожить до конца нашего эксперимента. Получим смещенную выборку - у нас в данных будут только совсем тяжелобольные, наверняка наше лечение на них действовало иначе. Ну и если оно кому-то совсем-совсем помогло, мы его исключаем из выборки (он дожил до конца). Это смещает наши оценки.
3. Непараметрические модели, вроде модели Каплана-Мейера, не делают предположений о распределении. Качество оценок KM падает, если есть несколько конкурирующих рисков - т.е. например смерть, вызванная разными причинами. Вот, например, как это видят врачи. Вот реализация KM в библиотеке lifelines, см там же модель Кокса.
4. Предположим, что мы знаем распределение данных, не знаем только его параметры. С этим обычно работают в теории надежности и анализе выживаемости - пусть у нас время до отказа хорошо описывается распределением Вейбулла. Тогда мы можем оценить параметры распределения на доступных нам данных. В scipy есть тип CensoredData, позволяющий подбирать параметры распределения для цензурированных выборок.
from scipy.stats import weibull_min
rng = np.random.default_rng()
x = weibull_min.rvs(2.5, loc=0, scale=30, size=250, random_state=rng)
x[x > 40] = 40
data = CensoredData.right_censored(x, x == 40)
print(data)
weibull_min.fit(data, floc=0)
(2.3575922823897315, 0, 30.40650074451254) - близко к истинным параметрам распределения (2.5, 30)
5. XGBoost явно поддерживает цензурированные данные - см https://xgboost.readthedocs.io/en/stable/tutorials/aft_survival_analysis.html
6. Тобит-модель, она же модель Тобина. Вот пример с использованием библиотеки py4etrics
7. Модель Хекмана, развитие модели Тобина на случаи "неслучайного цензурирования". Например, некоторые люди тратят на алкоголь все свободные деньги, а некоторые не пьют алкоголь вовсе - и тратят на него 0. Очевидно, складывать их в одну модельную кучу было бы ошибкой.
8. В библиотеке вероятностного моделирования PyMC есть хорошая поддержка цензурированных данных. Наверное, это самый лучший (и самый заморочный) способ с ними работать.
9. При моделировании продаж обычно делают так называемое "восстановление спроса", например через EM алгоритм. Самый тривиальный подход - более-менее случайно назначаем "истинные значения" цензурированным данным, затем на части данных учим модель, предсказываем цензурированные значения для другой части - и так по кругу на случайных разбиениях на трейн и тест, пока не надоест или не сойдется. Чтобы точно сошлось, можно использовать отжиг - уменьшать "скорость" обучения - т.е. величину, на которую можно поменять ранее предсказанное значение. Предсказанные значения не должны быть меньше цензурированных (для цензурирования справа). Так же, кстати, поступают с восстановлением пропущеных значений.
10. В финансах используют цензурированную квантильную регрессию CQR- см например https://github.com/CyberAgentAILab/cenreg
Для любой из этих техник библиотек для R больше, чем для Python.
Если знаете какой-нибудь хороший подход, про который я тут не написал, напишите мне, пожалуйста.
Рекомендовали книжку Statistical Methods for Reliability Data, но я ее не читал.