split more population/sample calculations

This commit is contained in:
Dennis Eichhorn 2020-06-14 13:22:12 +02:00
parent ad2634e32a
commit d556756283
5 changed files with 91 additions and 8 deletions

View File

@ -46,9 +46,26 @@ final class Correlation
*
* @since 1.0.0
*/
public static function bravaisPersonCorrelationCoefficient(array $x, array $y) : float
public static function bravaisPersonCorrelationCoefficientPopulation(array $x, array $y) : float
{
return MeasureOfDispersion::empiricalCovariance($x, $y) / (MeasureOfDispersion::standardDeviationSample($x) * MeasureOfDispersion::standardDeviationSample($y));
return MeasureOfDispersion::empiricalCovariance($x, $y) / (MeasureOfDispersion::standardDeviationPopulation($x) * MeasureOfDispersion::standardDeviationPopulation($y));
}
/**
* Calculage bravais person correlation coefficient.
*
* Example: ([4, 5, 9, 1, 3], [4, 5, 9, 1, 3])
*
* @param array<int|float> $x Values
* @param array<int|float> $y Values
*
* @return float
*
* @since 1.0.0
*/
public static function bravaisPersonCorrelationCoefficientSample(array $x, array $y) : float
{
return MeasureOfDispersion::sampleCovariance($x, $y) / (MeasureOfDispersion::standardDeviationSample($x) * MeasureOfDispersion::standardDeviationSample($y));
}
/**

View File

@ -170,7 +170,7 @@ final class Error
*/
public static function getCoefficientOfDetermination(array $observed, array $forecasted) : float
{
return Correlation::bravaisPersonCorrelationCoefficient($observed, $forecasted) ** 2;
return Correlation::bravaisPersonCorrelationCoefficientPopulation($observed, $forecasted) ** 2;
}
/**

View File

@ -101,11 +101,14 @@ final class MeasureOfDispersion
$mean = $mean !== null ? $mean : Average::arithmeticMean($values);
$sum = 0.0;
$valueCount = 0;
foreach ($values as $value) {
$sum += ($value - $mean) ** 2;
++$valueCount;
}
return \sqrt($sum / (\count($values) - 1));
return \sqrt($sum / ($valueCount - 1));
}
/**
@ -127,11 +130,14 @@ final class MeasureOfDispersion
$mean = $mean !== null ? $mean : Average::arithmeticMean($values);
$sum = 0.0;
$valueCount = 0;
foreach ($values as $value) {
$sum += ($value - $mean) ** 2;
++$valueCount;
}
return \sqrt($sum / \count($values));
return \sqrt($sum / $valueCount);
}
/**
@ -241,7 +247,37 @@ final class MeasureOfDispersion
$sum += ($x[$i] - $xMean) * ($y[$i] - $yMean);
}
return $sum / ($count - 1);
return $sum / $count;
}
/**
* Calculage empirical covariance on a sample
*
* Example: ([4, 5, 9, 1, 3], [4, 5, 9, 1, 3])
*
* @latex \sigma_{XY} = cov(X, Y) = \sum_{i = 1}^{N}\frac{\left(x_{i} - \bar{X}\right) \left(y_{i} - \bar{Y}\right)}{N - 1}
*
* @param array<int, int|float> $x Values
* @param array<int, int|float> $y Values
* @param float $meanX Mean
* @param float $meanY Mean
*
* @return float
*
* @throws ZeroDivisionException This exception is thrown if the size of the x array is less than 2
* @throws InvalidDimensionException This exception is thrown if x and y have different dimensions
*
* @since 1.0.0
*/
public static function sampleCovariance(array $x, array $y, float $meanX = null, float $meanY = null) : float
{
$count = \count($x);
if ($count < 2) {
throw new ZeroDivisionException();
}
return self::empiricalCovariance($x, $y, $meanX, $meanY) * $count / ($count - 1);
}
/**

View File

@ -27,11 +27,26 @@ class CorrelationTest extends \PHPUnit\Framework\TestCase
* @testdox The correlation coefficient (Bravis Person) is calculated correctly
* @group framework
*/
public function testBravisPersonCorrelationCoefficient() : void
public function testBravisPersonCorrelationCoefficientPopulation() : void
{
self::assertEqualsWithDelta(
0.8854,
Correlation::bravaisPersonCorrelationCoefficient(
Correlation::bravaisPersonCorrelationCoefficientPopulation(
[1, 2, 3, 4, 5, 6, 7],
[3, 4, 5, 9, 7, 8, 9]
), 0.01
);
}
/**
* @testdox The correlation coefficient (Bravis Person) is calculated correctly on a sample
* @group framework
*/
public function testBravisPersonCorrelationCoefficientSample() : void
{
self::assertEqualsWithDelta(
0.8854,
Correlation::bravaisPersonCorrelationCoefficientSample(
[1, 2, 3, 4, 5, 6, 7],
[3, 4, 5, 9, 7, 8, 9]
), 0.01

View File

@ -56,6 +56,21 @@ class MeasureOfDispersionTest extends \PHPUnit\Framework\TestCase
);
}
/**
* @testdox The empirical covariance on a sample is correctly calculated
* @group framework
*/
public function testSampleCovariance() : void
{
self::assertEqualsWithDelta(
4.0,
MeasureOfDispersion::sampleCovariance(
[1, 2, 3, 4, 5, 6, 7],
[3, 4, 5, 9, 7, 8, 9]
), 0.01
);
}
/**
* @testdox The sample variance is correctly calculated
* @group framework