FP法を用いた見積り手法について

## はじめに
提案活動をはじめとするITコンサルティングを行ううえで、欠かせないのがシステムの見積り（規模/工数/工期/金額）なのですが、お客さま（発注側）からは詳細なRFP（提案依頼書）の提供もあれば、要求仕様（機能要件/非機能要件）等も不明瞭なメモ程度の提案依頼等もあり、その中で発注側及び受注側の双方が納得できる精度の高い見積りを作るのは至難の業です。

この見積もりの精度が低いと工数オーバーで予算が足りなくなり、プロジェクトが炎上したり、逆に、必要以上にリスク費用を見積りに乗せた結果、見積りが競合他社より高額となり、受注に結び付かないことが往々にあります。
また、提案するプロジェクトごとに要求されるシステムの実装形式や開発手法、開発言語等の開発条件の組み合わせも千差万別の中で、精度が高く正確な「見積り」を作成することは、プロジェクトの成否を分けるうえで非常に重要になります。

一般にソフトウェア開発における見積り手法には、一般に以下のようなものがありますが、いずれも過去の類似プロジェクトの実績値や個別な見積り対象となる構成要素から工数を見積もるだけの経験値、あるいはスキルや専門知識による「直感」等が必要となります。
<table>
  <caption>ソフトウェア開発における見積り手法</caption>
  <tr>
    <td> 類推（比較）見積り法 </td> <td>過去の類似プロジェクト事例の実績を参考に比較して見積る方法</td>
  </tr>
  <tr>
    <td> トップダウン見積り法 </td> <td>プロジェクトの作業分解構成図（WBS）に応じて、フェーズ、作業、タスク等の見積り可能なコンポーネントに細分化して見積る方法</td>
  </tr>
  <tr>
    <td> ボトムアップ見積り </td> <td>プロジェクトの成果物の構成要素を洗い出し、それぞれに必要な工数などを見積って積み上げる方法</td>
  </tr>
  <tr>
    <td> 三点見積もり法 </td> <td>個々のタスクに必要な作業量を判断するために、最良推定値、楽観値、悲観値の３つの値の平均を使用して見積もる方法</td>
  </tr>
  <tr>
    <td> パラメトリック見積り法 </td> <td>類似のプロジェクトの過去データを使用し、工数などを目的変数として、説明変数に規模や要因などを設定し、数学的な関数として表す方法</td>
  </tr>
</table>

そこで、見積りする者の経験値やスキル度合い等が異なる中で、誰が見積もりの計測を行っても同じ結果が得られ、また見積もり作業によるばらつきを抑えることができる見積り手法が無いかと考え、たどり着いたのが今回ご紹介するFP（ファンクションポイント）法を用いた見積り手法となります。
なお、FP法に関する情報は、書籍やネット上で検索してもまだまだ乏しく、私自身、見積りで活用するまでには、試行錯誤の連続でしたが、何とか日々の業務で使いこなせるところまできました。

FP法は聞いた事あるけど、「どうやってやるの？」って思っている方々への「基礎編」的な意味合いの記事として解説いたします。

## FP（ファンクションポイント）法とは
FP法とは「ファンクションポイント法（Function Point method）」の略で、1979年に米国IBM社のアラン・アルブレクト（Allan J. Albrecht）氏により開発基盤に影響されないソフトウェア規模計測尺度を目指して考案されたもので、ユーザに見えるシステムの機能（ファンクション）に着目し、機能数やデータ入出力などとその重みを積算してスコア化することにより、ソフトウェア規模を定量化する手法のことを云います。

FP法には、以下のような特徴があります。
* 誰が見積もりをしても、システムの機能（ファンクション）数をもとに算出するだけでソフトウェア規模の見積もりが同等に実施できる
* ボトムアップ見積もりをするほど情報が無い段階や過去の類似プロジェクト事例の実績が無くても、決まったルールに則り見積もりをすることで開発規模の可視化ができる
* ソースコード行数を用いたSLOC（Source Lines of Code）法による見積もりに比べ、プログラミング言語の種類や書き方、機能の実装方法などに依存されない
* 類推見積もり法や担当者の経験値から算出するよりも説得力のある見積もりを出すことができる
* オンプレミスやクラウド等のシステム実装形式、ウォータフォールモデルやアジャイル型の開発手法などに依存されず、ソフトウェア規模（スコア）に差がでない
* 利用者から見た機能要件に基づき、定量的で分かりやすいため、お客さま（発注側）の納得や理解を得やすい

