123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- <?php
- namespace MathPHP\Tests\InformationTheory;
- use MathPHP\InformationTheory\Entropy;
- use MathPHP\Exception;
- class EntropyTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @dataProvider dataProviderForShannonEntropy
- */
- public function testShannonEntropy(array $p, $expected)
- {
- // When
- $H = Entropy::shannonEntropy($p);
- // Then
- $this->assertEqualsWithDelta($expected, $H, 0.001);
- }
- public function dataProviderForShannonEntropy(): array
- {
- return [
- // Test data created from: http://www.shannonentropy.netmark.pl/
- [
- [1],
- 0
- ],
- [
- [0.6, 0.4],
- 0.97095,
- ],
- [
- [0.514, 0.486],
- 0.99941,
- ],
- [
- [0.231, 0.385, 0.308, 0.077],
- 1.82625,
- ],
- // Test data from: http://www.csun.edu/~twang/595DM/Slides/Information%20&%20Entropy.pdf
- [
- [4 / 9, 3 / 9, 2 / 9],
- 1.5304755,
- ],
- // Test data from: http://www.cs.rochester.edu/u/james/CSC248/Lec6.pdf
- [
- [0.4, 0.1, 0.25, 0.25],
- 1.86,
- ],
- // Other
- [
- [1 / 2, 1 / 4, 1 / 4, 0],
- 3 / 2,
- ],
- ];
- }
- public function testShannonEntropyExceptionNotProbabilityDistributionThatAddsUpToOne()
- {
- // Given
- $p = [0.2, 0.2, 0.1];
- // Then
- $this->expectException(Exception\BadDataException::class);
- // When
- Entropy::shannonEntropy($p);
- }
- /**
- * @dataProvider dataProviderForShannonNatEntropy
- */
- public function testShannonNatEntropy(array $p, $expected)
- {
- // When
- $H = Entropy::shannonNatEntropy($p);
- // Then
- $this->assertEqualsWithDelta($expected, $H, 0.000001);
- }
- public function dataProviderForShannonNatEntropy(): array
- {
- return [
- [
- [1],
- 0
- ],
- [
- [0.6, 0.4],
- 0.67301166700925,
- ],
- [
- [0.514, 0.486],
- 0.69275512932254,
- ],
- [
- [0.231, 0.385, 0.308, 0.077],
- 1.2661221087912,
- ],
- [
- [4 / 9, 3 / 9, 2 / 9],
- 1.06085694715802,
- ],
- ];
- }
- public function testShannonNatEntropyExceptionNotProbabilityDistributionThatAddsUpToOne()
- {
- // Given
- $p = [0.2, 0.2, 0.1];
- // Then
- $this->expectException(Exception\BadDataException::class);
- // When
- Entropy::shannonNatEntropy($p);
- }
- /**
- * @dataProvider dataProviderForShannonHartleyEntropy
- */
- public function testShannonHartleyEntropy(array $p, $expected)
- {
- // When
- $H = Entropy::shannonHartleyEntropy($p);
- // Then
- $this->assertEqualsWithDelta($expected, $H, 0.000001);
- }
- public function dataProviderForShannonHartleyEntropy(): array
- {
- return [
- [
- [1],
- 0
- ],
- [
- [0.6, 0.4],
- 0.29228525323863,
- ],
- [
- [0.514, 0.486],
- 0.30085972997496,
- ],
- [
- [0.231, 0.385, 0.308, 0.077],
- 0.54986984526372,
- ],
- [
- [4 / 9, 3 / 9, 2 / 9],
- 0.46072431823946,
- ],
- ];
- }
- public function testShannonHartleyEntropyExceptionNotProbabilityDistributionThatAddsUpToOne()
- {
- // Given
- $p = [0.2, 0.2, 0.1];
- // Then
- $this->expectException(Exception\BadDataException::class);
- // When
- Entropy::shannonHartleyEntropy($p);
- }
- /**
- * @dataProvider dataProviderForCrossEntropy
- */
- public function testCrossEntropy(array $p, array $q, $expected)
- {
- // When
- $BD = Entropy::crossEntropy($p, $q);
- // Then
- $this->assertEqualsWithDelta($expected, $BD, 0.01);
- }
- public function dataProviderForCrossEntropy(): array
- {
- return [
- // Test data from: http://www.cs.rochester.edu/u/james/CSC248/Lec6.pdf
- [
- [0.4, 0.1, 0.25, 0.25],
- [0.25, 0.25, 0.25, 0.25],
- 2,
- ],
- [
- [0.4, 0.1, 0.25, 0.25],
- [0.4, 0.1, 0.1, 0.4],
- 2.02,
- ],
- ];
- }
- public function testCrossEntropyExceptionArraysDifferentLength()
- {
- // Given
- $p = [0.4, 0.5, 0.1];
- $q = [0.2, 0.8];
- // Then
- $this->expectException(Exception\BadDataException::class);
- // When
- Entropy::crossEntropy($p, $q);
- }
- public function testCrossEntropyExceptionNotProbabilityDistributionThatAddsUpToOne()
- {
- // Given
- $p = [0.2, 0.2, 0.1];
- $q = [0.2, 0.4, 0.6];
- // Then
- $this->expectException(Exception\BadDataException::class);
- // When
- Entropy::crossEntropy($p, $q);
- }
- /**
- * @dataProvider dataProviderForShannonEntropy
- */
- public function testJointEntropy(array $p, $expected)
- {
- // When
- $H = Entropy::jointEntropy($p);
- // Then
- $this->assertEqualsWithDelta($expected, $H, 0.001);
- }
- public function testJointEntropyExceptionNotProbabilityDistributionThatAddsUpToOne()
- {
- // Given
- $p = [0.2, 0.2, 0.1];
- // Then
- $this->expectException(Exception\BadDataException::class);
- // When
- Entropy::jointEntropy($p);
- }
- /**
- * @dataProvider dataProviderForRenyiEntropy
- */
- public function testRenyiEntropy(array $p, $α, $expected)
- {
- // When
- $H = Entropy::renyiEntropy($p, $α);
- // Then
- $this->assertEqualsWithDelta($expected, $H, 0.001);
- }
- public function dataProviderForRenyiEntropy(): array
- {
- return [
- [
- [0.4, 0.6], 0.5, 0.985352,
- [0.2, 0.3, 0.5], 0.8, 1.504855,
- ],
- ];
- }
- public function testRenyiEntropyExceptionNotProbabilityDistributionThatAddsUpToOne()
- {
- // Given
- $p = [0.2, 0.2, 0.1];
- $α = 0.5;
- // Then
- $this->expectException(Exception\BadDataException::class);
- // When
- Entropy::renyiEntropy($p, $α);
- }
- public function testRenyiEntropyExceptionAlphaOutOfBounds()
- {
- // Given
- $p = [0.4, 0.4, 0.2];
- $α = -3;
- // Then
- $this->expectException(Exception\OutOfBoundsException::class);
- // When
- Entropy::renyiEntropy($p, $α);
- }
- public function testRenyiEntropyExceptionAlphaEqualsOne()
- {
- // Given
- $p = [0.4, 0.4, 0.2];
- $α = 1;
- // Then
- $this->expectException(Exception\OutOfBoundsException::class);
- // When
- Entropy::renyiEntropy($p, $α);
- }
- /**
- * @dataProvider dataProviderForPerplexity
- */
- public function testPerplexity(array $p, $expected)
- {
- // When
- $H = Entropy::perplexity($p);
- // Then
- $this->assertEqualsWithDelta($expected, $H, 0.001);
- }
- public function dataProviderForPerplexity(): array
- {
- return [
- [
- [1 / 10, 1 / 10, 1 / 10, 1 / 10, 1 / 10, 1 / 10, 1 / 10, 1 / 10, 1 / 10, 1 / 10],
- 10
- ],
- [
- [1],
- 1
- ],
- [
- [0.6, 0.4],
- 1.960130896546316,
- ],
- [
- [0.514, 0.486],
- 1.999182253549837,
- ],
- [
- [0.231, 0.385, 0.308, 0.077],
- 3.546141242991336,
- ],
- [
- [4 / 9, 3 / 9, 2 / 9],
- 2.888810361450759,
- ],
- [
- [1 / 2, 1 / 4, 1 / 4, 0],
- 2.82842712474619,
- ],
- ];
- }
- public function testPerplexityExceptionNotProbabilityDistributionThatAddsUpToOne()
- {
- // Given
- $p = [0.2, 0.2, 0.1];
- // Then
- $this->expectException(Exception\BadDataException::class);
- // When
- Entropy::perplexity($p);
- }
- }
|