ソフトウェアのバグのばらつきについて

ソフトウェアの設計書、ソースコード、テスト仕様書等から発見されるバグは、開発するソフトウェアの仕様、開発環境、開発要員等が異なるため、件数にはばらつきが発生します。このばらつきがどのような傾向になるか把握することは、ソフトウェアの開発が適切な状態になっているかを判断するために参考になります。 このソフトウェアのバグのばらつきについて考えてみました。

目次

1.開発規模とバグ数

ソフトウェア開発プロジェクト(単にプロジェクトと呼ぶ)では、開発プロセスに従ってソフトウェアを作成しますが、一般にその作成されたソフトウェアの開発規模はソースコードの行数で表すことがあります。バグはソースコード内に含まれ、一般にバグ数はソースコード行数が多くなると増加します。

また開発規模が同じでもバグ数は異なり、このバグ数を確率変数$X$で表すことにします。 開発規模が$k$で、バグ数$X$がある特定の値$x$のとき、すなわち$X=x$となるときの確率を$P_{x}(k)$と表します。

開発規模が増加するときバグ数は増加しますが、これを以下のように仮定します。

【仮定】

    開発規模$k$が$k+ \Delta k$になるとき、バグ数$X$が$x+1$になるのは、以下の2つの場合しか存在しない。
  • ①開発規模が$k$の時点で既にバグ数が$x+1$であり、$k+ \Delta k$となってもバグ数は$x+1$のままである。
  • ②開発規模$k$が$k+ \Delta k$になるときバグ数が$x$から$x+1$になる。

したがって、$k+ \Delta k$でバグ数が$x+1$の確率$P_{x+1}(k+ \Delta k)$は、①の場合の確率$P_{x+1}(k)$と②の場合の確率$P_{x}(k)$を用いて以下のように表すことができます。

\[ P_{x+1}(k+ \Delta k) = (1-p_{1}) \cdot P_{x+1}(k) + p_{1} \cdot P_{x}(k) \qquad \ldots \text{(1)} \]

ここで、$p_{1}$は開発規模が$k$でバグ数が$X=x$の時点からバグ数が$X=x+1$になる確率であり、$(1-p_{1})$は開発規模が$k$でバグ数が$X=x+1$の時点からそのままの値になっている確率です。

式(1)を変形すると、

\[ \frac{P_{x+1}(k+ \Delta k) - P_{x+1}(k)}{\Delta k} = - \frac{p_{1}}{\Delta k} \cdot P_{x+1}(k) + \frac{p_{1}}{\Delta k} \cdot P_{x}(k) \]

ここで、$\frac{p_{1}}{\Delta k} = p$、$0 \le p \le 1$とおき、$\Delta k \to 0$として、

\[ \frac{P_{x+1}(k+ \Delta k) - P_{x+1}(k)}{\Delta k} \to \frac{d P_{x+1}(k)}{dk} \]

とすると、

\[ \frac{d P_{x+1}(k)}{dk} = - p \cdot P_{x+1}(k) + p \cdot P_{x}(k) \qquad \ldots \text{(2)} \]

と表すことができます。 この式(2)を解くことにより、確率分布関数$P_{x}(k)$を求めます。

まず、$P_{0}(k)$について考えます。 $P_{0}(0) = 1$、$P_{-1}(0)=0$とすると、$x = -1$のとき式(2)は、 \[ \frac{d P_{0}(k)}{dk} = - p \cdot P_{0}(k) \] となり、これは、 \[ \frac{1}{P_{0}(k)} \cdot \frac{d P_{0}(k)}{dk} = - p \] です。

この式を$P_{0}(0) = 1$を使って解くと、 \[ P_{0}(k) = e^{-pk} \] を得ます。

