見積りに関する情報と知見

# はじめに
書籍「データ指向のソフトウェア品質マネジメント」[1]を読んだことをきっかけに、見積りについて学びなおしたことをメモ。
書籍に詳しく記載されていないことを中心に、情報を整理する。
更に、経験則から見積りについて重要と思う知見と見積りの仕方を整理しておく。

# 一般知識
## 見積りモデル[2]
### COCOMO見積りモデル[3][4]
* B. BoehmがTRWで収集したデータに基づき提案したモデル（COnstructive COst MOdel）である。
* 開発規模をLOCで表し，工数を見積る。
* COCOMOでは、開発するソフトウェアの規模と開発工数、開発期間に、非線形の関係があると考えている。すなわち、開発するソフトウェアの規模が大きくなると、より多くの工数、コストが必要になると考える。
* COCOMOの階層
 * 初級COCOMO：プログラム規模のみを変数とする
 * 中級COCOMO：プログラム規模と開発特性をパラメータとするモデル
 * 上級COCOMO：プログラム規模と開発工程毎の開発特性をパラメータとするモデル
* 見積り式

```math
y = ax^b\\

y:平均的な開発工数,x:プログラム規模\\
a:係数（a>0）,b:係数（b>1）

```
```math
z = y\times\prod\alpha_i\\

z:開発工数\\
\alpha_i:開発特性（コスト誘因）に基づく修正係数

```
* 見積りツールが以下のサイトにある。  
http://itref.fc2web.com/management/cocomo.html

### CoBRA見積りモデル[5]
* 独フラウンホーファー財団実験的ソフトウェア工学研究所協会（IESE）から発表された。
* 考え方
 * 規模がほぼ同じでも、かかる工数に違いがある。
* 見積り式
 * 実績データに照らして、変動要因とその定量化を検証し、αを計算。 
 * コスト変動要因のオーバーヘッドを考慮。経験豊富なPL等の熟練者の知見を基に、変動要因とその影響を定量化。

```math
工数 = α \times 規模 \times (1 + \sum CO_i)\\

α:理想的な状態での生産性\\
CO_i:個々の工数増加要因による増加率

```

* 見積り手順
 1. 規模の推定
 2. 変動要因の影響度の評価
 3. 見積りの実行

* CoBRAモデルの構築手順
 1. 変動要因の抽出・定義
 2. 実績データの収集
 3. モデルの構築・改善

## 規模の計測補法
### ファンクションポイント[6]
* 概要と特徴
 * ファンクションポイントは、ソフトウェアの機能の大きさを表す指標で、誰が計測しても同じ値になるという特徴があります。
 * ファンクションポイントの大きさは、データの流れとデータを溜める場所の２種類によって表現します。
 * 機能ごとに点数が定められており、その点数を合計することでソフトウェアの規模を定量化します。

日本ファンクションポイントユーザ会という団体が存在している。
http://www.jfpug.gr.jp/app-def/S-102/wp/

## 法則
### DeMarco‐Glassの法則[2]
>* 「ほとんどのコスト見積りは低すぎる傾向がある」
 * 不必要な作業を追加するよりは、作業項目を忘れる。
 * ソフトウェアの機能も同様に忘れられているものの方が多い。
 * データ等の根拠がない場合は「楽観的に」なりがちである。
 * 不慮の事態が起こりがち：安定した開発はない
 * 「早期の見積り」「時間をかけず、熟慮しないで実施」 

### 不確実性コーン[9][10]
> 　不確実性コーンは、プロジェクトが進行するにつれて見積もりのバラツキがどのように推移していくのかを表しています。横軸はマイルストーンを、縦軸はそれぞれの時期に見積もったプロジェクト規模（工数・スケジュール）を示しています。このグラフを基にプロジェクトが持つ不確実性の特徴を見ていきましょう。
>  
> 　まず一つめの特徴となるのが「バラツキの幅」です。プロジェクトの初期には、見積もりは非常に高いバラツキを持っています。例えば「初期コンセプト」の段階では、最も大きい見積もりで4倍、最も少ない見積もりで0.25倍となっています。つまり、16倍もの開きがあることになります。
> 
> 　二つめは「不確実性の減るタイミング」です。グラフを見ると、時間の経過とともに不確実性が自然に減っていくように見えます。しかし、実はそうではなく、不確実性は各フェイズで意思決定が行なわれることにで小さくなります。製品コンセプトや仕様が明らかになるコミットメントを得ることで、不確実性は小さくなるのです。逆にいえば、意思決定をしなければ、大きな不確実性を抱えたまま、プロジェクトが進んでしまうということになります。
>
>　三つめは「不確実性の減るペース」です。グラフではマイルストーンが等間隔で配置されているため、プロジェクトの後半（「ユーザーインタフェース設計完了」の段階）になってやっとバラツキが「0.8～1.25倍」へと縮まっているように見えます。しかし、実際のタイムスケール的には初期30パーセントの時点でここに到達します。このことから、プロジェクト初期に不確実性に対処することがいかに重要であるかが分かります。

