mirror of
https://github.com/Llewellynvdm/php-ml.git
synced 2024-11-28 15:56:36 +00:00
Upgrade to PHP 7.1 (#150)
* upgrade to PHP 7.1 * bump travis and composer to PHP 7.1 * fix tests
This commit is contained in:
parent
331d4b133e
commit
653c7c772d
@ -4,9 +4,6 @@ matrix:
|
|||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- os: linux
|
|
||||||
php: '7.0'
|
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
php: '7.1'
|
php: '7.1'
|
||||||
|
|
||||||
@ -18,7 +15,7 @@ matrix:
|
|||||||
language: generic
|
language: generic
|
||||||
env:
|
env:
|
||||||
- _OSX=10.11
|
- _OSX=10.11
|
||||||
- _PHP: php70
|
- _PHP: php71
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then /usr/bin/env bash tools/prepare_osx_env.sh ; fi
|
- if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then /usr/bin/env bash tools/prepare_osx_env.sh ; fi
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.0.0"
|
"php": "^7.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^6.0",
|
"phpunit/phpunit": "^6.0",
|
||||||
|
@ -11,13 +11,13 @@ class Apriori implements Associator
|
|||||||
{
|
{
|
||||||
use Trainable, Predictable;
|
use Trainable, Predictable;
|
||||||
|
|
||||||
const ARRAY_KEY_ANTECEDENT = 'antecedent';
|
public const ARRAY_KEY_ANTECEDENT = 'antecedent';
|
||||||
|
|
||||||
const ARRAY_KEY_CONFIDENCE = 'confidence';
|
public const ARRAY_KEY_CONFIDENCE = 'confidence';
|
||||||
|
|
||||||
const ARRAY_KEY_CONSEQUENT = 'consequent';
|
public const ARRAY_KEY_CONSEQUENT = 'consequent';
|
||||||
|
|
||||||
const ARRAY_KEY_SUPPORT = 'support';
|
public const ARRAY_KEY_SUPPORT = 'support';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimum relative probability of frequent transactions.
|
* Minimum relative probability of frequent transactions.
|
||||||
@ -116,7 +116,7 @@ class Apriori implements Associator
|
|||||||
/**
|
/**
|
||||||
* Generate rules for each k-length frequent item set.
|
* Generate rules for each k-length frequent item set.
|
||||||
*/
|
*/
|
||||||
private function generateAllRules()
|
private function generateAllRules(): void
|
||||||
{
|
{
|
||||||
for ($k = 2; !empty($this->large[$k]); ++$k) {
|
for ($k = 2; !empty($this->large[$k]); ++$k) {
|
||||||
foreach ($this->large[$k] as $frequent) {
|
foreach ($this->large[$k] as $frequent) {
|
||||||
@ -130,7 +130,7 @@ class Apriori implements Associator
|
|||||||
*
|
*
|
||||||
* @param mixed[] $frequent
|
* @param mixed[] $frequent
|
||||||
*/
|
*/
|
||||||
private function generateRules(array $frequent)
|
private function generateRules(array $frequent): void
|
||||||
{
|
{
|
||||||
foreach ($this->antecedents($frequent) as $antecedent) {
|
foreach ($this->antecedents($frequent) as $antecedent) {
|
||||||
if ($this->confidence <= ($confidence = $this->confidence($frequent, $antecedent))) {
|
if ($this->confidence <= ($confidence = $this->confidence($frequent, $antecedent))) {
|
||||||
|
@ -14,8 +14,8 @@ class DecisionTree implements Classifier
|
|||||||
{
|
{
|
||||||
use Trainable, Predictable;
|
use Trainable, Predictable;
|
||||||
|
|
||||||
const CONTINUOUS = 1;
|
public const CONTINUOUS = 1;
|
||||||
const NOMINAL = 2;
|
public const NOMINAL = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
@ -72,7 +72,7 @@ class DecisionTree implements Classifier
|
|||||||
$this->maxDepth = $maxDepth;
|
$this->maxDepth = $maxDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
$this->samples = array_merge($this->samples, $samples);
|
$this->samples = array_merge($this->samples, $samples);
|
||||||
$this->targets = array_merge($this->targets, $targets);
|
$this->targets = array_merge($this->targets, $targets);
|
||||||
@ -354,7 +354,7 @@ class DecisionTree implements Classifier
|
|||||||
/**
|
/**
|
||||||
* Used to set predefined features to consider while deciding which column to use for a split
|
* Used to set predefined features to consider while deciding which column to use for a split
|
||||||
*/
|
*/
|
||||||
protected function setSelectedFeatures(array $selectedFeatures)
|
protected function setSelectedFeatures(array $selectedFeatures): void
|
||||||
{
|
{
|
||||||
$this->selectedFeatures = $selectedFeatures;
|
$this->selectedFeatures = $selectedFeatures;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ class AdaBoost implements Classifier
|
|||||||
/**
|
/**
|
||||||
* Sets the base classifier that will be used for boosting (default = DecisionStump)
|
* Sets the base classifier that will be used for boosting (default = DecisionStump)
|
||||||
*/
|
*/
|
||||||
public function setBaseClassifier(string $baseClassifier = DecisionStump::class, array $classifierOptions = [])
|
public function setBaseClassifier(string $baseClassifier = DecisionStump::class, array $classifierOptions = []): void
|
||||||
{
|
{
|
||||||
$this->baseClassifier = $baseClassifier;
|
$this->baseClassifier = $baseClassifier;
|
||||||
$this->classifierOptions = $classifierOptions;
|
$this->classifierOptions = $classifierOptions;
|
||||||
@ -93,7 +93,7 @@ class AdaBoost implements Classifier
|
|||||||
/**
|
/**
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
// Initialize usual variables
|
// Initialize usual variables
|
||||||
$this->labels = array_keys(array_count_values($targets));
|
$this->labels = array_keys(array_count_values($targets));
|
||||||
@ -149,7 +149,7 @@ class AdaBoost implements Classifier
|
|||||||
$classifier->setSampleWeights($this->weights);
|
$classifier->setSampleWeights($this->weights);
|
||||||
$classifier->train($this->samples, $this->targets);
|
$classifier->train($this->samples, $this->targets);
|
||||||
} else {
|
} else {
|
||||||
list($samples, $targets) = $this->resample();
|
[$samples, $targets] = $this->resample();
|
||||||
$classifier->train($samples, $targets);
|
$classifier->train($samples, $targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +216,7 @@ class AdaBoost implements Classifier
|
|||||||
/**
|
/**
|
||||||
* Updates the sample weights
|
* Updates the sample weights
|
||||||
*/
|
*/
|
||||||
protected function updateWeights(Classifier $classifier, float $alpha)
|
protected function updateWeights(Classifier $classifier, float $alpha): void
|
||||||
{
|
{
|
||||||
$sumOfWeights = array_sum($this->weights);
|
$sumOfWeights = array_sum($this->weights);
|
||||||
$weightsT1 = [];
|
$weightsT1 = [];
|
||||||
|
@ -106,7 +106,7 @@ class Bagging implements Classifier
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
$this->samples = array_merge($this->samples, $samples);
|
$this->samples = array_merge($this->samples, $samples);
|
||||||
$this->targets = array_merge($this->targets, $targets);
|
$this->targets = array_merge($this->targets, $targets);
|
||||||
@ -117,7 +117,7 @@ class Bagging implements Classifier
|
|||||||
$this->classifiers = $this->initClassifiers();
|
$this->classifiers = $this->initClassifiers();
|
||||||
$index = 0;
|
$index = 0;
|
||||||
foreach ($this->classifiers as $classifier) {
|
foreach ($this->classifiers as $classifier) {
|
||||||
list($samples, $targets) = $this->getRandomSubset($index);
|
[$samples, $targets] = $this->getRandomSubset($index);
|
||||||
$classifier->train($samples, $targets);
|
$classifier->train($samples, $targets);
|
||||||
++$index;
|
++$index;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class KNearestNeighbors implements Classifier
|
|||||||
/**
|
/**
|
||||||
* @param Distance|null $distanceMetric (if null then Euclidean distance as default)
|
* @param Distance|null $distanceMetric (if null then Euclidean distance as default)
|
||||||
*/
|
*/
|
||||||
public function __construct(int $k = 3, Distance $distanceMetric = null)
|
public function __construct(int $k = 3, ?Distance $distanceMetric = null)
|
||||||
{
|
{
|
||||||
if (null === $distanceMetric) {
|
if (null === $distanceMetric) {
|
||||||
$distanceMetric = new Euclidean();
|
$distanceMetric = new Euclidean();
|
||||||
|
@ -9,12 +9,12 @@ class Adaline extends Perceptron
|
|||||||
/**
|
/**
|
||||||
* Batch training is the default Adaline training algorithm
|
* Batch training is the default Adaline training algorithm
|
||||||
*/
|
*/
|
||||||
const BATCH_TRAINING = 1;
|
public const BATCH_TRAINING = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Online training: Stochastic gradient descent learning
|
* Online training: Stochastic gradient descent learning
|
||||||
*/
|
*/
|
||||||
const ONLINE_TRAINING = 2;
|
public const ONLINE_TRAINING = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Training type may be either 'Batch' or 'Online' learning
|
* Training type may be either 'Batch' or 'Online' learning
|
||||||
|
@ -14,7 +14,7 @@ class DecisionStump extends WeightedClassifier
|
|||||||
{
|
{
|
||||||
use Predictable, OneVsRest;
|
use Predictable, OneVsRest;
|
||||||
|
|
||||||
const AUTO_SELECT = -1;
|
public const AUTO_SELECT = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
@ -86,7 +86,7 @@ class DecisionStump extends WeightedClassifier
|
|||||||
/**
|
/**
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
protected function trainBinary(array $samples, array $targets, array $labels)
|
protected function trainBinary(array $samples, array $targets, array $labels): void
|
||||||
{
|
{
|
||||||
$this->binaryLabels = $labels;
|
$this->binaryLabels = $labels;
|
||||||
$this->featureCount = count($samples[0]);
|
$this->featureCount = count($samples[0]);
|
||||||
@ -146,7 +146,7 @@ class DecisionStump extends WeightedClassifier
|
|||||||
* points to be probed. The more split counts, the better performance but
|
* points to be probed. The more split counts, the better performance but
|
||||||
* worse processing time (Default value is 10.0)
|
* worse processing time (Default value is 10.0)
|
||||||
*/
|
*/
|
||||||
public function setNumericalSplitCount(float $count)
|
public function setNumericalSplitCount(float $count): void
|
||||||
{
|
{
|
||||||
$this->numSplitCount = $count;
|
$this->numSplitCount = $count;
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ class DecisionStump extends WeightedClassifier
|
|||||||
// Before trying all possible split points, let's first try
|
// Before trying all possible split points, let's first try
|
||||||
// the average value for the cut point
|
// the average value for the cut point
|
||||||
$threshold = array_sum($values) / (float) count($values);
|
$threshold = array_sum($values) / (float) count($values);
|
||||||
list($errorRate, $prob) = $this->calculateErrorRate($targets, $threshold, $operator, $values);
|
[$errorRate, $prob] = $this->calculateErrorRate($targets, $threshold, $operator, $values);
|
||||||
if ($split == null || $errorRate < $split['trainingErrorRate']) {
|
if ($split == null || $errorRate < $split['trainingErrorRate']) {
|
||||||
$split = ['value' => $threshold, 'operator' => $operator,
|
$split = ['value' => $threshold, 'operator' => $operator,
|
||||||
'prob' => $prob, 'column' => $col,
|
'prob' => $prob, 'column' => $col,
|
||||||
@ -181,7 +181,7 @@ class DecisionStump extends WeightedClassifier
|
|||||||
// Try other possible points one by one
|
// Try other possible points one by one
|
||||||
for ($step = $minValue; $step <= $maxValue; $step += $stepSize) {
|
for ($step = $minValue; $step <= $maxValue; $step += $stepSize) {
|
||||||
$threshold = (float) $step;
|
$threshold = (float) $step;
|
||||||
list($errorRate, $prob) = $this->calculateErrorRate($targets, $threshold, $operator, $values);
|
[$errorRate, $prob] = $this->calculateErrorRate($targets, $threshold, $operator, $values);
|
||||||
if ($errorRate < $split['trainingErrorRate']) {
|
if ($errorRate < $split['trainingErrorRate']) {
|
||||||
$split = ['value' => $threshold, 'operator' => $operator,
|
$split = ['value' => $threshold, 'operator' => $operator,
|
||||||
'prob' => $prob, 'column' => $col,
|
'prob' => $prob, 'column' => $col,
|
||||||
@ -203,7 +203,7 @@ class DecisionStump extends WeightedClassifier
|
|||||||
|
|
||||||
foreach (['=', '!='] as $operator) {
|
foreach (['=', '!='] as $operator) {
|
||||||
foreach ($distinctVals as $val) {
|
foreach ($distinctVals as $val) {
|
||||||
list($errorRate, $prob) = $this->calculateErrorRate($targets, $val, $operator, $values);
|
[$errorRate, $prob] = $this->calculateErrorRate($targets, $val, $operator, $values);
|
||||||
|
|
||||||
if ($split == null || $split['trainingErrorRate'] < $errorRate) {
|
if ($split == null || $split['trainingErrorRate'] < $errorRate) {
|
||||||
$split = ['value' => $val, 'operator' => $operator,
|
$split = ['value' => $val, 'operator' => $operator,
|
||||||
@ -289,7 +289,7 @@ class DecisionStump extends WeightedClassifier
|
|||||||
return $this->binaryLabels[1];
|
return $this->binaryLabels[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function resetBinary()
|
protected function resetBinary(): void
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,17 +11,17 @@ class LogisticRegression extends Adaline
|
|||||||
/**
|
/**
|
||||||
* Batch training: Gradient descent algorithm (default)
|
* Batch training: Gradient descent algorithm (default)
|
||||||
*/
|
*/
|
||||||
const BATCH_TRAINING = 1;
|
public const BATCH_TRAINING = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Online training: Stochastic gradient descent learning
|
* Online training: Stochastic gradient descent learning
|
||||||
*/
|
*/
|
||||||
const ONLINE_TRAINING = 2;
|
public const ONLINE_TRAINING = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conjugate Batch: Conjugate Gradient algorithm
|
* Conjugate Batch: Conjugate Gradient algorithm
|
||||||
*/
|
*/
|
||||||
const CONJUGATE_GRAD_TRAINING = 3;
|
public const CONJUGATE_GRAD_TRAINING = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cost function to optimize: 'log' and 'sse' are supported <br>
|
* Cost function to optimize: 'log' and 'sse' are supported <br>
|
||||||
@ -97,7 +97,7 @@ class LogisticRegression extends Adaline
|
|||||||
* Sets the learning rate if gradient descent algorithm is
|
* Sets the learning rate if gradient descent algorithm is
|
||||||
* selected for training
|
* selected for training
|
||||||
*/
|
*/
|
||||||
public function setLearningRate(float $learningRate)
|
public function setLearningRate(float $learningRate): void
|
||||||
{
|
{
|
||||||
$this->learningRate = $learningRate;
|
$this->learningRate = $learningRate;
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ class LogisticRegression extends Adaline
|
|||||||
* Lambda (λ) parameter of regularization term. If 0 is given,
|
* Lambda (λ) parameter of regularization term. If 0 is given,
|
||||||
* then the regularization term is cancelled
|
* then the regularization term is cancelled
|
||||||
*/
|
*/
|
||||||
public function setLambda(float $lambda)
|
public function setLambda(float $lambda): void
|
||||||
{
|
{
|
||||||
$this->lambda = $lambda;
|
$this->lambda = $lambda;
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ class LogisticRegression extends Adaline
|
|||||||
/**
|
/**
|
||||||
* Executes Conjugate Gradient method to optimize the weights of the LogReg model
|
* Executes Conjugate Gradient method to optimize the weights of the LogReg model
|
||||||
*/
|
*/
|
||||||
protected function runConjugateGradient(array $samples, array $targets, \Closure $gradientFunc)
|
protected function runConjugateGradient(array $samples, array $targets, \Closure $gradientFunc): void
|
||||||
{
|
{
|
||||||
if (empty($this->optimizer)) {
|
if (empty($this->optimizer)) {
|
||||||
$this->optimizer = (new ConjugateGradient($this->featureCount))
|
$this->optimizer = (new ConjugateGradient($this->featureCount))
|
||||||
|
@ -88,12 +88,12 @@ class Perceptron implements Classifier, IncrementalEstimator
|
|||||||
$this->maxIterations = $maxIterations;
|
$this->maxIterations = $maxIterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function partialTrain(array $samples, array $targets, array $labels = [])
|
public function partialTrain(array $samples, array $targets, array $labels = []): void
|
||||||
{
|
{
|
||||||
$this->trainByLabel($samples, $targets, $labels);
|
$this->trainByLabel($samples, $targets, $labels);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function trainBinary(array $samples, array $targets, array $labels)
|
public function trainBinary(array $samples, array $targets, array $labels): void
|
||||||
{
|
{
|
||||||
if ($this->normalizer) {
|
if ($this->normalizer) {
|
||||||
$this->normalizer->transform($samples);
|
$this->normalizer->transform($samples);
|
||||||
@ -111,7 +111,7 @@ class Perceptron implements Classifier, IncrementalEstimator
|
|||||||
$this->runTraining($samples, $targets);
|
$this->runTraining($samples, $targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function resetBinary()
|
protected function resetBinary(): void
|
||||||
{
|
{
|
||||||
$this->labels = [];
|
$this->labels = [];
|
||||||
$this->optimizer = null;
|
$this->optimizer = null;
|
||||||
@ -148,6 +148,8 @@ class Perceptron implements Classifier, IncrementalEstimator
|
|||||||
/**
|
/**
|
||||||
* Trains the perceptron model with Stochastic Gradient Descent optimization
|
* Trains the perceptron model with Stochastic Gradient Descent optimization
|
||||||
* to get the correct set of weights
|
* to get the correct set of weights
|
||||||
|
*
|
||||||
|
* @return void|mixed
|
||||||
*/
|
*/
|
||||||
protected function runTraining(array $samples, array $targets)
|
protected function runTraining(array $samples, array $targets)
|
||||||
{
|
{
|
||||||
@ -169,7 +171,7 @@ class Perceptron implements Classifier, IncrementalEstimator
|
|||||||
* Executes a Gradient Descent algorithm for
|
* Executes a Gradient Descent algorithm for
|
||||||
* the given cost function
|
* the given cost function
|
||||||
*/
|
*/
|
||||||
protected function runGradientDescent(array $samples, array $targets, \Closure $gradientFunc, bool $isBatch = false)
|
protected function runGradientDescent(array $samples, array $targets, \Closure $gradientFunc, bool $isBatch = false): void
|
||||||
{
|
{
|
||||||
$class = $isBatch ? GD::class : StochasticGD::class;
|
$class = $isBatch ? GD::class : StochasticGD::class;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ class MLPClassifier extends MultilayerPerceptron implements Classifier
|
|||||||
/**
|
/**
|
||||||
* @param mixed $target
|
* @param mixed $target
|
||||||
*/
|
*/
|
||||||
protected function trainSample(array $sample, $target)
|
protected function trainSample(array $sample, $target): void
|
||||||
{
|
{
|
||||||
|
|
||||||
// Feed-forward.
|
// Feed-forward.
|
||||||
|
@ -13,9 +13,9 @@ class NaiveBayes implements Classifier
|
|||||||
{
|
{
|
||||||
use Trainable, Predictable;
|
use Trainable, Predictable;
|
||||||
|
|
||||||
const CONTINUOS = 1;
|
public const CONTINUOS = 1;
|
||||||
const NOMINAL = 2;
|
public const NOMINAL = 2;
|
||||||
const EPSILON = 1e-10;
|
public const EPSILON = 1e-10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var array
|
||||||
@ -57,7 +57,7 @@ class NaiveBayes implements Classifier
|
|||||||
*/
|
*/
|
||||||
private $labels = [];
|
private $labels = [];
|
||||||
|
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
$this->samples = array_merge($this->samples, $samples);
|
$this->samples = array_merge($this->samples, $samples);
|
||||||
$this->targets = array_merge($this->targets, $targets);
|
$this->targets = array_merge($this->targets, $targets);
|
||||||
@ -77,7 +77,7 @@ class NaiveBayes implements Classifier
|
|||||||
* Calculates vital statistics for each label & feature. Stores these
|
* Calculates vital statistics for each label & feature. Stores these
|
||||||
* values in private array in order to avoid repeated calculation
|
* values in private array in order to avoid repeated calculation
|
||||||
*/
|
*/
|
||||||
private function calculateStatistics(string $label, array $samples)
|
private function calculateStatistics(string $label, array $samples): void
|
||||||
{
|
{
|
||||||
$this->std[$label] = array_fill(0, $this->featureCount, 0);
|
$this->std[$label] = array_fill(0, $this->featureCount, 0);
|
||||||
$this->mean[$label] = array_fill(0, $this->featureCount, 0);
|
$this->mean[$label] = array_fill(0, $this->featureCount, 0);
|
||||||
|
@ -14,7 +14,7 @@ class SVC extends SupportVectorMachine implements Classifier
|
|||||||
int $kernel = Kernel::LINEAR,
|
int $kernel = Kernel::LINEAR,
|
||||||
float $cost = 1.0,
|
float $cost = 1.0,
|
||||||
int $degree = 3,
|
int $degree = 3,
|
||||||
float $gamma = null,
|
?float $gamma = null,
|
||||||
float $coef0 = 0.0,
|
float $coef0 = 0.0,
|
||||||
float $tolerance = 0.001,
|
float $tolerance = 0.001,
|
||||||
int $cacheSize = 100,
|
int $cacheSize = 100,
|
||||||
|
@ -14,7 +14,7 @@ abstract class WeightedClassifier implements Classifier
|
|||||||
/**
|
/**
|
||||||
* Sets the array including a weight for each sample
|
* Sets the array including a weight for each sample
|
||||||
*/
|
*/
|
||||||
public function setSampleWeights(array $weights)
|
public function setSampleWeights(array $weights): void
|
||||||
{
|
{
|
||||||
$this->weights = $weights;
|
$this->weights = $weights;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class DBSCAN implements Clusterer
|
|||||||
*/
|
*/
|
||||||
private $distanceMetric;
|
private $distanceMetric;
|
||||||
|
|
||||||
public function __construct(float $epsilon = 0.5, int $minSamples = 3, Distance $distanceMetric = null)
|
public function __construct(float $epsilon = 0.5, int $minSamples = 3, ?Distance $distanceMetric = null)
|
||||||
{
|
{
|
||||||
if (null === $distanceMetric) {
|
if (null === $distanceMetric) {
|
||||||
$distanceMetric = new Euclidean();
|
$distanceMetric = new Euclidean();
|
||||||
|
@ -71,7 +71,7 @@ class FuzzyCMeans implements Clusterer
|
|||||||
$this->maxIterations = $maxIterations;
|
$this->maxIterations = $maxIterations;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function initClusters()
|
protected function initClusters(): void
|
||||||
{
|
{
|
||||||
// Membership array is a matrix of cluster number by sample counts
|
// Membership array is a matrix of cluster number by sample counts
|
||||||
// We initilize the membership array with random values
|
// We initilize the membership array with random values
|
||||||
@ -80,7 +80,7 @@ class FuzzyCMeans implements Clusterer
|
|||||||
$this->updateClusters();
|
$this->updateClusters();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function generateRandomMembership(int $rows, int $cols)
|
protected function generateRandomMembership(int $rows, int $cols): void
|
||||||
{
|
{
|
||||||
$this->membership = [];
|
$this->membership = [];
|
||||||
for ($i = 0; $i < $rows; ++$i) {
|
for ($i = 0; $i < $rows; ++$i) {
|
||||||
@ -98,7 +98,7 @@ class FuzzyCMeans implements Clusterer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function updateClusters()
|
protected function updateClusters(): void
|
||||||
{
|
{
|
||||||
$dim = $this->space->getDimension();
|
$dim = $this->space->getDimension();
|
||||||
if (!$this->clusters) {
|
if (!$this->clusters) {
|
||||||
@ -136,7 +136,7 @@ class FuzzyCMeans implements Clusterer
|
|||||||
return $sum;
|
return $sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function updateMembershipMatrix()
|
protected function updateMembershipMatrix(): void
|
||||||
{
|
{
|
||||||
for ($i = 0; $i < $this->clustersNumber; ++$i) {
|
for ($i = 0; $i < $this->clustersNumber; ++$i) {
|
||||||
for ($k = 0; $k < $this->sampleCount; ++$k) {
|
for ($k = 0; $k < $this->sampleCount; ++$k) {
|
||||||
|
@ -9,8 +9,8 @@ use Phpml\Exception\InvalidArgumentException;
|
|||||||
|
|
||||||
class KMeans implements Clusterer
|
class KMeans implements Clusterer
|
||||||
{
|
{
|
||||||
const INIT_RANDOM = 1;
|
public const INIT_RANDOM = 1;
|
||||||
const INIT_KMEANS_PLUS_PLUS = 2;
|
public const INIT_KMEANS_PLUS_PLUS = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
|
@ -64,17 +64,17 @@ class Cluster extends Point implements IteratorAggregate, Countable
|
|||||||
return $point;
|
return $point;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attachAll(SplObjectStorage $points)
|
public function attachAll(SplObjectStorage $points): void
|
||||||
{
|
{
|
||||||
$this->points->addAll($points);
|
$this->points->addAll($points);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function detachAll(SplObjectStorage $points)
|
public function detachAll(SplObjectStorage $points): void
|
||||||
{
|
{
|
||||||
$this->points->removeAll($points);
|
$this->points->removeAll($points);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateCentroid()
|
public function updateCentroid(): void
|
||||||
{
|
{
|
||||||
if (!$count = count($this->points)) {
|
if (!$count = count($this->points)) {
|
||||||
return;
|
return;
|
||||||
@ -109,7 +109,7 @@ class Cluster extends Point implements IteratorAggregate, Countable
|
|||||||
return count($this->points);
|
return count($this->points);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCoordinates(array $newCoordinates)
|
public function setCoordinates(array $newCoordinates): void
|
||||||
{
|
{
|
||||||
$this->coordinates = $newCoordinates;
|
$this->coordinates = $newCoordinates;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ class Point implements ArrayAccess
|
|||||||
* @param mixed $offset
|
* @param mixed $offset
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
public function offsetSet($offset, $value)
|
public function offsetSet($offset, $value): void
|
||||||
{
|
{
|
||||||
$this->coordinates[$offset] = $value;
|
$this->coordinates[$offset] = $value;
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ class Point implements ArrayAccess
|
|||||||
/**
|
/**
|
||||||
* @param mixed $offset
|
* @param mixed $offset
|
||||||
*/
|
*/
|
||||||
public function offsetUnset($offset)
|
public function offsetUnset($offset): void
|
||||||
{
|
{
|
||||||
unset($this->coordinates[$offset]);
|
unset($this->coordinates[$offset]);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class Space extends SplObjectStorage
|
|||||||
/**
|
/**
|
||||||
* @param null $data
|
* @param null $data
|
||||||
*/
|
*/
|
||||||
public function addPoint(array $coordinates, $data = null)
|
public function addPoint(array $coordinates, $data = null): void
|
||||||
{
|
{
|
||||||
$this->attach($this->newPoint($coordinates), $data);
|
$this->attach($this->newPoint($coordinates), $data);
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ class Space extends SplObjectStorage
|
|||||||
* @param Point $point
|
* @param Point $point
|
||||||
* @param null $data
|
* @param null $data
|
||||||
*/
|
*/
|
||||||
public function attach($point, $data = null)
|
public function attach($point, $data = null): void
|
||||||
{
|
{
|
||||||
if (!$point instanceof Point) {
|
if (!$point instanceof Point) {
|
||||||
throw new InvalidArgumentException('can only attach points to spaces');
|
throw new InvalidArgumentException('can only attach points to spaces');
|
||||||
@ -180,7 +180,7 @@ class Space extends SplObjectStorage
|
|||||||
private function initializeRandomClusters(int $clustersNumber) : array
|
private function initializeRandomClusters(int $clustersNumber) : array
|
||||||
{
|
{
|
||||||
$clusters = [];
|
$clusters = [];
|
||||||
list($min, $max) = $this->getBoundaries();
|
[$min, $max] = $this->getBoundaries();
|
||||||
|
|
||||||
for ($n = 0; $n < $clustersNumber; ++$n) {
|
for ($n = 0; $n < $clustersNumber; ++$n) {
|
||||||
$clusters[] = new Cluster($this, $this->getRandomPoint($min, $max)->getCoordinates());
|
$clusters[] = new Cluster($this, $this->getRandomPoint($min, $max)->getCoordinates());
|
||||||
|
@ -8,7 +8,7 @@ use Phpml\Dataset\Dataset;
|
|||||||
|
|
||||||
class RandomSplit extends Split
|
class RandomSplit extends Split
|
||||||
{
|
{
|
||||||
protected function splitDataset(Dataset $dataset, float $testSize)
|
protected function splitDataset(Dataset $dataset, float $testSize): void
|
||||||
{
|
{
|
||||||
$samples = $dataset->getSamples();
|
$samples = $dataset->getSamples();
|
||||||
$labels = $dataset->getTargets();
|
$labels = $dataset->getTargets();
|
||||||
|
@ -29,7 +29,7 @@ abstract class Split
|
|||||||
*/
|
*/
|
||||||
protected $testLabels = [];
|
protected $testLabels = [];
|
||||||
|
|
||||||
public function __construct(Dataset $dataset, float $testSize = 0.3, int $seed = null)
|
public function __construct(Dataset $dataset, float $testSize = 0.3, ?int $seed = null)
|
||||||
{
|
{
|
||||||
if (0 >= $testSize || 1 <= $testSize) {
|
if (0 >= $testSize || 1 <= $testSize) {
|
||||||
throw InvalidArgumentException::percentNotInRange('testSize');
|
throw InvalidArgumentException::percentNotInRange('testSize');
|
||||||
@ -61,7 +61,7 @@ abstract class Split
|
|||||||
return $this->testLabels;
|
return $this->testLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function seedGenerator(int $seed = null)
|
protected function seedGenerator(?int $seed = null): void
|
||||||
{
|
{
|
||||||
if (null === $seed) {
|
if (null === $seed) {
|
||||||
mt_srand();
|
mt_srand();
|
||||||
|
@ -9,7 +9,7 @@ use Phpml\Dataset\Dataset;
|
|||||||
|
|
||||||
class StratifiedRandomSplit extends RandomSplit
|
class StratifiedRandomSplit extends RandomSplit
|
||||||
{
|
{
|
||||||
protected function splitDataset(Dataset $dataset, float $testSize)
|
protected function splitDataset(Dataset $dataset, float $testSize): void
|
||||||
{
|
{
|
||||||
$datasets = $this->splitByTarget($dataset);
|
$datasets = $this->splitByTarget($dataset);
|
||||||
|
|
||||||
|
@ -17,14 +17,14 @@ class FilesDataset extends ArrayDataset
|
|||||||
$this->scanRootPath($rootPath);
|
$this->scanRootPath($rootPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function scanRootPath(string $rootPath)
|
private function scanRootPath(string $rootPath): void
|
||||||
{
|
{
|
||||||
foreach (glob($rootPath.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR) as $dir) {
|
foreach (glob($rootPath.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR) as $dir) {
|
||||||
$this->scanDir($dir);
|
$this->scanDir($dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function scanDir(string $dir)
|
private function scanDir(string $dir): void
|
||||||
{
|
{
|
||||||
$target = basename($dir);
|
$target = basename($dir);
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ abstract class EigenTransformerBase
|
|||||||
* top eigenVectors along with the largest eigenValues. The total explained variance
|
* top eigenVectors along with the largest eigenValues. The total explained variance
|
||||||
* of these eigenVectors will be no less than desired $totalVariance value
|
* of these eigenVectors will be no less than desired $totalVariance value
|
||||||
*/
|
*/
|
||||||
protected function eigenDecomposition(array $matrix)
|
protected function eigenDecomposition(array $matrix): void
|
||||||
{
|
{
|
||||||
$eig = new EigenvalueDecomposition($matrix);
|
$eig = new EigenvalueDecomposition($matrix);
|
||||||
$eigVals = $eig->getRealEigenvalues();
|
$eigVals = $eig->getRealEigenvalues();
|
||||||
|
@ -10,10 +10,10 @@ use Phpml\Math\Matrix;
|
|||||||
|
|
||||||
class KernelPCA extends PCA
|
class KernelPCA extends PCA
|
||||||
{
|
{
|
||||||
const KERNEL_RBF = 1;
|
public const KERNEL_RBF = 1;
|
||||||
const KERNEL_SIGMOID = 2;
|
public const KERNEL_SIGMOID = 2;
|
||||||
const KERNEL_LAPLACIAN = 3;
|
public const KERNEL_LAPLACIAN = 3;
|
||||||
const KERNEL_LINEAR = 4;
|
public const KERNEL_LINEAR = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selected kernel function
|
* Selected kernel function
|
||||||
@ -50,7 +50,7 @@ class KernelPCA extends PCA
|
|||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function __construct(int $kernel = self::KERNEL_RBF, float $totalVariance = null, int $numFeatures = null, float $gamma = null)
|
public function __construct(int $kernel = self::KERNEL_RBF, ?float $totalVariance = null, ?int $numFeatures = null, ?float $gamma = null)
|
||||||
{
|
{
|
||||||
$availableKernels = [self::KERNEL_RBF, self::KERNEL_SIGMOID, self::KERNEL_LAPLACIAN, self::KERNEL_LINEAR];
|
$availableKernels = [self::KERNEL_RBF, self::KERNEL_SIGMOID, self::KERNEL_LAPLACIAN, self::KERNEL_LINEAR];
|
||||||
if (!in_array($kernel, $availableKernels)) {
|
if (!in_array($kernel, $availableKernels)) {
|
||||||
|
@ -47,7 +47,7 @@ class LDA extends EigenTransformerBase
|
|||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function __construct(float $totalVariance = null, int $numFeatures = null)
|
public function __construct(?float $totalVariance = null, ?int $numFeatures = null)
|
||||||
{
|
{
|
||||||
if ($totalVariance !== null && ($totalVariance < 0.1 || $totalVariance > 0.99)) {
|
if ($totalVariance !== null && ($totalVariance < 0.1 || $totalVariance > 0.99)) {
|
||||||
throw new \Exception('Total variance can be a value between 0.1 and 0.99');
|
throw new \Exception('Total variance can be a value between 0.1 and 0.99');
|
||||||
|
@ -32,7 +32,7 @@ class PCA extends EigenTransformerBase
|
|||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function __construct(float $totalVariance = null, int $numFeatures = null)
|
public function __construct(?float $totalVariance = null, ?int $numFeatures = null)
|
||||||
{
|
{
|
||||||
if ($totalVariance !== null && ($totalVariance < 0.1 || $totalVariance > 0.99)) {
|
if ($totalVariance !== null && ($totalVariance < 0.1 || $totalVariance > 0.99)) {
|
||||||
throw new \Exception('Total variance can be a value between 0.1 and 0.99');
|
throw new \Exception('Total variance can be a value between 0.1 and 0.99');
|
||||||
@ -73,7 +73,7 @@ class PCA extends EigenTransformerBase
|
|||||||
return $this->reduce($data);
|
return $this->reduce($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function calculateMeans(array $data, int $n)
|
protected function calculateMeans(array $data, int $n): void
|
||||||
{
|
{
|
||||||
// Calculate means for each dimension
|
// Calculate means for each dimension
|
||||||
$this->means = [];
|
$this->means = [];
|
||||||
|
@ -13,14 +13,14 @@ class TfIdfTransformer implements Transformer
|
|||||||
*/
|
*/
|
||||||
private $idf;
|
private $idf;
|
||||||
|
|
||||||
public function __construct(array $samples = null)
|
public function __construct(?array $samples = null)
|
||||||
{
|
{
|
||||||
if ($samples) {
|
if ($samples) {
|
||||||
$this->fit($samples);
|
$this->fit($samples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fit(array $samples)
|
public function fit(array $samples): void
|
||||||
{
|
{
|
||||||
$this->countTokensFrequency($samples);
|
$this->countTokensFrequency($samples);
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ class TfIdfTransformer implements Transformer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transform(array &$samples)
|
public function transform(array &$samples): void
|
||||||
{
|
{
|
||||||
foreach ($samples as &$sample) {
|
foreach ($samples as &$sample) {
|
||||||
foreach ($sample as $index => &$feature) {
|
foreach ($sample as $index => &$feature) {
|
||||||
@ -39,7 +39,7 @@ class TfIdfTransformer implements Transformer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function countTokensFrequency(array $samples)
|
private function countTokensFrequency(array $samples): void
|
||||||
{
|
{
|
||||||
$this->idf = array_fill_keys(array_keys($samples[0]), 0);
|
$this->idf = array_fill_keys(array_keys($samples[0]), 0);
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class TokenCountVectorizer implements Transformer
|
|||||||
*/
|
*/
|
||||||
private $frequencies;
|
private $frequencies;
|
||||||
|
|
||||||
public function __construct(Tokenizer $tokenizer, StopWords $stopWords = null, float $minDF = 0.0)
|
public function __construct(Tokenizer $tokenizer, ?StopWords $stopWords = null, float $minDF = 0.0)
|
||||||
{
|
{
|
||||||
$this->tokenizer = $tokenizer;
|
$this->tokenizer = $tokenizer;
|
||||||
$this->stopWords = $stopWords;
|
$this->stopWords = $stopWords;
|
||||||
@ -44,12 +44,12 @@ class TokenCountVectorizer implements Transformer
|
|||||||
$this->frequencies = [];
|
$this->frequencies = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fit(array $samples)
|
public function fit(array $samples): void
|
||||||
{
|
{
|
||||||
$this->buildVocabulary($samples);
|
$this->buildVocabulary($samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transform(array &$samples)
|
public function transform(array &$samples): void
|
||||||
{
|
{
|
||||||
foreach ($samples as &$sample) {
|
foreach ($samples as &$sample) {
|
||||||
$this->transformSample($sample);
|
$this->transformSample($sample);
|
||||||
@ -63,7 +63,7 @@ class TokenCountVectorizer implements Transformer
|
|||||||
return array_flip($this->vocabulary);
|
return array_flip($this->vocabulary);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildVocabulary(array &$samples)
|
private function buildVocabulary(array &$samples): void
|
||||||
{
|
{
|
||||||
foreach ($samples as $index => $sample) {
|
foreach ($samples as $index => $sample) {
|
||||||
$tokens = $this->tokenizer->tokenize($sample);
|
$tokens = $this->tokenizer->tokenize($sample);
|
||||||
@ -73,7 +73,7 @@ class TokenCountVectorizer implements Transformer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function transformSample(string &$sample)
|
private function transformSample(string &$sample): void
|
||||||
{
|
{
|
||||||
$counts = [];
|
$counts = [];
|
||||||
$tokens = $this->tokenizer->tokenize($sample);
|
$tokens = $this->tokenizer->tokenize($sample);
|
||||||
@ -113,7 +113,7 @@ class TokenCountVectorizer implements Transformer
|
|||||||
return $this->vocabulary[$token] ?? false;
|
return $this->vocabulary[$token] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addTokenToVocabulary(string $token)
|
private function addTokenToVocabulary(string $token): void
|
||||||
{
|
{
|
||||||
if ($this->isStopWord($token)) {
|
if ($this->isStopWord($token)) {
|
||||||
return;
|
return;
|
||||||
@ -129,7 +129,7 @@ class TokenCountVectorizer implements Transformer
|
|||||||
return $this->stopWords && $this->stopWords->isStopWord($token);
|
return $this->stopWords && $this->stopWords->isStopWord($token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function updateFrequency(string $token)
|
private function updateFrequency(string $token): void
|
||||||
{
|
{
|
||||||
if (!isset($this->frequencies[$token])) {
|
if (!isset($this->frequencies[$token])) {
|
||||||
$this->frequencies[$token] = 0;
|
$this->frequencies[$token] = 0;
|
||||||
@ -138,7 +138,7 @@ class TokenCountVectorizer implements Transformer
|
|||||||
++$this->frequencies[$token];
|
++$this->frequencies[$token];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkDocumentFrequency(array &$samples)
|
private function checkDocumentFrequency(array &$samples): void
|
||||||
{
|
{
|
||||||
if ($this->minDF > 0) {
|
if ($this->minDF > 0) {
|
||||||
$beyondMinimum = $this->getBeyondMinimumIndexes(count($samples));
|
$beyondMinimum = $this->getBeyondMinimumIndexes(count($samples));
|
||||||
@ -148,7 +148,7 @@ class TokenCountVectorizer implements Transformer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resetBeyondMinimum(array &$sample, array $beyondMinimum)
|
private function resetBeyondMinimum(array &$sample, array $beyondMinimum): void
|
||||||
{
|
{
|
||||||
foreach ($beyondMinimum as $index) {
|
foreach ($beyondMinimum as $index) {
|
||||||
$sample[$index] = 0;
|
$sample[$index] = 0;
|
||||||
|
@ -28,7 +28,7 @@ trait OneVsRest
|
|||||||
/**
|
/**
|
||||||
* Train a binary classifier in the OvR style
|
* Train a binary classifier in the OvR style
|
||||||
*/
|
*/
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
// Clears previous stuff.
|
// Clears previous stuff.
|
||||||
$this->reset();
|
$this->reset();
|
||||||
@ -36,7 +36,7 @@ trait OneVsRest
|
|||||||
$this->trainBylabel($samples, $targets);
|
$this->trainBylabel($samples, $targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function trainByLabel(array $samples, array $targets, array $allLabels = [])
|
protected function trainByLabel(array $samples, array $targets, array $allLabels = []): void
|
||||||
{
|
{
|
||||||
// Overwrites the current value if it exist. $allLabels must be provided for each partialTrain run.
|
// Overwrites the current value if it exist. $allLabels must be provided for each partialTrain run.
|
||||||
if (!empty($allLabels)) {
|
if (!empty($allLabels)) {
|
||||||
@ -63,7 +63,7 @@ trait OneVsRest
|
|||||||
$this->classifiers[$label] = $this->getClassifierCopy();
|
$this->classifiers[$label] = $this->getClassifierCopy();
|
||||||
}
|
}
|
||||||
|
|
||||||
list($binarizedTargets, $classifierLabels) = $this->binarizeTargets($targets, $label);
|
[$binarizedTargets, $classifierLabels] = $this->binarizeTargets($targets, $label);
|
||||||
$this->classifiers[$label]->trainBinary($samples, $binarizedTargets, $classifierLabels);
|
$this->classifiers[$label]->trainBinary($samples, $binarizedTargets, $classifierLabels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ trait OneVsRest
|
|||||||
/**
|
/**
|
||||||
* Resets the classifier and the vars internally used by OneVsRest to create multiple classifiers.
|
* Resets the classifier and the vars internally used by OneVsRest to create multiple classifiers.
|
||||||
*/
|
*/
|
||||||
public function reset()
|
public function reset(): void
|
||||||
{
|
{
|
||||||
$this->classifiers = [];
|
$this->classifiers = [];
|
||||||
$this->allLabels = [];
|
$this->allLabels = [];
|
||||||
@ -158,7 +158,7 @@ trait OneVsRest
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
abstract protected function resetBinary();
|
abstract protected function resetBinary(): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each classifier that make use of OvR approach should be able to
|
* Each classifier that make use of OvR approach should be able to
|
||||||
|
@ -61,7 +61,7 @@ class ConjugateGradient extends GD
|
|||||||
*/
|
*/
|
||||||
protected function gradient(array $theta) : array
|
protected function gradient(array $theta) : array
|
||||||
{
|
{
|
||||||
list(, $gradient) = parent::gradient($theta);
|
[, $gradient] = parent::gradient($theta);
|
||||||
|
|
||||||
return $gradient;
|
return $gradient;
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ class ConjugateGradient extends GD
|
|||||||
*/
|
*/
|
||||||
protected function cost(array $theta) : float
|
protected function cost(array $theta) : float
|
||||||
{
|
{
|
||||||
list($cost) = parent::gradient($theta);
|
[$cost] = parent::gradient($theta);
|
||||||
|
|
||||||
return array_sum($cost) / $this->sampleCount;
|
return array_sum($cost) / $this->sampleCount;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class GD extends StochasticGD
|
|||||||
$theta = $this->theta;
|
$theta = $this->theta;
|
||||||
|
|
||||||
// Calculate update terms for each sample
|
// Calculate update terms for each sample
|
||||||
list($errors, $updates, $totalPenalty) = $this->gradient($theta);
|
[$errors, $updates, $totalPenalty] = $this->gradient($theta);
|
||||||
|
|
||||||
$this->updateWeightsWithUpdates($updates, $totalPenalty);
|
$this->updateWeightsWithUpdates($updates, $totalPenalty);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ class GD extends StochasticGD
|
|||||||
$target = $this->targets[$index];
|
$target = $this->targets[$index];
|
||||||
|
|
||||||
$result = ($this->gradientCb)($theta, $sample, $target);
|
$result = ($this->gradientCb)($theta, $sample, $target);
|
||||||
list($cost, $grad, $penalty) = array_pad($result, 3, 0);
|
[$cost, $grad, $penalty] = array_pad($result, 3, 0);
|
||||||
|
|
||||||
$costs[] = $cost;
|
$costs[] = $cost;
|
||||||
$gradient[] = $grad;
|
$gradient[] = $grad;
|
||||||
@ -73,7 +73,7 @@ class GD extends StochasticGD
|
|||||||
return [$costs, $gradient, $totalPenalty];
|
return [$costs, $gradient, $totalPenalty];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function updateWeightsWithUpdates(array $updates, float $penalty)
|
protected function updateWeightsWithUpdates(array $updates, float $penalty): void
|
||||||
{
|
{
|
||||||
// Updates all weights at once
|
// Updates all weights at once
|
||||||
for ($i = 0; $i <= $this->dimensions; ++$i) {
|
for ($i = 0; $i <= $this->dimensions; ++$i) {
|
||||||
@ -96,7 +96,7 @@ class GD extends StochasticGD
|
|||||||
/**
|
/**
|
||||||
* Clears the optimizer internal vars after the optimization process.
|
* Clears the optimizer internal vars after the optimization process.
|
||||||
*/
|
*/
|
||||||
protected function clear()
|
protected function clear(): void
|
||||||
{
|
{
|
||||||
$this->sampleCount = null;
|
$this->sampleCount = null;
|
||||||
parent::clear();
|
parent::clear();
|
||||||
|
@ -191,7 +191,7 @@ class StochasticGD extends Optimizer
|
|||||||
|
|
||||||
$result = ($this->gradientCb)($theta, $sample, $target);
|
$result = ($this->gradientCb)($theta, $sample, $target);
|
||||||
|
|
||||||
list($error, $gradient, $penalty) = array_pad($result, 3, 0);
|
[$error, $gradient, $penalty] = array_pad($result, 3, 0);
|
||||||
|
|
||||||
// Update bias
|
// Update bias
|
||||||
$this->theta[0] -= $this->learningRate * $gradient;
|
$this->theta[0] -= $this->learningRate * $gradient;
|
||||||
@ -249,7 +249,7 @@ class StochasticGD extends Optimizer
|
|||||||
/**
|
/**
|
||||||
* Clears the optimizer internal vars after the optimization process.
|
* Clears the optimizer internal vars after the optimization process.
|
||||||
*/
|
*/
|
||||||
protected function clear()
|
protected function clear(): void
|
||||||
{
|
{
|
||||||
$this->samples = [];
|
$this->samples = [];
|
||||||
$this->targets = [];
|
$this->targets = [];
|
||||||
|
@ -20,7 +20,7 @@ trait Trainable
|
|||||||
* @param array $samples
|
* @param array $samples
|
||||||
* @param array $targets
|
* @param array $targets
|
||||||
*/
|
*/
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
$this->samples = array_merge($this->samples, $samples);
|
$this->samples = array_merge($this->samples, $samples);
|
||||||
$this->targets = array_merge($this->targets, $targets);
|
$this->targets = array_merge($this->targets, $targets);
|
||||||
|
@ -119,7 +119,7 @@ class EigenvalueDecomposition
|
|||||||
/**
|
/**
|
||||||
* Symmetric Householder reduction to tridiagonal form.
|
* Symmetric Householder reduction to tridiagonal form.
|
||||||
*/
|
*/
|
||||||
private function tred2()
|
private function tred2(): void
|
||||||
{
|
{
|
||||||
// This is derived from the Algol procedures tred2 by
|
// This is derived from the Algol procedures tred2 by
|
||||||
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
|
// Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
|
||||||
@ -236,7 +236,7 @@ class EigenvalueDecomposition
|
|||||||
* Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
|
* Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
|
||||||
* Fortran subroutine in EISPACK.
|
* Fortran subroutine in EISPACK.
|
||||||
*/
|
*/
|
||||||
private function tql2()
|
private function tql2(): void
|
||||||
{
|
{
|
||||||
for ($i = 1; $i < $this->n; ++$i) {
|
for ($i = 1; $i < $this->n; ++$i) {
|
||||||
$this->e[$i - 1] = $this->e[$i];
|
$this->e[$i - 1] = $this->e[$i];
|
||||||
@ -343,7 +343,7 @@ class EigenvalueDecomposition
|
|||||||
* Vol.ii-Linear Algebra, and the corresponding
|
* Vol.ii-Linear Algebra, and the corresponding
|
||||||
* Fortran subroutines in EISPACK.
|
* Fortran subroutines in EISPACK.
|
||||||
*/
|
*/
|
||||||
private function orthes()
|
private function orthes(): void
|
||||||
{
|
{
|
||||||
$low = 0;
|
$low = 0;
|
||||||
$high = $this->n - 1;
|
$high = $this->n - 1;
|
||||||
@ -428,7 +428,7 @@ class EigenvalueDecomposition
|
|||||||
* @param int|float $yr
|
* @param int|float $yr
|
||||||
* @param int|float $yi
|
* @param int|float $yi
|
||||||
*/
|
*/
|
||||||
private function cdiv($xr, $xi, $yr, $yi)
|
private function cdiv($xr, $xi, $yr, $yi): void
|
||||||
{
|
{
|
||||||
if (abs($yr) > abs($yi)) {
|
if (abs($yr) > abs($yi)) {
|
||||||
$r = $yi / $yr;
|
$r = $yi / $yr;
|
||||||
@ -451,7 +451,7 @@ class EigenvalueDecomposition
|
|||||||
* Vol.ii-Linear Algebra, and the corresponding
|
* Vol.ii-Linear Algebra, and the corresponding
|
||||||
* Fortran subroutine in EISPACK.
|
* Fortran subroutine in EISPACK.
|
||||||
*/
|
*/
|
||||||
private function hqr2()
|
private function hqr2(): void
|
||||||
{
|
{
|
||||||
// Initialize
|
// Initialize
|
||||||
$nn = $this->n;
|
$nn = $this->n;
|
||||||
|
@ -13,7 +13,7 @@ class Covariance
|
|||||||
*
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public static function fromXYArrays(array $x, array $y, bool $sample = true, float $meanX = null, float $meanY = null) : float
|
public static function fromXYArrays(array $x, array $y, bool $sample = true, ?float $meanX = null, ?float $meanY = null) : float
|
||||||
{
|
{
|
||||||
if (empty($x) || empty($y)) {
|
if (empty($x) || empty($y)) {
|
||||||
throw InvalidArgumentException::arrayCantBeEmpty();
|
throw InvalidArgumentException::arrayCantBeEmpty();
|
||||||
@ -51,7 +51,7 @@ class Covariance
|
|||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public static function fromDataset(array $data, int $i, int $k, bool $sample = true, float $meanX = null, float $meanY = null) : float
|
public static function fromDataset(array $data, int $i, int $k, bool $sample = true, ?float $meanX = null, ?float $meanY = null) : float
|
||||||
{
|
{
|
||||||
if (empty($data)) {
|
if (empty($data)) {
|
||||||
throw InvalidArgumentException::arrayCantBeEmpty();
|
throw InvalidArgumentException::arrayCantBeEmpty();
|
||||||
@ -112,7 +112,7 @@ class Covariance
|
|||||||
*
|
*
|
||||||
* @param array|null $means
|
* @param array|null $means
|
||||||
*/
|
*/
|
||||||
public static function covarianceMatrix(array $data, array $means = null) : array
|
public static function covarianceMatrix(array $data, ?array $means = null) : array
|
||||||
{
|
{
|
||||||
$n = count($data[0]);
|
$n = count($data[0]);
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class Mean
|
|||||||
/**
|
/**
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
private static function checkArrayLength(array $array)
|
private static function checkArrayLength(array $array): void
|
||||||
{
|
{
|
||||||
if (empty($array)) {
|
if (empty($array)) {
|
||||||
throw InvalidArgumentException::arrayCantBeEmpty();
|
throw InvalidArgumentException::arrayCantBeEmpty();
|
||||||
|
@ -76,7 +76,7 @@ class ClassificationReport
|
|||||||
return $this->average;
|
return $this->average;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function computeMetrics(array $truePositive, array $falsePositive, array $falseNegative)
|
private function computeMetrics(array $truePositive, array $falsePositive, array $falseNegative): void
|
||||||
{
|
{
|
||||||
foreach ($truePositive as $label => $tp) {
|
foreach ($truePositive as $label => $tp) {
|
||||||
$this->precision[$label] = $this->computePrecision($tp, $falsePositive[$label]);
|
$this->precision[$label] = $this->computePrecision($tp, $falsePositive[$label]);
|
||||||
@ -85,7 +85,7 @@ class ClassificationReport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function computeAverage()
|
private function computeAverage(): void
|
||||||
{
|
{
|
||||||
foreach (['precision', 'recall', 'f1score'] as $metric) {
|
foreach (['precision', 'recall', 'f1score'] as $metric) {
|
||||||
$values = array_filter($this->{$metric});
|
$values = array_filter($this->{$metric});
|
||||||
|
@ -6,7 +6,7 @@ namespace Phpml\Metric;
|
|||||||
|
|
||||||
class ConfusionMatrix
|
class ConfusionMatrix
|
||||||
{
|
{
|
||||||
public static function compute(array $actualLabels, array $predictedLabels, array $labels = null) : array
|
public static function compute(array $actualLabels, array $predictedLabels, ?array $labels = null) : array
|
||||||
{
|
{
|
||||||
$labels = $labels ? array_flip($labels) : self::getUniqueLabels($actualLabels);
|
$labels = $labels ? array_flip($labels) : self::getUniqueLabels($actualLabels);
|
||||||
$matrix = self::generateMatrixWithZeros($labels);
|
$matrix = self::generateMatrixWithZeros($labels);
|
||||||
|
@ -9,7 +9,7 @@ use Phpml\Exception\SerializeException;
|
|||||||
|
|
||||||
class ModelManager
|
class ModelManager
|
||||||
{
|
{
|
||||||
public function saveToFile(Estimator $estimator, string $filepath)
|
public function saveToFile(Estimator $estimator, string $filepath): void
|
||||||
{
|
{
|
||||||
if (!is_writable(dirname($filepath))) {
|
if (!is_writable(dirname($filepath))) {
|
||||||
throw FileException::cantSaveFile(basename($filepath));
|
throw FileException::cantSaveFile(basename($filepath));
|
||||||
|
@ -17,7 +17,7 @@ class Layer
|
|||||||
/**
|
/**
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function __construct(int $nodesNumber = 0, string $nodeClass = Neuron::class, ActivationFunction $activationFunction = null)
|
public function __construct(int $nodesNumber = 0, string $nodeClass = Neuron::class, ?ActivationFunction $activationFunction = null)
|
||||||
{
|
{
|
||||||
if (!in_array(Node::class, class_implements($nodeClass))) {
|
if (!in_array(Node::class, class_implements($nodeClass))) {
|
||||||
throw InvalidArgumentException::invalidLayerNodeClass();
|
throw InvalidArgumentException::invalidLayerNodeClass();
|
||||||
@ -33,7 +33,7 @@ class Layer
|
|||||||
*
|
*
|
||||||
* @return Neuron
|
* @return Neuron
|
||||||
*/
|
*/
|
||||||
private function createNode(string $nodeClass, ActivationFunction $activationFunction = null)
|
private function createNode(string $nodeClass, ?ActivationFunction $activationFunction = null)
|
||||||
{
|
{
|
||||||
if (Neuron::class == $nodeClass) {
|
if (Neuron::class == $nodeClass) {
|
||||||
return new Neuron($activationFunction);
|
return new Neuron($activationFunction);
|
||||||
@ -42,7 +42,7 @@ class Layer
|
|||||||
return new $nodeClass();
|
return new $nodeClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addNode(Node $node)
|
public function addNode(Node $node): void
|
||||||
{
|
{
|
||||||
$this->nodes[] = $node;
|
$this->nodes[] = $node;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ abstract class LayeredNetwork implements Network
|
|||||||
*/
|
*/
|
||||||
protected $layers;
|
protected $layers;
|
||||||
|
|
||||||
public function addLayer(Layer $layer)
|
public function addLayer(Layer $layer): void
|
||||||
{
|
{
|
||||||
$this->layers[] = $layer;
|
$this->layers[] = $layer;
|
||||||
}
|
}
|
||||||
@ -29,7 +29,7 @@ abstract class LayeredNetwork implements Network
|
|||||||
return $this->layers;
|
return $this->layers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeLayers()
|
public function removeLayers(): void
|
||||||
{
|
{
|
||||||
unset($this->layers);
|
unset($this->layers);
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
|
|||||||
/**
|
/**
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function __construct(int $inputLayerFeatures, array $hiddenLayers, array $classes, int $iterations = 10000, ActivationFunction $activationFunction = null, int $theta = 1)
|
public function __construct(int $inputLayerFeatures, array $hiddenLayers, array $classes, int $iterations = 10000, ?ActivationFunction $activationFunction = null, int $theta = 1)
|
||||||
{
|
{
|
||||||
if (empty($hiddenLayers)) {
|
if (empty($hiddenLayers)) {
|
||||||
throw InvalidArgumentException::invalidLayersNumber();
|
throw InvalidArgumentException::invalidLayersNumber();
|
||||||
@ -78,7 +78,7 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
|
|||||||
$this->initNetwork();
|
$this->initNetwork();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function initNetwork()
|
private function initNetwork(): void
|
||||||
{
|
{
|
||||||
$this->addInputLayer($this->inputLayerFeatures);
|
$this->addInputLayer($this->inputLayerFeatures);
|
||||||
$this->addNeuronLayers($this->hiddenLayers, $this->activationFunction);
|
$this->addNeuronLayers($this->hiddenLayers, $this->activationFunction);
|
||||||
@ -90,7 +90,7 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
|
|||||||
$this->backpropagation = new Backpropagation($this->theta);
|
$this->backpropagation = new Backpropagation($this->theta);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
$this->reset();
|
$this->reset();
|
||||||
$this->initNetwork();
|
$this->initNetwork();
|
||||||
@ -100,7 +100,7 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
|
|||||||
/**
|
/**
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function partialTrain(array $samples, array $targets, array $classes = [])
|
public function partialTrain(array $samples, array $targets, array $classes = []): void
|
||||||
{
|
{
|
||||||
if (!empty($classes) && array_values($classes) !== $this->classes) {
|
if (!empty($classes) && array_values($classes) !== $this->classes) {
|
||||||
// We require the list of classes in the constructor.
|
// We require the list of classes in the constructor.
|
||||||
@ -122,24 +122,24 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
|
|||||||
*/
|
*/
|
||||||
abstract protected function predictSample(array $sample);
|
abstract protected function predictSample(array $sample);
|
||||||
|
|
||||||
protected function reset()
|
protected function reset(): void
|
||||||
{
|
{
|
||||||
$this->removeLayers();
|
$this->removeLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addInputLayer(int $nodes)
|
private function addInputLayer(int $nodes): void
|
||||||
{
|
{
|
||||||
$this->addLayer(new Layer($nodes, Input::class));
|
$this->addLayer(new Layer($nodes, Input::class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addNeuronLayers(array $layers, ActivationFunction $activationFunction = null)
|
private function addNeuronLayers(array $layers, ?ActivationFunction $activationFunction = null): void
|
||||||
{
|
{
|
||||||
foreach ($layers as $neurons) {
|
foreach ($layers as $neurons) {
|
||||||
$this->addLayer(new Layer($neurons, Neuron::class, $activationFunction));
|
$this->addLayer(new Layer($neurons, Neuron::class, $activationFunction));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateSynapses()
|
private function generateSynapses(): void
|
||||||
{
|
{
|
||||||
$layersNumber = count($this->layers) - 1;
|
$layersNumber = count($this->layers) - 1;
|
||||||
for ($i = 0; $i < $layersNumber; ++$i) {
|
for ($i = 0; $i < $layersNumber; ++$i) {
|
||||||
@ -149,7 +149,7 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addBiasNodes()
|
private function addBiasNodes(): void
|
||||||
{
|
{
|
||||||
$biasLayers = count($this->layers) - 1;
|
$biasLayers = count($this->layers) - 1;
|
||||||
for ($i = 0; $i < $biasLayers; ++$i) {
|
for ($i = 0; $i < $biasLayers; ++$i) {
|
||||||
@ -157,7 +157,7 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateLayerSynapses(Layer $nextLayer, Layer $currentLayer)
|
private function generateLayerSynapses(Layer $nextLayer, Layer $currentLayer): void
|
||||||
{
|
{
|
||||||
foreach ($nextLayer->getNodes() as $nextNeuron) {
|
foreach ($nextLayer->getNodes() as $nextNeuron) {
|
||||||
if ($nextNeuron instanceof Neuron) {
|
if ($nextNeuron instanceof Neuron) {
|
||||||
@ -166,14 +166,14 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generateNeuronSynapses(Layer $currentLayer, Neuron $nextNeuron)
|
private function generateNeuronSynapses(Layer $currentLayer, Neuron $nextNeuron): void
|
||||||
{
|
{
|
||||||
foreach ($currentLayer->getNodes() as $currentNeuron) {
|
foreach ($currentLayer->getNodes() as $currentNeuron) {
|
||||||
$nextNeuron->addSynapse(new Synapse($currentNeuron));
|
$nextNeuron->addSynapse(new Synapse($currentNeuron));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function trainSamples(array $samples, array $targets)
|
private function trainSamples(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
foreach ($targets as $key => $target) {
|
foreach ($targets as $key => $target) {
|
||||||
$this->trainSample($samples[$key], $target);
|
$this->trainSample($samples[$key], $target);
|
||||||
|
@ -23,7 +23,7 @@ class Input implements Node
|
|||||||
return $this->input;
|
return $this->input;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setInput(float $input)
|
public function setInput(float $input): void
|
||||||
{
|
{
|
||||||
$this->input = $input;
|
$this->input = $input;
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,14 @@ class Neuron implements Node
|
|||||||
*/
|
*/
|
||||||
protected $output;
|
protected $output;
|
||||||
|
|
||||||
public function __construct(ActivationFunction $activationFunction = null)
|
public function __construct(?ActivationFunction $activationFunction = null)
|
||||||
{
|
{
|
||||||
$this->activationFunction = $activationFunction ?: new ActivationFunction\Sigmoid();
|
$this->activationFunction = $activationFunction ?: new ActivationFunction\Sigmoid();
|
||||||
$this->synapses = [];
|
$this->synapses = [];
|
||||||
$this->output = 0;
|
$this->output = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addSynapse(Synapse $synapse)
|
public function addSynapse(Synapse $synapse): void
|
||||||
{
|
{
|
||||||
$this->synapses[] = $synapse;
|
$this->synapses[] = $synapse;
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ class Neuron implements Node
|
|||||||
return $this->output;
|
return $this->output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function reset()
|
public function reset(): void
|
||||||
{
|
{
|
||||||
$this->output = 0;
|
$this->output = 0;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ class Synapse
|
|||||||
/**
|
/**
|
||||||
* @param float|null $weight
|
* @param float|null $weight
|
||||||
*/
|
*/
|
||||||
public function __construct(Node $node, float $weight = null)
|
public function __construct(Node $node, ?float $weight = null)
|
||||||
{
|
{
|
||||||
$this->node = $node;
|
$this->node = $node;
|
||||||
$this->weight = $weight ?: $this->generateRandomWeight();
|
$this->weight = $weight ?: $this->generateRandomWeight();
|
||||||
@ -37,7 +37,7 @@ class Synapse
|
|||||||
return $this->weight * $this->node->getOutput();
|
return $this->weight * $this->node->getOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changeWeight(float $delta)
|
public function changeWeight(float $delta): void
|
||||||
{
|
{
|
||||||
$this->weight += $delta;
|
$this->weight += $delta;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class Backpropagation
|
|||||||
/**
|
/**
|
||||||
* @param mixed $targetClass
|
* @param mixed $targetClass
|
||||||
*/
|
*/
|
||||||
public function backpropagate(array $layers, $targetClass)
|
public function backpropagate(array $layers, $targetClass): void
|
||||||
{
|
{
|
||||||
$layersNumber = count($layers);
|
$layersNumber = count($layers);
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@ class Pipeline implements Estimator
|
|||||||
$this->estimator = $estimator;
|
$this->estimator = $estimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addTransformer(Transformer $transformer)
|
public function addTransformer(Transformer $transformer): void
|
||||||
{
|
{
|
||||||
$this->transformers[] = $transformer;
|
$this->transformers[] = $transformer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setEstimator(Estimator $estimator)
|
public function setEstimator(Estimator $estimator): void
|
||||||
{
|
{
|
||||||
$this->estimator = $estimator;
|
$this->estimator = $estimator;
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ class Pipeline implements Estimator
|
|||||||
return $this->estimator;
|
return $this->estimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
foreach ($this->transformers as $transformer) {
|
foreach ($this->transformers as $transformer) {
|
||||||
$transformer->fit($samples);
|
$transformer->fit($samples);
|
||||||
@ -71,7 +71,7 @@ class Pipeline implements Estimator
|
|||||||
return $this->estimator->predict($samples);
|
return $this->estimator->predict($samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function transformSamples(array &$samples)
|
private function transformSamples(array &$samples): void
|
||||||
{
|
{
|
||||||
foreach ($this->transformers as $transformer) {
|
foreach ($this->transformers as $transformer) {
|
||||||
$transformer->transform($samples);
|
$transformer->transform($samples);
|
||||||
|
@ -8,8 +8,8 @@ use Phpml\Preprocessing\Imputer\Strategy;
|
|||||||
|
|
||||||
class Imputer implements Preprocessor
|
class Imputer implements Preprocessor
|
||||||
{
|
{
|
||||||
const AXIS_COLUMN = 0;
|
public const AXIS_COLUMN = 0;
|
||||||
const AXIS_ROW = 1;
|
public const AXIS_ROW = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var mixed
|
* @var mixed
|
||||||
@ -43,19 +43,19 @@ class Imputer implements Preprocessor
|
|||||||
$this->samples = $samples;
|
$this->samples = $samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fit(array $samples)
|
public function fit(array $samples): void
|
||||||
{
|
{
|
||||||
$this->samples = $samples;
|
$this->samples = $samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transform(array &$samples)
|
public function transform(array &$samples): void
|
||||||
{
|
{
|
||||||
foreach ($samples as &$sample) {
|
foreach ($samples as &$sample) {
|
||||||
$this->preprocessSample($sample);
|
$this->preprocessSample($sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function preprocessSample(array &$sample)
|
private function preprocessSample(array &$sample): void
|
||||||
{
|
{
|
||||||
foreach ($sample as $column => &$value) {
|
foreach ($sample as $column => &$value) {
|
||||||
if ($value === $this->missingValue) {
|
if ($value === $this->missingValue) {
|
||||||
|
@ -10,9 +10,9 @@ use Phpml\Math\Statistic\StandardDeviation;
|
|||||||
|
|
||||||
class Normalizer implements Preprocessor
|
class Normalizer implements Preprocessor
|
||||||
{
|
{
|
||||||
const NORM_L1 = 1;
|
public const NORM_L1 = 1;
|
||||||
const NORM_L2 = 2;
|
public const NORM_L2 = 2;
|
||||||
const NORM_STD = 3;
|
public const NORM_STD = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int
|
* @var int
|
||||||
@ -46,7 +46,7 @@ class Normalizer implements Preprocessor
|
|||||||
$this->norm = $norm;
|
$this->norm = $norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fit(array $samples)
|
public function fit(array $samples): void
|
||||||
{
|
{
|
||||||
if ($this->fitted) {
|
if ($this->fitted) {
|
||||||
return;
|
return;
|
||||||
@ -64,7 +64,7 @@ class Normalizer implements Preprocessor
|
|||||||
$this->fitted = true;
|
$this->fitted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function transform(array &$samples)
|
public function transform(array &$samples): void
|
||||||
{
|
{
|
||||||
$methods = [
|
$methods = [
|
||||||
self::NORM_L1 => 'normalizeL1',
|
self::NORM_L1 => 'normalizeL1',
|
||||||
@ -80,7 +80,7 @@ class Normalizer implements Preprocessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function normalizeL1(array &$sample)
|
private function normalizeL1(array &$sample): void
|
||||||
{
|
{
|
||||||
$norm1 = 0;
|
$norm1 = 0;
|
||||||
foreach ($sample as $feature) {
|
foreach ($sample as $feature) {
|
||||||
@ -97,7 +97,7 @@ class Normalizer implements Preprocessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function normalizeL2(array &$sample)
|
private function normalizeL2(array &$sample): void
|
||||||
{
|
{
|
||||||
$norm2 = 0;
|
$norm2 = 0;
|
||||||
foreach ($sample as $feature) {
|
foreach ($sample as $feature) {
|
||||||
@ -114,7 +114,7 @@ class Normalizer implements Preprocessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function normalizeSTD(array &$sample)
|
private function normalizeSTD(array &$sample): void
|
||||||
{
|
{
|
||||||
foreach ($sample as $i => $val) {
|
foreach ($sample as $i => $val) {
|
||||||
if ($this->std[$i] != 0) {
|
if ($this->std[$i] != 0) {
|
||||||
|
@ -30,7 +30,7 @@ class LeastSquares implements Regression
|
|||||||
*/
|
*/
|
||||||
private $coefficients;
|
private $coefficients;
|
||||||
|
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
$this->samples = array_merge($this->samples, $samples);
|
$this->samples = array_merge($this->samples, $samples);
|
||||||
$this->targets = array_merge($this->targets, $targets);
|
$this->targets = array_merge($this->targets, $targets);
|
||||||
@ -64,7 +64,7 @@ class LeastSquares implements Regression
|
|||||||
/**
|
/**
|
||||||
* coefficient(b) = (X'X)-1X'Y.
|
* coefficient(b) = (X'X)-1X'Y.
|
||||||
*/
|
*/
|
||||||
private function computeCoefficients()
|
private function computeCoefficients(): void
|
||||||
{
|
{
|
||||||
$samplesMatrix = $this->getSamplesMatrix();
|
$samplesMatrix = $this->getSamplesMatrix();
|
||||||
$targetsMatrix = $this->getTargetsMatrix();
|
$targetsMatrix = $this->getTargetsMatrix();
|
||||||
|
@ -15,7 +15,7 @@ class SVR extends SupportVectorMachine implements Regression
|
|||||||
int $degree = 3,
|
int $degree = 3,
|
||||||
float $epsilon = 0.1,
|
float $epsilon = 0.1,
|
||||||
float $cost = 1.0,
|
float $cost = 1.0,
|
||||||
float $gamma = null,
|
?float $gamma = null,
|
||||||
float $coef0 = 0.0,
|
float $coef0 = 0.0,
|
||||||
float $tolerance = 0.001,
|
float $tolerance = 0.001,
|
||||||
int $cacheSize = 100,
|
int $cacheSize = 100,
|
||||||
|
@ -9,20 +9,20 @@ abstract class Kernel
|
|||||||
/**
|
/**
|
||||||
* u'*v.
|
* u'*v.
|
||||||
*/
|
*/
|
||||||
const LINEAR = 0;
|
public const LINEAR = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (gamma*u'*v + coef0)^degree.
|
* (gamma*u'*v + coef0)^degree.
|
||||||
*/
|
*/
|
||||||
const POLYNOMIAL = 1;
|
public const POLYNOMIAL = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* exp(-gamma*|u-v|^2).
|
* exp(-gamma*|u-v|^2).
|
||||||
*/
|
*/
|
||||||
const RBF = 2;
|
public const RBF = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tanh(gamma*u'*v + coef0).
|
* tanh(gamma*u'*v + coef0).
|
||||||
*/
|
*/
|
||||||
const SIGMOID = 3;
|
public const SIGMOID = 3;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ class SupportVectorMachine
|
|||||||
float $cost = 1.0,
|
float $cost = 1.0,
|
||||||
float $nu = 0.5,
|
float $nu = 0.5,
|
||||||
int $degree = 3,
|
int $degree = 3,
|
||||||
float $gamma = null,
|
?float $gamma = null,
|
||||||
float $coef0 = 0.0,
|
float $coef0 = 0.0,
|
||||||
float $epsilon = 0.1,
|
float $epsilon = 0.1,
|
||||||
float $tolerance = 0.001,
|
float $tolerance = 0.001,
|
||||||
@ -124,7 +124,7 @@ class SupportVectorMachine
|
|||||||
$this->varPath = $rootPath.'var'.DIRECTORY_SEPARATOR;
|
$this->varPath = $rootPath.'var'.DIRECTORY_SEPARATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setBinPath(string $binPath)
|
public function setBinPath(string $binPath): void
|
||||||
{
|
{
|
||||||
$this->ensureDirectorySeparator($binPath);
|
$this->ensureDirectorySeparator($binPath);
|
||||||
$this->verifyBinPath($binPath);
|
$this->verifyBinPath($binPath);
|
||||||
@ -132,7 +132,7 @@ class SupportVectorMachine
|
|||||||
$this->binPath = $binPath;
|
$this->binPath = $binPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setVarPath(string $varPath)
|
public function setVarPath(string $varPath): void
|
||||||
{
|
{
|
||||||
if (!is_writable($varPath)) {
|
if (!is_writable($varPath)) {
|
||||||
throw InvalidArgumentException::pathNotWritable($varPath);
|
throw InvalidArgumentException::pathNotWritable($varPath);
|
||||||
@ -142,7 +142,7 @@ class SupportVectorMachine
|
|||||||
$this->varPath = $varPath;
|
$this->varPath = $varPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function train(array $samples, array $targets)
|
public function train(array $samples, array $targets): void
|
||||||
{
|
{
|
||||||
$this->samples = array_merge($this->samples, $samples);
|
$this->samples = array_merge($this->samples, $samples);
|
||||||
$this->targets = array_merge($this->targets, $targets);
|
$this->targets = array_merge($this->targets, $targets);
|
||||||
@ -234,14 +234,14 @@ class SupportVectorMachine
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function ensureDirectorySeparator(string &$path)
|
private function ensureDirectorySeparator(string &$path): void
|
||||||
{
|
{
|
||||||
if (substr($path, -1) !== DIRECTORY_SEPARATOR) {
|
if (substr($path, -1) !== DIRECTORY_SEPARATOR) {
|
||||||
$path .= DIRECTORY_SEPARATOR;
|
$path .= DIRECTORY_SEPARATOR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function verifyBinPath(string $path)
|
private function verifyBinPath(string $path): void
|
||||||
{
|
{
|
||||||
if (!is_dir($path)) {
|
if (!is_dir($path)) {
|
||||||
throw InvalidArgumentException::pathNotFound($path);
|
throw InvalidArgumentException::pathNotFound($path);
|
||||||
|
@ -9,25 +9,25 @@ abstract class Type
|
|||||||
/**
|
/**
|
||||||
* classification.
|
* classification.
|
||||||
*/
|
*/
|
||||||
const C_SVC = 0;
|
public const C_SVC = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* classification.
|
* classification.
|
||||||
*/
|
*/
|
||||||
const NU_SVC = 1;
|
public const NU_SVC = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* distribution estimation.
|
* distribution estimation.
|
||||||
*/
|
*/
|
||||||
const ONE_CLASS_SVM = 2;
|
public const ONE_CLASS_SVM = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* regression.
|
* regression.
|
||||||
*/
|
*/
|
||||||
const EPSILON_SVR = 3;
|
public const EPSILON_SVR = 3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* regression.
|
* regression.
|
||||||
*/
|
*/
|
||||||
const NU_SVR = 4;
|
public const NU_SVR = 4;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ class AprioriTest extends TestCase
|
|||||||
[2, 4],
|
[2, 4],
|
||||||
];
|
];
|
||||||
|
|
||||||
public function testGreek()
|
public function testGreek(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori(0.5, 0.5);
|
$apriori = new Apriori(0.5, 0.5);
|
||||||
$apriori->train($this->sampleGreek, []);
|
$apriori->train($this->sampleGreek, []);
|
||||||
@ -49,14 +49,14 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertEquals('alpha', $apriori->predict([['alpha', 'epsilon'], ['beta', 'theta']])[1][0][0]);
|
$this->assertEquals('alpha', $apriori->predict([['alpha', 'epsilon'], ['beta', 'theta']])[1][0][0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPowerSet()
|
public function testPowerSet(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
|
|
||||||
$this->assertCount(8, $this->invoke($apriori, 'powerSet', [['a', 'b', 'c']]));
|
$this->assertCount(8, $this->invoke($apriori, 'powerSet', [['a', 'b', 'c']]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testApriori()
|
public function testApriori(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori(3 / 7);
|
$apriori = new Apriori(3 / 7);
|
||||||
$apriori->train($this->sampleBasket, []);
|
$apriori->train($this->sampleBasket, []);
|
||||||
@ -73,7 +73,7 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertTrue($this->invoke($apriori, 'contains', [$L[2], [3, 4]]));
|
$this->assertTrue($this->invoke($apriori, 'contains', [$L[2], [3, 4]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetRules()
|
public function testGetRules(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori(0.4, 0.8);
|
$apriori = new Apriori(0.4, 0.8);
|
||||||
$apriori->train($this->sampleChars, []);
|
$apriori->train($this->sampleChars, []);
|
||||||
@ -81,21 +81,21 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertCount(19, $apriori->getRules());
|
$this->assertCount(19, $apriori->getRules());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAntecedents()
|
public function testAntecedents(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
|
|
||||||
$this->assertCount(6, $this->invoke($apriori, 'antecedents', [['a', 'b', 'c']]));
|
$this->assertCount(6, $this->invoke($apriori, 'antecedents', [['a', 'b', 'c']]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItems()
|
public function testItems(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
$apriori->train($this->sampleGreek, []);
|
$apriori->train($this->sampleGreek, []);
|
||||||
$this->assertCount(4, $this->invoke($apriori, 'items', []));
|
$this->assertCount(4, $this->invoke($apriori, 'items', []));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFrequent()
|
public function testFrequent(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori(0.51);
|
$apriori = new Apriori(0.51);
|
||||||
$apriori->train($this->sampleGreek, []);
|
$apriori->train($this->sampleGreek, []);
|
||||||
@ -104,7 +104,7 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertCount(2, $this->invoke($apriori, 'frequent', [[['alpha'], ['beta']]]));
|
$this->assertCount(2, $this->invoke($apriori, 'frequent', [[['alpha'], ['beta']]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCandidates()
|
public function testCandidates(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
$apriori->train($this->sampleGreek, []);
|
$apriori->train($this->sampleGreek, []);
|
||||||
@ -115,7 +115,7 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertCount(3, $this->invoke($apriori, 'candidates', [[['alpha'], ['beta'], ['theta']]]));
|
$this->assertCount(3, $this->invoke($apriori, 'candidates', [[['alpha'], ['beta'], ['theta']]]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testConfidence()
|
public function testConfidence(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
$apriori->train($this->sampleGreek, []);
|
$apriori->train($this->sampleGreek, []);
|
||||||
@ -124,7 +124,7 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertEquals(1, $this->invoke($apriori, 'confidence', [['alpha', 'beta'], ['alpha']]));
|
$this->assertEquals(1, $this->invoke($apriori, 'confidence', [['alpha', 'beta'], ['alpha']]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSupport()
|
public function testSupport(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
$apriori->train($this->sampleGreek, []);
|
$apriori->train($this->sampleGreek, []);
|
||||||
@ -133,7 +133,7 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertEquals(0.5, $this->invoke($apriori, 'support', [['epsilon']]));
|
$this->assertEquals(0.5, $this->invoke($apriori, 'support', [['epsilon']]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFrequency()
|
public function testFrequency(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
$apriori->train($this->sampleGreek, []);
|
$apriori->train($this->sampleGreek, []);
|
||||||
@ -142,7 +142,7 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertEquals(2, $this->invoke($apriori, 'frequency', [['epsilon']]));
|
$this->assertEquals(2, $this->invoke($apriori, 'frequency', [['epsilon']]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testContains()
|
public function testContains(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertFalse($this->invoke($apriori, 'contains', [[['a'], ['b']], ['c']]));
|
$this->assertFalse($this->invoke($apriori, 'contains', [[['a'], ['b']], ['c']]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSubset()
|
public function testSubset(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ class AprioriTest extends TestCase
|
|||||||
$this->assertFalse($this->invoke($apriori, 'subset', [['a'], ['a', 'b']]));
|
$this->assertFalse($this->invoke($apriori, 'subset', [['a'], ['a', 'b']]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEquals()
|
public function testEquals(): void
|
||||||
{
|
{
|
||||||
$apriori = new Apriori();
|
$apriori = new Apriori();
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ class AprioriTest extends TestCase
|
|||||||
return $method->invokeArgs($object, $params);
|
return $method->invokeArgs($object, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
$classifier = new Apriori(0.5, 0.5);
|
$classifier = new Apriori(0.5, 0.5);
|
||||||
$classifier->train($this->sampleGreek, []);
|
$classifier->train($this->sampleGreek, []);
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class DecisionTreeLeafTest extends TestCase
|
class DecisionTreeLeafTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testHTMLOutput()
|
public function testHTMLOutput(): void
|
||||||
{
|
{
|
||||||
$leaf = new DecisionTreeLeaf();
|
$leaf = new DecisionTreeLeaf();
|
||||||
$leaf->value = 1;
|
$leaf->value = 1;
|
||||||
|
@ -35,7 +35,7 @@ class DecisionTreeTest extends TestCase
|
|||||||
private function getData($input)
|
private function getData($input)
|
||||||
{
|
{
|
||||||
$targets = array_column($input, 4);
|
$targets = array_column($input, 4);
|
||||||
array_walk($input, function (&$v) {
|
array_walk($input, function (&$v): void {
|
||||||
array_splice($v, 4, 1);
|
array_splice($v, 4, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -44,14 +44,14 @@ class DecisionTreeTest extends TestCase
|
|||||||
|
|
||||||
public function testPredictSingleSample()
|
public function testPredictSingleSample()
|
||||||
{
|
{
|
||||||
list($data, $targets) = $this->getData($this->data);
|
[$data, $targets] = $this->getData($this->data);
|
||||||
$classifier = new DecisionTree(5);
|
$classifier = new DecisionTree(5);
|
||||||
$classifier->train($data, $targets);
|
$classifier->train($data, $targets);
|
||||||
$this->assertEquals('Dont_play', $classifier->predict(['sunny', 78, 72, 'false']));
|
$this->assertEquals('Dont_play', $classifier->predict(['sunny', 78, 72, 'false']));
|
||||||
$this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
|
$this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
|
||||||
$this->assertEquals('Dont_play', $classifier->predict(['rain', 60, 60, 'true']));
|
$this->assertEquals('Dont_play', $classifier->predict(['rain', 60, 60, 'true']));
|
||||||
|
|
||||||
list($data, $targets) = $this->getData($this->extraData);
|
[$data, $targets] = $this->getData($this->extraData);
|
||||||
$classifier->train($data, $targets);
|
$classifier->train($data, $targets);
|
||||||
$this->assertEquals('Dont_play', $classifier->predict(['scorching', 95, 90, 'true']));
|
$this->assertEquals('Dont_play', $classifier->predict(['scorching', 95, 90, 'true']));
|
||||||
$this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
|
$this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
|
||||||
@ -59,9 +59,9 @@ class DecisionTreeTest extends TestCase
|
|||||||
return $classifier;
|
return $classifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
list($data, $targets) = $this->getData($this->data);
|
[$data, $targets] = $this->getData($this->data);
|
||||||
$classifier = new DecisionTree(5);
|
$classifier = new DecisionTree(5);
|
||||||
$classifier->train($data, $targets);
|
$classifier->train($data, $targets);
|
||||||
|
|
||||||
@ -78,9 +78,9 @@ class DecisionTreeTest extends TestCase
|
|||||||
$this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
|
$this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTreeDepth()
|
public function testTreeDepth(): void
|
||||||
{
|
{
|
||||||
list($data, $targets) = $this->getData($this->data);
|
[$data, $targets] = $this->getData($this->data);
|
||||||
$classifier = new DecisionTree(5);
|
$classifier = new DecisionTree(5);
|
||||||
$classifier->train($data, $targets);
|
$classifier->train($data, $targets);
|
||||||
$this->assertTrue(5 >= $classifier->actualDepth);
|
$this->assertTrue(5 >= $classifier->actualDepth);
|
||||||
|
@ -42,7 +42,7 @@ class AdaBoostTest extends TestCase
|
|||||||
return $classifier;
|
return $classifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
// Instantinate new Percetron trained for OR problem
|
// Instantinate new Percetron trained for OR problem
|
||||||
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
||||||
|
@ -36,7 +36,7 @@ class BaggingTest extends TestCase
|
|||||||
|
|
||||||
public function testPredictSingleSample()
|
public function testPredictSingleSample()
|
||||||
{
|
{
|
||||||
list($data, $targets) = $this->getData($this->data);
|
[$data, $targets] = $this->getData($this->data);
|
||||||
$classifier = $this->getClassifier();
|
$classifier = $this->getClassifier();
|
||||||
// Testing with default options
|
// Testing with default options
|
||||||
$classifier->train($data, $targets);
|
$classifier->train($data, $targets);
|
||||||
@ -44,7 +44,7 @@ class BaggingTest extends TestCase
|
|||||||
$this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
|
$this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
|
||||||
$this->assertEquals('Dont_play', $classifier->predict(['rain', 60, 60, 'true']));
|
$this->assertEquals('Dont_play', $classifier->predict(['rain', 60, 60, 'true']));
|
||||||
|
|
||||||
list($data, $targets) = $this->getData($this->extraData);
|
[$data, $targets] = $this->getData($this->extraData);
|
||||||
$classifier->train($data, $targets);
|
$classifier->train($data, $targets);
|
||||||
$this->assertEquals('Dont_play', $classifier->predict(['scorching', 95, 90, 'true']));
|
$this->assertEquals('Dont_play', $classifier->predict(['scorching', 95, 90, 'true']));
|
||||||
$this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
|
$this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
|
||||||
@ -52,9 +52,9 @@ class BaggingTest extends TestCase
|
|||||||
return $classifier;
|
return $classifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
list($data, $targets) = $this->getData($this->data);
|
[$data, $targets] = $this->getData($this->data);
|
||||||
$classifier = $this->getClassifier(5);
|
$classifier = $this->getClassifier(5);
|
||||||
$classifier->train($data, $targets);
|
$classifier->train($data, $targets);
|
||||||
|
|
||||||
@ -71,9 +71,9 @@ class BaggingTest extends TestCase
|
|||||||
$this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
|
$this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBaseClassifiers()
|
public function testBaseClassifiers(): void
|
||||||
{
|
{
|
||||||
list($data, $targets) = $this->getData($this->data);
|
[$data, $targets] = $this->getData($this->data);
|
||||||
$baseClassifiers = $this->getAvailableBaseClassifiers();
|
$baseClassifiers = $this->getAvailableBaseClassifiers();
|
||||||
|
|
||||||
foreach ($baseClassifiers as $base => $params) {
|
foreach ($baseClassifiers as $base => $params) {
|
||||||
@ -119,7 +119,7 @@ class BaggingTest extends TestCase
|
|||||||
}
|
}
|
||||||
shuffle($populated);
|
shuffle($populated);
|
||||||
$targets = array_column($populated, 4);
|
$targets = array_column($populated, 4);
|
||||||
array_walk($populated, function (&$v) {
|
array_walk($populated, function (&$v): void {
|
||||||
array_splice($v, 4, 1);
|
array_splice($v, 4, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class RandomForestTest extends BaggingTest
|
|||||||
return [DecisionTree::class => ['depth' => 5]];
|
return [DecisionTree::class => ['depth' => 5]];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testOtherBaseClassifier()
|
public function testOtherBaseClassifier(): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$classifier = new RandomForest();
|
$classifier = new RandomForest();
|
||||||
|
@ -11,7 +11,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class KNearestNeighborsTest extends TestCase
|
class KNearestNeighborsTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testPredictSingleSampleWithDefaultK()
|
public function testPredictSingleSampleWithDefaultK(): void
|
||||||
{
|
{
|
||||||
$samples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
$samples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
||||||
$labels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
$labels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
||||||
@ -30,7 +30,7 @@ class KNearestNeighborsTest extends TestCase
|
|||||||
$this->assertEquals('a', $classifier->predict([3, 10]));
|
$this->assertEquals('a', $classifier->predict([3, 10]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPredictArrayOfSamples()
|
public function testPredictArrayOfSamples(): void
|
||||||
{
|
{
|
||||||
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
||||||
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
||||||
@ -45,7 +45,7 @@ class KNearestNeighborsTest extends TestCase
|
|||||||
$this->assertEquals($testLabels, $predicted);
|
$this->assertEquals($testLabels, $predicted);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPredictArrayOfSamplesUsingChebyshevDistanceMetric()
|
public function testPredictArrayOfSamplesUsingChebyshevDistanceMetric(): void
|
||||||
{
|
{
|
||||||
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
||||||
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
||||||
@ -60,7 +60,7 @@ class KNearestNeighborsTest extends TestCase
|
|||||||
$this->assertEquals($testLabels, $predicted);
|
$this->assertEquals($testLabels, $predicted);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
||||||
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
||||||
|
@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class AdalineTest extends TestCase
|
class AdalineTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testPredictSingleSample()
|
public function testPredictSingleSample(): void
|
||||||
{
|
{
|
||||||
// AND problem
|
// AND problem
|
||||||
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
||||||
@ -64,7 +64,7 @@ class AdalineTest extends TestCase
|
|||||||
$this->assertEquals(1, $classifier->predict([3.0, 9.5]));
|
$this->assertEquals(1, $classifier->predict([3.0, 9.5]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
// Instantinate new Percetron trained for OR problem
|
// Instantinate new Percetron trained for OR problem
|
||||||
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
||||||
|
@ -53,7 +53,7 @@ class DecisionStumpTest extends TestCase
|
|||||||
return $classifier;
|
return $classifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
// Instantinate new Percetron trained for OR problem
|
// Instantinate new Percetron trained for OR problem
|
||||||
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
||||||
|
@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class PerceptronTest extends TestCase
|
class PerceptronTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testPredictSingleSample()
|
public function testPredictSingleSample(): void
|
||||||
{
|
{
|
||||||
// AND problem
|
// AND problem
|
||||||
$samples = [[0, 0], [1, 0], [0, 1], [1, 1], [0.6, 0.6]];
|
$samples = [[0, 0], [1, 0], [0, 1], [1, 1], [0.6, 0.6]];
|
||||||
@ -67,7 +67,7 @@ class PerceptronTest extends TestCase
|
|||||||
$this->assertEquals(1, $classifier->predict([3.0, 9.5]));
|
$this->assertEquals(1, $classifier->predict([3.0, 9.5]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
// Instantinate new Percetron trained for OR problem
|
// Instantinate new Percetron trained for OR problem
|
||||||
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
||||||
|
@ -11,7 +11,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class MLPClassifierTest extends TestCase
|
class MLPClassifierTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testMLPClassifierLayersInitialization()
|
public function testMLPClassifierLayersInitialization(): void
|
||||||
{
|
{
|
||||||
$mlp = new MLPClassifier(2, [2], [0, 1]);
|
$mlp = new MLPClassifier(2, [2], [0, 1]);
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
$this->assertContainsOnly(Neuron::class, $layers[2]->getNodes());
|
$this->assertContainsOnly(Neuron::class, $layers[2]->getNodes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSynapsesGeneration()
|
public function testSynapsesGeneration(): void
|
||||||
{
|
{
|
||||||
$mlp = new MLPClassifier(2, [2], [0, 1]);
|
$mlp = new MLPClassifier(2, [2], [0, 1]);
|
||||||
$layers = $mlp->getLayers();
|
$layers = $mlp->getLayers();
|
||||||
@ -50,7 +50,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBackpropagationLearning()
|
public function testBackpropagationLearning(): void
|
||||||
{
|
{
|
||||||
// Single layer 2 classes.
|
// Single layer 2 classes.
|
||||||
$network = new MLPClassifier(2, [2], ['a', 'b']);
|
$network = new MLPClassifier(2, [2], ['a', 'b']);
|
||||||
@ -65,7 +65,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
$this->assertEquals('b', $network->predict([0, 0]));
|
$this->assertEquals('b', $network->predict([0, 0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBackpropagationTrainingReset()
|
public function testBackpropagationTrainingReset(): void
|
||||||
{
|
{
|
||||||
// Single layer 2 classes.
|
// Single layer 2 classes.
|
||||||
$network = new MLPClassifier(2, [2], ['a', 'b'], 1000);
|
$network = new MLPClassifier(2, [2], ['a', 'b'], 1000);
|
||||||
@ -86,7 +86,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
$this->assertEquals('a', $network->predict([0, 1]));
|
$this->assertEquals('a', $network->predict([0, 1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBackpropagationPartialTraining()
|
public function testBackpropagationPartialTraining(): void
|
||||||
{
|
{
|
||||||
// Single layer 2 classes.
|
// Single layer 2 classes.
|
||||||
$network = new MLPClassifier(2, [2], ['a', 'b'], 1000);
|
$network = new MLPClassifier(2, [2], ['a', 'b'], 1000);
|
||||||
@ -109,7 +109,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
$this->assertEquals('b', $network->predict([0, 0]));
|
$this->assertEquals('b', $network->predict([0, 0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBackpropagationLearningMultilayer()
|
public function testBackpropagationLearningMultilayer(): void
|
||||||
{
|
{
|
||||||
// Multi-layer 2 classes.
|
// Multi-layer 2 classes.
|
||||||
$network = new MLPClassifier(5, [3, 2], ['a', 'b']);
|
$network = new MLPClassifier(5, [3, 2], ['a', 'b']);
|
||||||
@ -124,7 +124,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
$this->assertEquals('b', $network->predict([0, 0, 0, 0, 0]));
|
$this->assertEquals('b', $network->predict([0, 0, 0, 0, 0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testBackpropagationLearningMulticlass()
|
public function testBackpropagationLearningMulticlass(): void
|
||||||
{
|
{
|
||||||
// Multi-layer more than 2 classes.
|
// Multi-layer more than 2 classes.
|
||||||
$network = new MLPClassifier(5, [3, 2], ['a', 'b', 4]);
|
$network = new MLPClassifier(5, [3, 2], ['a', 'b', 4]);
|
||||||
@ -140,7 +140,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
$this->assertEquals(4, $network->predict([0, 0, 0, 0, 0]));
|
$this->assertEquals(4, $network->predict([0, 0, 0, 0, 0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
// Instantinate new Percetron trained for OR problem
|
// Instantinate new Percetron trained for OR problem
|
||||||
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
$samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
|
||||||
@ -163,7 +163,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidLayersNumber()
|
public function testThrowExceptionOnInvalidLayersNumber(): void
|
||||||
{
|
{
|
||||||
new MLPClassifier(2, [], [0, 1]);
|
new MLPClassifier(2, [], [0, 1]);
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidPartialTrainingClasses()
|
public function testThrowExceptionOnInvalidPartialTrainingClasses(): void
|
||||||
{
|
{
|
||||||
$classifier = new MLPClassifier(2, [2], [0, 1]);
|
$classifier = new MLPClassifier(2, [2], [0, 1]);
|
||||||
$classifier->partialTrain(
|
$classifier->partialTrain(
|
||||||
@ -184,7 +184,7 @@ class MLPClassifierTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidClassesNumber()
|
public function testThrowExceptionOnInvalidClassesNumber(): void
|
||||||
{
|
{
|
||||||
new MLPClassifier(2, [2], [0]);
|
new MLPClassifier(2, [2], [0]);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class NaiveBayesTest extends TestCase
|
class NaiveBayesTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testPredictSingleSample()
|
public function testPredictSingleSample(): void
|
||||||
{
|
{
|
||||||
$samples = [[5, 1, 1], [1, 5, 1], [1, 1, 5]];
|
$samples = [[5, 1, 1], [1, 5, 1], [1, 1, 5]];
|
||||||
$labels = ['a', 'b', 'c'];
|
$labels = ['a', 'b', 'c'];
|
||||||
@ -23,7 +23,7 @@ class NaiveBayesTest extends TestCase
|
|||||||
$this->assertEquals('c', $classifier->predict([1, 1, 6]));
|
$this->assertEquals('c', $classifier->predict([1, 1, 6]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPredictArrayOfSamples()
|
public function testPredictArrayOfSamples(): void
|
||||||
{
|
{
|
||||||
$trainSamples = [[5, 1, 1], [1, 5, 1], [1, 1, 5]];
|
$trainSamples = [[5, 1, 1], [1, 5, 1], [1, 1, 5]];
|
||||||
$trainLabels = ['a', 'b', 'c'];
|
$trainLabels = ['a', 'b', 'c'];
|
||||||
@ -47,7 +47,7 @@ class NaiveBayesTest extends TestCase
|
|||||||
$this->assertEquals($testLabels, $classifier->predict($testSamples));
|
$this->assertEquals($testLabels, $classifier->predict($testSamples));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
$trainSamples = [[5, 1, 1], [1, 5, 1], [1, 1, 5]];
|
$trainSamples = [[5, 1, 1], [1, 5, 1], [1, 1, 5]];
|
||||||
$trainLabels = ['a', 'b', 'c'];
|
$trainLabels = ['a', 'b', 'c'];
|
||||||
|
@ -11,7 +11,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class SVCTest extends TestCase
|
class SVCTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testPredictSingleSampleWithLinearKernel()
|
public function testPredictSingleSampleWithLinearKernel(): void
|
||||||
{
|
{
|
||||||
$samples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
$samples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
||||||
$labels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
$labels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
||||||
@ -30,7 +30,7 @@ class SVCTest extends TestCase
|
|||||||
$this->assertEquals('a', $classifier->predict([3, 10]));
|
$this->assertEquals('a', $classifier->predict([3, 10]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPredictArrayOfSamplesWithLinearKernel()
|
public function testPredictArrayOfSamplesWithLinearKernel(): void
|
||||||
{
|
{
|
||||||
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
||||||
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
||||||
@ -45,7 +45,7 @@ class SVCTest extends TestCase
|
|||||||
$this->assertEquals($testLabels, $predictions);
|
$this->assertEquals($testLabels, $predictions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveAndRestore()
|
public function testSaveAndRestore(): void
|
||||||
{
|
{
|
||||||
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
$trainSamples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
|
||||||
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
$trainLabels = ['a', 'a', 'a', 'b', 'b', 'b'];
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class DBSCANTest extends TestCase
|
class DBSCANTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testDBSCANSamplesClustering()
|
public function testDBSCANSamplesClustering(): void
|
||||||
{
|
{
|
||||||
$samples = [[1, 1], [8, 7], [1, 2], [7, 8], [2, 1], [8, 9]];
|
$samples = [[1, 1], [8, 7], [1, 2], [7, 8], [2, 1], [8, 9]];
|
||||||
$clustered = [
|
$clustered = [
|
||||||
@ -32,7 +32,7 @@ class DBSCANTest extends TestCase
|
|||||||
$this->assertEquals($clustered, $dbscan->cluster($samples));
|
$this->assertEquals($clustered, $dbscan->cluster($samples));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDBSCANSamplesClusteringAssociative()
|
public function testDBSCANSamplesClusteringAssociative(): void
|
||||||
{
|
{
|
||||||
$samples = ['a' => [1, 1], 'b' => [9, 9], 'c' => [1, 2], 'd' => [9, 8], 'e' => [7, 7], 'f' => [8, 7]];
|
$samples = ['a' => [1, 1], 'b' => [9, 9], 'c' => [1, 2], 'd' => [9, 8], 'e' => [7, 7], 'f' => [8, 7]];
|
||||||
$clustered = [
|
$clustered = [
|
||||||
|
@ -25,7 +25,7 @@ class FuzzyCMeansTest extends TestCase
|
|||||||
return $fcm;
|
return $fcm;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMembershipMatrix()
|
public function testMembershipMatrix(): void
|
||||||
{
|
{
|
||||||
$fcm = $this->testFCMSamplesClustering();
|
$fcm = $this->testFCMSamplesClustering();
|
||||||
$clusterCount = 2;
|
$clusterCount = 2;
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class KMeansTest extends TestCase
|
class KMeansTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testKMeansSamplesClustering()
|
public function testKMeansSamplesClustering(): void
|
||||||
{
|
{
|
||||||
$samples = [[1, 1], [8, 7], [1, 2], [7, 8], [2, 1], [8, 9]];
|
$samples = [[1, 1], [8, 7], [1, 2], [7, 8], [2, 1], [8, 9]];
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ class KMeansTest extends TestCase
|
|||||||
$this->assertCount(0, $samples);
|
$this->assertCount(0, $samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testKMeansInitializationMethods()
|
public function testKMeansInitializationMethods(): void
|
||||||
{
|
{
|
||||||
$samples = [
|
$samples = [
|
||||||
[180, 155], [186, 159], [119, 185], [141, 147], [157, 158],
|
[180, 155], [186, 159], [119, 185], [141, 147], [157, 158],
|
||||||
@ -53,7 +53,7 @@ class KMeansTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidClusterNumber()
|
public function testThrowExceptionOnInvalidClusterNumber(): void
|
||||||
{
|
{
|
||||||
new KMeans(0);
|
new KMeans(0);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ class RandomSplitTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnToSmallTestSize()
|
public function testThrowExceptionOnToSmallTestSize(): void
|
||||||
{
|
{
|
||||||
new RandomSplit(new ArrayDataset([], []), 0);
|
new RandomSplit(new ArrayDataset([], []), 0);
|
||||||
}
|
}
|
||||||
@ -21,12 +21,12 @@ class RandomSplitTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnToBigTestSize()
|
public function testThrowExceptionOnToBigTestSize(): void
|
||||||
{
|
{
|
||||||
new RandomSplit(new ArrayDataset([], []), 1);
|
new RandomSplit(new ArrayDataset([], []), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDatasetRandomSplitWithoutSeed()
|
public function testDatasetRandomSplitWithoutSeed(): void
|
||||||
{
|
{
|
||||||
$dataset = new ArrayDataset(
|
$dataset = new ArrayDataset(
|
||||||
$samples = [[1], [2], [3], [4]],
|
$samples = [[1], [2], [3], [4]],
|
||||||
@ -44,7 +44,7 @@ class RandomSplitTest extends TestCase
|
|||||||
$this->assertCount(3, $randomSplit2->getTrainSamples());
|
$this->assertCount(3, $randomSplit2->getTrainSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDatasetRandomSplitWithSameSeed()
|
public function testDatasetRandomSplitWithSameSeed(): void
|
||||||
{
|
{
|
||||||
$dataset = new ArrayDataset(
|
$dataset = new ArrayDataset(
|
||||||
$samples = [[1], [2], [3], [4], [5], [6], [7], [8]],
|
$samples = [[1], [2], [3], [4], [5], [6], [7], [8]],
|
||||||
@ -62,7 +62,7 @@ class RandomSplitTest extends TestCase
|
|||||||
$this->assertEquals($randomSplit1->getTrainSamples(), $randomSplit2->getTrainSamples());
|
$this->assertEquals($randomSplit1->getTrainSamples(), $randomSplit2->getTrainSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDatasetRandomSplitWithDifferentSeed()
|
public function testDatasetRandomSplitWithDifferentSeed(): void
|
||||||
{
|
{
|
||||||
$dataset = new ArrayDataset(
|
$dataset = new ArrayDataset(
|
||||||
$samples = [[1], [2], [3], [4], [5], [6], [7], [8]],
|
$samples = [[1], [2], [3], [4], [5], [6], [7], [8]],
|
||||||
@ -78,7 +78,7 @@ class RandomSplitTest extends TestCase
|
|||||||
$this->assertNotEquals($randomSplit1->getTrainSamples(), $randomSplit2->getTrainSamples());
|
$this->assertNotEquals($randomSplit1->getTrainSamples(), $randomSplit2->getTrainSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRandomSplitCorrectSampleAndLabelPosition()
|
public function testRandomSplitCorrectSampleAndLabelPosition(): void
|
||||||
{
|
{
|
||||||
$dataset = new ArrayDataset(
|
$dataset = new ArrayDataset(
|
||||||
$samples = [[1], [2], [3], [4]],
|
$samples = [[1], [2], [3], [4]],
|
||||||
|
@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class StratifiedRandomSplitTest extends TestCase
|
class StratifiedRandomSplitTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testDatasetStratifiedRandomSplitWithEvenDistribution()
|
public function testDatasetStratifiedRandomSplitWithEvenDistribution(): void
|
||||||
{
|
{
|
||||||
$dataset = new ArrayDataset(
|
$dataset = new ArrayDataset(
|
||||||
$samples = [[1], [2], [3], [4], [5], [6], [7], [8]],
|
$samples = [[1], [2], [3], [4], [5], [6], [7], [8]],
|
||||||
@ -28,7 +28,7 @@ class StratifiedRandomSplitTest extends TestCase
|
|||||||
$this->assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 'b'));
|
$this->assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 'b'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDatasetStratifiedRandomSplitWithEvenDistributionAndNumericTargets()
|
public function testDatasetStratifiedRandomSplitWithEvenDistributionAndNumericTargets(): void
|
||||||
{
|
{
|
||||||
$dataset = new ArrayDataset(
|
$dataset = new ArrayDataset(
|
||||||
$samples = [[1], [2], [3], [4], [5], [6], [7], [8]],
|
$samples = [[1], [2], [3], [4], [5], [6], [7], [8]],
|
||||||
|
@ -12,12 +12,12 @@ class ArrayDatasetTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidArgumentsSize()
|
public function testThrowExceptionOnInvalidArgumentsSize(): void
|
||||||
{
|
{
|
||||||
new ArrayDataset([0, 1], [0]);
|
new ArrayDataset([0, 1], [0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testArrayDataset()
|
public function testArrayDataset(): void
|
||||||
{
|
{
|
||||||
$dataset = new ArrayDataset(
|
$dataset = new ArrayDataset(
|
||||||
$samples = [[1], [2], [3], [4]],
|
$samples = [[1], [2], [3], [4]],
|
||||||
|
@ -12,12 +12,12 @@ class CsvDatasetTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\FileException
|
* @expectedException \Phpml\Exception\FileException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnMissingFile()
|
public function testThrowExceptionOnMissingFile(): void
|
||||||
{
|
{
|
||||||
new CsvDataset('missingFile', 3);
|
new CsvDataset('missingFile', 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSampleCsvDatasetWithHeaderRow()
|
public function testSampleCsvDatasetWithHeaderRow(): void
|
||||||
{
|
{
|
||||||
$filePath = dirname(__FILE__).'/Resources/dataset.csv';
|
$filePath = dirname(__FILE__).'/Resources/dataset.csv';
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ class CsvDatasetTest extends TestCase
|
|||||||
$this->assertCount(10, $dataset->getTargets());
|
$this->assertCount(10, $dataset->getTargets());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSampleCsvDatasetWithoutHeaderRow()
|
public function testSampleCsvDatasetWithoutHeaderRow(): void
|
||||||
{
|
{
|
||||||
$filePath = dirname(__FILE__).'/Resources/dataset.csv';
|
$filePath = dirname(__FILE__).'/Resources/dataset.csv';
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ class CsvDatasetTest extends TestCase
|
|||||||
$this->assertCount(11, $dataset->getTargets());
|
$this->assertCount(11, $dataset->getTargets());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLongCsvDataset()
|
public function testLongCsvDataset(): void
|
||||||
{
|
{
|
||||||
$filePath = dirname(__FILE__).'/Resources/longdataset.csv';
|
$filePath = dirname(__FILE__).'/Resources/longdataset.csv';
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class GlassDatasetTest extends TestCase
|
class GlassDatasetTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testLoadingWineDataset()
|
public function testLoadingWineDataset(): void
|
||||||
{
|
{
|
||||||
$glass = new GlassDataset();
|
$glass = new GlassDataset();
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class IrisDatasetTest extends TestCase
|
class IrisDatasetTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testLoadingIrisDataset()
|
public function testLoadingIrisDataset(): void
|
||||||
{
|
{
|
||||||
$iris = new IrisDataset();
|
$iris = new IrisDataset();
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class WineDatasetTest extends TestCase
|
class WineDatasetTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testLoadingWineDataset()
|
public function testLoadingWineDataset(): void
|
||||||
{
|
{
|
||||||
$wine = new WineDataset();
|
$wine = new WineDataset();
|
||||||
|
|
||||||
|
@ -12,12 +12,12 @@ class FilesDatasetTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\DatasetException
|
* @expectedException \Phpml\Exception\DatasetException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnMissingRootFolder()
|
public function testThrowExceptionOnMissingRootFolder(): void
|
||||||
{
|
{
|
||||||
new FilesDataset('some/not/existed/path');
|
new FilesDataset('some/not/existed/path');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadFilesDatasetWithBBCData()
|
public function testLoadFilesDatasetWithBBCData(): void
|
||||||
{
|
{
|
||||||
$rootPath = dirname(__FILE__).'/Resources/bbc';
|
$rootPath = dirname(__FILE__).'/Resources/bbc';
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class KernelPCATest extends TestCase
|
class KernelPCATest extends TestCase
|
||||||
{
|
{
|
||||||
public function testKernelPCA()
|
public function testKernelPCA(): void
|
||||||
{
|
{
|
||||||
// Acceptable error
|
// Acceptable error
|
||||||
$epsilon = 0.001;
|
$epsilon = 0.001;
|
||||||
@ -37,7 +37,7 @@ class KernelPCATest extends TestCase
|
|||||||
// Due to the fact that the sign of values can be flipped
|
// Due to the fact that the sign of values can be flipped
|
||||||
// during the calculation of eigenValues, we have to compare
|
// during the calculation of eigenValues, we have to compare
|
||||||
// absolute value of the values
|
// absolute value of the values
|
||||||
array_map(function ($val1, $val2) use ($epsilon) {
|
array_map(function ($val1, $val2) use ($epsilon): void {
|
||||||
$this->assertEquals(abs($val1), abs($val2), '', $epsilon);
|
$this->assertEquals(abs($val1), abs($val2), '', $epsilon);
|
||||||
}, $transformed, $reducedData);
|
}, $transformed, $reducedData);
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class LDATest extends TestCase
|
class LDATest extends TestCase
|
||||||
{
|
{
|
||||||
public function testLDA()
|
public function testLDA(): void
|
||||||
{
|
{
|
||||||
// Acceptable error
|
// Acceptable error
|
||||||
$epsilon = 0.001;
|
$epsilon = 0.001;
|
||||||
@ -43,7 +43,7 @@ class LDATest extends TestCase
|
|||||||
$control = array_merge($control, array_slice($transformed, 0, 3));
|
$control = array_merge($control, array_slice($transformed, 0, 3));
|
||||||
$control = array_merge($control, array_slice($transformed, -3));
|
$control = array_merge($control, array_slice($transformed, -3));
|
||||||
|
|
||||||
$check = function ($row1, $row2) use ($epsilon) {
|
$check = function ($row1, $row2) use ($epsilon): void {
|
||||||
// Due to the fact that the sign of values can be flipped
|
// Due to the fact that the sign of values can be flipped
|
||||||
// during the calculation of eigenValues, we have to compare
|
// during the calculation of eigenValues, we have to compare
|
||||||
// absolute value of the values
|
// absolute value of the values
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class PCATest extends TestCase
|
class PCATest extends TestCase
|
||||||
{
|
{
|
||||||
public function testPCA()
|
public function testPCA(): void
|
||||||
{
|
{
|
||||||
// Acceptable error
|
// Acceptable error
|
||||||
$epsilon = 0.001;
|
$epsilon = 0.001;
|
||||||
@ -39,7 +39,7 @@ class PCATest extends TestCase
|
|||||||
// Due to the fact that the sign of values can be flipped
|
// Due to the fact that the sign of values can be flipped
|
||||||
// during the calculation of eigenValues, we have to compare
|
// during the calculation of eigenValues, we have to compare
|
||||||
// absolute value of the values
|
// absolute value of the values
|
||||||
array_map(function ($val1, $val2) use ($epsilon) {
|
array_map(function ($val1, $val2) use ($epsilon): void {
|
||||||
$this->assertEquals(abs($val1), abs($val2), '', $epsilon);
|
$this->assertEquals(abs($val1), abs($val2), '', $epsilon);
|
||||||
}, $transformed, $reducedData);
|
}, $transformed, $reducedData);
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ class PCATest extends TestCase
|
|||||||
$newRow = [[$transformed[$i]]];
|
$newRow = [[$transformed[$i]]];
|
||||||
$newRow2 = $pca->transform($row);
|
$newRow2 = $pca->transform($row);
|
||||||
|
|
||||||
array_map(function ($val1, $val2) use ($epsilon) {
|
array_map(function ($val1, $val2) use ($epsilon): void {
|
||||||
$this->assertEquals(abs($val1), abs($val2), '', $epsilon);
|
$this->assertEquals(abs($val1), abs($val2), '', $epsilon);
|
||||||
}, $newRow, $newRow2);
|
}, $newRow, $newRow2);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class StopWordsTest extends TestCase
|
class StopWordsTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testCustomStopWords()
|
public function testCustomStopWords(): void
|
||||||
{
|
{
|
||||||
$stopWords = new StopWords(['lorem', 'ipsum', 'dolor']);
|
$stopWords = new StopWords(['lorem', 'ipsum', 'dolor']);
|
||||||
|
|
||||||
@ -25,12 +25,12 @@ class StopWordsTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidLanguage()
|
public function testThrowExceptionOnInvalidLanguage(): void
|
||||||
{
|
{
|
||||||
StopWords::factory('Lorem');
|
StopWords::factory('Lorem');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEnglishStopWords()
|
public function testEnglishStopWords(): void
|
||||||
{
|
{
|
||||||
$stopWords = StopWords::factory('English');
|
$stopWords = StopWords::factory('English');
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ class StopWordsTest extends TestCase
|
|||||||
$this->assertFalse($stopWords->isStopWord('strategy'));
|
$this->assertFalse($stopWords->isStopWord('strategy'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPolishStopWords()
|
public function testPolishStopWords(): void
|
||||||
{
|
{
|
||||||
$stopWords = StopWords::factory('Polish');
|
$stopWords = StopWords::factory('Polish');
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class StopWordsTest extends TestCase
|
|||||||
$this->assertFalse($stopWords->isStopWord('transhumanizm'));
|
$this->assertFalse($stopWords->isStopWord('transhumanizm'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testFrenchStopWords()
|
public function testFrenchStopWords(): void
|
||||||
{
|
{
|
||||||
$stopWords = StopWords::factory('French');
|
$stopWords = StopWords::factory('French');
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class TfIdfTransformerTest extends TestCase
|
class TfIdfTransformerTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testTfIdfTransformation()
|
public function testTfIdfTransformation(): void
|
||||||
{
|
{
|
||||||
// https://en.wikipedia.org/wiki/Tf-idf
|
// https://en.wikipedia.org/wiki/Tf-idf
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class TokenCountVectorizerTest extends TestCase
|
class TokenCountVectorizerTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testTransformationWithWhitespaceTokenizer()
|
public function testTransformationWithWhitespaceTokenizer(): void
|
||||||
{
|
{
|
||||||
$samples = [
|
$samples = [
|
||||||
'Lorem ipsum dolor sit amet dolor',
|
'Lorem ipsum dolor sit amet dolor',
|
||||||
@ -47,7 +47,7 @@ class TokenCountVectorizerTest extends TestCase
|
|||||||
$this->assertSame($tokensCounts, $samples);
|
$this->assertSame($tokensCounts, $samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTransformationWithMinimumDocumentTokenCountFrequency()
|
public function testTransformationWithMinimumDocumentTokenCountFrequency(): void
|
||||||
{
|
{
|
||||||
// word at least in half samples
|
// word at least in half samples
|
||||||
$samples = [
|
$samples = [
|
||||||
@ -100,7 +100,7 @@ class TokenCountVectorizerTest extends TestCase
|
|||||||
$this->assertSame($tokensCounts, $samples);
|
$this->assertSame($tokensCounts, $samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTransformationWithStopWords()
|
public function testTransformationWithStopWords(): void
|
||||||
{
|
{
|
||||||
$samples = [
|
$samples = [
|
||||||
'Lorem ipsum dolor sit amet dolor',
|
'Lorem ipsum dolor sit amet dolor',
|
||||||
|
@ -15,7 +15,7 @@ class ComparisonTest extends TestCase
|
|||||||
*
|
*
|
||||||
* @dataProvider provideData
|
* @dataProvider provideData
|
||||||
*/
|
*/
|
||||||
public function testResult($a, $b, string $operator, bool $expected)
|
public function testResult($a, $b, string $operator, bool $expected): void
|
||||||
{
|
{
|
||||||
$result = Comparison::compare($a, $b, $operator);
|
$result = Comparison::compare($a, $b, $operator);
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ class ComparisonTest extends TestCase
|
|||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
* @expectedExceptionMessage Invalid operator "~=" provided
|
* @expectedExceptionMessage Invalid operator "~=" provided
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionWhenOperatorIsInvalid()
|
public function testThrowExceptionWhenOperatorIsInvalid(): void
|
||||||
{
|
{
|
||||||
Comparison::compare(1, 1, '~=');
|
Comparison::compare(1, 1, '~=');
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ class ChebyshevTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
private $distanceMetric;
|
private $distanceMetric;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
$this->distanceMetric = new Chebyshev();
|
$this->distanceMetric = new Chebyshev();
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ class ChebyshevTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidArguments()
|
public function testThrowExceptionOnInvalidArguments(): void
|
||||||
{
|
{
|
||||||
$a = [0, 1, 2];
|
$a = [0, 1, 2];
|
||||||
$b = [0, 2];
|
$b = [0, 2];
|
||||||
@ -30,7 +30,7 @@ class ChebyshevTest extends TestCase
|
|||||||
$this->distanceMetric->distance($a, $b);
|
$this->distanceMetric->distance($a, $b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForOneDimension()
|
public function testCalculateDistanceForOneDimension(): void
|
||||||
{
|
{
|
||||||
$a = [4];
|
$a = [4];
|
||||||
$b = [2];
|
$b = [2];
|
||||||
@ -41,7 +41,7 @@ class ChebyshevTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance);
|
$this->assertEquals($expectedDistance, $actualDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForTwoDimensions()
|
public function testCalculateDistanceForTwoDimensions(): void
|
||||||
{
|
{
|
||||||
$a = [4, 6];
|
$a = [4, 6];
|
||||||
$b = [2, 5];
|
$b = [2, 5];
|
||||||
@ -52,7 +52,7 @@ class ChebyshevTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance);
|
$this->assertEquals($expectedDistance, $actualDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForThreeDimensions()
|
public function testCalculateDistanceForThreeDimensions(): void
|
||||||
{
|
{
|
||||||
$a = [6, 10, 3];
|
$a = [6, 10, 3];
|
||||||
$b = [2, 5, 5];
|
$b = [2, 5, 5];
|
||||||
|
@ -14,7 +14,7 @@ class EuclideanTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
private $distanceMetric;
|
private $distanceMetric;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
$this->distanceMetric = new Euclidean();
|
$this->distanceMetric = new Euclidean();
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ class EuclideanTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidArguments()
|
public function testThrowExceptionOnInvalidArguments(): void
|
||||||
{
|
{
|
||||||
$a = [0, 1, 2];
|
$a = [0, 1, 2];
|
||||||
$b = [0, 2];
|
$b = [0, 2];
|
||||||
@ -30,7 +30,7 @@ class EuclideanTest extends TestCase
|
|||||||
$this->distanceMetric->distance($a, $b);
|
$this->distanceMetric->distance($a, $b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForOneDimension()
|
public function testCalculateDistanceForOneDimension(): void
|
||||||
{
|
{
|
||||||
$a = [4];
|
$a = [4];
|
||||||
$b = [2];
|
$b = [2];
|
||||||
@ -41,7 +41,7 @@ class EuclideanTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance);
|
$this->assertEquals($expectedDistance, $actualDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForTwoDimensions()
|
public function testCalculateDistanceForTwoDimensions(): void
|
||||||
{
|
{
|
||||||
$a = [4, 6];
|
$a = [4, 6];
|
||||||
$b = [2, 5];
|
$b = [2, 5];
|
||||||
@ -52,7 +52,7 @@ class EuclideanTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance);
|
$this->assertEquals($expectedDistance, $actualDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForThreeDimensions()
|
public function testCalculateDistanceForThreeDimensions(): void
|
||||||
{
|
{
|
||||||
$a = [6, 10, 3];
|
$a = [6, 10, 3];
|
||||||
$b = [2, 5, 5];
|
$b = [2, 5, 5];
|
||||||
|
@ -14,7 +14,7 @@ class ManhattanTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
private $distanceMetric;
|
private $distanceMetric;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
$this->distanceMetric = new Manhattan();
|
$this->distanceMetric = new Manhattan();
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ class ManhattanTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidArguments()
|
public function testThrowExceptionOnInvalidArguments(): void
|
||||||
{
|
{
|
||||||
$a = [0, 1, 2];
|
$a = [0, 1, 2];
|
||||||
$b = [0, 2];
|
$b = [0, 2];
|
||||||
@ -30,7 +30,7 @@ class ManhattanTest extends TestCase
|
|||||||
$this->distanceMetric->distance($a, $b);
|
$this->distanceMetric->distance($a, $b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForOneDimension()
|
public function testCalculateDistanceForOneDimension(): void
|
||||||
{
|
{
|
||||||
$a = [4];
|
$a = [4];
|
||||||
$b = [2];
|
$b = [2];
|
||||||
@ -41,7 +41,7 @@ class ManhattanTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance);
|
$this->assertEquals($expectedDistance, $actualDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForTwoDimensions()
|
public function testCalculateDistanceForTwoDimensions(): void
|
||||||
{
|
{
|
||||||
$a = [4, 6];
|
$a = [4, 6];
|
||||||
$b = [2, 5];
|
$b = [2, 5];
|
||||||
@ -52,7 +52,7 @@ class ManhattanTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance);
|
$this->assertEquals($expectedDistance, $actualDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForThreeDimensions()
|
public function testCalculateDistanceForThreeDimensions(): void
|
||||||
{
|
{
|
||||||
$a = [6, 10, 3];
|
$a = [6, 10, 3];
|
||||||
$b = [2, 5, 5];
|
$b = [2, 5, 5];
|
||||||
|
@ -14,7 +14,7 @@ class MinkowskiTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
private $distanceMetric;
|
private $distanceMetric;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp(): void
|
||||||
{
|
{
|
||||||
$this->distanceMetric = new Minkowski();
|
$this->distanceMetric = new Minkowski();
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ class MinkowskiTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidArguments()
|
public function testThrowExceptionOnInvalidArguments(): void
|
||||||
{
|
{
|
||||||
$a = [0, 1, 2];
|
$a = [0, 1, 2];
|
||||||
$b = [0, 2];
|
$b = [0, 2];
|
||||||
@ -30,7 +30,7 @@ class MinkowskiTest extends TestCase
|
|||||||
$this->distanceMetric->distance($a, $b);
|
$this->distanceMetric->distance($a, $b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForOneDimension()
|
public function testCalculateDistanceForOneDimension(): void
|
||||||
{
|
{
|
||||||
$a = [4];
|
$a = [4];
|
||||||
$b = [2];
|
$b = [2];
|
||||||
@ -41,7 +41,7 @@ class MinkowskiTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance);
|
$this->assertEquals($expectedDistance, $actualDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForTwoDimensions()
|
public function testCalculateDistanceForTwoDimensions(): void
|
||||||
{
|
{
|
||||||
$a = [4, 6];
|
$a = [4, 6];
|
||||||
$b = [2, 5];
|
$b = [2, 5];
|
||||||
@ -52,7 +52,7 @@ class MinkowskiTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
|
$this->assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForThreeDimensions()
|
public function testCalculateDistanceForThreeDimensions(): void
|
||||||
{
|
{
|
||||||
$a = [6, 10, 3];
|
$a = [6, 10, 3];
|
||||||
$b = [2, 5, 5];
|
$b = [2, 5, 5];
|
||||||
@ -63,7 +63,7 @@ class MinkowskiTest extends TestCase
|
|||||||
$this->assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
|
$this->assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateDistanceForThreeDimensionsWithDifferentLambda()
|
public function testCalculateDistanceForThreeDimensionsWithDifferentLambda(): void
|
||||||
{
|
{
|
||||||
$distanceMetric = new Minkowski($lambda = 5);
|
$distanceMetric = new Minkowski($lambda = 5);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class RBFTest extends TestCase
|
class RBFTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testComputeRBFKernelFunction()
|
public function testComputeRBFKernelFunction(): void
|
||||||
{
|
{
|
||||||
$rbf = new RBF($gamma = 0.001);
|
$rbf = new RBF($gamma = 0.001);
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class EigenDecompositionTest extends TestCase
|
class EigenDecompositionTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testSymmetricMatrixEigenPairs()
|
public function testSymmetricMatrixEigenPairs(): void
|
||||||
{
|
{
|
||||||
// Acceptable error
|
// Acceptable error
|
||||||
$epsilon = 0.001;
|
$epsilon = 0.001;
|
||||||
|
@ -12,12 +12,12 @@ class MatrixTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidMatrixSupplied()
|
public function testThrowExceptionOnInvalidMatrixSupplied(): void
|
||||||
{
|
{
|
||||||
new Matrix([[1, 2], [3]]);
|
new Matrix([[1, 2], [3]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCreateMatrixFromFlatArray()
|
public function testCreateMatrixFromFlatArray(): void
|
||||||
{
|
{
|
||||||
$flatArray = [1, 2, 3, 4];
|
$flatArray = [1, 2, 3, 4];
|
||||||
$matrix = Matrix::fromFlatArray($flatArray);
|
$matrix = Matrix::fromFlatArray($flatArray);
|
||||||
@ -32,7 +32,7 @@ class MatrixTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\MatrixException
|
* @expectedException \Phpml\Exception\MatrixException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidColumnNumber()
|
public function testThrowExceptionOnInvalidColumnNumber(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
$matrix = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
||||||
$matrix->getColumnValues(4);
|
$matrix->getColumnValues(4);
|
||||||
@ -41,13 +41,13 @@ class MatrixTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\MatrixException
|
* @expectedException \Phpml\Exception\MatrixException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnGetDeterminantIfArrayIsNotSquare()
|
public function testThrowExceptionOnGetDeterminantIfArrayIsNotSquare(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
$matrix = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
||||||
$matrix->getDeterminant();
|
$matrix->getDeterminant();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetMatrixDeterminant()
|
public function testGetMatrixDeterminant(): void
|
||||||
{
|
{
|
||||||
//http://matrix.reshish.com/determinant.php
|
//http://matrix.reshish.com/determinant.php
|
||||||
$matrix = new Matrix([
|
$matrix = new Matrix([
|
||||||
@ -68,7 +68,7 @@ class MatrixTest extends TestCase
|
|||||||
$this->assertEquals(1116.5035, $matrix->getDeterminant(), '', $delta = 0.0001);
|
$this->assertEquals(1116.5035, $matrix->getDeterminant(), '', $delta = 0.0001);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMatrixTranspose()
|
public function testMatrixTranspose(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([
|
$matrix = new Matrix([
|
||||||
[3, 3, 3],
|
[3, 3, 3],
|
||||||
@ -88,7 +88,7 @@ class MatrixTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnMultiplyWhenInconsistentMatrixSupplied()
|
public function testThrowExceptionOnMultiplyWhenInconsistentMatrixSupplied(): void
|
||||||
{
|
{
|
||||||
$matrix1 = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
$matrix1 = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
||||||
$matrix2 = new Matrix([[3, 2, 1], [6, 5, 4]]);
|
$matrix2 = new Matrix([[3, 2, 1], [6, 5, 4]]);
|
||||||
@ -96,7 +96,7 @@ class MatrixTest extends TestCase
|
|||||||
$matrix1->multiply($matrix2);
|
$matrix1->multiply($matrix2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMatrixMultiplyByMatrix()
|
public function testMatrixMultiplyByMatrix(): void
|
||||||
{
|
{
|
||||||
$matrix1 = new Matrix([
|
$matrix1 = new Matrix([
|
||||||
[1, 2, 3],
|
[1, 2, 3],
|
||||||
@ -117,7 +117,7 @@ class MatrixTest extends TestCase
|
|||||||
$this->assertEquals($product, $matrix1->multiply($matrix2)->toArray());
|
$this->assertEquals($product, $matrix1->multiply($matrix2)->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDivideByScalar()
|
public function testDivideByScalar(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([
|
$matrix = new Matrix([
|
||||||
[4, 6, 8],
|
[4, 6, 8],
|
||||||
@ -135,7 +135,7 @@ class MatrixTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\MatrixException
|
* @expectedException \Phpml\Exception\MatrixException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionWhenInverseIfArrayIsNotSquare()
|
public function testThrowExceptionWhenInverseIfArrayIsNotSquare(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
$matrix = new Matrix([[1, 2, 3], [4, 5, 6]]);
|
||||||
$matrix->inverse();
|
$matrix->inverse();
|
||||||
@ -144,7 +144,7 @@ class MatrixTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\MatrixException
|
* @expectedException \Phpml\Exception\MatrixException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionWhenInverseIfMatrixIsSingular()
|
public function testThrowExceptionWhenInverseIfMatrixIsSingular(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([
|
$matrix = new Matrix([
|
||||||
[0, 0, 0],
|
[0, 0, 0],
|
||||||
@ -155,7 +155,7 @@ class MatrixTest extends TestCase
|
|||||||
$matrix->inverse();
|
$matrix->inverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testInverseMatrix()
|
public function testInverseMatrix(): void
|
||||||
{
|
{
|
||||||
//http://ncalculators.com/matrix/inverse-matrix.htm
|
//http://ncalculators.com/matrix/inverse-matrix.htm
|
||||||
$matrix = new Matrix([
|
$matrix = new Matrix([
|
||||||
@ -173,7 +173,7 @@ class MatrixTest extends TestCase
|
|||||||
$this->assertEquals($inverseMatrix, $matrix->inverse()->toArray(), '', $delta = 0.0001);
|
$this->assertEquals($inverseMatrix, $matrix->inverse()->toArray(), '', $delta = 0.0001);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCrossOutMatrix()
|
public function testCrossOutMatrix(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([
|
$matrix = new Matrix([
|
||||||
[3, 4, 2],
|
[3, 4, 2],
|
||||||
@ -189,14 +189,14 @@ class MatrixTest extends TestCase
|
|||||||
$this->assertEquals($crossOuted, $matrix->crossOut(1, 1)->toArray());
|
$this->assertEquals($crossOuted, $matrix->crossOut(1, 1)->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testToScalar()
|
public function testToScalar(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([[1, 2, 3], [3, 2, 3]]);
|
$matrix = new Matrix([[1, 2, 3], [3, 2, 3]]);
|
||||||
|
|
||||||
$this->assertEquals($matrix->toScalar(), 1);
|
$this->assertEquals($matrix->toScalar(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMultiplyByScalar()
|
public function testMultiplyByScalar(): void
|
||||||
{
|
{
|
||||||
$matrix = new Matrix([
|
$matrix = new Matrix([
|
||||||
[4, 6, 8],
|
[4, 6, 8],
|
||||||
@ -211,7 +211,7 @@ class MatrixTest extends TestCase
|
|||||||
$this->assertEquals($result, $matrix->multiplyByScalar(-2)->toArray());
|
$this->assertEquals($result, $matrix->multiplyByScalar(-2)->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAdd()
|
public function testAdd(): void
|
||||||
{
|
{
|
||||||
$array1 = [1, 1, 1];
|
$array1 = [1, 1, 1];
|
||||||
$array2 = [2, 2, 2];
|
$array2 = [2, 2, 2];
|
||||||
@ -223,7 +223,7 @@ class MatrixTest extends TestCase
|
|||||||
$this->assertEquals($result, $m1->add($m2)->toArray()[0]);
|
$this->assertEquals($result, $m1->add($m2)->toArray()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSubtract()
|
public function testSubtract(): void
|
||||||
{
|
{
|
||||||
$array1 = [1, 1, 1];
|
$array1 = [1, 1, 1];
|
||||||
$array2 = [2, 2, 2];
|
$array2 = [2, 2, 2];
|
||||||
@ -235,7 +235,7 @@ class MatrixTest extends TestCase
|
|||||||
$this->assertEquals($result, $m1->subtract($m2)->toArray()[0]);
|
$this->assertEquals($result, $m1->subtract($m2)->toArray()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testTransposeArray()
|
public function testTransposeArray(): void
|
||||||
{
|
{
|
||||||
$array = [
|
$array = [
|
||||||
[1, 1, 1],
|
[1, 1, 1],
|
||||||
@ -250,7 +250,7 @@ class MatrixTest extends TestCase
|
|||||||
$this->assertEquals($transposed, Matrix::transposeArray($array));
|
$this->assertEquals($transposed, Matrix::transposeArray($array));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDot()
|
public function testDot(): void
|
||||||
{
|
{
|
||||||
$vect1 = [2, 2, 2];
|
$vect1 = [2, 2, 2];
|
||||||
$vect2 = [3, 3, 3];
|
$vect2 = [3, 3, 3];
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class ProductTest extends TestCase
|
class ProductTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testScalarProduct()
|
public function testScalarProduct(): void
|
||||||
{
|
{
|
||||||
$this->assertEquals(10, Product::scalar([2, 3], [-1, 4]));
|
$this->assertEquals(10, Product::scalar([2, 3], [-1, 4]));
|
||||||
$this->assertEquals(-0.1, Product::scalar([1, 4, 1], [-2, 0.5, -0.1]));
|
$this->assertEquals(-0.1, Product::scalar([1, 4, 1], [-2, 0.5, -0.1]));
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class SetTest extends TestCase
|
class SetTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testUnion()
|
public function testUnion(): void
|
||||||
{
|
{
|
||||||
$union = Set::union(new Set([3, 1]), new Set([3, 2, 2]));
|
$union = Set::union(new Set([3, 1]), new Set([3, 2, 2]));
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ class SetTest extends TestCase
|
|||||||
$this->assertEquals(3, $union->cardinality());
|
$this->assertEquals(3, $union->cardinality());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIntersection()
|
public function testIntersection(): void
|
||||||
{
|
{
|
||||||
$intersection = Set::intersection(new Set(['C', 'A']), new Set(['B', 'C']));
|
$intersection = Set::intersection(new Set(['C', 'A']), new Set(['B', 'C']));
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ class SetTest extends TestCase
|
|||||||
$this->assertEquals(1, $intersection->cardinality());
|
$this->assertEquals(1, $intersection->cardinality());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testDifference()
|
public function testDifference(): void
|
||||||
{
|
{
|
||||||
$difference = Set::difference(new Set(['C', 'A', 'B']), new Set(['A']));
|
$difference = Set::difference(new Set(['C', 'A', 'B']), new Set(['A']));
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ class SetTest extends TestCase
|
|||||||
$this->assertEquals(2, $difference->cardinality());
|
$this->assertEquals(2, $difference->cardinality());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPower()
|
public function testPower(): void
|
||||||
{
|
{
|
||||||
$power = Set::power(new Set(['A', 'B']));
|
$power = Set::power(new Set(['A', 'B']));
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ class SetTest extends TestCase
|
|||||||
$this->assertCount(4, $power);
|
$this->assertCount(4, $power);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCartesian()
|
public function testCartesian(): void
|
||||||
{
|
{
|
||||||
$cartesian = Set::cartesian(new Set(['A']), new Set([1, 2]));
|
$cartesian = Set::cartesian(new Set(['A']), new Set([1, 2]));
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ class SetTest extends TestCase
|
|||||||
$this->assertCount(2, $cartesian);
|
$this->assertCount(2, $cartesian);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testContains()
|
public function testContains(): void
|
||||||
{
|
{
|
||||||
$set = new Set(['B', 'A', 2, 1]);
|
$set = new Set(['B', 'A', 2, 1]);
|
||||||
|
|
||||||
@ -65,21 +65,21 @@ class SetTest extends TestCase
|
|||||||
$this->assertFalse($set->containsAll(['A', 'B', 'C']));
|
$this->assertFalse($set->containsAll(['A', 'B', 'C']));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testRemove()
|
public function testRemove(): void
|
||||||
{
|
{
|
||||||
$set = new Set(['B', 'A', 2, 1]);
|
$set = new Set(['B', 'A', 2, 1]);
|
||||||
|
|
||||||
$this->assertEquals((new Set([1, 2, 2, 2, 'B']))->toArray(), $set->remove('A')->toArray());
|
$this->assertEquals((new Set([1, 2, 2, 2, 'B']))->toArray(), $set->remove('A')->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAdd()
|
public function testAdd(): void
|
||||||
{
|
{
|
||||||
$set = new Set(['B', 'A', 2, 1]);
|
$set = new Set(['B', 'A', 2, 1]);
|
||||||
$set->addAll(['foo', 'bar']);
|
$set->addAll(['foo', 'bar']);
|
||||||
$this->assertEquals(6, $set->cardinality());
|
$this->assertEquals(6, $set->cardinality());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEmpty()
|
public function testEmpty(): void
|
||||||
{
|
{
|
||||||
$set = new Set([1, 2]);
|
$set = new Set([1, 2]);
|
||||||
$set->removeAll([2, 1]);
|
$set->removeAll([2, 1]);
|
||||||
@ -87,7 +87,7 @@ class SetTest extends TestCase
|
|||||||
$this->assertTrue($set->isEmpty());
|
$this->assertTrue($set->isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testToArray()
|
public function testToArray(): void
|
||||||
{
|
{
|
||||||
$set = new Set([1, 2, 2, 3, 'A', false, '', 1.1, -1, -10, 'B']);
|
$set = new Set([1, 2, 2, 3, 'A', false, '', 1.1, -1, -10, 'B']);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class CorrelationTest extends TestCase
|
class CorrelationTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testPearsonCorrelation()
|
public function testPearsonCorrelation(): void
|
||||||
{
|
{
|
||||||
//http://www.stat.wmich.edu/s216/book/node126.html
|
//http://www.stat.wmich.edu/s216/book/node126.html
|
||||||
$delta = 0.001;
|
$delta = 0.001;
|
||||||
@ -32,7 +32,7 @@ class CorrelationTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* @expectedException \Phpml\Exception\InvalidArgumentException
|
* @expectedException \Phpml\Exception\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function testThrowExceptionOnInvalidArgumentsForPearsonCorrelation()
|
public function testThrowExceptionOnInvalidArgumentsForPearsonCorrelation(): void
|
||||||
{
|
{
|
||||||
Correlation::pearson([1, 2, 4], [3, 5]);
|
Correlation::pearson([1, 2, 4], [3, 5]);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class CovarianceTest extends TestCase
|
class CovarianceTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testSimpleCovariance()
|
public function testSimpleCovariance(): void
|
||||||
{
|
{
|
||||||
// Acceptable error
|
// Acceptable error
|
||||||
$epsilon = 0.001;
|
$epsilon = 0.001;
|
||||||
|
@ -9,7 +9,7 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class GaussianTest extends TestCase
|
class GaussianTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testPdf()
|
public function testPdf(): void
|
||||||
{
|
{
|
||||||
$std = 1.0;
|
$std = 1.0;
|
||||||
$mean = 0.0;
|
$mean = 0.0;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user