次に$P_{1}(k)$について考えます。 \[ \frac{d P_{1}(k)}{dk} = - p \cdot P_{1}(k) + p \cdot P_{0}(k) \] \[ \frac{d P_{1}(k)}{dk} + p \cdot P_{1}(k) = p \cdot e^{-pk} \] この微分方程式は、次の微分方程式、 \[ \frac{d}{dx}f + P(x)f = Q(x) \] の一般解、 \[ f = exp(- \int{P(x) dx}) \cdot \{ \int{Q(x) \cdot exp( \int{P(x) dx} ) dx} + C \} \] を用いて解くことができ、 \[ P_{1}(k) = \exp \Bigl [ - \int{p dk} \Bigr ] \cdot \Bigl \{ \int{p \cdot e^{-pk} } \cdot \exp \Bigl [ \int{p dk} \Bigr ] dk + C \Bigr \} \] \[ P_{1}(k) = e^{ - pk} \cdot \{ pk + C \} \] を得ることができます。 $P_{1}(0)=0$より、$C=0$となり、 \[ P_{1}(k) = p \cdot k \cdot e^{ - pk} \] を得ます。 次に$P_{2}(k)$について考えます。 \[ \frac{d P_{2}(k)}{dk} = - p \cdot P_{2}(k) + p \cdot P_{1}(k) \] \[ \frac{d P_{2}(k)}{dk} + p \cdot P_{2}(k) = p^{2} \cdot k \cdot e^{ - pk} \] \[ P_{2}(k) = \exp \Bigl [ - \int { p dk } \Bigr ] \cdot \Bigl \{ \int{p^{2} \cdot k \cdot e^{-pk} } \cdot \exp \Bigl [ \int{p dk} \Bigr ]dk + C \Bigr \} \] $P_{2}(0)=0$より、$C=0$となり、 \[ P_{2}(k) = \frac{1}{2} (pk)^{2} \cdot e^{ - pk} \] を得ます。 次に$P_{3}(k)$について考えます。 \[ \frac{d P_{3}(k)}{dk} = - p \cdot P_{3}(k) + p \cdot P_{2}(k) \] \[ \frac{d P_{3}(k)}{dk} + p \cdot P_{3}(k) = p \cdot \frac{1}{2} (pk)^{2} \cdot e^{ - pk} \] $P_{3}(0)=0$を使うと、 \[ P_{3}(k) = \frac{1}{2 \cdot 3} (pk)^{3} \cdot e^{ - pk} \] を得ます。 以上より、一般解として、 \[ P_{x}(k) = \frac{1}{x!} (pk)^{x} \cdot e^{ - pk} \qquad \ldots \text{(3)} \] を得ることができ、 $P_{x}(k)$はポアソン分布になります。

2.バグ密度の平均と分散

一般にソフトウェア開発では個々のソフトウェアの開発規模は同一ではありません。しかし、バグ密度の平均や分散を求めるために、今、開発規模$k$が同一の複数のソフトウェアがあると仮定します。

まず、バグ数$X$と開発規模$k$から定義したバグ密度$\frac{X}{k}$の平均$E[ \frac{X}{k} ]$を式(3)を用いて計算してみます。 \[ E \Bigl [ \frac{X}{k} \Bigr ] = \sum_{x=0}^{\infty} \frac{x}{k} \frac{1}{x!} (pk)^{x} e^{ - pk} \] \[ = \frac{1}{k} pk \sum_{x=1}^{\infty} \frac{1}{(x-1)!} (pk)^{x-1} e^{ - pk} \] ここで、$x-1= x^{\prime}$とおくと、平均$E[ \frac{X}{k} ]$は、 \[ E \Bigl [ \frac{X}{k} \Bigr ] = p \sum_{x=0}^{\infty} \frac{1}{x^{\prime}!} (pk)^{x^{\prime}} e^{ - pk} = p \] \[ E \Bigl [ \frac{X}{k} \Bigr ] = p \qquad \ldots \text{(4)} \] となります。

次に、バグ密度の分散$V[ \frac{X}{k} ]$を計算します。 \[ V \Bigl [ \frac{X}{k} \Bigr ] = E \Bigl [ \left( \frac{X}{k} \right)^{2} \Bigr ] - \left( E \Bigl [ \frac{X}{k} \Bigr ] \right)^{2} \] ですので、 まず、$E[ (\frac{X}{k})^{2} ]$を計算します。 \[ E \Bigl [ \left(\frac{X}{k} \right)^{2} \Bigr ] = E \Bigl [ \frac{X}{k} \left( \frac{X}{k} - \frac{1}{k} \right) + \frac{X}{k^{2}} \Bigr ] = E \Bigl [ \frac{X}{k} \left( \frac{X}{k} - \frac{1}{k} \right) \Bigr ] + E \Bigl [ \frac{X}{k^{2}} \Bigr ] \] \[ E \Bigl [ \frac{X}{k} \left( \frac{X}{k} - \frac{1}{k} \right) \Bigr ] = \sum_{x=0}^{\infty} \frac{x}{k} \left( \frac{x}{k} - \frac{1}{k} \right) \frac{1}{x!} (pk)^{x} e^{ - pk} = p^{2} \] \[ E \Bigl [ \frac{X}{k^{2}} \Bigr ] = \frac{1}{k}E \Bigl [ \frac{X}{k} \Bigr ] = \frac{p}{k} \] したがって、 \[ E \Bigl [ \left(\frac{X}{k} \right)^{2} \Bigr ] = E \Bigl [ \frac{X}{k} \left( \frac{X}{k} - \frac{1}{k} \right) \Bigr ] + E \Bigl [ \frac{X}{k^{2}} \Bigr ] = p^{2} + \frac{p}{k} \] になります。 以上より、分散は、 \[ V \Bigl [ \frac{X}{k} \Bigr ] = E \Bigl [ \left( \frac{X}{k} \right)^{2} \Bigr ] - \left( E \Bigl [ \frac{X}{k} \Bigr ] \right)^{2} = p^{2} + \frac{p}{k} - p^{2} = \frac{p}{k}   \qquad \ldots \text{(5)} \] この分散より標準偏差は、 \[ σ = \sqrt{V \Bigl [ \frac{X}{k} \Bigr ]} = \sqrt{ \frac{p}{k} } \qquad \ldots \text{(6)} \] になります。

