ExperimentTest.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. namespace MathPHP\Tests\Statistics;
  3. use MathPHP\Statistics\Experiment;
  4. use MathPHP\Exception;
  5. class ExperimentTest extends \PHPUnit\Framework\TestCase
  6. {
  7. /**
  8. * @test riskRatio
  9. * @dataProvider dataProviderForRiskRatio
  10. * @param int $a
  11. * @param int $b
  12. * @param int $c
  13. * @param int $d
  14. * @param array $expected
  15. */
  16. public function testRiskRatio(int $a, int $b, int $c, int $d, array $expected)
  17. {
  18. // When
  19. $riskRation = Experiment::riskRatio($a, $b, $c, $d);
  20. // Then
  21. $this->assertEqualsWithDelta($expected['RR'], $riskRation['RR'], 0.001);
  22. $this->assertEqualsWithDelta($expected['ci_lower_bound'], $riskRation['ci_lower_bound'], 0.001);
  23. $this->assertEqualsWithDelta($expected['ci_upper_bound'], $riskRation['ci_upper_bound'], 0.001);
  24. $this->assertEqualsWithDelta($expected['p'], $riskRation['p'], 0.0001);
  25. }
  26. /**
  27. * @return array [a, b, c, d, rr]
  28. */
  29. public function dataProviderForRiskRatio(): array
  30. {
  31. return [
  32. [20, 80, 1, 99, ['RR' => 20, 'ci_lower_bound' => 2.7361, 'ci_upper_bound' => 146.1912, 'p' => 0.0032]],
  33. [100, 200, 20, 400, ['RR' => 7, 'ci_lower_bound' => 4.4337, 'ci_upper_bound' => 11.0516, 'p' => 0.0001]],
  34. [43, 26, 54, 654, ['RR' => 8.1707, 'ci_lower_bound' => 5.9614, 'ci_upper_bound' => 11.1987, 'p' => 0.0001]],
  35. [53, 58, 11, 40, ['RR' => 2.2138, 'ci_lower_bound' => 1.2666, 'ci_upper_bound' => 3.8693, 'p' => 0.0053]],
  36. [59, 33, 17, 44, ['RR' => 2.3012, 'ci_lower_bound' => 1.4944, 'ci_upper_bound' => 3.5434, 'p' => 0.0002]],
  37. [28, 129, 4, 133, ['RR' => 6.1083, 'ci_lower_bound' => 2.1976, 'ci_upper_bound' => 16.9784, 'p' => 0.0005]],
  38. [1000, 49000, 100, 49900, ['RR' => 10, 'ci_lower_bound' => 8.1449, 'ci_upper_bound' => 12.2776, 'p' => 0.0001]],
  39. ];
  40. }
  41. /**
  42. * @test oddsRatio
  43. * @dataProvider dataProviderForOddsRatio
  44. * @param int $a
  45. * @param int $b
  46. * @param int $c
  47. * @param int $d
  48. * @param array $expected
  49. */
  50. public function testOddsRatio(int $a, int $b, int $c, int $d, array $expected)
  51. {
  52. // When
  53. $oddsRatio = Experiment::oddsRatio($a, $b, $c, $d);
  54. // Then
  55. $this->assertEqualsWithDelta($expected['OR'], $oddsRatio['OR'], 0.001);
  56. $this->assertEqualsWithDelta($expected['ci_lower_bound'], $oddsRatio['ci_lower_bound'], 0.001);
  57. $this->assertEqualsWithDelta($expected['ci_upper_bound'], $oddsRatio['ci_upper_bound'], 0.001);
  58. $this->assertEqualsWithDelta($expected['p'], $oddsRatio['p'], 0.0001);
  59. }
  60. /**
  61. * @return array [a, b, c, d, or]
  62. */
  63. public function dataProviderForOddsRatio(): array
  64. {
  65. return [
  66. [20, 80, 1, 99, ['OR' => 24.7500, 'ci_lower_bound' => 3.2509, 'ci_upper_bound' => 188.4303, 'p' => 0.0019]],
  67. [100, 200, 20, 400, ['OR' => 10.0000, 'ci_lower_bound' => 6.0096, 'ci_upper_bound' => 16.6400, 'p' => 0.0001]],
  68. [43, 26, 54, 654, ['OR' => 20.0299, 'ci_lower_bound' => 11.4361, 'ci_upper_bound' => 35.0817, 'p' => 0.0001]],
  69. [53, 58, 11, 40, ['OR' => 3.3229, 'ci_lower_bound' => 1.5475, 'ci_upper_bound' => 7.1351, 'p' => 0.0021]],
  70. [59, 33, 17, 44, ['OR' => 4.6275, 'ci_lower_bound' => 2.2901, 'ci_upper_bound' => 9.3505, 'p' => 0.0001]],
  71. [28, 129, 4, 133, ['OR' => 7.2171, 'ci_lower_bound' => 2.4624, 'ci_upper_bound' => 21.1522, 'p' => 0.0003]],
  72. [1000, 49000, 100, 49900, ['OR' => 10.1837, 'ci_lower_bound' => 8.2883, 'ci_upper_bound' => 12.5125, 'p' => 0.0001]],
  73. ];
  74. }
  75. /**
  76. * @test likelihoodRatio
  77. * @dataProvider dataProviderForLikelihoodRatio
  78. * @param int $a
  79. * @param int $b
  80. * @param int $c
  81. * @param int $d
  82. * @param array $expected
  83. */
  84. public function testLikelihoodRatio(int $a, int $b, int $c, int $d, array $expected)
  85. {
  86. // When
  87. $likelihoodRatio = Experiment::likelihoodRatio($a, $b, $c, $d);
  88. // Then
  89. $this->assertEqualsWithDelta($expected['LL+'], $likelihoodRatio['LL+'], 0.001);
  90. $this->assertEqualsWithDelta($expected['LL-'], $likelihoodRatio['LL-'], 0.001);
  91. }
  92. /**
  93. * @return array [a, b, c, d, ll]
  94. */
  95. public function dataProviderForLikelihoodRatio(): array
  96. {
  97. return [
  98. [20, 180, 10, 1820, ['LL+' => 7.4074, 'LL-' => 0.3663]],
  99. [20, 80, 1, 99, ['LL+' => 2.131, 'LL-' => 0.0861]],
  100. [100, 200, 20, 400, ['LL+' => 2.5, 'LL-' => 0.25]],
  101. [43, 26, 54, 654, ['LL+' => 11.594, 'LL-' => 0.5788]],
  102. [53, 58, 11, 40, ['LL+' => 1.3992, 'LL-' => 0.4211]],
  103. [59, 33, 17, 44, ['LL+' => 1.8114, 'LL-' => 0.3914]],
  104. [28, 129, 4, 133, ['LL+' => 1.7771, 'LL-' => 0.2462]],
  105. [1000, 49000, 100, 49900, ['LL+' => 1.8349, 'LL-' => 0.1802]],
  106. ];
  107. }
  108. /**
  109. * @test likelihoodRatioSS
  110. * @dataProvider dataProviderForLikelihoodRatioSS
  111. * @param float $sensitivity
  112. * @param float $specificity
  113. * @param array $expected
  114. */
  115. public function testLikelihoodRatioSS(float $sensitivity, float $specificity, array $expected)
  116. {
  117. // When
  118. $likelihoodRatio = Experiment::likelihoodRatioSS($sensitivity, $specificity);
  119. // Then
  120. $this->assertEqualsWithDelta($expected['LL+'], $likelihoodRatio['LL+'], 0.001);
  121. $this->assertEqualsWithDelta($expected['LL-'], $likelihoodRatio['LL-'], 0.001);
  122. }
  123. /**
  124. * @return array [sensitivity, specificity]
  125. */
  126. public function dataProviderForLikelihoodRatioSS(): array
  127. {
  128. return [
  129. [0.67, 0.91, ['LL+' => 7.4444, 'LL-' => 0.3626]],
  130. [0.90, 0.85, ['LL+' => 6, 'LL-' => 0.1176]]
  131. ];
  132. }
  133. /**
  134. * @test likelihoodRatioSS exception if sensitivity or specificity are > 1.0
  135. */
  136. public function testLikelihoodRatioSSException()
  137. {
  138. // Given
  139. $sensitivity = 1.2;
  140. $specificity = 1.5;
  141. // Then
  142. $this->expectException(Exception\OutOfBoundsException::class);
  143. // When
  144. Experiment::likelihoodRatioSS($sensitivity, $specificity);
  145. }
  146. }