読者です 読者をやめる 読者になる 読者になる

hidekatsu-izuno 日々の記録

プログラミング、経済政策など伊津野英克が興味あることについて適当に語ります(旧サイト:A.R.N [日記])

続・工数見積りの海を彷徨う(ロバスト回帰編)

開発

前回のエントリでは、通常の回帰分析を用いて、機能数から工数を算出したが、その結果を見ると、経験的な工数に比べ、多少高めに出ているのではないという疑念があり、改善の余地があるのではないかと考えていた。

勘と経験よりもデータから求められた結果の方が正しいと思われるかもしれないが、まったく根拠がないわけではない。例えば、FP値(IFPUG/新規開発)のデータ群を見ると、平均値 1,798 に対し中央値 878 となっており倍近い開きがある。一般に平均値よりも中央値の方がよりデータ全体の実態を表していると考えられている。

前回のエントリの結論は、通常の回帰分析手法を用いている以上、外れ値は除去したとはいえ、まだ平均値的な値に寄っている可能性がある。

というわけで、引き続き調べていたところ、ロバスト回帰という外れ値や誤差に強い分析手法があることを知った。そもそもの話として通常の回帰分析は外れ値に強く影響されるため、誤差が正規分布していると仮定できない場合には適用すること自体が不適切であるようだ。

さすがにロバスト回帰分析を行うとなると、EXCELではつらい。ということで今回は R を使うことにした。

まず、画面数、帳票数、バッチ数と工数[人時]にロバスト回帰を行う。

> lmrob(MH ~ VC + RC + BC - 1, data_all, setting="KS2014")

Call:
lmrob(formula = MH ~ VC + RC + BC - 1, data = data_all, setting = "KS2014")
 \--> method = "SMDM"
Coefficients:
    VC      RC      BC  
 86.36  118.69   56.22

この結果に従えば、次のようになる。

工数[開発5工程/人時]=86.36×画面数+118.69×帳票数+56.22×バッチ数

前回、重回帰分析をした場合同様、帳票の係数の方が画面よりも大きい。しかしこの係数自体は、あまり信用出来ない。例えば、データを500人月以下に絞ると次のようになる。

> lmrob(MH ~ VC + RC + BC - 1, subset(data_all, MH < 80000), setting="KS2014")

Call:
lmrob(formula = MH ~ VC + RC + BC - 1, data = subset(data_all, MH < 80000),     setting = "KS2014")
 \--> method = "SMDM"
Coefficients:
   VC     RC     BC  
89.74  83.71  54.99

たまたま、大きめのプロジェクトに複雑な帳票が多かったのではないかと思われる(あるいは大規模な業務システムほど、複雑な帳票が増える傾向にあるということかもしれない)。

恣意的ではあるが、今回も係数は画面:帳票:バッチ=1.5:1.0:0.7 を使うことにする(この関係の導出については引き続き課題として残っている)。

> lmrob(MH ~ FC - 1, transform(data_all, FC = 1.5 * VC + RC + 0.7 * BC), setting="KS2014")

Call:
lmrob(formula = MH ~ FC - 1, data = transform(data_all, FC = 1.5 * VC + RC +     0.7 * BC), setting = "KS2014")
 \--> method = "SMDM"
Coefficients:
   FC  
70.63

この結果から式は次のようになる。

工数[開発5工程/人時]=105.95×画面数+70.63×帳票数+49.44×バッチ数

1画面あたり0.66 人月(=105.95/160)。経験的には結構いい線を突いているのではという感じがある。

f:id:hidekatsu-izuno:20160429233333p:plain

規模の係数についてはよくわからない(累乗モデルを適用すると累乗が 1 以下になる)。データを眺めてみたが、規模が大きくなるにつれ係数が大きくなる傾向はあるが、分散だけが広がっているようにも見える。

なお、FP(IFPUG/新規開発)⇒工数の関係についてもロバスト回帰にて求めた。

> lmrob(MH ~ FP - 1, data_fp, setting="KS2014")

Call:
lmrob(formula = MH ~ FP - 1, data = data_fp, setting = "KS2014")
 \--> method = "SMDM"
Coefficients:
   FP  
15.12

FP値から工数を求める場合は、次の式で計算できることになる。

工数[開発5工程/人時]=15.12×FP値

さて、この結果をどのように考えるべきだろうか。おそらく、前回の結果は間違いというよりもリスクを含めた上での平均的な工数見積になっていて、それに対し今回の結果は大半のプロジェクトにとって妥当な工数が見積れていると考えられる。

システム開発プロジェクトは、妥当な見積り工数から見て5倍は上振れする場合があり、妥当な見積りが出せるだけでは十分ではなく、リスク管理がとても重要であるというある意味誰もが知っている話に落ち着く。

1.5倍程度の開きであれば創意工夫でなんとかなる部分もありそうだが、5倍の開きともなるとどうにもならない。リスクがあるならばそれに見合った見積りを出し、それが望めないならば断るということをしない限り、プロジェクトの成功はとても望めそうもない。