1 <?php 2 3 declare(strict_types=1); 4 5 namespace Phpml\DimensionReduction; 6 7 use Phpml\Math\LinearAlgebra\EigenvalueDecomposition; 8 use Phpml\Math\Matrix; 9 10 /** 11 * Class to compute eigen pairs (values & vectors) of a given matrix 12 * with the consideration of numFeatures or totalVariance to be preserved 13 * 14 * @author hp 15 */ 16 abstract class EigenTransformerBase 17 { 18 /** 19 * Total variance to be conserved after the reduction 20 * 21 * @var float 22 */ 23 public $totalVariance = 0.9; 24 25 /** 26 * Number of features to be preserved after the reduction 27 * 28 * @var int 29 */ 30 public $numFeatures = null; 31 32 /** 33 * Top eigenvectors of the matrix 34 * 35 * @var array 36 */ 37 protected $eigVectors = []; 38 39 /** 40 * Top eigenValues of the matrix 41 * 42 * @var array 43 */ 44 protected $eigValues = []; 45 46 /** 47 * Calculates eigenValues and eigenVectors of the given matrix. Returns 48 * top eigenVectors along with the largest eigenValues. The total explained variance 49 * of these eigenVectors will be no less than desired $totalVariance value 50 */ 51 protected function eigenDecomposition(array $matrix): void 52 { 53 $eig = new EigenvalueDecomposition($matrix); 54 $eigVals = $eig->getRealEigenvalues(); 55 $eigVects = $eig->getEigenvectors(); 56 57 $totalEigVal = array_sum($eigVals); 58 // Sort eigenvalues in descending order 59 arsort($eigVals); 60 61 $explainedVar = 0.0; 62 $vectors = []; 63 $values = []; 64 foreach ($eigVals as $i => $eigVal) { 65 $explainedVar += $eigVal / $totalEigVal; 66 $vectors[] = $eigVects[$i]; 67 $values[] = $eigVal; 68 69 if ($this->numFeatures !== null) { 70 if (count($vectors) == $this->numFeatures) { 71 break; 72 } 73 } else { 74 if ($explainedVar >= $this->totalVariance) { 75 break; 76 } 77 } 78 } 79 80 $this->eigValues = $values; 81 $this->eigVectors = $vectors; 82 } 83 84 /** 85 * Returns the reduced data 86 */ 87 protected function reduce(array $data): array 88 { 89 $m1 = new Matrix($data); 90 $m2 = new Matrix($this->eigVectors); 91 92 return $m1->multiply($m2->transpose())->toArray(); 93 } 94 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body