3.開発規模が異なるソフトウェアのバグ密度の平均とその平均の標準偏差

1つのソフトウェアは一般に複数の構成要素(これを以下ではソフトウェアモジュールと呼ぶ。例えば関数など)から構成されています。 今、ソフトウェアMが図1のように、ソフトウェアモジュール$M_{1}, \ldots M_{i-1}, M_{i},\ldots M_{n}$、$1 \le i \le n$ で構成されているとします。

図1 ソフトウェアモジュールのイメージ

図1 ソフトウェアモジュールのイメージ

ソフトウェアモジュール$M_{i}$は開発規模$k_{i}$、バグ数$X_{i}=x_{i}$であったとします。 この開発規模$k_{i}$、バグ数$X_{i}=x_{i}$は、散布図にすると一般に図2のようなグラフになります。

図2 ソフトウェアモジュールのイメージ

図2 ソフトウェアモジュールのイメージ

ソフトウェアモジュール$M_{i}$のバグ密度を$Y_{i} = \frac{X_{i}}{k_{i}}$とします。これを用いて、ソフトウェアモジュールMのバグ密度$\bar{Y}$を以下のように定義します。 \[ \bar{Y} = \frac{Y_{1} \cdot k_{1} + Y_{2} \cdot k_{2} + \ldots + Y_{i} \cdot k_{i} + \ldots + Y_{n} \cdot k_{n}}{ k_{1} + k_{2} + \ldots + k_{i} + \ldots + k_{n}} \qquad \ldots \text{(7)} \] ここで、ソフトウェアモジュール$M_{i}$のバグは式(3)のポアソン分布に全て従うと仮定します。従って、バグ密度$Y_{i} = \frac{X_{i}}{k_{i}}$の平均は、 \[ E [ Y_{i} ]=p \qquad \ldots \text{(8)} \\\\ \] 標準偏差は \[ σ = \sqrt{V \Bigl [ \frac{X_{i}}{k_{i}} \Bigr ]} = \sqrt{\frac{p}{k_{i}}} \qquad \ldots \text{(9)} \] になります。この仮定を踏まえて、$\bar{Y}$の平均を求めてみます。 \[ E \Bigl [ \bar{Y} \Bigr ] = E \Biggl [ \frac{ \sum_{x=1}^{n} Y_{i} \cdot k_{i} }{ \sum_{x=1}^{n} k_{i} } \Biggr] = \frac{1}{\sum_{x=1}^{n} k_{i}} \sum_{x=1}^{n} k_{i} \cdot E [Y_{i}] \] $E [Y_{i}]=p$であることから、バグ密度の平均$E[\bar{Y}]$は、 \[ E \bigl [ \bar{Y} \bigr ]=p \qquad \ldots \text{(10)} \] となります。

次にバグ密度の平均の分散を計算します。 \[ V \bigl [ \bar{Y} \bigr ] = V \Biggl [ \frac{ \sum_{x=1}^{n} Y_{i} \cdot k_{i} }{ \sum_{x=1}^{n} k_{i} } \Biggr] = \frac{1}{ \left( \sum_{x=1}^{n} k_{i} \right) ^{2} } \sum_{x=1}^{n} k_{i} ^{2} \cdot V [Y_{i}] \\\\ = \frac{1}{ \left( \sum_{x=1}^{n} k_{i} \right) ^{2} } \sum_{x=1}^{n} k_{i} ^{2} \cdot \frac{p}{k_{i}} = \frac{p}{ \sum_{x=1}^{n} k_{i} } \qquad \ldots \text{(11)} \] $\sum_{x=1}^{n} k_{i} = K$とおくと、$K$はソフトウェアMの全体開発規模を表し、 \[ V \bigl [ \bar{Y} \bigr ] =\frac{p}{K} \qquad \ldots \text{(12)} \] となります。 この分散より標準偏差は、 \[ σ = \sqrt{V \Bigl [ \bar{Y} \Bigr ]} = \sqrt{\frac{p}{K}} \qquad \ldots \text{(13)} \] になります。

