Как предсказать "смерть" open-source проекта с помощью статистики выживания

Как предсказать "смерть" open-source проекта с помощью статистики выживания

Авторы публикации

Рубрика

IT-Технологии

Просмотры

0

Журнал

Журнал «Научный лидер» выпуск # 18 (271), Май ‘26

Поделиться

Большинство метрик анализа репозиториев работают в бинарной логике: проект «жив» или «умер». На практике open-source проекты редко закрывают ся мгновенно: они постепенно теряют активность, проходя через «период полу жизни». В статье показано, как применить упрощенный анализ выживаемости (оценку Каплана–Мейера) к данным коммитов и issue с GitHub, чтобы получить кривую вероятности «заморозки» репозитория через N месяцев. Рассматрива ются подготовка данных, интуитивное объяснение функции выживаемости, ре ализация на Python с использованием библиотеки lifelines и интерпретация результатов для разработчиков, пользователей и инвесторов

«Как предсказать "смерть" open-source проекта с помощью статистики выживания»

Введение

Жизненный цикл open-source проекта не линеен. После всплеска начального интереса многие репозитории переходят в режим поддержки, затем редких правок, и только потом фактически останавливаются. Традиционные подходы (классификация «активен/заброшен» по порогу дней без коммитов) игнорируют два ключевых аспекта:

  •  
    1. Временную динамику: риск «заморозки» меняется со временем.
    2. Правостороннее цензурирование: на момент анализа часть проектов еще активна, и мы не знаем, когда они остановятся.

Статистика выживаемости (survival analysis) изначально разрабатывалась для медицины и инженерии надежности, но идеально ложится на задачу моделирования

«времени до события» (time-to-event). В нашем случае событие – это переход репозитория в состояние «заморозки», а время – месяцы с момента создания или первой значимой активности.

Данные и определение события

Для построения модели потребуются:

  • repo_id – уникальный идентификатор репозитория;
  • start_date – дата создания репозитория или первого коммита;
  • last_activity_date – дата последнего коммита, PR или issue, связанного с кодом;
  • snapshot_date – дата сбора данных.

Определение «заморозки». Проект считается замерзшим, если в течение Tfreeze = 6 месяцев не зафиксировано ни одного коммита и ни одного issue/PR, требующего изменений в коде. Порог можно адаптировать под домен (например, 3 месяца для веб-фреймворков, 12 месяцев для системных утилит).

Цензурирование. Если на snapshot_date проект еще активен, его наблюдение считается цензурированным: мы знаем, что он «выжил» до текущего момента, но не знаем точное время «смерти». Это ключевое отличие от обычной регрессии и причина, почему Kaplan-Meier предпочтительнее простых средних.

Статистика выживания: интуитивное объяснение

Функция выживаемости S(t) определяет вероятность того, что проект останется активным дольше времени t:

S(t) = P (T > t),

где T – случайная величина «время до заморозки».

Оценщик Каплана–Мейера строит ступенчатую кривую S(t), обновляя ее в моменты наблюдаемых «смертей» проектов. Формула:

Sˆ(t) = Y 1 − di ,niti≤t

где:

  • t – момент времени, когда зафиксирована заморозка хотя бы одного проекта;
  • d – число проектов, замерзших в момент ti;
  • n – число проектов, «находящихся под риском» незадолго до ti (активных и еще не цензурированных).

Аналогия. Представьте, что вы наблюдаете за 100 новыми репозиториями. Через 3 месяца 10 из них замораживаются. Из оставшихся 90 еще 5 перестают получать коммиты к 6-му месяцу, а 20 мы просто теряем из виду (цензурирование, т.к. они все еще активны на момент среза). Каплан–Мейер аккуратно учитывает каждый шаг, не «выбрасывая» живые проекты и не искажая статистику средними значениями.

Реализация на Python с использованием lifelines

Для расчетов удобно использовать библиотеку lifelines. Ниже приведен минимальный рабочий пайплайн.

import pandas as pd
import numpy as np
from lifelines import KaplanMeierFitter
import matplotlib.pyplot as plt

# 1. Загружаем данные (пример формата: данные из GHTorrent или GitHub API)
# Колонки: repo_id, created_at, last_activity_at, snapshot_date
df = pd.read_csv("github_repos_activity.csv", parse_dates=["created_at", "last_activity_at", "snapshot_date"])

