forked from jorgecasas/php-ml
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
317 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
declare (strict_types = 1); | ||
|
||
namespace Phpml\Classification; | ||
|
||
use Phpml\Classification\Traits\Predictable; | ||
use Phpml\Classification\Traits\Trainable; | ||
use Phpml\Math\Kernel; | ||
|
||
class SVC implements Classifier | ||
{ | ||
use Trainable, Predictable; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
private $kernel; | ||
|
||
/** | ||
* @var float | ||
*/ | ||
private $cost; | ||
|
||
/** | ||
* @param int $kernel | ||
* @param float $cost | ||
*/ | ||
public function __construct(int $kernel, float $cost) | ||
{ | ||
$this->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) | ||
{ | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,6 @@ | |
|
||
interface Dataset | ||
{ | ||
const SOME = 'z'; | ||
/** | ||
* @return array | ||
*/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
|
||
declare (strict_types = 1); | ||
|
||
namespace Phpml\SupportVectorMachine; | ||
|
||
class DataTransformer | ||
{ | ||
/** | ||
* @param array $samples | ||
* @param array $labels | ||
* | ||
* @return string | ||
*/ | ||
public static function trainingSet(array $samples, array $labels): string | ||
{ | ||
$set = ''; | ||
$numericLabels = self::numericLabels($labels); | ||
foreach ($labels as $index => $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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
declare (strict_types = 1); | ||
|
||
namespace Phpml\SupportVectorMachine; | ||
|
||
abstract class Kernel | ||
{ | ||
/** | ||
* u'*v. | ||
*/ | ||
const LINEAR = 0; | ||
|
||
/** | ||
* (gamma*u'*v + coef0)^degree. | ||
*/ | ||
const POLYNOMIAL = 1; | ||
|
||
/** | ||
* exp(-gamma*|u-v|^2). | ||
*/ | ||
const RBF = 2; | ||
|
||
/** | ||
* tanh(gamma*u'*v + coef0). | ||
*/ | ||
const SIGMOID = 3; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
declare (strict_types = 1); | ||
|
||
namespace Phpml\SupportVectorMachine; | ||
|
||
class SupportVectorMachine | ||
{ | ||
/** | ||
* @var int | ||
*/ | ||
private $type; | ||
|
||
/** | ||
* @var int | ||
*/ | ||
private $kernel; | ||
|
||
/** | ||
* @var float | ||
*/ | ||
private $cost; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $binPath; | ||
|
||
/** | ||
* @var | ||
*/ | ||
private $varPath; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $model; | ||
|
||
/** | ||
* @param int $type | ||
* @param int $kernel | ||
* @param float $cost | ||
*/ | ||
public function __construct(int $type, int $kernel, float $cost) | ||
{ | ||
$this->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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare (strict_types = 1); | ||
|
||
namespace Phpml\SupportVectorMachine; | ||
|
||
abstract class Type | ||
{ | ||
/** | ||
* classification. | ||
*/ | ||
const C_SVC = 0; | ||
|
||
/** | ||
* classification. | ||
*/ | ||
const NU_SVC = 1; | ||
|
||
/** | ||
* distribution estimation. | ||
*/ | ||
const ONE_CLASS_SVM = 2; | ||
|
||
/** | ||
* regression. | ||
*/ | ||
const EPSILON_SVR = 3; | ||
|
||
/** | ||
* regression. | ||
*/ | ||
const NU_SVR = 4; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
declare (strict_types = 1); | ||
|
||
namespace tests\SupportVectorMachine; | ||
|
||
use Phpml\SupportVectorMachine\DataTransformer; | ||
|
||
class DataTransformerTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
public function testTransformDatasetToTrainingSet() | ||
{ | ||
$samples = [[1, 1], [2, 1], [3, 2], [4, 5]]; | ||
$labels = ['a', 'a', 'b', 'b']; | ||
|
||
$trainingSet = | ||
'0 0:1 1:1 '.PHP_EOL. | ||
'0 0:2 1:1 '.PHP_EOL. | ||
'1 0:3 1:2 '.PHP_EOL. | ||
'1 0:4 1:5 '.PHP_EOL | ||
; | ||
|
||
$this->assertEquals($trainingSet, DataTransformer::trainingSet($samples, $labels)); | ||
} | ||
} |
Oops, something went wrong.