## ファンクションポイントの計算方法には種類がある
FP（ファンクションポイント）は、開発する機能やデータ等の「タイプ」や「複雑性」等によって計算されますが、実はこの計算手法には、IFPUG法、SPR法、MESMA法など、いろいろな種類があります。
その数あるファンクションポイントの計測手法の中で、ISO/JIS規格にも採用されているIFPUG法が最も一般的に利用されています。

IFPUG法は、1986年にアメリカで設立された非営利団体であるIPFUG（International Function Point Users Group）や1994年に設立されたJFPUG（日本ファンクションポイントユーザー会）がFPの評価法についての標準的なガイドラインを発行する等、FP法の普及や手法の確立に尽力したこともあり、ISOおよびJISの規格にも制定されるなど、開発規模の計測手段として定番化しています。

## FP（IFPUG）法の見積り手順

### 1. データFPの計測
先ずは、システムにおけるデータ機能との関連を確認しながら進めるため、データのFPを算出します。
このデータFPは、データベースやデータ格納ファイルのようにデータ保持するための機能で、テンポラリファイルやバックアップデータのような一時データは対象外なので注意が必要です。

#### ◆ データファンクションの種類
**● ILF（Internal Logical File）：内部論理ファイル**

:::note info
自分（内部）のシステム内で作成（追加）、更新、参照、削除する論理ファイル（エンティティ）
:::

**● EIF（External Interface File）：外部インタフェースファイル**

:::note info
外部の他システムで作成したファイル（参照のみ）
:::

#### ◆ カウントの方法
**● RET（Record Element Type）：レコード種類数**

:::note info
サブエンティティ（エンティティに属するエンティティ）の数のこと。
対象テーブルと明細テーブルが1対Nの関係である場合や1つのデータ・ファンクションの中に異なる意味を持つデータのまとまりが混在している場合、その個数をカウントします。
＜例１＞会員種別で「個人会員」と「法人会員」という異なる意味合いを持つレコードが混在している場合、レコード種類は２とする。
＜例２＞ログファイルに、アクセス履歴、ダウンロード履歴、変更履歴の異なる３種類のデータを出力する場合、レコード種類は３とする。
なお、混在していない場合は、レコード種類数を１とします。　
:::

**● DET（Data Element Type）：データ種類数**

:::note info
取り扱うデータ項目（フィールド）数のことで、エンティティのカラムなどを指します。
ただし、削除フラグやシステム更新日等、ユーザーが認識できない論理的なデータ項目の数はカウントしません。
また、繰り返し発生し、順序性のないデータ項目は、最初の１回だけをカウントします。
:::

データ・ファンクションの複雑度（重み付け）は、各エンティティごとに「レコード種類（RET：Record Element Type）数」と「データ項目（DET：Data Element Type）数」で評価し、「低」「中」「高」を判定します。

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/111ef16e-d821-55cc-c899-b117c595de88.jpeg)

次に、各エンティティの重み付けをデータFPの表に当て、それぞれのカウントに重みの掛け算をしたものがデータファンクションの未調整FP（UFP）になります。

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/4f4ba14f-1001-113d-66b7-85ab6548102a.jpeg)
<br>
**＜Excelを用いたデータFP（未調整FP）の算出例＞**

![WS000014.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/fe35aed1-6417-190a-061b-2e4ce8572ef2.jpeg)


### 2. トランザクションFPの計測
次に、データファンクションに対して登録・更新や出力などのデータ操作を行う機能であるトランザクションのFPを算出します。
画面からの入出力、帳票出力、データ連携ファイルの入出力などが該当します。

#### ◆ トランザクションファンクションの種類
**● EI (External Input)：外部入力**

:::note info
画面や他のアプリケーションなどからのデータ入力によって、データファンクションを追加、変更、削除する処理（機能）のこと。なお、バッチによってデータを更新する処理も含みます。
例えば、〇〇登録機能、〇〇編集機能、〇〇削除機能、〇〇月次バッチ処理など
:::

**● EO (External Output)：外部出力**

:::note info
ILFやEIFのデータをもとに、画面や帳票、他のアプリケーションなどにデータを出力する処理（機能）のこと。
ただし、出力データに計算や導出データ（合計値や平均値、グラフ等）などのデータ加工・編集を含むものです。
例えば、〇〇検索/一覧機能、〇〇グラフ表示機能、〇〇帳票出力機能、〇〇PDFファイル出力機能など
:::

