montecarlo-subgroup-prediction

Par divinevideo · divine-mobile

Corrige les simulations Monte Carlo de complétion de projet qui donnent des dates identiques pour tous les sous-groupes (jalons, priorités, epics). À utiliser quand : (1) toutes les prédictions des sous-groupes convergent vers la même date malgré des quantités restantes différentes, (2) la mise à l'échelle proportionnelle du débit produit des résultats plats/identiques, (3) l'application du taux global de périmètre aux sous-groupes individuels fait que les simulations atteignent le plafond `max_weeks` sans jamais converger, (4) vous construisez des outils de prévision de projet qui prédisent la complétion pour des sous-groupes d'un backlog plus large. Couvre le modèle de tirage hypergéométrique pour les jalons et le modèle de priorité cumulatif pour les priorités séquentielles.

npx skills add https://github.com/divinevideo/divine-mobile --skill montecarlo-subgroup-prediction

Mise à l'échelle des prédictions de sous-groupes Monte Carlo

Problème

Lors de l'exécution de simulations Monte Carlo pour la complétion de projets, la prédiction de dates pour les sous-groupes (jalons, priorités, épiques) au sein d'un projet plus large produit des résultats identiques pour tous les groupes, ou les simulations divergent et atteignent le plafond max_weeks.

Contexte / Conditions de déclenchement

  • Construction d'un outil de prévision de projets qui prédit les dates pour les jalons individuels ou les groupes de priorités au sein d'un backlog de projet plus large
  • Toutes les prédictions de sous-groupes affichent la même date malgré des comptages restants très différents (par exemple, un jalon de 5 éléments affiche la même date qu'un jalon de 46 éléments)
  • Les simulations atteignent max_weeks (104) et produisent des dates à plus de 2 ans dans le futur
  • Le taux de scope appliqué par groupe crée une vélocité nette négative (les éléments augmentent chaque semaine)

Causes profondes

1. La mise à l'échelle proportionnelle est mathématiquement constante

Si vous mettez à l'échelle le débit proportionnellement :

share = remaining_i / total_remaining
scaled_throughput = overall_throughput * share
weeks = remaining_i / scaled_throughput
      = remaining_i / (overall_throughput * remaining_i / total_remaining)
      = total_remaining / overall_throughput  # CONSTANT pour tous les groupes !

Chaque sous-groupe prédit le même nombre de semaines indépendamment de la taille.

2. Le taux de scope global surpasse le débit du sous-groupe

Si le taux de scope du projet global est de 50 éléments/semaine et que vous l'appliquez à un sous-groupe avec seulement 5 éléments restants (share = 1,6 %), le débit mis à l'échelle pourrait être ~0,6/semaine tandis que le scope mis à l'échelle est ~0,8/semaine. La vélocité nette est négative — la simulation ne converge jamais et atteint max_weeks.

3. created_at GitHub ≠ « Ajouté au tableau »

Le taux de scope calculé à partir des dates created_at reflète le moment où les problèmes GitHub ont été créés, non quand ils ont été ajoutés au tableau du projet. Le triage en masse ou l'importation de vieux problèmes gonfle considérablement le taux de scope apparent.

Solution

Utilisez différents modèles de simulation pour différents types de sous-groupes :

Pour les priorités séquentielles (P0, P1, P2...) : modèle cumulatif

Les priorités plus élevées sont complétées en premier. La prédiction de chaque priorité inclut tous les travaux de priorité supérieure qui doivent être terminés avant :

sorted_priorities = sorted(priorities, key=lambda p: p["name"])
cumulative_before = 0

for p in sorted_priorities:
    effective_remaining = cumulative_before + p["remaining"]
    result = simulate(
        remaining=effective_remaining,
        throughput_history=full_project_throughput,  # NON mise à l'échelle
        scope_rate=0.0,  # Ne pas appliquer le scope par groupe
    )
    result.remaining = p["remaining"]  # Afficher le reste réel
    cumulative_before += p["remaining"]

Pour les jalons/épiques : modèle de tirage hypergéométrique

Les éléments de chaque jalon sont tirés aléatoirement du pool de travail global. Les jalons plus petits se terminent plus tôt en raison d'une variance plus élevée :

for i in range(n_simulations):
    subset_left = remaining
    pool_left = total_remaining
    weeks = 0
    while subset_left > 0 and weeks < max_weeks:
        throughput = rng.choice(throughput_samples)
        draw_size = min(throughput, pool_left)
        if draw_size > 0 and pool_left > 0:
            other = pool_left - subset_left
            # Combien d'éléments complétés proviennent de ce jalon ?
            drawn = rng.hypergeometric(subset_left, max(other, 0), draw_size)
            subset_left -= drawn
            pool_left -= draw_size
            pool_left = max(pool_left, subset_left)
        weeks += 1

Principes clés

  1. Ne pas mettre à l'échelle le débit proportionnellement — cela produit des résultats identiques
  2. Ne pas appliquer le taux de scope global aux sous-groupes — cela cause une divergence
  3. Utiliser le débit complet du projet pour les prédictions de priorités (modèle cumulatif)
  4. Utiliser l'échantillonnage hypergéométrique pour les prédictions de jalons (tirages discrets)
  5. Afficher le taux de scope à titre informatif plutôt que de l'incorporer dans le MC par groupe

Vérification

  • Les sous-groupes avec moins d'éléments restants devraient prédire des dates plus tôt
  • Les sous-groupes plus petits devraient avoir des intervalles de confiance plus larges (plus de variance)
  • Aucune prédiction ne devrait atteindre le plafond max_weeks dans des conditions normales
  • Les prédictions de priorités devraient être ordonnées (P0 < P1 < P2 < P3)

Exemple

Avec un débit de [2, 29, 44, 34, 11, 24, 33, 54, 34, 101, 57, 81, 0] et 303 éléments restants au total :

Avant correction (mise à l'échelle proportionnelle) :

MVP Rel 1 (5 left):   Apr 13    # Tous identiques !
MVP Rel 2 (46 left):  Apr 13
Release 3 (33 left):  Apr 13

Après correction (tirages hypergéométriques) :

MVP Rel 1 (5 left):   Apr 6     # Différenciés par taille
MVP Rel 2 (46 left):  Apr 13
Release 3 (33 left):  Apr 13
Zap Store (10 left):  Apr 13

Notes

  • Le modèle proportionnel continu (subset_throughput = throughput * share) est mathématiquement équivalent à « tout se termine quand le projet se termine » car l'équation différentielle d(subset)/dt = -T*(subset/pool) préserve les ratios
  • La distribution hypergéométrique est le modèle statistique correct pour « tirer sans remplacement dans un pool mixte »
  • Pour les très petits sous-groupes (< 5 éléments), le modèle hypergéométrique produit une variance élevée — c'est correct et reflète une incertitude véritable
  • Envisagez de plafonner scope_rate à min(scope_rate, throughput * 0.5) si vous l'utilisez, pour éviter les simulations divergentes

Skills similaires