### DoCAP[7]
* PDCAでも、CAPDoでもなく、DoCAP。
* まずはやってみて、やってみた結果をもとに、計画を立てる（見直す）。
* やってみないと計画を立てるもとになる実績がわからない。
* 人によって能力は異なるため、実績も変わる。他人の実績をもとに計画を立てても失敗する。
* Doがなければ、Checkができない。Doがなければ、妥当なPlanができない。

# 知見（私見）
## 見積りに関する知見（私見）
* 見積り工数の利用目的は複数あり、目的によって余裕を持たせるべきか否かが変わる
 * 必要となるリソース・予算・期間を確保するために利用する見積り工数（問題を避けるための見積り工数）：余裕を持たせる
 * 進捗を監視するための見積り工数（問題を早く検出するための見積り工数）：余裕を持たせない
 * これは、CCPMのバッファ管理と似たような考え方かもしれない。
* テストの規模はコード行数ではない、派生開発の場合は変更範囲ではない影響範囲もテストする
 * テスト工程はコード行数を規模としないほうがよい
 * V字の工程の左と右で見積りモデルを変えたほうがよい
 * 工程毎に見積りモデルを変えたほうがよ
* 人は小さいことのほうが想像がしやすい
 * 工程毎に見積り、集計する
 * 要求を分解し（必要に応じて仕様化し）、分解した要求毎に見積り、集計する
 * 担当者毎に見積り、集計する
* 人は相対見積りのほうが想像がしやすい
 * 分解した要求毎に見積った工数を比較検証する
 * LOCはあくまで相対見積りをするために算出する
* 変わりにくいことを規模としたほうが見積り精度は高まる
 * ソースコードの規模（LOC）より変わりにくいことがないか検討する
 * Outputの規模よりInputの規模のほうが変わりにくい、作業のインプットの成果物の規模から見積もれないか検討する
 * LOCよりテストケース数のほうが変わりにくいことがある、テストケース数を規模とすることを検討する
 * 分解した要求の数は変わりにくい、要求の粒度が小さければ要求の数を規模とすることを検討する、このとき必要に応じて重みづけをする
* 人の能力によって見積り工数は大きく変わる、作業を続けると人は能力が向上する
 * 能力の違いによって生産性に6倍以上の差がありそう（後述）
 * 人毎の実績データから見積りをすべき
 * 早く少し作業を実施し、実績工数から見積りを見直す
* 自分の予想は外れる
 * どの程度予想が外れるかを知っておく
 * 実績工数が自分の予想の2倍～3倍大きくなることが多いようであれば、自分が最初に見積もった工数を2倍～3倍しておく

## 生産性に関する知見（私見）
昔から飛び抜けた能力を持つエンジニアと平均的な能力のエンジニアで、生産性が数倍違うという話を聞いていましたが、やっと自分の業務でデータから事実確認できました。
コードリーディングとコーディングで6倍以上の差がありそうです。（6分の1の人も能力がないわけではなく普通に成果物は生み出せる、できる人が圧倒的過ぎる）
一方で、テストについては、自動化環境とテストケース共通のドライバ・スタブが準備できると、人が変わっても2倍くらいは生産性を上げることができることも確認できました。
生産性を大幅に向上させるためには、以下の取り組みがポイントではないかと考えています。

* 参考記事
 * 「プログラマの質、チームの質」，https://agnozingdays.hatenablog.com/entry/2013/12/06/193133
 * 「プログラマーには、コーディングの生産性で10倍、コードレビューの速度では6倍もの能力差があるという」，https://www.publickey1.jp/blog/09/106.html
 * 「優秀なエンジニア5人は二流の1000人を完全に凌駕する」，http://el.jibun.atmarkit.co.jp/rails/2011/06/51000-6676.html

### 生産性向上のポイント
#### V字の左の生産性向上のポイント
* 飛び抜けた能力を持つエンジニアを見つける
* 飛び抜けた能力を持つエンジニアをチームに入れる
* 飛び抜けた能力を持つエンジニアを邪魔せず、最高のパフォーマンスを発揮してもらう（短期的な生産性向上のためには、能力があるからリーダーとしてチームをまとめてもらうのではなく、能力があるからプロダクトをガンガン開発してもらうがよさそう）
* 飛び抜けた能力を持つエンジニアを作る ⇨ これはどうすればいいか、まだわかっていない
* 飛び抜けた能力を持つエンジニアの給与を上げる（マネージャーと同等以上？）

