RegressionTest.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <?php
  2. namespace MathPHP\Tests\Statistics\Regression;
  3. use MathPHP\Statistics\Regression\Linear;
  4. class RegressionTest extends \PHPUnit\Framework\TestCase
  5. {
  6. /**
  7. * @test correlationCoefficient
  8. * @dataProvider dataProviderForR
  9. * @param array $points
  10. * @param float $r
  11. */
  12. public function testCorrelationCoefficient(array $points, float $r)
  13. {
  14. // Given
  15. $regression = new Linear($points);
  16. // Then
  17. $this->assertEqualsWithDelta($r, $regression->correlationCoefficient(), 0.001);
  18. }
  19. /**
  20. * @test r
  21. * @dataProvider dataProviderForR
  22. * @param array $points
  23. * @param float $r
  24. */
  25. public function testR(array $points, float $r)
  26. {
  27. $regression = new Linear($points);
  28. $this->assertEqualsWithDelta($r, $regression->r($points), 0.001);
  29. }
  30. /**
  31. * @return array [points, r]
  32. */
  33. public function dataProviderForR(): array
  34. {
  35. return [
  36. [
  37. [ [1,2], [2,3], [4,5], [5,7], [6,8] ],
  38. 0.993
  39. ],
  40. [
  41. [ [4,390], [9,580], [10,650], [14,730], [4,410], [7,530], [12,600], [22,790], [1,350], [3,400], [8,590], [11,640], [5,450], [6,520], [10,690], [11,690], [16,770], [13,700], [13,730], [10,640] ],
  42. 0.9336
  43. ],
  44. ];
  45. }
  46. /**
  47. * @test coefficientOfDetermination
  48. * @dataProvider dataProviderForR2
  49. * @param array $points
  50. * @param float $r2
  51. */
  52. public function testCoefficientOfDetermination(array $points, float $r2)
  53. {
  54. // Given
  55. $regression = new Linear($points);
  56. // Then
  57. $this->assertEqualsWithDelta($r2, $regression->coefficientOfDetermination($points), 0.001);
  58. }
  59. /**
  60. * @test r2
  61. * @dataProvider dataProviderForR2
  62. * @param array $points
  63. * @param float $r2
  64. */
  65. public function testR2(array $points, float $r2)
  66. {
  67. // Given
  68. $regression = new Linear($points);
  69. // Then
  70. $this->assertEqualsWithDelta($r2, $regression->r2($points), 0.001);
  71. }
  72. /**
  73. * @return array [points, r2]
  74. */
  75. public function dataProviderForR2(): array
  76. {
  77. return [
  78. [
  79. [ [1,2], [2,3], [4,5], [5,7], [6,8] ],
  80. 0.986049
  81. ],
  82. [
  83. [ [4,390], [9,580], [10,650], [14,730], [4,410], [7,530], [12,600], [22,790], [1,350], [3,400], [8,590], [11,640], [5,450], [6,520], [10,690], [11,690], [16,770], [13,700], [13,730], [10,640] ],
  84. 0.87160896
  85. ],
  86. ];
  87. }
  88. /**
  89. * @test toString
  90. */
  91. public function testToString()
  92. {
  93. // Given
  94. $regression = new Linear([[1,2],[3,3],[3,4],[4,6]]);
  95. // Then
  96. $this->assertTrue(\is_string($regression->__toString()));
  97. }
  98. /**
  99. * @test sumOfSquaresTotal
  100. * @dataProvider dataProviderForSumOfSquaresTotal
  101. * @param array $points
  102. * @param float $SUStot
  103. */
  104. public function testSumOfSquaresTotal(array $points, float $SUStot)
  105. {
  106. // Given
  107. $regression = new Linear($points);
  108. // Then
  109. $this->assertEqualsWithDelta($SUStot, $regression->sumOfSquaresTotal(), 0.0001);
  110. }
  111. /**
  112. * @return array [points, SUStot]
  113. */
  114. public function dataProviderForSumOfSquaresTotal(): array
  115. {
  116. return [
  117. [ [[1,3], [2,6], [3,7], [4,11], [5,12], [6,13], [7,17]], 136.8571],
  118. [ [[1,2], [2,3], [4,5], [5,7], [6,8]], 26],
  119. ];
  120. }
  121. /**
  122. * @test yHat
  123. * @dataProvider dataProviderForYHat()
  124. * @param array $points
  125. * @param array $yhat
  126. */
  127. public function testYHat(array $points, array $yhat)
  128. {
  129. // Given
  130. $regression = new Linear($points);
  131. // Then
  132. $this->assertEqualsWithDelta($yhat, $regression->yHat(), 0.01);
  133. }
  134. /**
  135. * @return array [points, yHat]
  136. */
  137. public function dataProviderForYHat(): array
  138. {
  139. return [
  140. [
  141. [ [1,2], [2,3], [4,5], [5,7], [6,8] ], // m = 1.2209302325581, b = 0.60465116279069
  142. [ 1.82558139534879, 3.04651162790689, 5.48837209302309, 6.70930232558119, 7.93023255813929] // evaluate y = mx + b
  143. ],
  144. // Example data from http://faculty.cas.usf.edu/mbrannick/regression/regbas.html
  145. [
  146. [ [61,105], [62,120], [63,120], [65,160], [65,120], [68,145], [69,175], [70,160], [72,185], [75,210] ],
  147. [ 108.19, 115.16, 122.13, 136.06, 136.06, 156.97, 163.94, 170.91, 184.84, 205.75 ],
  148. ],
  149. ];
  150. }
  151. /**
  152. * @test sumOfSquaresRegression
  153. * @dataProvider dataProviderForSumOfSquaresRegression
  154. * @param array $points
  155. * @param float $SSreg
  156. */
  157. public function testSumOfSquaresRegression(array $points, float $SSreg)
  158. {
  159. // Given
  160. $regression = new Linear($points);
  161. // Then
  162. $this->assertEqualsWithDelta($SSreg, $regression->sumOfSquaresRegression(), 0.00001);
  163. }
  164. /**
  165. * @return array [points, SSreg]
  166. */
  167. public function dataProviderForSumOfSquaresRegression(): array
  168. {
  169. return [
  170. [
  171. [ [1,2], [2,3], [4,5], [5,7], [6,8] ], // y mean = 5; yhat = [1.82558139534879, 3.04651162790689, 5.48837209302309, 6.70930232558119, 7.93023255813929]
  172. 25.63953488371927 // 10.07693347755574 + 3.81611681990299 + 0.23850730124375 + 2.92171444023726 + 8.58626284477953
  173. ],
  174. [
  175. [ [61,105], [62,120], [63,120], [65,160], [65,120], [68,145], [69,175], [70,160], [72,185], [75,210] ], // y mean = 150; yhat = [108.1914893617, 115.15957446809, 122.12765957447, 136.06382978723, 136.06382978723, 156.96808510638, 163.93617021277, 170.90425531915, 184.84042553191, 205.74468085106]
  176. 9128.19148936100534 // 1747.95156179284427 + 1213.85525124456621 + 776.86736079663386 + 194.21684019929783 + 194.21684019929783 + 48.55421004975478 + 194.21684019929783 + 436.98789044821107 + 1213.85525124456621 + 3107.46944318653545
  177. ],
  178. ];
  179. }
  180. /**
  181. * @test sumOfSquaresResidual
  182. * @dataProvider dataProviderForSumOfSquaresResidual
  183. * @param array $points
  184. * @param float $SSres
  185. */
  186. public function testSumOfSquareResidual(array $points, float $SSres)
  187. {
  188. // Given
  189. $regression = new Linear($points);
  190. // Then
  191. $this->assertEqualsWithDelta($SSres, $regression->sumOfSquaresResidual(), 0.00001);
  192. }
  193. /**
  194. * @return array [points, SSres]
  195. */
  196. public function dataProviderForSumOfSquaresResidual()
  197. {
  198. return [
  199. [
  200. [ [1,2], [2,3], [4,5], [5,7], [6,8] ], // yhat = [1.82558139534879, 3.04651162790689, 5.48837209302309, 6.70930232558119, 7.93023255813929]
  201. 0.36046511627907 // 0.03042184964848 + 0.00216333153055 + 0.23850730124375 + 0.0845051379125 + 0.00486749594379
  202. ],
  203. [
  204. [ [61,105], [62,120], [63,120], [65,160], [65,120], [68,145], [69,175], [70,160], [72,185], [75,210] ], // yhat = [108.1914893617, 115.15957446809, 122.12765957447, 136.06382978723, 136.06382978723, 156.96808510638, 163.93617021277, 170.90425531915, 184.84042553191, 205.74468085106]
  205. 1271.80851063820534 // 10.18560434584427 + 23.42971932996621 + 4.52693526483386 + 572.94024445469783 + 258.04662743309783 + 143.23506111355478 + 122.40832956079783 + 118.90278406521107 + 0.02546401086621 + 18.10774105933545
  206. ],
  207. ];
  208. }
  209. /**
  210. * @test The sum of squares of Y equals the sum of squares regression plus the sum of squares of error (residual)
  211. * SStotal = SSreg + SSres
  212. * @dataProvider dataProviderForSumOfSquaresEqualsSumOfSQuaresRegressionPlusSumOfSquaresResidual
  213. * @param array $points
  214. */
  215. public function testSumOfSquaresEqualsSumOfSQuaresRegressionPlusSumOfSquaresResidual(array $points)
  216. {
  217. // Given
  218. $regression = new Linear($points);
  219. // Wheb
  220. $SStot = $regression->sumOfSquaresTotal();
  221. $SSreg = $regression->sumOfSquaresRegression();
  222. $SSres = $regression->sumOfSquaresResidual();
  223. // Then
  224. $this->assertEqualsWithDelta($SStot, $SSreg + $SSres, 0.001);
  225. }
  226. /**
  227. * @return array [points]
  228. */
  229. public function dataProviderForSumOfSquaresEqualsSumOfSQuaresRegressionPlusSumOfSquaresResidual(): array
  230. {
  231. return [
  232. [ [[1,2], [2,3], [4,5], [5,7], [6,8]] ],
  233. [ [[1,3], [2,6], [3,7], [4,11], [5,12], [6,13], [7,17]] ],
  234. [ [[61,105], [62,120], [63,120], [65,160], [65,120], [68,145], [69,175], [70,160], [72,185], [75,210]] ],
  235. ];
  236. }
  237. }