next up previous contents
Next: 6.7 Entwurfsprüfung Up: 6. Der persönliche Softwareprozeß Previous: 6.5 Maße im PSP

Unterabschnitte

  
6.6 Größenschätzung

Sorgfältige und genaue Planung ist eines der Hauptmerkmale des PSP. Dazu gehört insbesondere eine gute Schätzung des (Zeit)Aufwandes für ein Projekt. Diese Schätzung wird im PSP auf dem Umweg über die Größe des entstehenden Programms vorgenommen, weil davon ausgegangen wird, daß erstens die Anforderungen bereits bekannt sind und zweitens die Entwicklungszeit dann recht gut mit der Größe korreliert. Diese Annahmen sind innerhalb des üblichen Anwendungsbereichs des PSP oftmals gut erfüllt.

Das große Problem beim Schätzen ist ganz allgemein, daß einerseits eine Schätzung möglichst früh gemacht werden soll, andererseits eine genaue Schätzung Informationen über Details benötigt, die so früh noch nicht vorhanden sind. Es gilt also, eine Möglichkeit zu finden, wie man das nötige Maß von Detailinformationen durch anderes ersetzen kann, um auch ohne sie zu einer genauen frühen Schätzung zu kommen. Um das zu erreichen, muß man auf direktes Schätzen verzichten und stattdessen die Schätzung über einen Vergleich mit Bekanntem vornehmen. Auf diese Weise lassen sich historische Daten über frühere Entwicklungsarbeiten nutzbringend in der Schätzung einsetzen.

6.6.1 Gesamtvorgehen

Gehen wir einmal davon aus, daß wir eine Entwicklung in einer objektorientierten Programmiersprache schätzen sollen (andernfalls läßt sich das Verfahren anpassen, indem wir Module statt Objektklassen benutzen etc.). Dann funktioniert das PSP-Größenschätzverfahren folgendermaßen: Ausgangspunkt der Schätzung ist ein sogenannter konzeptueller Entwurf. Ein solcher identifiziert die Hauptkomponenten, die zur Lösung des Problems vermutlich benötigt werden, z.B. auf der Ebene von Objektklassen und beschreibt grob deren Funktionalität. Der Zweck des konzeptuellen Entwurfs ist lediglich die Größenschätzung; er stellt keine Festlegung des tatsächlichen Entwurfs dar, obwohl er in der Regel natürlich eine gute Grundlage dafür bildet. Bei größeren Aufgaben kann die Herstellung eines konzeptuellen Entwurfs eine beträchtliche Arbeit sein, die mehrere Tage dauert, weil man bis zu einer Ebene von Komponenten herunterbrechen muß, die man gut schätzen kann; aber in jedem Fall steht der Aufwand in einem sinnvollen Verhältnis zum Gesamtaufwand. Im konzeptuellen Entwurf läßt sich auch etwa abschätzen, welche Teile eines bestehenden Programms als Basisprogramm übernommen werden können und wie umfangreich die Änderungen daran sind, wenn das Problem die Erweiterung eines bestehenden Programms ist, und wie viele andere bestehende Komponenten in welchem Gesamtumfang unverändert wiederverwendet werden können.

Die Schätzungen von Basis, Löschungen, Modifikationen, Zufügungen und neuen Objekten werden zusammengerechnet und ergeben die initiale Schätzung. Diese wird schließlich mit Hilfe historischer Daten über die Genauigkeit früherer Schätzung korrigiert, indem man eine lineare Regression berechnet, die die initiale Schätzung auf die wirkliche Schätzung abbildet. Diesen Schätzprozeß werden wir nun etwas genauer besprechen, wobei wir uns auf folgendes Beispiel beziehen:

Base Program                                         LOC
  Base size (B)                                      295
  LOC deleted (D)                                     25
  LOC modified (M)                                    30