**● EQ (External Inquiry)：外部照会**

:::note info
ILFやEIFのデータをもとに、内部論理ファイル（ILF）を更新せず、画面や帳票、他のアプリケーションなどにデータを出力する処理（機能）のこと。
ただし、EO (外部出力）とは逆で、出力データに計算や導出データ（合計値や平均値、グラフ等）などのデータ加工・編集を含まないものです。
例えば、〇〇帳票出力機能、〇〇CSVファイル出力機能など
:::

#### ◆ カウントの方法
**● FTR（File Type Reference）：関連ファイル数**

:::note info
トランザクション・ファンクションが読み書き処理するデータの保存先数や関連ファイル数のこと。
:::

**● DET（Data Element Type）：データ項目数**

:::note info
トランザクション・ファンクションが入出力するデータ項目数、およびプロセスを起動するトリガー数のこと。
なお、画面・帳票のヘッダーなどはDETの数に含めません。
:::
<br>
トランザクションファンクションの複雑度（重み付け）は、各トランザクションファンクションごとに「関連ファイル（FTR：File Type Reference）数」と「データ項目（DET：Data Element Type）数」で評価し、「低」「中」「高」を判定します。

EI (外部入力）トランザクションファンクションのFTR数とDET数を比較して重み付け「低／中／高」を判定します。

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/5abb3fac-289e-fec1-8f1e-cfe911fbd7d8.jpeg)

EO (外部出力）トランザクションファンクションのFTR数とDET数を比較して重み付け「低／中／高」を判定します。

![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/5a98e677-4d82-eb77-5659-4479d0646ffd.jpeg)

EQ (外部照会）トランザクションファンクションのFTR数とDET数を比較して重み付け「低／中／高」を判定します。

![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/e16c5541-fbab-e955-ef75-33f185ef14ef.jpeg)
<br>
各トランザクションファンクションの重み付けをトランザクションFPの表に当て、それぞれのカウントに重みの掛け算をしたものがトランザクションファンクションの未調整FP（UFP）になります。

![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/5db3742b-34ef-3284-31ae-e3a4abb4c42a.jpeg)

**＜Excelを用いたトランザクションFP（未調整FP）の算出例＞**

![WS000016.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/b80d801f-6750-8463-c2f7-adfa7e701c28.jpeg)



### 3. システム特性係数の算出
さらに、以下の14項目のシステム特性ごとに影響度（0～5）のランクをつけ、それらのスケールを合算し、TDI（システム特性の合計値）を求めたうえで、VAF（システム特性係数）を算出します。
#### システム特性係数の計算式
  
    VAF / VAFA /VAFB   ＝ （TDI × 0.01） ＋ 0.65 
    
    * TDI（Total Degree of Influence）：システム特性（スケール）の合計値
    * VAF（Value Adjustment Factor）：システム特性係数
    * VAFA（VAF of application after enhancement）：機能拡張後のアプリケーションのシステム特性係数
    * VAFB（VAF of application before enhancement）：機能拡張前のアプリケーションのシステム特性係数

<table>
  <caption>システム特性（スケール）の算出例</caption>
　<thead>
    <tr>
      <th>#</th>
      <th>項目名</th>
      <th>説明</th>
      <th>影響度</th> 
      <th>スケール</th>  
    </tr>
  </thead>
  <tr>
    <td>1</td>
    <td>データ通信</td>
    <td>アプリケーションやシステムと制御情報やデータを送受信しているか</td>
    <td>３＝影響度：中</td>
    <td> 3 </td>   
  </tr>
  <tr>
    <td>2</td>
    <td>分散データ処理</td>
    <td>分散処理しているか</td>
    <td>１＝影響度：軽微</td>
    <td> 1 </td>   
  </tr>
  <tr>
    <td>3</td>
    <td>パフォーマンス</td>
    <td>レスポンスやスループットの性能目標はあるか</td>
    <td>４＝影響度：大</td>
    <td> 4 </td>   
  </tr>
  <tr>
    <td>4</td>
    <td>高負荷構成</td>
    <td>システムの利用頻度は高いか</td>
    <td>５＝システム全体に影響</td>
    <td> 5 </td>
  <tr>
    <td>5</td>
    <td>トランザクション量</td>
    <td>トランザクション量は多いか</td>
    <td>４＝影響度：大</td>
    <td> 4 </td>   
  </tr>
  <tr>
    <td>6</td>
    <td>オンラインデータ入力</td>
    <td>オンライン入力する方法は多いか</td>
    <td>３＝影響度：中</td>
    <td> 3 </td>   
  </tr>
  <tr>
    <td>7</td>
    <td>エンドユーザー効率性</td>
    <td>アプリケーションはエンドユーザーの効率を考慮して設計されているか</td>
    <td>５＝システム全体に影響</td>
    <td> 5 </td>
  </tr>
  <tr>
    <td>8</td>
    <td>オンライン更新</td>
    <td>オンラインで論理内部ファイルを更新する機能はあるか</td>
    <td>４＝影響度：大</td>
    <td> 4 </td>   
  </tr>
  <tr>
    <td>9</td>
    <td>複雑な処理</td>
    <td>アプリケーションに広範な論理的または数学的処理はあるか</td>
    <td>４＝影響度：大</td>
    <td> 4 </td>   
  </tr>
  <tr>
    <td>10</td>
    <td>再利用可能性</td>
    <td>再利用を考慮して開発されているか</td>
    <td>４＝影響度：大</td>
    <td> 4 </td>   
  </tr>
  <tr>
    <td>11</td>
    <td>インストール容易性</td>
    <td>インストールが簡単になるように開発されているか</td>
    <td>２＝影響度：小</td>
    <td> 2 </td>   
  </tr>
  <tr>
    <td>12</td>
    <td>操作容易性</td>
    <td>起動、バックアップ、およびリカバリ手順等が効率的、また自動化されているか</td>
    <td>５＝システム全体に影響</td>
    <td> 5 </td>   
  </tr>
  <tr>
    <td>13</td>
    <td>複数サイト</td>
    <td>複数のサイトで使用することを考慮して開発されているか</td>
    <td>４＝影響度：大</td>
    <td> 4 </td>  
  </tr>
  <tr>
    <td>14</td>
    <td>変更容易性</td>
    <td>システム改修を考慮して開発されているか</td>
    <td>４＝影響度：大</td>
    <td> 4 </td>   
  </tr>
</table>

### システム特性（詳細）※参考（一部）
#### 01) データ通信（Data Communication）
アプリケーションが通信を行う度合い。
<table>
　<thead>
    <tr>
      <th>項目</th>
      <th>評価点の説明</th>
    </tr>
  </thead>
  <tr>
    <td>0</td>
    <td>バッチ処理のみ、又はスタンドアローンＰＣで稼動</td>
  </tr>
  <tr>
    <td>1</td>
    <td>バッチ処理であるが、リモート（遠隔操作）での入力又は印刷有り</td>
  </tr>
  <tr>
    <td>2</td>
    <td>バッチ処理であるが、リモート（遠隔操作）での入力と印刷の両方を持つ</td>
  </tr>
  <tr>
    <td>3</td>
    <td>オンラインでデータ収集するか、バッチ処理のためのリモート（遠隔操作）によるフロントエンド又は照会システム</td>
  </tr>
  <tr>
    <td>4</td>
    <td>フロントエンド以上の通信機能を持つが、1種類の通信プロトコルだけをサポートする</td>
  </tr>
  <tr>
    <td>5</td>
    <td>フロントエンド以上の通信機能を持つが、複数種類（HTTP，SMTP，POP3，IMAP4，DHCP，DNS等）の通信プロトコルをサポートする</td>
  </tr>
</table>

### 4. プロジェクトFP（開発規模）の算出
最後に、データFP及びトランザクションFPで算出した未調整FPに、VAF（システム特性係数）をかけ合わせ、プロジェクトの開発規模にあたるプロジェクトFPを算出します。

#### ◆ 新規開発プロジェクトFP（DFP：Development FP）の場合
:::note info
新規開発する場合に使用します。
なお、既存システムからデータ移行する場合、新規開発と移行作業の両方について規模を見積もります。
:::

    DFP ＝（UFP ＋ CFP）× VAF
    
        * DFP：新規開発プロジェクトのFP
        * UFP：利用可能なトランザクションファンクションの未調整FP値 ＋ 利用可能なデータファンクションの未調整FP値
        * CFP：データ移行機能のFP値
        * VAF：システム特性係数

#### ◆ 改良開発プロジェクトFP（EFP：Enhanced FP）の場合
:::note info
既存システムへ追加・変更・削除等の改良開発（機能拡張）する場合に使用します。
エンティティやトランザクションを変更しない改修の場合、FP値は0となるので、その部分は工夫が必要です。
:::

    EFP ＝｛（ADD ＋ CHGA ＋ CFP）× VAFA｝＋（DEL × VAFB）
    
        * EFP：機能拡張プロジェクトのFP
        * ADD：機能拡張プロジェクトで追加される機能の未調整FP
        * CHGA：機能拡張プロジェクトで変更される機能の変更後の未調整FP
        * DEL：機能拡張プロジェクトで削除される機能の未調整FP
        * VAFA：機能拡張後のアプリケーションの調整係数（システム特性FP）
        * VAFB：機能拡張前のアプリケーションの調整係数（システム特性FP）
        * CFP：移行機能の未調整FP

#### ◆ アプリケーションFP（AFP：Application FP）の場合
:::note info
既存システムの開発規模を算出するために使用します。
機能拡張FPを算出する際、既存システムの規模が必要となります。
アプリケーションFP計測は、導入されているシステム全機能を計測したものになります。一度導入されたシステムに機能の追加、変更、削除が発生した時はアプリケーションFP値も更新する必要があります。そのため、計測は次の2種類に分け求めます。
:::

**＜初期アプリケーションFP計測の計算＞の場合**

    EFP ＝ UFP × VAF
    
        * AFP：アプリケーションのFP
        * UFP：利用可能な未調整FP
        * VAF：システム特性係数

**＜更新アプリケーションFP計測の計算＞の場合**

    AFP ＝ ｛（UFPB ＋ ADD ＋ CHGA）－（CHGB ＋ DEL）｝× VAFA
    
        * AFP：アプリケーションのFP
        * UFPB：機能拡張プロジェクト開始前（初期）のアプリケーションの未調整FP
        * ADD：機能拡張プロジェクトで追加される機能の未調整FP
        * CHGA：機能拡張プロジェクトで変更される機能の変更後の未調整FP
        * CHGB：機能拡張プロジェクトで変更される機能の変更前の未調整FP
        * DEL：機能拡張プロジェクトで削除される機能の未調整FP
        * VAFA：機能拡張後のアプリケーションの調整係数（システム特性FP）

## 生産性（FP）からの工数算出
最終的に算出されたプロジェクトFP（開発規模）数をFP生産性で除算し、工数を算出します。

**●　全体開発工数（人月） ＝　プロジェクトFP数　÷　FP生産性（FP数/人月）**

:::note info
工程別のFP生産性は、以下の開発種別ごとに場合分けして算出を行います。
なお、工程別FP生産性は、独立行政法人情報処理推進機構（IPA）が発行するエンタプライズ分野のソフトウェア開発データを収集・分析してまとめたソフトウェア開発データ白書などより引用します。
:::

### ■ 開発種別
* 新規開発：① 新規（開発部90%以上) 
* 改良開発：② 拡張（開発部10～90%)
 　　　　　③ 改修・保守（開発部10%未満）
* 再開発　：④ 再開発（近代化：モダナイゼーション等）

### ◆ 工程別 FP 生産性：新規開発の場合（※1,000FPの場合の参考例）
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/0824a2f3-1e4e-87cb-26a4-a8c820be3299.png)

