PHP: Klasse zur statistischen Fehlererrechnung und Prozessfähigkeitsuntersuchung
In diesem Beitrag geht es darum, aus festgestellten Messergebnissen, die zum Beispiel in einer Datenbank abgelegt sind, eine sogenannte Prozessfähigkeitsanalyse zu erstellen.
Diese wird beispielsweise in der Automobilindustrie für die Qualitätssicherung gefordert und benötigt.
Bekannte geforderte Werte sind der Prozessfähigkeitsindex CpK – eine Kennzahl zur statistischen Bewertung eines Prozesses – oder ebenenfalls der Six-Sigma-Wert sowie einige andere Werte.
Mininum, Maximum, Durchschnitt, Median, Abstand (Range), Modus, Moment, Varianz, Standardabweichung, Standardfehler, Schiefe, Woelbung (Exzess), Variationskoeffizient, Prozessfaehigkeitsindex, Wahrscheinlichkeitsdichtefunktion, Verteilungsfunktion, PPM und Fehlerhaftigkeit können mit unten gelisteter PHP-Klasse bestimmt werden.
Ausgangslage der zu berechnenden Werte zur Prozessfähigkeitsanalyse können Messdaten aus dem Messlabor sein, die stichprobenartig von produzierten Bauteilen für die Automobilindustrie erfasst wurden.
Hier ein Beispiel errechneter Werte in tabellarischer Form:
Messpunkt: | MP 1.0 | MP 2.0 | MP 3.0 | MP 4.0 | MP 5.0 | MP 6.0 |
Funktionsmaß: | 1.5000 | 24.1000 | 73.5000 | 34.0000 | 8.0000 | 13.4000 |
Untere Toleranzgrenze: | 1.4000 | 23.9000 | 73.2000 | 33.7000 | 7.8000 | 13.1000 |
Obere Toleranzgrenze: | 1.6000 | 24.3000 | 73.8000 | 34.3000 | 8.2000 | 13.7000 |
Untere Eingriffsgrenze: | 1.4000 | 23.9000 | 73.2000 | 33.7000 | 7.8000 | 13.1000 |
Obere Eingriffsgrenze: | 1.6000 | 24.3000 | 73.8000 | 34.3000 | 8.2000 | 13.7000 |
Toleranz: | 0.2000 | 0.4000 | 0.6000 | 0.6000 | 0.4000 | 0.6000 |
Eingriffsbereich: | 0.2000 | 0.4000 | 0.6000 | 0.6000 | 0.4000 | 0.6000 |
Anzahl | 12 | 12 | 12 | 12 | 12 | 12 |
davon außerhalb Toleranz: | 0 | 0 | 0 | 0 | 0 | 0 |
Modus: | 10 | 2 | 3 | 2 | 6 | 3 |
Minimum: | 1.5000 | 23.9600 | 73.6800 | 33.8700 | 8.0000 | 13.3500 |
Maximum: | 1.5100 | 24.0800 | 73.7700 | 34.0300 | 8.0200 | 13.4100 |
Mittelwert: | 1.5017 | 24.0233 | 73.7225 | 33.9250 | 8.0117 | 13.3808 |
Median: | 1.5000 | 24.0300 | 73.7300 | 33.9150 | 8.0100 | 13.3900 |
Range: | 0.0100 | 0.1200 | 0.0900 | 0.1600 | 0.0200 | 0.0600 |
Summe: | 18.0200 | 288.2800 | 884.6700 | 407.1000 | 96.1400 | 160.5700 |
StaAbw. Stichproben: | 0.0039 | 0.0365 | 0.0360 | 0.0514 | 0.0072 | 0.0239 |
Varianz Stichproben: | 0.0000 | 0.0013 | 0.0013 | 0.0026 | 0.0001 | 0.0006 |
Schiefe: | 2.0552 | -0.2669 | 0.3193 | 1.0679 | -0.2623 | 0.0739 |
Exzess: | 2.6400 | -0.5722 | -1.9740 | 0.0575 | -0.6851 | -1.7922 |
Variationskoeffizient: | 0.2592 | 0.1520 | 0.0488 | 0.1516 | 0.0896 | 0.1787 |
Standardfehler: | 0.0011 | 0.0105 | 0.0104 | 0.0148 | 0.0021 | 0.0069 |
Messergebnis: | 1.5017 ± 0.0011 |
24.0233 ± 0.0105 |
73.7225 ± 0.0104 |
33.9250 ± 0.0148 |
8.0117 ± 0.0021 |
13.3808 ± 0.0069 |
Obere Toleranz – Mittelwert: | 0.0983 | 0.2767 | 0.0775 | 0.3750 | 0.1883 | 0.3192 |
Mittelwert – untere Toleranz: | 0.1017 | 0.1233 | 0.5225 | 0.2250 | 0.2117 | 0.2808 |
Cpo: | 8.4208 | 2.5256 | 0.7184 | 2.4303 | 8.7466 | 4.4485 |
Cpu: | 8.7062 | 1.1259 | 4.8432 | 1.4582 | 9.8302 | 3.9142 |
Cp: | 0.1168 | 0.5477 | 0.3596 | 0.5143 | 0.1077 | 0.2392 |
CpK: | 8.4208 | 1.1259 | 0.7184 | 1.4582 | 8.7466 | 3.9142 |
Dichtefunktion: | 0.00000 | 0.00133 | 0.03912 | 0.00003 | 0.00000 | 0.00000 |
IST-Wert | IST-Wert | IST-Wert | IST-Wert | IST-Wert | IST-Wert | |
Teil 1 | 1.5000 | 24.0800 | 73.7500 | 33.9800 | 8.0000 | 13.3500 |
Teil 2 | 1.5000 | 24.0500 | 73.7600 | 33.9300 | 8.0100 | 13.4000 |
Teil 3 | 1.5000 | 23.9700 | 73.7700 | 34.0300 | 8.0000 | 13.3600 |
Teil 4 | 1.5100 | 24.0000 | 73.7600 | 33.9000 | 8.0100 | 13.4100 |
Teil 5 | 1.5100 | 23.9600 | 73.7100 | 33.9200 | 8.0200 | 13.4100 |
Teil 6 | 1.5000 | 24.0600 | 73.7700 | 33.8900 | 8.0200 | 13.3700 |
Teil 7 | 1.5000 | 24.0100 | 73.7000 | 33.8700 | 8.0200 | 13.3700 |
Teil 8 | 1.5000 | 24.0600 | 73.7000 | 33.8800 | 8.0100 | 13.3600 |
Teil 9 | 1.5000 | 24.0200 | 73.6900 | 33.8800 | 8.0200 | 13.4100 |
Teil 10 | 1.5000 | 24.0400 | 73.6900 | 33.9100 | 8.0100 | 13.3500 |
Teil 11 | 1.5000 | 24.0100 | 73.6800 | 34.0000 | 8.0100 | 13.4000 |
Teil 12 | 1.5000 | 24.0200 | 73.6900 | 33.9100 | 8.0100 | 13.3800 |
In folgendem kleinen Code-Beispiel wird ein Array statisch befüllt, also nicht aus einer Datenbank.
Nach der Erzeugung einer Instanz der Klasse `calcStatistics‘ kann auf dessen Eigenschaften (Variablen) zugegriffen werden.
<?PHP /* * by Hofmann R. Julian // ~ 2013 */ error_reporting(E_ALL ^ E_NOTICE); require_once('statistics.php'); $messergebnisse = array(13.3500, 13.4000, 13.3600, 13.4100, 13.4100, 13.3700, 13.3700, 13.3600, 13.4100, 13.3500, 13.4000, 13.3800); $calc = new calcStatistics($messergebnisse, 13.7000, 13.1000); $calc->calcAllStatistics(); print 'Exzess' . ': ' . $calc->kurtosis . "\n"; print 'Modus' . ': ' . $calc->mode . "\n"; print 'Dichte' . ': ' . $calc->density . "\n"; print 'CpK' . ': ' . $calc->C_pK . "\n"; print 'Variationskoeffizient' . ': '. $calc->variationCoefficient . "\n"; print 'Messergebnis' . ': ' . $calc->average . ' ± ' . $calc->standardError . "\n"; ?>
Die Methode `calcAllStatistics‘ ruft alle relevanten Methoden der Klasse `calcStatistics‘ auf.
Bei einem Aufruf über das Commandline-Interface sieht die Ausgabe dann so aus:
Hier also die Klasse `calcStatistics':
<?PHP /* * statistics.php * by Hofmann R. Julian // ~ 2013 */ error_reporting(E_ALL ^ E_NOTICE); class calcStatistics { var $records; var $counted, $sum; var $minimum = NULL, $maximum = NULL, $average = NULL; var $median, $range, $mode; var $moment = array(2 => NULL, 3 => NULL, 4 => NULL); var $variancePopulation = NULL, $varianceExamples = NULL; var $standardDeviationPopulation, $standardDeviationExamples = NULL; var $standardError, $skewness, $kurtosis, $variationCoefficient; var $upperLimit = NULL, $lowerLimit = NULL; var $C_uL, $C_lL, $C_p, $C_pK = NULL; var $density = NULL, $distribution = NULL; var $noncomforming = NULL; function calcStatistics(&$records, $upperLimit = NULL, $lowerLimit = NULL) { $this->records = $records; $this->counted = count($this->records); $this->sum = array_sum($this->records); if ($upperLimit != NULL) $this->upperLimit = $upperLimit; if ($lowerLimit != NULL) $this->lowerLimit = $lowerLimit; } function calcAllStatistics() { $this->calcMinimum(); $this->calcMaximum(); $this->calcAverage(); $this->calcMedian(); $this->calcRange(); $this->calcMode(); $this->calcVariancePopulation(); $this->calcVarianceExamples(); $this->calcStandardDeviationPopulation(); $this->calcStandardDeviationExamples(); $this->calcStandardError(); $this->calcSkewness(); $this->calcKurtosis(); $this->calcVariationCoefficient(); $this->calcProcessCapabilityIndex(); $this->calcDensity(); $this->calcDistribution(); $this->calcPartsPerMillion(); $this->calcNonconforming(); } /* Minimum */ function calcMinimum() { $this->minimum = min($this->records); } /* Maximum */ function calcMaximum() { $this->maximum = max($this->records); } /* Durchschnitt */ function calcAverage() { $this->average = $this->sum / $this->counted; } /* Median */ function calcMedian() { $copiedRecords = $this->records; sort($copiedRecords); if ($this->counted % 2) $this->median = ($copiedRecords[($this->counted + 1) / 2]); else $this->median = ($copiedRecords[($this->counted) / 2] + $copiedRecords[(($this->counted) / 2) + 1]) / 2; } /* Abstand */ function calcRange() { if ($this->minimum == NULL) $this->calcMinimum(); if ($this->maximum == NULL) $this->calcMaximum(); $this->range = $this->maximum - $this->minimum; } /* Modus */ function calcMode() { $vals = array(); foreach ($this->records as $record) $vals["$record"]++; $this->mode = max($vals); } /* Moment */ function calcMoment($exp) { if ($this->average == NULL) $this->calcAverage(); foreach ($this->records as $record) $this->moment[$exp] += pow($this->average - $record, $exp); } /* Varianz Grundgesamtheit */ function calcVariancePopulation() { if ($this->moment[2] == NULL) $this->calcMoment(2); $this->variancePopulation = $this->moment[2] / $this->counted; } /* Varianz Stichproben */ function calcVarianceExamples() { if ($this->moment[2] == NULL) $this->calcMoment(2); $this->varianceExamples = $this->moment[2] / ($this->counted - 1); } /* Standardabweichung Grundgesamtheit */ function calcStandardDeviationPopulation() { if ($this->variancePopulation == NULL) $this->calcVariancePopulation(); $this->standardDeviationPopulation = sqrt($this->variancePopulation); } /* Standardabweichung Stichproben */ function calcStandardDeviationExamples() { if ($this->varianceExamples == NULL) $this->calcVarianceExamples(); $this->standardDeviationExamples = sqrt($this->varianceExamples); } /* Standardfehler */ function calcStandardError() { if ($this->moment[2] == NULL) $this->calcMoment(2); $this->standardError = sqrt($this->moment[2] / ($this->counted * ($this->counted - 1))); } /* Schiefe */ function calcSkewness() { if ($this->standardDeviationExamples == NULL) $this->calcStandardDeviationExamples(); if ($this->moment[3] == NULL) $this->calcMoment(3); $this->skewness = ($this->counted / (($this->counted - 1) * ($this->counted - 2))) * (1 / pow($this->standardDeviationExamples, 3)) * $this->moment[3]; } /* Exzess, Woelbung */ function calcKurtosis() { if ($this->standardDeviationExamples == NULL) $this->calcStandardDeviationExamples(); if ($this->moment[4] == NULL) $this->calcMoment(4); $this->kurtosis = ( (($this->counted * ($this->counted + 1)) / (($this->counted - 1) * ($this->counted - 2) * ($this->counted - 3))) * (1 / pow($this->standardDeviationExamples, 4)) * $this->moment[4]) - (3 * (pow(($this->counted - 1), 2) / (($this->counted - 2) * ($this->counted - 3)))); } /* Variationskoeffizient */ function calcVariationCoefficient() { if ($this->standardDeviationExamples == NULL) $this->calcStandardDeviationExamples(); $this->variationCoefficient = ($this->standardDeviationExamples / $this->average) * 100; } /* Prozessfaehigkeitsindex */ function calcProcessCapabilityIndex($upperLimit = NULL, $lowerLimit = NULL) { if ($upperLimit != NULL) $this->upperLimit = $upperLimit; if ($lowerLimit != NULL) $this->lowerLimit = $lowerLimit; if ($this->upperLimit == NULL || $this->lowerLimit == NULL) return; if ($this->standardDeviationExamples == NULL) $this->calcStandardDeviationExamples(); $this->C_uL = ($this->upperLimit - $this->average) / (3 * $this->standardDeviationExamples); $this->C_lL = ($this->average - $this->lowerLimit) / (3 * $this->standardDeviationExamples); $this->C_p = (6 * $this->standardDeviationExamples / ($this->upperLimit - $this->lowerLimit)); $this->C_pK = ($this->C_uL > $this->C_lL) ? $this->C_lL : $this->C_uL; } /* Wahrscheinlichkeitsdichtefunktion */ function calcDensity() { if ($this->C_pK == NULL) $this->calcProcessCapabilityIndex(); if ($this->C_pK == NULL) return; $stabw = 1; $E = 0; $this->density = ( (1 / sqrt(2 * pi() * $stabw * $stabw)) * exp((-(($this->C_pK * 3) - $E) * (($this->C_pK * 3) - $E)) / (2 * $stabw * $stabw))); } /* Verteilungsfunktion */ function calcDistribution() { if (!function_exists('stats_cdf_normal')) return; if ($this->C_pK == NULL) $this->calcProcessCapabilityIndex(); if ($this->C_pK == NULL) return; $stabw = 1; $E = 0; $this->distribution = stats_cdf_normal($this->C_pK * 3, $E, $stabw, 1); } /* Teile pro Million */ function calcPartsPerMillion() { if ($this->distribution == NULL) $this->calcDistribution(); if ($this->distribution == NULL) return; $ppm = (1 - $this->distribution) * 1000000; $this->ppm = array($ppm, $ppm / 10000); } /* Fehlerhaftigkeit */ function calcNonconforming($upperLimit = NULL, $lowerLimit = NULL) { if ($upperLimit != NULL) $this->upperLimit = $upperLimit; if ($lowerLimit != NULL) $this->lowerLimit = $lowerLimit; if ($this->upperLimit == NULL || $this->lowerLimit == NULL) return; $this->nonconforming = 0; foreach ($this->records as $record) if ($record < $this->lowerLimit || $record > $this->upperLimit) $this->nonconforming++; } } ?>
Getestet wurde die PHP-Klasse mit php5.2.13 auf OpenBSD 4.8 und php5.5.6 auf gentoo Linux.
Um zu verstehen, was die errechneten Werte aussagen sollen (worauf dieser Beitrag hier nicht eingeht) und wie sie mathematisch errechnet werden, kann ich folgendes Buch empfehlen:
“Schnelleinstieg Statistik” von Stefan Hagl (ISBN-10: 3448086215).