# 2. Определяем длительность жизни репозитория и цензурирование
FROZE_MONTHS = 6
df["duration_months"] = (
   (df["last_activity_at"] - df["created_at"]).dt.days / 30.44
)

# Событие: репозиторий "замёрз" (нет активности дольше FROZE_MONTHS на момент snapshot_date)
df["event"] = (
   (df["snapshot_date"] - df["last_activity_at"]).dt.days / 30.44
) >= FROZE_MONTHS

# Цензурируем активные репозитории (ещё не замёрзли)
mask_active = ~df["event"]
df.loc[mask_active, "duration_months"] = (
   (df.loc[mask_active, "snapshot_date"] - df.loc[mask_active, "created_at"]).dt.days / 30.44
)

# 3. Строим кривую выживания Каплана-Мейера
kmf = KaplanMeierFitter()
kmf.fit(durations=df["duration_months"], event_observed=df["event"], label="Выживаемость репозиториев")

# 4. Визуализация
plt.figure(figsize=(8, 5))
kmf.plot_survival_function(ci_show=True)
plt.axhline(0.5, color="gray", linestyle="--", linewidth=1)
plt.axvline(kmf.median_survival_time_, color="red", linestyle="--", linewidth=1)
plt.xlabel("Время (месяцы)")
plt.ylabel("Вероятность выживания, S(t)")
plt.title("Кривая выживания репозиториев (с цензурированием)")
plt.grid(True, alpha=0.3)
plt.show()

Интерпретация результатов и «период полужизни»

После построения кривой можно извлечь несколько практических метрик:

  • Медианное время жизни (kmf.median_survival_time_) – момент, когда S(t) =

0.5. Это и есть «период полужизни»: к этому сроку половина проектов из выборки уже замерзла.

  • Вероятность выживания через N месяцев: kmf.survival_function_at_times(N). Например, S(24) = 0.62 означает, что через 2 года 62% репозиториев все еще активны.
  • Сегментный анализ: разбивая выборку по языку, количеству звезд или раз- меру комьюнити, можно строить несколько кривых на одном графике и сравнивать устойчивость экосистем.

На реальных данных GitHub (по выборкам за 2015–2023 гг.) кривая обычно имеет характерную форму: резкий спад в первые 3–6 месяцев (отсев экспериментальных форков), затем плавный пологий хвост. Медианное время жизни часто составляет 18–30 месяцев для типичных user-репозиториев и 40+ месяцев для проектов с > 500 звезд.

Заключение и ограничения

Применение статистики выживаемости к данным GitHub позволяет перейти от бинарных метрик к вероятностным прогнозам, учитывающим время и цензурирование. Каплан–Мейер дает прозрачную, не требующую сложных предположений оценку риска «заморозки», которую легко интерпретировать и визуализировать.

Ограничения:

  •  
    1. Определение «смерти» через порог месяцев без активности субъективно и может не учитывать проекты в режиме долгосрочной поддержки (LTS).
    2. Модель не учитывает коварианты (размер команды, финансирование, наличие CI/CD). Для их включения требуется регрессия Кокса (Cox PH) или случайные леса выживания.
    3. Данные GitHub API подвержены выборочному смещению: приватные репозитории, архивированные проекты и репозитории без issue-трекинга могут искажать выборку.

Перспективы: расширение модели за счет динамического обновления кривых, использования scikit-survival для предсказания индивидуальных рисков и интеграции с метриками CHAOSS (bus factor, time to response, contribution diversity). В сочетании с мониторингом активности такой подход станет полезным инструментом для оценки надежности зависимостей в enterprise-стеке и принятия решений о форках или спонсорстве.

Список литературы

  1. Трофимова Е.А., Кисляк Н.В., Гилев Д.В., – Теория вероятностей и математи- ческая статистика: учебное пособие. – Екатеринбург: Издательство Уральского университета, 2018.
  2. Воробьев Э.И., Статическое моделирование и анализ данных с применением язы- ка программирования Python. – Воронеж, 2017.
  3. Emily C. Zabor, Survival analysis in R. – 2025.
Справка о публикации и препринт статьи
предоставляется сразу после оплаты
Прием материалов
c по
Остался последний день
Размещение электронной версии
Загрузка материалов в elibrary
Публикация за 24 часа
Узнать подробнее
Акция
Cкидка 20% на размещение статьи, начиная со второй
Бонусная программа
Узнать подробнее