以上のようにソフトウェアモジュール$M_{i}$、$1 \le i \le n$のバグ密度が、式(8)と式(9)を満たす全て同じポアソン分布から得られている場合は、ソフトウェアMの全体のバグ密度は式(10)、標準偏差は式(13)で表すことができます。

4.バグ密度の評価

ソフトウェアのモジュールから摘出されるバグの件数について、「多過ぎる」、「少な過ぎる」を判断するために、前述したバグ密度の平均、標準偏差を用いることができます。

表1に6つのソフトウェアモジュールの開発規模(単位:KL=キロライン)と摘出されたバグ数、計算されたバグ密度を示します。表1の「合計」の行の「開発規模」と「バグ数」の列は6つのモジュールの開発規模の合計とバグ数の合計であり、「バグ密度」はそのバグ数の合計を開発規模の合計で割った数値です。表1の「標準偏差σ」は、式(9)を用いて、式(9)の$p$を「合計」の行のバグ密度3.00、式(9)の$k$を各モジュールの「開発規模」の数値(例えば、モジュール1では開発規模7KL)にして計算したものです。「下限」は、「合計」の行のバグ密度3.00から標準偏差の3倍を引いた数値であり、「上限」は、「合計」の行のバグ密度3.00から標準偏差の3倍を足した数値です。この上限と下限の間に各モジュールのバグ密度があるかどうかを示した列を「許容範囲内か?」の列に示しています。各モジュールの「標準化されたバグ密度」は、以下の式によって計算します。 \[ y_{i} = \frac{ \frac{x_{i}}{k_{i}} - p }{ σ_{i} } \] ここで、$y_{i}$はモジュール$i$の標準化されたバグ密度、$x_{i}$はモジュール$i$のバグ数、$k_{i}$はモジュール$i$の開発規模、$p$は「合計」の行のバグ密度、$ σ _{i}$はモジュール$i$の標準偏差です。標準化されたバグ密度は、バグ密度が平均からどのくらい離れているかを標準偏差の倍数で表した数値になっています。

表1 ソフトウェアモジュールのバグ密度等の計算例

表1 ソフトウェアモジュールのバグ密度等の計算例

図3は、縦軸をバグ密度、横軸を開発規模にして、モジュールのバグ密度を散布図にプロットしたものです。上限と下限は標準偏差から計算していますが、開発規模が小さくなるに従い、上限と下限の幅が広くなっているのがわかります。

図3 モジュールごとのバグ密度(x軸:開発規模)

図3 モジュールごとのバグ密度(x軸:開発規模)

図4に、横軸をモジュールの番号、縦軸をバグ密度にしたときのグラフを示します。このグラフは欠陥についての管理図と同じものです。開発規模がモジュールごとに異なるため、上限と下限が上下に変動していることがわかります。 表1からモジュール3と4のバグ密度は6.00件/KLで同じですが、開発規模が異なるため、モジュール3は上限を超えています。このことからモジュール3はバグが多過ぎると評価できます。

図4 モジュールごとのバグ密度(x軸:モジュール番号)

図4 モジュールごとのバグ密度(x軸:モジュール番号)

図5は、縦軸を標準化されたバグ密度、横軸をモジュールの番号にしたときのグラフを示します。このグラフでは上限と下限は水平の直線になります。モジュール3は管理限界である上限を超えており、バグが多過ぎることがわかります。

図5 モジュールごとの標準化されたバグ密度(x軸:モジュール番号)

図5 モジュールごとの標準化されたバグ密度(x軸:モジュール番号)

5.まとめ

バグ数は開発規模を用いて式(3)に示すようなポアソン分布になります。このことから、バグ密度の標準偏差は式(6)に示すように開発規模に依存することが導かれます。プロジェクトの開発活動から得られたバグ数と開発規模からバグ密度を計算して単純に比較してしまうと、標準偏差が開発規模と関係があることから間違った判断をしてしまうことになり注意が必要です。



本ブログの記載内容に関する免責事項

  • 著者は、数学、特に確率統計の専門家ではありませんので、本ブログに記載した内容については厳密性の欠如や誤りが含まれているかもしれません。しかし、導出された結果については、著者の現場経験から概ね妥当であると考えており、そのためブログとして著者の考えをまとめました。「プライバシーポリシー及び免責事項」に記載していますが、本ブログの内容の利用により生じた損害に対して、いかなる理由であっても著者は一切の責任を負いませんので予めご了承ください。
  • 本ブログの内容は、予告なく変更・削除する場合がありますのでご了承ください。