diff --git a/src/Phpml/Classification/SVC.php b/src/Phpml/Classification/SVC.php new file mode 100644 index 0000000..5279539 --- /dev/null +++ b/src/Phpml/Classification/SVC.php @@ -0,0 +1,53 @@ +kernel = $kernel; + $this->cost = $cost; + } + + /** + * @param array $samples + * @param array $labels + */ + public function train(array $samples, array $labels) + { + $this->samples = $samples; + $this->labels = $labels; + } + + /** + * @param array $sample + * + * @return mixed + */ + protected function predictSample(array $sample) + { + } +} diff --git a/src/Phpml/Classification/SupportVectorMachine.php b/src/Phpml/Classification/SupportVectorMachine.php deleted file mode 100644 index 5eb84e6..0000000 --- a/src/Phpml/Classification/SupportVectorMachine.php +++ /dev/null @@ -1,78 +0,0 @@ -kernel = $kernel; - $this->C = $C; - $this->tolerance = $tolerance; - $this->upperBound = $upperBound; - - $this->binPath = realpath(implode(DIRECTORY_SEPARATOR, array(dirname(__FILE__), '..', '..', '..', 'bin'))) . DIRECTORY_SEPARATOR; - } - - /** - * @param array $samples - * @param array $labels - */ - public function train(array $samples, array $labels) - { - $this->samples = $samples; - $this->labels = $labels; - } - - /** - * @param array $sample - * - * @return mixed - */ - protected function predictSample(array $sample) - { - } -} diff --git a/src/Phpml/Dataset/Dataset.php b/src/Phpml/Dataset/Dataset.php index 2bc4043..4e04931 100644 --- a/src/Phpml/Dataset/Dataset.php +++ b/src/Phpml/Dataset/Dataset.php @@ -6,7 +6,6 @@ namespace Phpml\Dataset; interface Dataset { - const SOME = 'z'; /** * @return array */ diff --git a/src/Phpml/SupportVectorMachine/DataTransformer.php b/src/Phpml/SupportVectorMachine/DataTransformer.php new file mode 100644 index 0000000..4e01fc8 --- /dev/null +++ b/src/Phpml/SupportVectorMachine/DataTransformer.php @@ -0,0 +1,59 @@ + $label) { + $set .= sprintf('%s %s %s', $numericLabels[$label], self::sampleRow($samples[$index]), PHP_EOL); + } + + return $set; + } + + /** + * @param array $labels + * + * @return array + */ + public static function numericLabels(array $labels): array + { + $numericLabels = []; + foreach ($labels as $label) { + if (isset($numericLabels[$label])) { + continue; + } + + $numericLabels[$label] = count($numericLabels); + } + + return $numericLabels; + } + + /** + * @param array $sample + * + * @return string + */ + private static function sampleRow(array $sample): string + { + $row = []; + foreach ($sample as $index => $feature) { + $row[] = sprintf('%s:%s', $index, $feature); + } + + return implode(' ', $row); + } +} diff --git a/src/Phpml/SupportVectorMachine/Kernel.php b/src/Phpml/SupportVectorMachine/Kernel.php new file mode 100644 index 0000000..4dddef6 --- /dev/null +++ b/src/Phpml/SupportVectorMachine/Kernel.php @@ -0,0 +1,28 @@ +type = $type; + $this->kernel = $kernel; + $this->cost = $cost; + + $rootPath = realpath(implode(DIRECTORY_SEPARATOR, [dirname(__FILE__), '..', '..', '..'])).DIRECTORY_SEPARATOR; + + $this->binPath = $rootPath.'bin'.DIRECTORY_SEPARATOR.'libsvm'.DIRECTORY_SEPARATOR; + $this->varPath = $rootPath.'var'.DIRECTORY_SEPARATOR; + } + + /** + * @param array $samples + * @param array $labels + */ + public function train(array $samples, array $labels) + { + $trainingSet = DataTransformer::trainingSet($samples, $labels); + file_put_contents($trainingSetFileName = $this->varPath.uniqid(), $trainingSet); + $modelFileName = $trainingSetFileName.'-model'; + + $command = sprintf('%ssvm-train -s %s -t %s -c %s %s %s', $this->binPath, $this->type, $this->kernel, $this->cost, $trainingSetFileName, $modelFileName); + $output = ''; + exec(escapeshellcmd($command), $output); + + $this->model = file_get_contents($modelFileName); + + unlink($trainingSetFileName); + unlink($modelFileName); + } + + /** + * @return string + */ + public function getModel() + { + return $this->model; + } +} diff --git a/src/Phpml/SupportVectorMachine/Type.php b/src/Phpml/SupportVectorMachine/Type.php new file mode 100644 index 0000000..49b03a0 --- /dev/null +++ b/src/Phpml/SupportVectorMachine/Type.php @@ -0,0 +1,33 @@ +assertEquals($trainingSet, DataTransformer::trainingSet($samples, $labels)); + } +} diff --git a/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php b/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php new file mode 100644 index 0000000..e06f715 --- /dev/null +++ b/tests/Phpml/SupportVectorMachine/SupportVectorMachineTest.php @@ -0,0 +1,36 @@ +train($samples, $labels); + + $this->assertEquals($model, $svm->getModel()); + } +} diff --git a/var/.gitkeep b/var/.gitkeep new file mode 100644 index 0000000..e69de29