### ◆ 工程別 FP 生産性：改良開発の場合（※1,000FPの場合の参考例）
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/f9fc7932-86d9-4468-b33e-d356de9d321f.png)

### ◆ 工程別 FP 生産性：再開発の場合（※1,000FPの場合の参考例）
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616980/ebae77ee-6306-fa2b-58ac-cbebe53f78b8.png)

## まとめ
FP法は、Excel等のスプレッドシートを用いて、FP数を算定するためのフォーマットを作成すれば、誰でも簡単に見積り規模（FP数）から工数までを算出し、見積ることができます。
なお、FP法も万能な見積り手法ではなく、以下のような留意する点がありますので、FP法の特徴を活かしながら、是非挑戦してみてください。

## FP法の留意点
* 機能要件を低・中・高の複雑度の分類で算定するため、対象とするアプリケーション開発の工数とソフトウェア製造量と直接的に合致しない場合がある
* 要件定義フェーズに入る前のソフトウェアの要件が定まらない段階では、完成する成果物（機能）を逆算して工数見積もりを行うため、初期段階では誤差が大きくなる傾向がある
* IFPUG法を用いた機能（データ）の複雑度評価は、過去の類例をもとに行われるため、過去に同様のシステムや機能を開発した類例（実績）がない場合、正確な見積もりはできない
* 類似する流用できそうな機能があったとしても、流用率を考慮する評価手段が無いため、計測された規模（FP数）を別途に調整する必要がある