チームの経験を再現性あるシミュレーションに変える
過去の実績データはある。しかしスケジュール予測にはまったく反映されない。ドリフト補正はその課題を解決する。過去のパフォーマンスをモデルに組み込み、予測の精度を上げるシミュレーション。暗黙知の仕組み化。
データはすでにある。工数管理システム、Excelの進捗管理表、GitHub Issuesもしくは大量のJiraチケット。何百ものタスクが見積もられ、実行され、頻繁に遅延し、完了している。それなのに、次のプロジェクトでは、またゼロから見積もる。
これはPMOの共通課題だ。仮にスケジュールを機械的にシミュレーションしても、チームがこれまで何も納品したことがないかのように「乾いた」予測を弾き出す。楽観・最頻・悲観の3点見積もりを入力し、エンジンが1万回のシナリオを回し、「85%の確率で守れる完了日」が出てくる。悪くない数字だ。しかし、その数字には現場の血が通っていない。
では、過去データがあったら結果は変わるだろうか?組織に合ったシミュレーションになるだろうか?
「わかっている」と「使っている」の明確な違い
ベテランのDevOpsリードに聞けば、こう答えるだろう。「セキュリティ対応は、毎回見積もりより長くかかる。」プロダクトマネジャーに聞けば「ステークホルダーの合意形成で2週間は消える」と返ってくる。彼らはこれを知っている。何度も経験してきたからだ。
しかし、その経験はだいたいの場合「暗黙知化」している。予測には反映されない。シミュレーションは、セキュリティ対応もデプロイ自動化も同じように扱う。同じ分布の形、同じ前提、同じ楽観。
これが予測精度における課題だ。データ不足でもない。直感の欠如でもない。経験則がシステムに反映されていないのである。
レストラン経営で考えてみてほしい。金曜の夜は忙しく、火曜のランチは空いている。同じ人数でシフトを組むことはない。しかし、機械的なスケジュール・シミュレーションがプロジェクトに対してやっているのは、まさにそれだ。タスクごとの実績パターンを無視して、すべてを均質に扱ってしまうのである。
予測の精度を学習によって高められるか?
実装アイデアはとてもシンプルだ。シミュレーションを回す前に、同種タスクの過去実績を調べる。セキュリティ対応が最頻値の140%かかっていたなら、モデルにそう伝える。デプロイ自動化が90%で収まっていたなら、それも取り込む。
これを「ドリフト」と呼ぶ。タスクカテゴリごとのドリフト係数、つまり過去の実績に基づいてシミュレーション期間をシフトさせる。
ここで重要なのは、ドリフト係数を1つの数値に固定しないことだ。ドリフト自体の不確実性もモデルに表現させる。セキュリティ対応は平均で140%超過していたが、あるスプリントでは120%、別のスプリントでは180%だった。このばらつきが重要だ。「140% ± 30%」と言うモデルは、「140%、以上」と言い切るモデルより誠実だ。
ここでディリクレ分布という概念が登場する。専門用語は無視して構わない。やっていることは明快だ。タスクカテゴリに対して不確実な重みを割り当てる。その重みはシミュレーションごとに変動する。結果として、期間の不確実性だけでなく「パターンに対する確信度の不確実性」もシミュレーションに組み込まれる。
カンタンにいうと:
- ドリフトなし: 「このタスクは5〜12日かかる可能性がある。」(機械的、乾いた予測、すべてのタスクで同じ前提)
- ドリフトあり: 「このタスクは5〜12日かかる可能性がある。ただし、このタイプのタスクは長引く傾向があるため、予測は8〜15日寄りになる。どの程度寄るかは、蓄積された実績データの量による。」(現実的、血の通った予測、過去実績により変動)
後者は、経験豊富なエンジニアやPMが実際に考えている方法に近い。違いは、その思考が誰かの頭の中にあるのか、共有モデルに組み込まれているかだ。いいかえると、暗黙知を再現可能なシステムに変換できているかどうかなのである。
実際のケースに当てはめると、どうなるか?
2つ例を挙げる。DevOpsチームとプロダクト開発だ。
DevOpsチーム
プラットフォームチームが大規模なインフラ刷新を計画している。コンテナオーケストレーションの更新、シークレット管理の全面改修、オブザーバビリティ基盤の移行、CI/CDパイプラインの再構築。8つのワークストリーム、12週間の目標。
チームリードは過去に3回、同様の刷新を経験している。パターンは体に染みついている。しかし、プロジェクトのシミュレーションはそのパターンを知らない。
過去2年分の実績をカテゴリ別に集計すると、体感どおりのデータが出てくる:
- セキュリティ・コンプライアンス タスクは一貫して超過する。実績平均は最頻見積もりの142%。ばらつきは中程度。レビューと是正のサイクルを慢性的に過小評価している。
- CI/CDパイプライン 作業は見積もりどおりに収まる。平均98%、ばらつきも小さい。チームはこの領域を熟知している。
- オブザーバビリティ・モニタリング タスクはワイルドカードだ。平均は118%だが、ばらつきが巨大。85%のものもあれば175%のものもある。サードパーティ連携の難度に強く依存している。
機械的なシミュレーションでは、これらはすべて無視される。すべてのタスクが同じ扱いを受ける。「85%の確率で守れる完了日」は14週間と出る。数字は乾いている。
ドリフト補正を適用すると:
- セキュリティタスクは長めの期間に引き寄せられる。チームの慢性的な過小評価が予測に反映される。
- CI/CD作業はそのまま。見積もりはすでに信頼できる。
- オブザーバビリティタスクは幅広い不確実なドリフトを受ける。「上振れ傾向はあるが、どの程度かは確信がない」とモデルが正直に表現する。
補正後の完了日は16.5週間。2.5週間の差は大きい。見積もりが変わったのではない。予測が、チームリードがすでに知っていたことに、ようやく耳を傾けた結果なのである。
さらに重要なのは、リスクがどこに集中しているかが可視化されることだ。セキュリティに関する予算超過リスクを事前に織り込める。オブザーバビリティは本当の不確実性が潜んでいる場所として認識される。この区別が、ステアリングコミッティの議論を「進捗は順調か?」から「どこに注意を集中すべきか?」に変える。
プロダクトチーム
プロダクト組織が新機能セットを開発している。ユーザーリサーチ、UXデザイン、フロントエンド開発、バックエンドAPI、結合テスト、段階的リリース。プロダクトマネジャーには四半期の目標がある。
このチームのデータは違う形をしている。実績が語るのは技術的な複雑さではなく、組織的な摩擦である:
- UXリサーチ・デザイン タスクは平均125%超過する。デザイナーが遅いのではない。ステークホルダーのフィードバックループがレビューサイクルを延ばしている。ドリフトは構造的であり、個人の問題ではない。
- フロントエンド開発 には別の問題がある。シンプルなUI作業は95%で収まる。アクセシビリティ対応やクロスブラウザ対応は155%に跳ね上がる。平均ドリフト115%は、2つのまったく異なる現実を隠している。
- ステークホルダー合意・承認 は見えないスケジュールキラーだ。平均ドリフト160%、標準偏差は巨大。すんなり通る機能もあれば、経営レビュー3回で動けなくなるものもある。チームはバッファを積む癖がついているが、その積み方が一定しない。
乾いたシミュレーションはこの実態を見ない。承認を「2〜5日の範囲の3日タスク」として平たく扱う。
ドリフト補正を適用すると、承認は「5日を中心に3〜8日のタスクで、商業的にセンシティブな機能では12日まで伸びるロングテール」として学習される。この調整だけで、プログラム全体の完了日が1週間ずれる場合もある。
プロダクトマネジャーは数学や統計を理解する必要はない。必要なのは、自分の組織を反映した予測だ。見積もりが描く理想化された(機械的に定義された)組織ではなく。
技術的な詳細・実装の設計
このセクションは技術に関心のある方向けです。実践的な示唆は次のセクションにあります。
ドリフトの仕組みは2層構造で実装されている。
第1層:履歴からの事後推定。 タスクカテゴリごとに、見積もりと実績の比率からドリフト係数の事後分布を算出する。セキュリティタスクの平均ドリフトが1.42、標準偏差が0.15なら、事後分布はN(1.42, 0.15)となる。観測数が多ければ事後分布は狭まる。少なければ広いまま。知っているふりをせず、正直にヘッジする。
第2層:ディリクレ重み付け。 タスクが既知のカテゴリに属していれば、そのカテゴリのドリフトが直接適用される。未分類のタスクやカテゴリをまたぐタスクの場合、ディリクレ分布から重みベクトルを引き、カテゴリ・ドリフトをブレンドする。ディリクレ分布は重みの合計を1に保ちつつ、ブレンド自体にも不確実性を持たせる。
数式はシミュレーション1回あたり一本に集約される:
drift_j = Σ_k [ w_k × μ_k ]
w_kはカテゴリkのディリクレ・サンプリングされた重み、μ_kはそのカテゴリの事後平均ドリフト。サンプリングされたタスク期間にこのdrift_jを乗じる。
信頼性を支える2つの性質:
-
退化可約性。 すべての事後分布が中立(ドリフト = 1.0、履歴シグナルなし)なら、モデルは標準的なシミュレーションに退化する。従来と同じ答えが返る。ドリフトは純粋に加法的であり、結果を悪化させることはない。
-
単調学習。 データが増えれば事後分布は狭まる。モデルの確信度は高まるが、それはデータで裏付けたからであって、仮定で省略したからではない。この違いは重要だ。
実装はオープンソースで公開している。github.com/lemur47/logic。スタンドアロンのPoC は examples/standalone/montecarlo/dirichlet_drift.py — 6つの検証カテゴリをカバーする23のテスト付きで、pytestで実行可能。
あなたが次のスプリントでできる3つのこと
ドリフトモデルを導入しなくても、今すぐ始められることがある。
1. 見積もりと実績をタスクカテゴリ別に記録し始める
タスクが完了したら、元の見積もりと実績期間を並べて記録する。カテゴリでタグ付けする。ざっくりでいい。「開発」「インフラ」「レビュー」「外部依存」程度で。カテゴリあたり20〜30件の完了タスクが溜まれば、パターンが見え始める。
すでに実績を記録しているがカテゴリ分けをしていないなら、トラッカーにフィールドを1つ追加するだけでいい。1列。それが最小限のデータパイプラインだ。
2. カテゴリ別ドリフト係数を計算する
カテゴリごとに、完了タスク全体の実績期間を最頻見積もりで割る。平均が平均バイアス。標準偏差がそのバイアスに対する確信度を示す。
ドリフト1.4、標準偏差0.05なら:「この種の作業は一貫して40%超過し、その傾向はかなり確実だ。」ドリフト1.15、標準偏差0.4なら:「この種の作業は超過傾向にあるが、どの程度かは正直わからない。」どちらも有用だ。後者のほうが誠実であり、誠実さが予測を信頼に足るものにする。
3. 現行プログラムでビフォー・アフターを比較する
次のスケジュールシミュレーションを2回実行する。1回はドリフトなし(従来どおり)、もう1回はドリフト係数を適用する。完了日を比較する。近ければ、見積もりはすでによく較正されている。乖離していれば、見積もりと実績にギャップが見つかったことになる。そのギャップこそ、ステアリングコミッティが話し合うべきテーマだ。
この投稿は pmo.run のプロジェクトデータを意思決定インテリジェンスに変えるシリーズの一部です。ドリフト補正モジュールはオープンソースで公開しています:github.com/lemur47/logic。前回の投稿 — あなたの見積もりは「点」。その裏に「形」が隠れている。 — では、ドリフトの土台となるシミュレーションの基本を解説しています。