#### V字の右の生産性向上のポイント
* 自動化
* 再利用可能なテスト資産（ドライバ・スタブ等）の作成

## 見積工数の使い方に関するポエム

工数削減を重要な課題としているプロジェクトの振り返りで、見積工数と実績工数の比較結果を分析しても、よいアクションに繋がらない。でも、なぜか自分の周りの多くの人が見積工数と実績工数の比較をしたがる。不思議です。
そこに、見積工数があるからだろうか？見積工数が目の前にあると、どうしても実績工数と比較したくなるのだろうか？プロジェクトの目標が、大幅に工数を削減することではなく、計画通りやることだと思わせてしまっているからだろうか？
これに関して、ある方からは、「目の前に見積りと実績が置いてあれば比べたくなるのは人情でしょう。」と言われた。

見積工数と実績工数の比較結果を分析した結果として、よく報告されているのは以下のようなことでした。
「計画通りでした。問題ありません。」
「計画に対して工数超過しました。見積りの仕方を見直します。」
計画の精度を高めても、チームの生産性は上がらないし、工数は削減されません。

生産性向上・工数削減のためには、工数比率の分析（パレート分析等）と、過去案件の実績工数との比較結果の分析のほうが、よい気づきが得られ、有効なアクションが導き出されます。
もちろん、開発中に進捗を監視し計画を見直すためには、見積工数と実績工数の比較結果を分析することは、すごく有効です。

見積りを使う目的は複数あります。目的を取り違えないようにすることが重要ですね。

# 私の工数見積りの仕方
私は、以下の3つの工数見積り方法を使い分け・組み合わせることが多い。

* 入力の量×実績工数
* 相対見積り
* 積み上げ

突き詰めると、勘で見積もる。
勘で見積もりやすいように工夫する。

## 入力の量×実績工数
DoCAPの考え方を適用。

1. 作業の入力の量を算出する。
1. 作業を実際にやってみて、実績工数を計測する。
1. 作業の入力の量に、作業のスピードをかけて、工数を見積る。

## 相対見積り
昔実施した作業の実績工数をもとに、見積り対象の作業を相対見積りで算出する。

## 積み上げ
作業を細分化し、細かくした作業毎に工数を見積り、見積った工数を合計する。


# 参考文献
[1] 野中誠，小池利和，小室睦，「データ指向のソフトウェア品質マネジメント」，日科技連出版社，2012
[2] 石谷靖，「ソフトウェア開発見積りの基本的な考え方」，IPA，2012，https://www.ipa.go.jp/files/000005394.pdf
[3] 奈良先端科学技術大学院大学，「ソフトウェアのコスト見積り」，2006，http://se-naist.jp/old/lecture/se2/2006/handouts/2006_se2_EffortEstimation.pdf
[4] 「COCOMOによるプロジェクト工数の見積もり」，http://itref.fc2web.com/management/cocomo.html
[5] 塩田英雄，「CoBRA法入門」，IPA，2011，https://www.ipa.go.jp/files/000004776.pdf
[6] 日本ファンクションポイントユーザ会，「ファンクションポイントはどう使える？」，2020，http://www.jfpug.gr.jp/app-def/S-102/wp/wp-content/uploads/HowCanWeUseFP202003.pdf
[7] @kaizen_nagoya，「「オープンソースプロジェクトで上手いことやってくための10の方法」を拝読し」，https://qiita.com/kaizen_nagoya/items/81265788e7cf8f7b230b 
[8] @kaizen_nagoya，「仮説・検証（38）プログラマで「飛び抜けた人が少ない」という仮説」，https://qiita.com/kaizen_nagoya/items/f0d22e20f6d2c58f2c1b
[9] 芝本秀徳，「プロジェクトの本質とはなにか」，https://xtech.nikkei.com/it/article/COLUMN/20131001/508039/
[10] @hirokidaichi，「不安とストレスから解放される見積りとスケジュール方法」，https://qiita.com/hirokidaichi/items/5a204a57a200569f755d
[11] 水野昇幸，「システムテスト、実施フェーズにおけるボトルネック／クリティカルチェーンを特定した残日数管理マネジメントとその効果」，ソフトウェア品質シンポジウム2013，2013，https://www.juse.jp/sqip/library/shousai/?id=151

# 見積りの事例が紹介されているQiitaの記事

https://qiita.com/yuno_miyako/items/8678cd542fbb7050e40e

https://qiita.com/yuchaman/items/843e163abe0cc8830841

https://qiita.com/koitaro/items/405fb3171aa0e04d94da