From ba7114a3f7880071226c8870826456ab62497741 Mon Sep 17 00:00:00 2001 From: Marcin Michalski Date: Fri, 26 Jan 2018 22:07:22 +0100 Subject: [PATCH] Add libsvm exception tests (#202) --- .../Exception/LibsvmCommandException.php | 4 +-- .../SupportVectorMachine.php | 25 ++++++++++--------- .../SupportVectorMachineTest.php | 19 ++++++++++++++ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/Phpml/Exception/LibsvmCommandException.php b/src/Phpml/Exception/LibsvmCommandException.php index 01d8079..a9d11e3 100644 --- a/src/Phpml/Exception/LibsvmCommandException.php +++ b/src/Phpml/Exception/LibsvmCommandException.php @@ -8,8 +8,8 @@ use Exception; class LibsvmCommandException extends Exception { - public static function failedToRun(string $command): self + public static function failedToRun(string $command, string $reason): self { - return new self(sprintf('Failed running libsvm command: "%s"', $command)); + return new self(sprintf('Failed running libsvm command: "%s" with reason: "%s"', $command, $reason)); } } diff --git a/src/Phpml/SupportVectorMachine/SupportVectorMachine.php b/src/Phpml/SupportVectorMachine/SupportVectorMachine.php index f66d5d7..ce7a7ba 100644 --- a/src/Phpml/SupportVectorMachine/SupportVectorMachine.php +++ b/src/Phpml/SupportVectorMachine/SupportVectorMachine.php @@ -153,16 +153,17 @@ class SupportVectorMachine $modelFileName = $trainingSetFileName.'-model'; $command = $this->buildTrainCommand($trainingSetFileName, $modelFileName); - $output = ''; - exec(escapeshellcmd($command), $output, $return); + $output = []; + exec(escapeshellcmd($command).' 2>&1', $output, $return); + + unlink($trainingSetFileName); if ($return !== 0) { - throw LibsvmCommandException::failedToRun($command); + throw LibsvmCommandException::failedToRun($command, array_pop($output)); } $this->model = file_get_contents($modelFileName); - unlink($trainingSetFileName); unlink($modelFileName); } @@ -184,19 +185,19 @@ class SupportVectorMachine $outputFileName = $testSetFileName.'-output'; $command = sprintf('%ssvm-predict%s %s %s %s', $this->binPath, $this->getOSExtension(), $testSetFileName, $modelFileName, $outputFileName); - $output = ''; - exec(escapeshellcmd($command), $output, $return); - - if ($return !== 0) { - throw LibsvmCommandException::failedToRun($command); - } - - $predictions = file_get_contents($outputFileName); + $output = []; + exec(escapeshellcmd($command).' 2>&1', $output, $return); unlink($testSetFileName); unlink($modelFileName); + $predictions = file_get_contents($outputFileName); + unlink($outputFileName); + if ($return !== 0) { + throw LibsvmCommandException::failedToRun($command, array_pop($output)); + } + if (in_array($this->type, [Type::C_SVC, Type::NU_SVC])) { $predictions = DataTransformer::predictions($predictions, $this->targets); } else { diff --git a/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php b/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php index 180b8d3..466c962 100644 --- a/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php +++ b/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Phpml\Tests\SupportVectorMachine; use Phpml\Exception\InvalidArgumentException; +use Phpml\Exception\LibsvmCommandException; use Phpml\SupportVectorMachine\Kernel; use Phpml\SupportVectorMachine\SupportVectorMachine; use Phpml\SupportVectorMachine\Type; @@ -105,4 +106,22 @@ SV $svm = new SupportVectorMachine(Type::C_SVC, Kernel::RBF); $svm->setBinPath('var'); } + + public function testThrowExceptionWhenLibsvmFailsDuringTrain(): void + { + $this->expectException(LibsvmCommandException::class); + $this->expectExceptionMessage('ERROR: unknown svm type'); + + $svm = new SupportVectorMachine(99, Kernel::RBF); + $svm->train([], []); + } + + public function testThrowExceptionWhenLibsvmFailsDuringPredict(): void + { + $this->expectException(LibsvmCommandException::class); + $this->expectExceptionMessage('can\'t open model file'); + + $svm = new SupportVectorMachine(Type::C_SVC, Kernel::RBF); + $svm->predict([1]); + } }