Projected LOC (P)
  Base_additions (BA)      (Type) (#meth) (size)     LOC
    readFromNetwork                                   40
    openAgain                                         15
  Total_base_additions ___________________________    55
  New_objects (NO)          Type   #meth   size      LOC
     Networkcomm             I/O     10      M       160
     BasicNetwork            I/O      8      S        96
     Crypt                   Comp     3      L        75
  Total_new_objects (NO)__________________________   331
Reused objects                                       LOC
     Longint                                         780
  Reused_total (R)                                   780
Estimation:
  Projected LOC (P)   BA+NO                          386
  Estimated New&changed LOC (N)  beta0+beta1(P+M)    488
  Estimated total LOC (T)  B+N-D-M+R                1508
  Prediction interval                          448 - 528
  Prediction interval level (%)                       70

Hierbei handelt es sich um ein Schätzformular, das im Laufe der Schätzprozedur ausgefüllt wird. Nun also das Vorgehen noch einmal in Schritten:

1.
Erstelle einen konzeptuellen Entwurf.
2.
Identifiziere ggf. das Basisprogramm, daß sich als Grundlage der neuen Entwicklung verwenden läßt und trage seine Größe unter B ein (hier: 295 LOC).
3.
Schätze, wie viele der Zeilen des Basisprogramms gelöscht oder geändert werden müssen und trage diese Werte unter D bzw. M ein (hier: 25 bzw. 30 LOC).
4.
Schätze, wie viele Zeilen am Basisprogramm vermutlich zugefügt werden, um die Aufgabe zu lösen. Diese Schätzung geht normalerweise Prozedur für Prozedur vor und schätzt die Länge ganz neuer Prozeduren oder die Länge von Zufügungen bei Prozeduränderungen. Ggf. kann man auch ähnlich vorgehen, wie bei der Schätzung der Objektklassengröße unten. Trage diese Zufügungen unter BA (base additions) ein. Im Beispiel gibt es zwei neue Prozeduren im Umfang von 40 und 15 LOC, insgesamt ist also BA gleich 55.
5.
Schätze nun den Umfang der noch ganz neu zuzufügenden Klassen, falls nötig. Dies ist bei umfangreicheren Erweiterungen eines Basisprogramms meist nötig und enthält sogar den gesamten Programmumfang, wenn es gar kein Basisprogramm gibt. Für jede Klasse gebe einen Namen an, eine Klassenart, die voraussichtliche Anzahl von Methoden und die Größenklasse: Im Beispiel haben wir drei neue Klassen: eine Ein/Ausgabeklasse Networkcomm mit mittlerer Größe der Methoden und voraussichtlich 10 Methoden, die insgesamt ungefähr 160 LOC lang werden müßte; eine Ein/Ausgabeklasse BasicNetwork mit 8 kleinen Methoden (insgesamt 96 LOC) und eine Berechnungsklasse Crypt mit 3 großen Methoden (insgesamt 75 LOC). Zusammen ergeben diese drei Klassen eine Zufügung von ,,new objects`` (NO) von 331 LOC.
6.
Schließlich notieren wir noch, daß wir im Beispiel voraussichtlich eine existierende Klasse wiederverwenden können, nämlich die Klasse Longint im Umfang von 780 LOC.
7.
Nun berechnen wir durch Addition den Schätzwert für die Zahl zugefügter Zeilen zu 55+331=386 LOC. Addieren wir hierzu die Zahl zu verändernder Zeilen, so erhalten wir die initiale Schätzung von 416.
8.
Diese Schätzung wird nun mit der linearen Regression korrigiert, um systematische Fehler auszugleichen, die vielleicht in der Schätzung stecken. Das genaue Verfahren steht unten im Abschnitt 6.6.3, jedenfalls werden historische Daten verwendet, um die Korrekturparameter zu erhalten und die korrigierte Schätzung zu ermitteln. Angenommen, unsere historischen Daten zeigen in einer linearen Regression an, daß die Schätzungen im Mittel um 10 Prozent und zusätzlich 30 Zeilen zu niedrig liegen, dann ergibt sich die korrigierte Schätzung zu 30+1.1*416=487.6 LOC. Zugleich berechnen wir dabei das Vorhersageintervall (prediction interval), das den Bereich angibt, in den der tatsächliche Wert von N nach den bisherigen Erfahrungen mit einer Wahrscheinlichkeit von im Beispiel 70% fallen wird. Dieses Vorhersageintervall wird unter Benutzung der t-Verteilung aus den gleichen historischen Daten berechnet, mit denen auch die lineare Regression durchgeführt wurde. Angenommen, die historischen Daten zeigen recht gleichmäßige Schätzungen an, also geringe Streuungen, dann könnte das 70%-Vorhersageintervall, wie im Beispiel angenommen eine Breite von 80 LOC haben, so daß wir ein Vorhersageintervall von 488-40 bis 488+40 LOC erhalten.
Voila!

Mit Hilfe einer zweiten linearen Regression kann man jetzt eine Umrechnung der geschätzen Größe in die zu erwartende Entwicklungszeit vornehmen, so daß man auch gleich eine Aufwandsschätzung erhält; siehe den Abschnitt 6.6.4.

Der Trick bei dieser Schätzmethode ist die geschickte Auswahl von Stellvertretern (Ersatzgrößen), um auf das in der Schätzphase noch fehlende Detailwissen verzichten zu können ohne viel Schätzgenauigkeit einzubüßen. Anstatt direkt den Umfang zu schätzen, benutze ich eine Zerlegung in Teile, die ich mir noch recht gut vorstellen kann. Ich schätze deren Größe dann zum Teil intuitiv, indem ich nur fünf grobe Größenklassen verwende, und benutze historische Daten, die den Inhalt meiner Intuition widerspiegeln, um zu einer guten Schätzung zu gelangen.

  
6.6.2 Bestimmung der Objektgrößenbereiche

Wie kommt man nun zu sinnvollen LOC-Werten für die einzelnen Größenklassen? Ausgangspunkt ist die Überlegung, daß die Werte möglichst meine intuitive Vorstellung davon, was ,,klein`` oder ,,mittel`` etc. ist, wiedergeben sollten. Diese Vorstellung hängt von Häufigkeiten ab: Das, was oft vorkommt, ist mittel, etwas größeres, was nur mäßig oft vorkommt, ist groß, und nur etwas recht seltenes kann sehr groß genannt werden; für klein und sehr klein geht es analog.

Für eine Normalverteilung lassen sich recht einfach einleuchtende Bereiche für eine solche Einteilung angeben: Etwa 38.3% aller Fälle liegen im Bereich von plus oder minus einer halben Standardabweichung um den Mittelwert, also in einem Bereich der Breite einer Standardabweichung; diese nenne ich ,,mittel``. Als ,,groß`` bzw. ,,klein`` bezeichne ich die Bereiche, die mehr als eine halbe, aber weniger als eineinhalb Standardabweichungen vom Mittelwert entfernt liegen; diese umfassen je 24.2% aller Fälle. Die verbleibenden zweimal 6.7% aller Fälle verteilen sich auf die Bereiche, die mehr als eineinhalb Standardabweichungen vom Mittelwert entfernt sind; diese nenne ich ,,sehr groß`` und ,,sehr klein``.

Also rechnen wir einfach Mittelwert m und Standardabweichung s unserer Methodengröße aus und erhalten die Grenzen der Bereiche wie oben angegeben? Als Schätzwerte für die Bereiche könnten wir dann deren Mitte verwenden, also m-2s, m-s, m, m+s, m+2s.

Leider nein, so geht es nicht, denn Methodengrößen sind üblicherweise nicht normalverteilt. Aber sie sind meistens ungefähr log-normal verteilt, so daß wir uns mit einem Trick behelfen können. Log-normale Verteilung bedeutet, daß die Logarithmen der Werte eine Normalverteilung haben. Dieser Effekt tritt sehr oft bei Größen auf, die zwar eine natürliche untere Schranke haben (zum Beispiel Null), aber keine obere und die dieser unteren Schranke häufig nahekommen. Somit können wir die ganze obige Prozedur mit den Logarithmen der Methodengrößen vornehmen und am Schluß delogarithmieren, um die Schätzgrößen jeder Größenklasse zu erhalten.

Beispiel: Gegeben sei eine Reihe von Klassen, die unsere historischen Daten für eine bestimmte Klassenart repräsentieren. Die Werte für die LOC pro Methode lauten für diese 13 Klassen 10.33, 6, 21.75, 29, 8.33, 6, 22.25, 28.33 12.33, 55.8, 20.5, 16.4, 23. Das ergibt einen Mittelwert von 20 und eine Standardabweichung von 12.84. Die zugehörigen Logarithmen (wir verwenden hier den natürlichen Logarithmus, man könnte aber auch einen anderen benutzen) lauten 2.335, 1.792, 3.08, 3.367, 2.12, 1.792, 3.102, 3.344, 2.512, 4.022, 3.02, 2.797, 3.135. Hier sind der Mittelwert 2.802 und die Standardabweichung 0.6346.

Wir erhalten also als Bereichsgrößen im logarithmischen Bereich (also in der Maßeinheit logLOC) die Werte
VS = 2.802 - 2*0.6346 = 1.533
S = 2.802 - 0.6346 = 2.167
M = 2.802
L = 2.802 + 0.6346 = 3.437
VL = 2.802 + 2*0.6346 = 4.071
und durch berechnen des inversen Logarithmus erhalten wir daraus für den nichtlogarithmischen Bereich (also in der Maßeinheit LOC) die Werte
VS = exp(1.533) = 4.63
S = exp(2.167) = 8.73
M = exp(2.802) = 16.48
L = exp(3.437) = 31.09
VL = exp(4.071) = 58.62

Wie wir sehen, sind die Werte von VS und VL jenseits des Bereichs, der von den Daten überhaupt erreicht wird (6.0 bis 55.8). Das ist nicht verblüffend, denn bei 13 Datenwerten repräsentiert ein Wert immerhin 7.7% und der ganze VS- bzw. VL-Bereich deckt ja nur 6.7% aller Werte ab.

Vor der Anwendung der beschriebenen Methode sollte man sicherstellen, daß die benutzten Daten auch tatsächlich eine ungefähr lognormale Verteilung haben. Dazu ist insbesondere zu fordern, daß genügend Daten vorhanden sind; mit viel weniger als den obigen 13 Punkten sollte man nicht anfangen. Wenn nicht genügend Werte da sind, kann man entweder die Größenbereiche per Intuition schätzen (oder die berechneten per Intuition korrigieren) oder gleich die Schätzung nicht über einen Größenbereich ausrechnen, sondern direkt vornehmen, also ,,diese Klasse hat vermutlich 10 Funktionen zu je, sagen wir mal 20 Zeilen``.

Warum soll man die Einteilung der Objektgrößenklassen getrennt für verschiedene Arten von Objektklassen vornehmen? Weil diese recht unterschiedliche Eigenschaften haben können im Hinblick nicht nur auf die absoluten Größen, sondern auch auf die Streuung zwischen den Größenklassen. Hier als Beispiel die Werte, die Humphrey für seine eigenen Größenklassen für C++ angibt:


Art      VS   S   M    L   VL

Comp 2.3 5.1 11 25 54
I/O 9 12 16 22 29
Die Berechnungsklassen haben also zwar geringere ,,klein``- und ,,mittel``-Größen, aber dennoch größere ,,groß``-Größen, weil ihre Streuung erheblich breiter ist als bei den Ein-/Ausgabeklassen.

  
6.6.3 Schätzkorrektur mit Regression

Der Verwendung der linearen Regression liegen zwei Überlegungen zugrunde.

1.
Es gibt im obigen Meßverfahren einen kleinen eingebauten systematischen Fehler: Wenn man die Größe von Objektklassen nur über die Größe der Methoden berechnet, vernachlässigt man den Datentyp selbst, der mit der Klasse definiert wird. Dadurch fallen die Schätzungen immer ein wenig zu niedrig aus.
2.
Außerdem, und das ist der bei weitem wichtigere Teil, machen Schätzer meist auch systematische Fehler. Viele Schätzer übersehen zum Beispiel gern Komponenten, so daß ihre Schätzungen zu niedrig werden oder sie veranschlagen die Größe der Komponenten immer etwas zu gering (andere machen sie zu hoch). In der Summe dieser Effekte ergibt sich jedenfalls neben allen Schwankungen in den Schätzungen, die von Fall zu Fall verschieden sind (also statistischer Fehler) ein gewisser Teil systematischer Fehler. Dieser läßt sich durch Vergleich mehrerer Schätzungen mit der Wirklichkeit berechnen und dann in späteren Schätzungen korrigieren.

Die Korrektur dieser zwei Teile des systematischen Fehlers leistet die lineare Regression. In der Terminologie des Abschnitts über Vorhersagesysteme (1.6.1) suchen wir also ein Vorhersagesystem zur Vorhersage der tatsächlichen Größe aus der geschätzten Größe. Wir verwenden dafür als Modell die Vorstellung ,,wenn Du als Größe s geschätzt hast, dann beträgt die tatsächliche Größe g = a*s + b``. Die Berechnungsprozedur zur Bestimmung der günstigsten Werte für a und b ist die lineare Regression auf Basis vergangener tatsächlicher Paare von Schätzung und wirklicher Größe. Die Berechnung geht genauso vor sich, wie im obenerwähnten Abschnitt gezeigt.

Solange die historischen Daten noch knapp sind, kann sich durch jeden neuen Datenpunkt eine spürbare Veränderung im Vorhersagesystem ergeben. In diesem Fall sollte das Vorhersagesystem also für jede Schätzung neu berechnet werden und zwar unter Verwendung aller bisher vorhandenen Datenpaare. Im Laufe der Zeit werden dann Änderungen immer seltener nötig, nehmen jedoch noch einen zusätzlichen Zug an: Nach einer Weile wird sich die Schätzpraxis verändern, weil man mehr und mehr Erfahrung im Schätzen sammelt. Dann spiegeln alte Datenpaare nicht mehr die gegenwärtige Schätzpraxis wider und sollten lieber nicht mehr bei der Berechnung des Vorhersagesystems benutzt werden. Es werden also im Laufe der Zeit nicht nur neue Datenpaare bei der Berechnung mit eingeschlossen, sondern irgendwann auch alte ausrangiert. Welche das sind und wann man sie ausschließt, bleibt dem Urteilsvermögen überlassen, wobei man sich durch eine graphische Betrachtung der Punktwolken der jüngsten und ältesten Datenpaare (in zwei verschiedenen Farben) helfen kann: Liegen die Punktwolken deutlich getrennt, so hat sich tatsächlich etwas geändert und die alten Punkte sollten nicht mehr benutzt werden.

  
6.6.4 Schätzung von Zeit aus Größe

Aus der Größenschätzung kann man ebenfalls mit einer linearen Regression auch eine Zeitschätzung erhalten, wenn man genügend historische Daten über diesen Zusammenhang hat und diese Daten eine ausreichend hohe Korrelation zwischen den beiden Größen zeigen, was üblicherweise der Fall ist, wenn die Größe anständig geschätzt wird.

Diese Berechnung ist genau der Fall, der im Abschnitt 1.6.1 besprochen wurde, nur daß nicht tatsächliche Größendaten als Eingabe dienen, sondern Größenschätzungen.


next up previous contents
Next: 6.7 Entwurfsprüfung Up: 6. Der persönliche Softwareprozeß Previous: 6.5 Maße im PSP
Lutz Prechelt
1999-04-13