[coding standard] fix imports order and drop unused docs typehints (#145)

* fix imports order

* drop unused docs typehints, make use of return types where possible
This commit is contained in:
Tomáš Votruba 2017-11-06 08:56:37 +01:00 committed by Arkadiusz Kondas
parent a0772658bf
commit f4650c696c
106 changed files with 302 additions and 1734 deletions

View File

@ -94,7 +94,7 @@ class CustomDistance implements Distance
*
* @return float
*/
public function distance(array $a, array $b): float
public function distance(array $a, array $b) : float
{
$distance = [];
$count = count($a);

View File

@ -49,9 +49,6 @@ class Apriori implements Associator
/**
* Apriori constructor.
*
* @param float $support
* @param float $confidence
*/
public function __construct(float $support = 0.0, float $confidence = 0.0)
{
@ -261,8 +258,6 @@ class Apriori implements Associator
*
* @param mixed[] $set
* @param mixed[] $subset
*
* @return float
*/
private function confidence(array $set, array $subset) : float
{
@ -276,8 +271,6 @@ class Apriori implements Associator
* @see \Phpml\Association\Apriori::samples
*
* @param mixed[] $sample
*
* @return float
*/
private function support(array $sample) : float
{
@ -290,8 +283,6 @@ class Apriori implements Associator
* @see \Phpml\Association\Apriori::samples
*
* @param mixed[] $sample
*
* @return int
*/
private function frequency(array $sample) : int
{
@ -307,8 +298,6 @@ class Apriori implements Associator
*
* @param mixed[][] $system
* @param mixed[] $set
*
* @return bool
*/
private function contains(array $system, array $set) : bool
{
@ -322,8 +311,6 @@ class Apriori implements Associator
*
* @param mixed[] $set
* @param mixed[] $subset
*
* @return bool
*/
private function subset(array $set, array $subset) : bool
{
@ -335,8 +322,6 @@ class Apriori implements Associator
*
* @param mixed[] $set1
* @param mixed[] $set2
*
* @return bool
*/
private function equals(array $set1, array $set2) : bool
{

View File

@ -4,11 +4,11 @@ declare(strict_types=1);
namespace Phpml\Classification;
use Phpml\Classification\DecisionTree\DecisionTreeLeaf;
use Phpml\Exception\InvalidArgumentException;
use Phpml\Helper\Predictable;
use Phpml\Helper\Trainable;
use Phpml\Math\Statistic\Mean;
use Phpml\Classification\DecisionTree\DecisionTreeLeaf;
class DecisionTree implements Classifier
{
@ -63,14 +63,10 @@ class DecisionTree implements Classifier
private $featureImportances = null;
/**
*
* @var array
*/
private $columnNames = null;
/**
* @param int $maxDepth
*/
public function __construct(int $maxDepth = 10)
{
$this->maxDepth = $maxDepth;
@ -129,8 +125,6 @@ class DecisionTree implements Classifier
/**
* @param array $records
* @param int $depth
*
* @return DecisionTreeLeaf
*/
protected function getSplitLeaf(array $records, int $depth = 0) : DecisionTreeLeaf
{
@ -190,11 +184,6 @@ class DecisionTree implements Classifier
return $split;
}
/**
* @param array $records
*
* @return DecisionTreeLeaf
*/
protected function getBestSplit(array $records) : DecisionTreeLeaf
{
$targets = array_intersect_key($this->targets, array_flip($records));
@ -277,10 +266,6 @@ class DecisionTree implements Classifier
/**
* @param mixed $baseValue
* @param array $colValues
* @param array $targets
*
* @return float
*/
public function getGiniIndex($baseValue, array $colValues, array $targets) : float
{
@ -342,8 +327,6 @@ class DecisionTree implements Classifier
/**
* @param array $columnValues
*
* @return bool
*/
protected static function isCategoricalColumn(array $columnValues) : bool
{
@ -376,8 +359,6 @@ class DecisionTree implements Classifier
* otherwise the given value will be used as a maximum for number of columns
* randomly selected for each split operation.
*
* @param int $numFeatures
*
* @return $this
*
* @throws InvalidArgumentException
@ -395,8 +376,6 @@ class DecisionTree implements Classifier
/**
* Used to set predefined features to consider while deciding which column to use for a split
*
* @param array $selectedFeatures
*/
protected function setSelectedFeatures(array $selectedFeatures)
{
@ -407,8 +386,6 @@ class DecisionTree implements Classifier
* A string array to represent columns. Useful when HTML output or
* column importances are desired to be inspected.
*
* @param array $names
*
* @return $this
*
* @throws InvalidArgumentException
@ -424,10 +401,7 @@ class DecisionTree implements Classifier
return $this;
}
/**
* @return string
*/
public function getHtml()
public function getHtml() : string
{
return $this->tree->getHTML($this->columnNames);
}
@ -436,10 +410,8 @@ class DecisionTree implements Classifier
* This will return an array including an importance value for
* each column in the given dataset. The importance values are
* normalized and their total makes 1.<br/>
*
* @return array
*/
public function getFeatureImportances()
public function getFeatureImportances() : array
{
if ($this->featureImportances !== null) {
return $this->featureImportances;
@ -473,11 +445,6 @@ class DecisionTree implements Classifier
/**
* Collects and returns an array of internal nodes that use the given
* column as a split criterion
*
* @param int $column
* @param DecisionTreeLeaf $node
*
* @return array
*/
protected function getSplitNodesByColumn(int $column, DecisionTreeLeaf $node) : array
{
@ -506,8 +473,6 @@ class DecisionTree implements Classifier
}
/**
* @param array $sample
*
* @return mixed
*/
protected function predictSample(array $sample)

View File

@ -71,31 +71,22 @@ class DecisionTreeLeaf
*/
public $level = 0;
/**
* @param array $record
*
* @return bool
*/
public function evaluate($record)
public function evaluate(array $record) : bool
{
$recordField = $record[$this->columnIndex];
if ($this->isContinuous) {
return Comparison::compare((string) $recordField, $this->numericValue, $this->operator);
}
return $recordField == $this->value;
}
/**
* Returns Mean Decrease Impurity (MDI) in the node.
* For terminal nodes, this value is equal to 0
*
* @param int $parentRecordCount
*
* @return float
*/
public function getNodeImpurityDecrease(int $parentRecordCount)
public function getNodeImpurityDecrease(int $parentRecordCount) : float
{
if ($this->isTerminal) {
return 0.0;
@ -119,12 +110,8 @@ class DecisionTreeLeaf
/**
* Returns HTML representation of the node including children nodes
*
* @param $columnNames
*
* @return string
*/
public function getHTML($columnNames = null)
public function getHTML($columnNames = null) : string
{
if ($this->isTerminal) {
$value = "<b>$this->classValue</b>";
@ -170,10 +157,8 @@ class DecisionTreeLeaf
/**
* HTML representation of the tree without column names
*
* @return string
*/
public function __toString()
public function __toString() : string
{
return $this->getHTML();
}

View File

@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Phpml\Classification\Ensemble;
use Phpml\Classification\Classifier;
use Phpml\Classification\Linear\DecisionStump;
use Phpml\Classification\WeightedClassifier;
use Phpml\Math\Statistic\Mean;
use Phpml\Math\Statistic\StandardDeviation;
use Phpml\Classification\Classifier;
use Phpml\Helper\Predictable;
use Phpml\Helper\Trainable;
use Phpml\Math\Statistic\Mean;
use Phpml\Math\Statistic\StandardDeviation;
class AdaBoost implements Classifier
{
@ -75,8 +75,6 @@ class AdaBoost implements Classifier
* ADAptive BOOSTing (AdaBoost) is an ensemble algorithm to
* improve classification performance of 'weak' classifiers such as
* DecisionStump (default base classifier of AdaBoost).
*
* @param int $maxIterations
*/
public function __construct(int $maxIterations = 50)
{
@ -85,9 +83,6 @@ class AdaBoost implements Classifier
/**
* Sets the base classifier that will be used for boosting (default = DecisionStump)
*
* @param string $baseClassifier
* @param array $classifierOptions
*/
public function setBaseClassifier(string $baseClassifier = DecisionStump::class, array $classifierOptions = [])
{
@ -96,9 +91,6 @@ class AdaBoost implements Classifier
}
/**
* @param array $samples
* @param array $targets
*
* @throws \Exception
*/
public function train(array $samples, array $targets)
@ -143,10 +135,8 @@ class AdaBoost implements Classifier
/**
* Returns the classifier with the lowest error rate with the
* consideration of current sample weights
*
* @return Classifier
*/
protected function getBestClassifier()
protected function getBestClassifier() : Classifier
{
$ref = new \ReflectionClass($this->baseClassifier);
if ($this->classifierOptions) {
@ -169,10 +159,8 @@ class AdaBoost implements Classifier
/**
* Resamples the dataset in accordance with the weights and
* returns the new dataset
*
* @return array
*/
protected function resample()
protected function resample() : array
{
$weights = $this->weights;
$std = StandardDeviation::population($weights);
@ -198,12 +186,8 @@ class AdaBoost implements Classifier
/**
* Evaluates the classifier and returns the classification error rate
*
* @param Classifier $classifier
*
* @return float
*/
protected function evaluateClassifier(Classifier $classifier)
protected function evaluateClassifier(Classifier $classifier) : float
{
$total = (float) array_sum($this->weights);
$wrong = 0;
@ -219,12 +203,8 @@ class AdaBoost implements Classifier
/**
* Calculates alpha of a classifier
*
* @param float $errorRate
*
* @return float
*/
protected function calculateAlpha(float $errorRate)
protected function calculateAlpha(float $errorRate) : float
{
if ($errorRate == 0) {
$errorRate = 1e-10;
@ -235,9 +215,6 @@ class AdaBoost implements Classifier
/**
* Updates the sample weights
*
* @param Classifier $classifier
* @param float $alpha
*/
protected function updateWeights(Classifier $classifier, float $alpha)
{
@ -256,8 +233,6 @@ class AdaBoost implements Classifier
}
/**
* @param array $sample
*
* @return mixed
*/
public function predictSample(array $sample)

View File

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Phpml\Classification\Ensemble;
use Phpml\Helper\Predictable;
use Phpml\Helper\Trainable;
use Phpml\Classification\Classifier;
use Phpml\Classification\DecisionTree;
use Phpml\Helper\Predictable;
use Phpml\Helper\Trainable;
class Bagging implements Classifier
{
@ -62,8 +62,6 @@ class Bagging implements Classifier
* Creates an ensemble classifier with given number of base classifiers
* Default number of base classifiers is 50.
* The more number of base classifiers, the better performance but at the cost of procesing time
*
* @param int $numClassifier
*/
public function __construct(int $numClassifier = 50)
{
@ -75,8 +73,6 @@ class Bagging implements Classifier
* e.g., random samples drawn from the original dataset with replacement (allow repeats),
* to train each base classifier.
*
* @param float $ratio
*
* @return $this
*
* @throws \Exception
@ -100,9 +96,6 @@ class Bagging implements Classifier
* given in the order they are in the constructor of the classifier and parameter
* names are neglected.
*
* @param string $classifier
* @param array $classifierOptions
*
* @return $this
*/
public function setClassifer(string $classifier, array $classifierOptions = [])
@ -113,10 +106,6 @@ class Bagging implements Classifier
return $this;
}
/**
* @param array $samples
* @param array $targets
*/
public function train(array $samples, array $targets)
{
$this->samples = array_merge($this->samples, $samples);
@ -134,12 +123,7 @@ class Bagging implements Classifier
}
}
/**
* @param int $index
*
* @return array
*/
protected function getRandomSubset(int $index)
protected function getRandomSubset(int $index) : array
{
$samples = [];
$targets = [];
@ -154,10 +138,7 @@ class Bagging implements Classifier
return [$samples, $targets];
}
/**
* @return array
*/
protected function initClassifiers()
protected function initClassifiers() : array
{
$classifiers = [];
for ($i = 0; $i < $this->numClassifier; ++$i) {
@ -185,8 +166,6 @@ class Bagging implements Classifier
}
/**
* @param array $sample
*
* @return mixed
*/
protected function predictSample(array $sample)

View File

@ -22,8 +22,6 @@ class RandomForest extends Bagging
* Initializes RandomForest with the given number of trees. More trees
* may increase the prediction performance while it will also substantially
* increase the processing time and the required memory
*
* @param int $numClassifier
*/
public function __construct(int $numClassifier = 50)
{
@ -65,9 +63,6 @@ class RandomForest extends Bagging
/**
* RandomForest algorithm is usable *only* with DecisionTree
*
* @param string $classifier
* @param array $classifierOptions
*
* @return $this
*
* @throws \Exception
@ -85,10 +80,8 @@ class RandomForest extends Bagging
* This will return an array including an importance value for
* each column in the given dataset. Importance values for a column
* is the average importance of that column in all trees in the forest
*
* @return array
*/
public function getFeatureImportances()
public function getFeatureImportances() : array
{
// Traverse each tree and sum importance of the columns
$sum = [];
@ -120,8 +113,6 @@ class RandomForest extends Bagging
* A string array to represent the columns is given. They are useful
* when trying to print some information about the trees such as feature importances
*
* @param array $names
*
* @return $this
*/
public function setColumnNames(array $names)

View File

@ -24,7 +24,6 @@ class KNearestNeighbors implements Classifier
private $distanceMetric;
/**
* @param int $k
* @param Distance|null $distanceMetric (if null then Euclidean distance as default)
*/
public function __construct(int $k = 3, Distance $distanceMetric = null)
@ -40,8 +39,6 @@ class KNearestNeighbors implements Classifier
}
/**
* @param array $sample
*
* @return mixed
*/
protected function predictSample(array $sample)
@ -61,13 +58,9 @@ class KNearestNeighbors implements Classifier
}
/**
* @param array $sample
*
* @return array
*
* @throws \Phpml\Exception\InvalidArgumentException
*/
private function kNeighborsDistances(array $sample)
private function kNeighborsDistances(array $sample) : array
{
$distances = [];

View File

@ -32,11 +32,6 @@ class Adaline extends Perceptron
* If normalizeInputs is set to true, then every input given to the algorithm will be standardized
* by use of standard deviation and mean calculation
*
* @param float $learningRate
* @param int $maxIterations
* @param bool $normalizeInputs
* @param int $trainingType
*
* @throws \Exception
*/
public function __construct(
@ -57,8 +52,6 @@ class Adaline extends Perceptron
/**
* Adapts the weights with respect to given samples and targets
* by use of gradient descent learning rule
*
* @param array $samples
* @param array $targets
*/
protected function runTraining(array $samples, array $targets)

View File

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Phpml\Classification\Linear;
use Phpml\Helper\Predictable;
use Phpml\Helper\OneVsRest;
use Phpml\Classification\WeightedClassifier;
use Phpml\Classification\DecisionTree;
use Phpml\Classification\WeightedClassifier;
use Phpml\Helper\OneVsRest;
use Phpml\Helper\Predictable;
use Phpml\Math\Comparison;
class DecisionStump extends WeightedClassifier
@ -77,8 +77,6 @@ class DecisionStump extends WeightedClassifier
* If columnIndex is given, then the stump tries to produce a decision node
* on this column, otherwise in cases given the value of -1, the stump itself
* decides which column to take for the decision (Default DecisionTree behaviour)
*
* @param int $columnIndex
*/
public function __construct(int $columnIndex = self::AUTO_SELECT)
{
@ -86,10 +84,6 @@ class DecisionStump extends WeightedClassifier
}
/**
* @param array $samples
* @param array $targets
* @param array $labels
*
* @throws \Exception
*/
protected function trainBinary(array $samples, array $targets, array $labels)
@ -151,8 +145,6 @@ class DecisionStump extends WeightedClassifier
* values in the column. Given <i>$count</i> value determines how many split
* points to be probed. The more split counts, the better performance but
* worse processing time (Default value is 10.0)
*
* @param float $count
*/
public function setNumericalSplitCount(float $count)
{
@ -161,14 +153,8 @@ class DecisionStump extends WeightedClassifier
/**
* Determines best split point for the given column
*
* @param array $samples
* @param array $targets
* @param int $col
*
* @return array
*/
protected function getBestNumericalSplit(array $samples, array $targets, int $col)
protected function getBestNumericalSplit(array $samples, array $targets, int $col) : array
{
$values = array_column($samples, $col);
// Trying all possible points may be accomplished in two general ways:
@ -207,13 +193,6 @@ class DecisionStump extends WeightedClassifier
return $split;
}
/**
* @param array $samples
* @param array $targets
* @param int $col
*
* @return array
*/
protected function getBestNominalSplit(array $samples, array $targets, int $col) : array
{
$values = array_column($samples, $col);
@ -240,13 +219,6 @@ class DecisionStump extends WeightedClassifier
/**
* Calculates the ratio of wrong predictions based on the new threshold
* value given as the parameter
*
* @param array $targets
* @param float $threshold
* @param string $operator
* @param array $values
*
* @return array
*/
protected function calculateErrorRate(array $targets, float $threshold, string $operator, array $values) : array
{
@ -293,10 +265,7 @@ class DecisionStump extends WeightedClassifier
* Probability of a sample is calculated as the proportion of the label
* within the labels of the training samples in the decision node
*
* @param array $sample
* @param mixed $label
*
* @return float
*/
protected function predictProbability(array $sample, $label) : float
{
@ -309,8 +278,6 @@ class DecisionStump extends WeightedClassifier
}
/**
* @param array $sample
*
* @return mixed
*/
protected function predictSampleBinary(array $sample)
@ -322,17 +289,11 @@ class DecisionStump extends WeightedClassifier
return $this->binaryLabels[1];
}
/**
* @return void
*/
protected function resetBinary()
{
}
/**
* @return string
*/
public function __toString()
public function __toString() : string
{
return "IF $this->column $this->operator $this->value ".
'THEN '.$this->binaryLabels[0].' '.

View File

@ -59,12 +59,6 @@ class LogisticRegression extends Adaline
*
* Penalty (Regularization term) can be 'L2' or empty string to cancel penalty term
*
* @param int $maxIterations
* @param bool $normalizeInputs
* @param int $trainingType
* @param string $cost
* @param string $penalty
*
* @throws \Exception
*/
public function __construct(
@ -102,8 +96,6 @@ class LogisticRegression extends Adaline
/**
* Sets the learning rate if gradient descent algorithm is
* selected for training
*
* @param float $learningRate
*/
public function setLearningRate(float $learningRate)
{
@ -113,8 +105,6 @@ class LogisticRegression extends Adaline
/**
* Lambda (λ) parameter of regularization term. If 0 is given,
* then the regularization term is cancelled
*
* @param float $lambda
*/
public function setLambda(float $lambda)
{
@ -125,9 +115,6 @@ class LogisticRegression extends Adaline
* Adapts the weights with respect to given samples and targets
* by use of selected solver
*
* @param array $samples
* @param array $targets
*
* @throws \Exception
*/
protected function runTraining(array $samples, array $targets)
@ -154,7 +141,6 @@ class LogisticRegression extends Adaline
*
* @param array $samples
* @param array $targets
* @param \Closure $gradientFunc
*/
protected function runConjugateGradient(array $samples, array $targets, \Closure $gradientFunc)
{
@ -170,11 +156,9 @@ class LogisticRegression extends Adaline
/**
* Returns the appropriate callback function for the selected cost function
*
* @return \Closure
*
* @throws \Exception
*/
protected function getCostFunction()
protected function getCostFunction() : \Closure
{
$penalty = 0;
if ($this->penalty == 'L2') {
@ -244,8 +228,6 @@ class LogisticRegression extends Adaline
/**
* Returns the output of the network, a float value between 0.0 and 1.0
*
* @param array $sample
*
* @return float
*/
protected function output(array $sample)
@ -257,12 +239,8 @@ class LogisticRegression extends Adaline
/**
* Returns the class value (either -1 or 1) for the given input
*
* @param array $sample
*
* @return int
*/
protected function outputClass(array $sample)
protected function outputClass(array $sample) : int
{
$output = $this->output($sample);
@ -278,20 +256,17 @@ class LogisticRegression extends Adaline
*
* The probability is simply taken as the distance of the sample
* to the decision plane.
*
* @param array $sample
* @param mixed $label
*
* @return float
*/
protected function predictProbability(array $sample, $label)
protected function predictProbability(array $sample, $label) : float
{
$predicted = $this->predictSampleBinary($sample);
if ((string) $predicted == (string) $label) {
$sample = $this->checkNormalizedSample($sample);
return abs($this->output($sample) - 0.5);
return (float) abs($this->output($sample) - 0.5);
}
return 0.0;

View File

@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Phpml\Classification\Linear;
use Phpml\Helper\Predictable;
use Phpml\Helper\OneVsRest;
use Phpml\Helper\Optimizer\StochasticGD;
use Phpml\Helper\Optimizer\GD;
use Phpml\Classification\Classifier;
use Phpml\Preprocessing\Normalizer;
use Phpml\Helper\OneVsRest;
use Phpml\Helper\Optimizer\GD;
use Phpml\Helper\Optimizer\StochasticGD;
use Phpml\Helper\Predictable;
use Phpml\IncrementalEstimator;
use Phpml\Preprocessing\Normalizer;
class Perceptron implements Classifier, IncrementalEstimator
{
@ -67,7 +67,6 @@ class Perceptron implements Classifier, IncrementalEstimator
*
* @param float $learningRate Value between 0.0(exclusive) and 1.0(inclusive)
* @param int $maxIterations Must be at least 1
* @param bool $normalizeInputs
*
* @throws \Exception
*/
@ -89,21 +88,11 @@ class Perceptron implements Classifier, IncrementalEstimator
$this->maxIterations = $maxIterations;
}
/**
* @param array $samples
* @param array $targets
* @param array $labels
*/
public function partialTrain(array $samples, array $targets, array $labels = [])
{
$this->trainByLabel($samples, $targets, $labels);
}
/**
* @param array $samples
* @param array $targets
* @param array $labels
*/
public function trainBinary(array $samples, array $targets, array $labels)
{
if ($this->normalizer) {
@ -139,8 +128,6 @@ class Perceptron implements Classifier, IncrementalEstimator
* If "false" is given, the optimization procedure will always be executed
* for $maxIterations times
*
* @param bool $enable
*
* @return $this
*/
public function setEarlyStop(bool $enable = true)
@ -152,10 +139,8 @@ class Perceptron implements Classifier, IncrementalEstimator
/**
* Returns the cost values obtained during the training.
*
* @return array
*/
public function getCostValues()
public function getCostValues() : array
{
return $this->costValues;
}
@ -163,9 +148,6 @@ class Perceptron implements Classifier, IncrementalEstimator
/**
* Trains the perceptron model with Stochastic Gradient Descent optimization
* to get the correct set of weights
*
* @param array $samples
* @param array $targets
*/
protected function runTraining(array $samples, array $targets)
{
@ -186,11 +168,6 @@ class Perceptron implements Classifier, IncrementalEstimator
/**
* Executes a Gradient Descent algorithm for
* the given cost function
*
* @param array $samples
* @param array $targets
* @param \Closure $gradientFunc
* @param bool $isBatch
*/
protected function runGradientDescent(array $samples, array $targets, \Closure $gradientFunc, bool $isBatch = false)
{
@ -211,12 +188,8 @@ class Perceptron implements Classifier, IncrementalEstimator
/**
* Checks if the sample should be normalized and if so, returns the
* normalized sample
*
* @param array $sample
*
* @return array
*/
protected function checkNormalizedSample(array $sample)
protected function checkNormalizedSample(array $sample) : array
{
if ($this->normalizer) {
$samples = [$sample];
@ -230,8 +203,6 @@ class Perceptron implements Classifier, IncrementalEstimator
/**
* Calculates net output of the network as a float value for the given input
*
* @param array $sample
*
* @return int
*/
protected function output(array $sample)
@ -250,12 +221,8 @@ class Perceptron implements Classifier, IncrementalEstimator
/**
* Returns the class value (either -1 or 1) for the given input
*
* @param array $sample
*
* @return int
*/
protected function outputClass(array $sample)
protected function outputClass(array $sample) : int
{
return $this->output($sample) > 0 ? 1 : -1;
}
@ -266,27 +233,22 @@ class Perceptron implements Classifier, IncrementalEstimator
* The probability is simply taken as the distance of the sample
* to the decision plane.
*
* @param array $sample
* @param mixed $label
*
* @return float
*/
protected function predictProbability(array $sample, $label)
protected function predictProbability(array $sample, $label) : float
{
$predicted = $this->predictSampleBinary($sample);
if ((string) $predicted == (string) $label) {
$sample = $this->checkNormalizedSample($sample);
return abs($this->output($sample));
return (float) abs($this->output($sample));
}
return 0.0;
}
/**
* @param array $sample
*
* @return mixed
*/
protected function predictSampleBinary(array $sample)

View File

@ -13,10 +13,8 @@ class MLPClassifier extends MultilayerPerceptron implements Classifier
* @param mixed $target
*
* @throws InvalidArgumentException
*
* @return int
*/
public function getTargetClass($target): int
public function getTargetClass($target) : int
{
if (!in_array($target, $this->classes)) {
throw InvalidArgumentException::invalidTarget($target);
@ -26,8 +24,6 @@ class MLPClassifier extends MultilayerPerceptron implements Classifier
}
/**
* @param array $sample
*
* @return mixed
*/
protected function predictSample(array $sample)
@ -47,7 +43,6 @@ class MLPClassifier extends MultilayerPerceptron implements Classifier
}
/**
* @param array $sample
* @param mixed $target
*/
protected function trainSample(array $sample, $target)

View File

@ -57,10 +57,6 @@ class NaiveBayes implements Classifier
*/
private $labels = [];
/**
* @param array $samples
* @param array $targets
*/
public function train(array $samples, array $targets)
{
$this->samples = array_merge($this->samples, $samples);
@ -80,11 +76,8 @@ class NaiveBayes implements Classifier
/**
* Calculates vital statistics for each label & feature. Stores these
* values in private array in order to avoid repeated calculation
*
* @param string $label
* @param array $samples
*/
private function calculateStatistics($label, $samples)
private function calculateStatistics(string $label, array $samples)
{
$this->std[$label] = array_fill(0, $this->featureCount, 0);
$this->mean[$label] = array_fill(0, $this->featureCount, 0);
@ -114,14 +107,8 @@ class NaiveBayes implements Classifier
/**
* Calculates the probability P(label|sample_n)
*
* @param array $sample
* @param int $feature
* @param string $label
*
* @return float
*/
private function sampleProbability($sample, $feature, $label)
private function sampleProbability(array $sample, int $feature, string $label) : float
{
$value = $sample[$feature];
if ($this->dataType[$label][$feature] == self::NOMINAL) {
@ -149,12 +136,8 @@ class NaiveBayes implements Classifier
/**
* Return samples belonging to specific label
*
* @param string $label
*
* @return array
*/
private function getSamplesByLabel($label)
private function getSamplesByLabel(string $label) : array
{
$samples = [];
for ($i = 0; $i < $this->sampleCount; ++$i) {
@ -167,8 +150,6 @@ class NaiveBayes implements Classifier
}
/**
* @param array $sample
*
* @return mixed
*/
protected function predictSample(array $sample)

View File

@ -10,17 +10,6 @@ use Phpml\SupportVectorMachine\Type;
class SVC extends SupportVectorMachine implements Classifier
{
/**
* @param int $kernel
* @param float $cost
* @param int $degree
* @param float|null $gamma
* @param float $coef0
* @param float $tolerance
* @param int $cacheSize
* @param bool $shrinking
* @param bool $probabilityEstimates
*/
public function __construct(
int $kernel = Kernel::LINEAR,
float $cost = 1.0,

View File

@ -6,10 +6,5 @@ namespace Phpml\Clustering;
interface Clusterer
{
/**
* @param array $samples
*
* @return array
*/
public function cluster(array $samples);
public function cluster(array $samples) : array;
}

View File

@ -24,12 +24,7 @@ class DBSCAN implements Clusterer
*/
private $distanceMetric;
/**
* @param float $epsilon
* @param int $minSamples
* @param Distance $distanceMetric
*/
public function __construct($epsilon = 0.5, $minSamples = 3, Distance $distanceMetric = null)
public function __construct(float $epsilon = 0.5, int $minSamples = 3, Distance $distanceMetric = null)
{
if (null === $distanceMetric) {
$distanceMetric = new Euclidean();
@ -40,12 +35,7 @@ class DBSCAN implements Clusterer
$this->distanceMetric = $distanceMetric;
}
/**
* @param array $samples
*
* @return array
*/
public function cluster(array $samples)
public function cluster(array $samples) : array
{
$clusters = [];
$visited = [];
@ -65,13 +55,7 @@ class DBSCAN implements Clusterer
return $clusters;
}
/**
* @param array $localSample
* @param array $samples
*
* @return array
*/
private function getSamplesInRegion($localSample, $samples)
private function getSamplesInRegion(array $localSample, array $samples) : array
{
$region = [];
@ -84,13 +68,7 @@ class DBSCAN implements Clusterer
return $region;
}
/**
* @param array $samples
* @param array $visited
*
* @return array
*/
private function expandCluster($samples, &$visited)
private function expandCluster(array $samples, array &$visited) : array
{
$cluster = [];

View File

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Phpml\Clustering;
use Phpml\Clustering\KMeans\Point;
use Phpml\Clustering\KMeans\Cluster;
use Phpml\Clustering\KMeans\Point;
use Phpml\Clustering\KMeans\Space;
use Phpml\Exception\InvalidArgumentException;
use Phpml\Math\Distance\Euclidean;
@ -58,11 +58,6 @@ class FuzzyCMeans implements Clusterer
private $samples;
/**
* @param int $clustersNumber
* @param float $fuzziness
* @param float $epsilon
* @param int $maxIterations
*
* @throws InvalidArgumentException
*/
public function __construct(int $clustersNumber, float $fuzziness = 2.0, float $epsilon = 1e-2, int $maxIterations = 100)
@ -85,10 +80,6 @@ class FuzzyCMeans implements Clusterer
$this->updateClusters();
}
/**
* @param int $rows
* @param int $cols
*/
protected function generateRandomMembership(int $rows, int $cols)
{
$this->membership = [];
@ -155,14 +146,7 @@ class FuzzyCMeans implements Clusterer
}
}
/**
*
* @param int $row
* @param int $col
*
* @return float
*/
protected function getDistanceCalc(int $row, int $col)
protected function getDistanceCalc(int $row, int $col) : float
{
$sum = 0.0;
$distance = new Euclidean();
@ -204,20 +188,15 @@ class FuzzyCMeans implements Clusterer
return $sum;
}
/**
* @return array
*/
public function getMembershipMatrix()
public function getMembershipMatrix() : array
{
return $this->membership;
}
/**
* @param array|Point[] $samples
*
* @return array
*/
public function cluster(array $samples)
public function cluster(array $samples) : array
{
// Initialize variables, clusters and membership matrix
$this->sampleCount = count($samples);

View File

@ -22,12 +22,6 @@ class KMeans implements Clusterer
*/
private $initialization;
/**
* @param int $clustersNumber
* @param int $initialization
*
* @throws InvalidArgumentException
*/
public function __construct(int $clustersNumber, int $initialization = self::INIT_KMEANS_PLUS_PLUS)
{
if ($clustersNumber <= 0) {
@ -38,12 +32,7 @@ class KMeans implements Clusterer
$this->initialization = $initialization;
}
/**
* @param array $samples
*
* @return array
*/
public function cluster(array $samples)
public function cluster(array $samples) : array
{
$space = new Space(count($samples[0]));
foreach ($samples as $sample) {

View File

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Phpml\Clustering\KMeans;
use IteratorAggregate;
use Countable;
use SplObjectStorage;
use IteratorAggregate;
use LogicException;
use SplObjectStorage;
class Cluster extends Point implements IteratorAggregate, Countable
{
@ -21,10 +21,6 @@ class Cluster extends Point implements IteratorAggregate, Countable
*/
protected $points;
/**
* @param Space $space
* @param array $coordinates
*/
public function __construct(Space $space, array $coordinates)
{
parent::__construct($coordinates);
@ -32,10 +28,7 @@ class Cluster extends Point implements IteratorAggregate, Countable
$this->points = new SplObjectStorage();
}
/**
* @return array
*/
public function getPoints()
public function getPoints() : array
{
$points = [];
foreach ($this->points as $point) {
@ -45,10 +38,7 @@ class Cluster extends Point implements IteratorAggregate, Countable
return $points;
}
/**
* @return array
*/
public function toArray()
public function toArray() : array
{
return [
'centroid' => parent::toArray(),
@ -56,14 +46,7 @@ class Cluster extends Point implements IteratorAggregate, Countable
];
}
/**
* @param Point $point
*
* @return Point
*
* @throws \LogicException
*/
public function attach(Point $point)
public function attach(Point $point) : Point
{
if ($point instanceof self) {
throw new LogicException('cannot attach a cluster to another');
@ -74,29 +57,18 @@ class Cluster extends Point implements IteratorAggregate, Countable
return $point;
}
/**
* @param Point $point
*
* @return Point
*/
public function detach(Point $point)
public function detach(Point $point) : Point
{
$this->points->detach($point);
return $point;
}
/**
* @param SplObjectStorage $points
*/
public function attachAll(SplObjectStorage $points)
{
$this->points->addAll($points);
}
/**
* @param SplObjectStorage $points
*/
public function detachAll(SplObjectStorage $points)
{
$this->points->removeAll($points);
@ -136,10 +108,7 @@ class Cluster extends Point implements IteratorAggregate, Countable
{
return count($this->points);
}
/**
* @param array $newCoordinates
*/
public function setCoordinates(array $newCoordinates)
{
$this->coordinates = $newCoordinates;

View File

@ -18,30 +18,21 @@ class Point implements ArrayAccess
*/
protected $coordinates;
/**
* @param array $coordinates
*/
public function __construct(array $coordinates)
{
$this->dimension = count($coordinates);
$this->coordinates = $coordinates;
}
/**
* @return array
*/
public function toArray()
public function toArray() : array
{
return $this->coordinates;
}
/**
* @param Point $point
* @param bool $precise
*
* @return int|mixed
*/
public function getDistanceWith(self $point, $precise = true)
public function getDistanceWith(self $point, bool $precise = true)
{
$distance = 0;
for ($n = 0; $n < $this->dimension; ++$n) {
@ -53,8 +44,6 @@ class Point implements ArrayAccess
}
/**
* @param array $points
*
* @return mixed
*/
public function getClosest(array $points)
@ -77,20 +66,15 @@ class Point implements ArrayAccess
return $minPoint;
}
/**
* @return array
*/
public function getCoordinates()
public function getCoordinates() : array
{
return $this->coordinates;
}
/**
* @param mixed $offset
*
* @return bool
*/
public function offsetExists($offset)
public function offsetExists($offset): bool
{
return isset($this->coordinates[$offset]);
}

View File

@ -4,10 +4,10 @@ declare(strict_types=1);
namespace Phpml\Clustering\KMeans;
use InvalidArgumentException;
use LogicException;
use Phpml\Clustering\KMeans;
use SplObjectStorage;
use LogicException;
use InvalidArgumentException;
class Space extends SplObjectStorage
{
@ -16,9 +16,6 @@ class Space extends SplObjectStorage
*/
protected $dimension;
/**
* @param $dimension
*/
public function __construct($dimension)
{
if ($dimension < 1) {
@ -28,10 +25,7 @@ class Space extends SplObjectStorage
$this->dimension = $dimension;
}
/**
* @return array
*/
public function toArray()
public function toArray() : array
{
$points = [];
foreach ($this as $point) {
@ -41,12 +35,7 @@ class Space extends SplObjectStorage
return ['points' => $points];
}
/**
* @param array $coordinates
*
* @return Point
*/
public function newPoint(array $coordinates)
public function newPoint(array $coordinates) : Point
{
if (count($coordinates) != $this->dimension) {
throw new LogicException('('.implode(',', $coordinates).') is not a point of this space');
@ -56,7 +45,6 @@ class Space extends SplObjectStorage
}
/**
* @param array $coordinates
* @param null $data
*/
public function addPoint(array $coordinates, $data = null)
@ -77,10 +65,7 @@ class Space extends SplObjectStorage
parent::attach($point, $data);
}
/**
* @return int
*/
public function getDimension()
public function getDimension() : int
{
return $this->dimension;
}
@ -107,13 +92,7 @@ class Space extends SplObjectStorage
return [$min, $max];
}
/**
* @param Point $min
* @param Point $max
*
* @return Point
*/
public function getRandomPoint(Point $min, Point $max)
public function getRandomPoint(Point $min, Point $max) : Point
{
$point = $this->newPoint(array_fill(0, $this->dimension, null));
@ -125,12 +104,9 @@ class Space extends SplObjectStorage
}
/**
* @param int $clustersNumber
* @param int $initMethod
*
* @return array|Cluster[]
*/
public function cluster(int $clustersNumber, int $initMethod = KMeans::INIT_RANDOM)
public function cluster(int $clustersNumber, int $initMethod = KMeans::INIT_RANDOM) : array
{
$clusters = $this->initializeClusters($clustersNumber, $initMethod);
@ -141,12 +117,9 @@ class Space extends SplObjectStorage
}
/**
* @param $clustersNumber
* @param $initMethod
*
* @return array|Cluster[]
*/
protected function initializeClusters(int $clustersNumber, int $initMethod)
protected function initializeClusters(int $clustersNumber, int $initMethod) : array
{
switch ($initMethod) {
case KMeans::INIT_RANDOM:
@ -166,12 +139,7 @@ class Space extends SplObjectStorage
return $clusters;
}
/**
* @param $clusters
*
* @return bool
*/
protected function iterate($clusters)
protected function iterate($clusters) : bool
{
$convergence = true;
@ -209,12 +177,7 @@ class Space extends SplObjectStorage
return $convergence;
}
/**
* @param int $clustersNumber
*
* @return array
*/
private function initializeRandomClusters(int $clustersNumber)
private function initializeRandomClusters(int $clustersNumber) : array
{
$clusters = [];
list($min, $max) = $this->getBoundaries();
@ -226,12 +189,7 @@ class Space extends SplObjectStorage
return $clusters;
}
/**
* @param int $clustersNumber
*
* @return array
*/
protected function initializeKMPPClusters(int $clustersNumber)
protected function initializeKMPPClusters(int $clustersNumber) : array
{
$clusters = [];
$this->rewind();

View File

@ -8,10 +8,6 @@ use Phpml\Dataset\Dataset;
class RandomSplit extends Split
{
/**
* @param Dataset $dataset
* @param float $testSize
*/
protected function splitDataset(Dataset $dataset, float $testSize)
{
$samples = $dataset->getSamples();

View File

@ -29,13 +29,6 @@ abstract class Split
*/
protected $testLabels = [];
/**
* @param Dataset $dataset
* @param float $testSize
* @param int $seed
*
* @throws InvalidArgumentException
*/
public function __construct(Dataset $dataset, float $testSize = 0.3, int $seed = null)
{
if (0 >= $testSize || 1 <= $testSize) {
@ -48,41 +41,26 @@ abstract class Split
abstract protected function splitDataset(Dataset $dataset, float $testSize);
/**
* @return array
*/
public function getTrainSamples()
public function getTrainSamples() : array
{
return $this->trainSamples;
}
/**
* @return array
*/
public function getTestSamples()
public function getTestSamples() : array
{
return $this->testSamples;
}
/**
* @return array
*/
public function getTrainLabels()
public function getTrainLabels() : array
{
return $this->trainLabels;
}
/**
* @return array
*/
public function getTestLabels()
public function getTestLabels() : array
{
return $this->testLabels;
}
/**
* @param int|null $seed
*/
protected function seedGenerator(int $seed = null)
{
if (null === $seed) {

View File

@ -9,10 +9,6 @@ use Phpml\Dataset\Dataset;
class StratifiedRandomSplit extends RandomSplit
{
/**
* @param Dataset $dataset
* @param float $testSize
*/
protected function splitDataset(Dataset $dataset, float $testSize)
{
$datasets = $this->splitByTarget($dataset);
@ -23,11 +19,9 @@ class StratifiedRandomSplit extends RandomSplit
}
/**
* @param Dataset $dataset
*
* @return Dataset[]|array
*/
private function splitByTarget(Dataset $dataset): array
private function splitByTarget(Dataset $dataset) : array
{
$targets = $dataset->getTargets();
$samples = $dataset->getSamples();
@ -44,13 +38,7 @@ class StratifiedRandomSplit extends RandomSplit
return $datasets;
}
/**
* @param array $uniqueTargets
* @param array $split
*
* @return array
*/
private function createDatasets(array $uniqueTargets, array $split): array
private function createDatasets(array $uniqueTargets, array $split) : array
{
$datasets = [];
foreach ($uniqueTargets as $target) {

View File

@ -37,7 +37,7 @@ class ArrayDataset implements Dataset
/**
* @return array
*/
public function getSamples(): array
public function getSamples() : array
{
return $this->samples;
}
@ -45,7 +45,7 @@ class ArrayDataset implements Dataset
/**
* @return array
*/
public function getTargets(): array
public function getTargets() : array
{
return $this->targets;
}

View File

@ -14,12 +14,6 @@ class CsvDataset extends ArrayDataset
protected $columnNames;
/**
* @param string $filepath
* @param int $features
* @param bool $headingRow
* @param string $delimiter
* @param int $maxLineLength
*
* @throws FileException
*/
public function __construct(string $filepath, int $features, bool $headingRow = true, string $delimiter = ',', int $maxLineLength = 0)
@ -50,10 +44,7 @@ class CsvDataset extends ArrayDataset
parent::__construct($samples, $targets);
}
/**
* @return array
*/
public function getColumnNames()
public function getColumnNames() : array
{
return $this->columnNames;
}

View File

@ -9,10 +9,10 @@ interface Dataset
/**
* @return array
*/
public function getSamples(): array;
public function getSamples() : array;
/**
* @return array
*/
public function getTargets(): array;
public function getTargets() : array;
}

View File

@ -8,11 +8,6 @@ use Phpml\Exception\DatasetException;
class FilesDataset extends ArrayDataset
{
/**
* @param string $rootPath
*
* @throws DatasetException
*/
public function __construct(string $rootPath)
{
if (!is_dir($rootPath)) {
@ -22,9 +17,6 @@ class FilesDataset extends ArrayDataset
$this->scanRootPath($rootPath);
}
/**
* @param string $rootPath
*/
private function scanRootPath(string $rootPath)
{
foreach (glob($rootPath.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR) as $dir) {
@ -32,9 +24,6 @@ class FilesDataset extends ArrayDataset
}
}
/**
* @param string $dir
*/
private function scanDir(string $dir)
{
$target = basename($dir);

View File

@ -90,7 +90,7 @@ abstract class EigenTransformerBase
*
* @return array
*/
protected function reduce(array $data)
protected function reduce(array $data) : array
{
$m1 = new Matrix($data);
$m2 = new Matrix($this->eigVectors);

View File

@ -44,14 +44,13 @@ class KernelPCA extends PCA
* will initialize the algorithm with an RBF kernel having the gamma parameter as 15,0. <br>
* This transformation will return the same number of rows with only <i>2</i> columns.
*
* @param int $kernel
* @param float $totalVariance Total variance to be preserved if numFeatures is not given
* @param int $numFeatures Number of columns to be returned
* @param float $gamma Gamma parameter is used with RBF and Sigmoid kernels
*
* @throws \Exception
*/
public function __construct(int $kernel = self::KERNEL_RBF, $totalVariance = null, $numFeatures = null, $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];
if (!in_array($kernel, $availableKernels)) {
@ -69,12 +68,8 @@ class KernelPCA extends PCA
* of this data while preserving $totalVariance or $numFeatures. <br>
* $data is an n-by-m matrix and returned array is
* n-by-k matrix where k <= m
*
* @param array $data
*
* @return array
*/
public function fit(array $data)
public function fit(array $data) : array
{
$numRows = count($data);
$this->data = $data;
@ -96,13 +91,8 @@ class KernelPCA extends PCA
/**
* Calculates similarity matrix by use of selected kernel function<br>
* An n-by-m matrix is given and an n-by-n matrix is returned
*
* @param array $data
* @param int $numRows
*
* @return array
*/
protected function calculateKernelMatrix(array $data, int $numRows)
protected function calculateKernelMatrix(array $data, int $numRows) : array
{
$kernelFunc = $this->getKernel();
@ -125,13 +115,8 @@ class KernelPCA extends PCA
* conversion:
*
* K = K N.K K.N + N.K.N where N is n-by-n matrix filled with 1/n
*
* @param array $matrix
* @param int $n
*
* @return array
*/
protected function centerMatrix(array $matrix, int $n)
protected function centerMatrix(array $matrix, int $n) : array
{
$N = array_fill(0, $n, array_fill(0, $n, 1.0 / $n));
$N = new Matrix($N, false);
@ -153,11 +138,9 @@ class KernelPCA extends PCA
/**
* Returns the callable kernel function
*
* @return \Closure
*
* @throws \Exception
*/
protected function getKernel()
protected function getKernel(): \Closure
{
switch ($this->kernel) {
case self::KERNEL_LINEAR:
@ -194,12 +177,7 @@ class KernelPCA extends PCA
}
}
/**
* @param array $sample
*
* @return array
*/
protected function getDistancePairs(array $sample)
protected function getDistancePairs(array $sample) : array
{
$kernel = $this->getKernel();
@ -211,12 +189,7 @@ class KernelPCA extends PCA
return $pairs;
}
/**
* @param array $pairs
*
* @return array
*/
protected function projectSample(array $pairs)
protected function projectSample(array $pairs) : array
{
// Normalize eigenvectors by eig = eigVectors / eigValues
$func = function ($eigVal, $eigVect) {
@ -235,13 +208,9 @@ class KernelPCA extends PCA
* Transforms the given sample to a lower dimensional vector by using
* the variables obtained during the last run of <code>fit</code>.
*
* @param array $sample
*
* @return array
*
* @throws \Exception
*/
public function transform(array $sample)
public function transform(array $sample) : array
{
if (!$this->fit) {
throw new \Exception('KernelPCA has not been fitted with respect to original dataset, please run KernelPCA::fit() first');

View File

@ -47,7 +47,7 @@ class LDA extends EigenTransformerBase
*
* @throws \Exception
*/
public function __construct($totalVariance = null, $numFeatures = null)
public function __construct(float $totalVariance = null, int $numFeatures = null)
{
if ($totalVariance !== null && ($totalVariance < 0.1 || $totalVariance > 0.99)) {
throw new \Exception('Total variance can be a value between 0.1 and 0.99');
@ -69,11 +69,6 @@ class LDA extends EigenTransformerBase
/**
* Trains the algorithm to transform the given data to a lower dimensional space.
*
* @param array $data
* @param array $classes
*
* @return array
*/
public function fit(array $data, array $classes) : array
{
@ -93,12 +88,8 @@ class LDA extends EigenTransformerBase
/**
* Returns unique labels in the dataset
*
* @param array $classes
*
* @return array
*/
protected function getLabels(array $classes): array
protected function getLabels(array $classes) : array
{
$counts = array_count_values($classes);
@ -108,11 +99,6 @@ class LDA extends EigenTransformerBase
/**
* Calculates mean of each column for each class and returns
* n by m matrix where n is number of labels and m is number of columns
*
* @param array $data
* @param array $classes
*
* @return array
*/
protected function calculateMeans(array $data, array $classes) : array
{
@ -159,13 +145,8 @@ class LDA extends EigenTransformerBase
* Returns in-class scatter matrix for each class, which
* is a n by m matrix where n is number of classes and
* m is number of columns
*
* @param array $data
* @param array $classes
*
* @return Matrix
*/
protected function calculateClassVar($data, $classes)
protected function calculateClassVar(array $data, array $classes) : Matrix
{
// s is an n (number of classes) by m (number of column) matrix
$s = array_fill(0, count($data[0]), array_fill(0, count($data[0]), 0));
@ -187,10 +168,8 @@ class LDA extends EigenTransformerBase
* Returns between-class scatter matrix for each class, which
* is an n by m matrix where n is number of classes and
* m is number of columns
*
* @return Matrix
*/
protected function calculateClassCov()
protected function calculateClassCov() : Matrix
{
// s is an n (number of classes) by m (number of column) matrix
$s = array_fill(0, count($this->overallMean), array_fill(0, count($this->overallMean), 0));
@ -207,13 +186,8 @@ class LDA extends EigenTransformerBase
/**
* Returns the result of the calculation (x - m)T.(x - m)
*
* @param array $row
* @param array $means
*
* @return Matrix
*/
protected function calculateVar(array $row, array $means)
protected function calculateVar(array $row, array $means) : Matrix
{
$x = new Matrix($row, false);
$m = new Matrix($means, false);
@ -226,13 +200,9 @@ class LDA extends EigenTransformerBase
* Transforms the given sample to a lower dimensional vector by using
* the eigenVectors obtained in the last run of <code>fit</code>.
*
* @param array $sample
*
* @return array
*
* @throws \Exception
*/
public function transform(array $sample)
public function transform(array $sample) : array
{
if (!$this->fit) {
throw new \Exception('LDA has not been fitted with respect to original dataset, please run LDA::fit() first');

View File

@ -32,7 +32,7 @@ class PCA extends EigenTransformerBase
*
* @throws \Exception
*/
public function __construct($totalVariance = null, $numFeatures = null)
public function __construct(float $totalVariance = null, int $numFeatures = null)
{
if ($totalVariance !== null && ($totalVariance < 0.1 || $totalVariance > 0.99)) {
throw new \Exception('Total variance can be a value between 0.1 and 0.99');
@ -57,12 +57,8 @@ class PCA extends EigenTransformerBase
* of this data while preserving $totalVariance or $numFeatures. <br>
* $data is an n-by-m matrix and returned array is
* n-by-k matrix where k <= m
*
* @param array $data
*
* @return array
*/
public function fit(array $data)
public function fit(array $data) : array
{
$n = count($data[0]);
@ -77,10 +73,6 @@ class PCA extends EigenTransformerBase
return $this->reduce($data);
}
/**
* @param array $data
* @param int $n
*/
protected function calculateMeans(array $data, int $n)
{
// Calculate means for each dimension
@ -94,13 +86,8 @@ class PCA extends EigenTransformerBase
/**
* Normalization of the data includes subtracting mean from
* each dimension therefore dimensions will be centered to zero
*
* @param array $data
* @param int $n
*
* @return array
*/
protected function normalize(array $data, int $n)
protected function normalize(array $data, int $n) : array
{
if (empty($this->means)) {
$this->calculateMeans($data, $n);
@ -120,13 +107,9 @@ class PCA extends EigenTransformerBase
* Transforms the given sample to a lower dimensional vector by using
* the eigenVectors obtained in the last run of <code>fit</code>.
*
* @param array $sample
*
* @return array
*
* @throws \Exception
*/
public function transform(array $sample)
public function transform(array $sample) : array
{
if (!$this->fit) {
throw new \Exception('PCA has not been fitted with respect to original dataset, please run PCA::fit() first');

View File

@ -6,12 +6,7 @@ namespace Phpml\Exception;
class DatasetException extends \Exception
{
/**
* @param string $path
*
* @return DatasetException
*/
public static function missingFolder(string $path)
public static function missingFolder(string $path) : DatasetException
{
return new self(sprintf('Dataset root folder "%s" missing.', $path));
}

View File

@ -6,32 +6,17 @@ namespace Phpml\Exception;
class FileException extends \Exception
{
/**
* @param string $filepath
*
* @return FileException
*/
public static function missingFile(string $filepath)
public static function missingFile(string $filepath) : FileException
{
return new self(sprintf('File "%s" missing.', $filepath));
}
/**
* @param string $filepath
*
* @return FileException
*/
public static function cantOpenFile(string $filepath)
public static function cantOpenFile(string $filepath) : FileException
{
return new self(sprintf('File "%s" can\'t be open.', $filepath));
}
/**
* @param string $filepath
*
* @return FileException
*/
public static function cantSaveFile(string $filepath)
public static function cantSaveFile(string $filepath) : FileException
{
return new self(sprintf('File "%s" can\'t be saved.', $filepath));
}

View File

@ -6,164 +6,95 @@ namespace Phpml\Exception;
class InvalidArgumentException extends \Exception
{
/**
* @return InvalidArgumentException
*/
public static function arraySizeNotMatch()
public static function arraySizeNotMatch() : InvalidArgumentException
{
return new self('Size of given arrays does not match');
}
/**
* @param $name
*
* @return InvalidArgumentException
*/
public static function percentNotInRange($name)
public static function percentNotInRange($name) : InvalidArgumentException
{
return new self(sprintf('%s must be between 0.0 and 1.0', $name));
}
/**
* @return InvalidArgumentException
*/
public static function arrayCantBeEmpty()
public static function arrayCantBeEmpty() : InvalidArgumentException
{
return new self('The array has zero elements');
}
/**
* @param int $minimumSize
*
* @return InvalidArgumentException
*/
public static function arraySizeToSmall($minimumSize = 2)
public static function arraySizeToSmall(int $minimumSize = 2) : InvalidArgumentException
{
return new self(sprintf('The array must have at least %d elements', $minimumSize));
}
/**
* @return InvalidArgumentException
*/
public static function matrixDimensionsDidNotMatch()
public static function matrixDimensionsDidNotMatch() : InvalidArgumentException
{
return new self('Matrix dimensions did not match');
}
/**
* @return InvalidArgumentException
*/
public static function inconsistentMatrixSupplied()
public static function inconsistentMatrixSupplied() : InvalidArgumentException
{
return new self('Inconsistent matrix supplied');
}
/**
* @return InvalidArgumentException
*/
public static function invalidClustersNumber()
public static function invalidClustersNumber() : InvalidArgumentException
{
return new self('Invalid clusters number');
}
/**
* @param mixed $target
*
* @return InvalidArgumentException
*/
public static function invalidTarget($target)
public static function invalidTarget($target) : InvalidArgumentException
{
return new self(sprintf('Target with value "%s" is not part of the accepted classes', $target));
}
/**
* @param string $language
*
* @return InvalidArgumentException
*/
public static function invalidStopWordsLanguage(string $language)
public static function invalidStopWordsLanguage(string $language) : InvalidArgumentException
{
return new self(sprintf('Can\'t find "%s" language for StopWords', $language));
}
/**
* @return InvalidArgumentException
*/
public static function invalidLayerNodeClass()
public static function invalidLayerNodeClass() : InvalidArgumentException
{
return new self('Layer node class must implement Node interface');
}
/**
* @return InvalidArgumentException
*/
public static function invalidLayersNumber()
public static function invalidLayersNumber() : InvalidArgumentException
{
return new self('Provide at least 1 hidden layer');
}
/**
* @return InvalidArgumentException
*/
public static function invalidClassesNumber()
public static function invalidClassesNumber() : InvalidArgumentException
{
return new self('Provide at least 2 different classes');
}
/**
* @return InvalidArgumentException
*/
public static function inconsistentClasses()
public static function inconsistentClasses() : InvalidArgumentException
{
return new self('The provided classes don\'t match the classes provided in the constructor');
}
/**
* @param string $file
*
* @return InvalidArgumentException
*/
public static function fileNotFound(string $file)
public static function fileNotFound(string $file) : InvalidArgumentException
{
return new self(sprintf('File "%s" not found', $file));
}
/**
* @param string $file
*
* @return InvalidArgumentException
*/
public static function fileNotExecutable(string $file)
public static function fileNotExecutable(string $file) : InvalidArgumentException
{
return new self(sprintf('File "%s" is not executable', $file));
}
/**
* @param string $path
*
* @return InvalidArgumentException
*/
public static function pathNotFound(string $path)
public static function pathNotFound(string $path) : InvalidArgumentException
{
return new self(sprintf('The specified path "%s" does not exist', $path));
}
/**
* @param string $path
*
* @return InvalidArgumentException
*/
public static function pathNotWritable(string $path)
public static function pathNotWritable(string $path) : InvalidArgumentException
{
return new self(sprintf('The specified path "%s" is not writable', $path));
}
/**
* @param string $operator
*
* @return InvalidArgumentException
*/
public static function invalidOperator(string $operator)
public static function invalidOperator(string $operator) : InvalidArgumentException
{
return new self(sprintf('Invalid operator "%s" provided', $operator));
}

View File

@ -6,26 +6,17 @@ namespace Phpml\Exception;
class MatrixException extends \Exception
{
/**
* @return MatrixException
*/
public static function notSquareMatrix()
public static function notSquareMatrix() : MatrixException
{
return new self('Matrix is not square matrix');
}
/**
* @return MatrixException
*/
public static function columnOutOfRange()
public static function columnOutOfRange() : MatrixException
{
return new self('Column out of range');
}
/**
* @return MatrixException
*/
public static function singularMatrix()
public static function singularMatrix() : MatrixException
{
return new self('Matrix is singular');
}

View File

@ -6,10 +6,7 @@ namespace Phpml\Exception;
class NormalizerException extends \Exception
{
/**
* @return NormalizerException
*/
public static function unknownNorm()
public static function unknownNorm() : NormalizerException
{
return new self('Unknown norm supplied.');
}

View File

@ -6,22 +6,12 @@ namespace Phpml\Exception;
class SerializeException extends \Exception
{
/**
* @param string $filepath
*
* @return SerializeException
*/
public static function cantUnserialize(string $filepath)
public static function cantUnserialize(string $filepath) : SerializeException
{
return new self(sprintf('"%s" can not be unserialized.', $filepath));
}
/**
* @param string $classname
*
* @return SerializeException
*/
public static function cantSerialize(string $classname)
public static function cantSerialize(string $classname) : SerializeException
{
return new self(sprintf('Class "%s" can not be serialized.', $classname));
}

View File

@ -13,32 +13,17 @@ class StopWords
*/
protected $stopWords;
/**
* @param array $stopWords
*/
public function __construct(array $stopWords)
{
$this->stopWords = array_fill_keys($stopWords, true);
}
/**
* @param string $token
*
* @return bool
*/
public function isStopWord(string $token): bool
public function isStopWord(string $token) : bool
{
return isset($this->stopWords[$token]);
}
/**
* @param string $language
*
* @return StopWords
*
* @throws InvalidArgumentException
*/
public static function factory($language = 'English'): StopWords
public static function factory(string $language = 'English') : StopWords
{
$className = __NAMESPACE__."\\StopWords\\$language";

View File

@ -34,11 +34,6 @@ class TokenCountVectorizer implements Transformer
*/
private $frequencies;
/**
* @param Tokenizer $tokenizer
* @param StopWords $stopWords
* @param float $minDF
*/
public function __construct(Tokenizer $tokenizer, StopWords $stopWords = null, float $minDF = 0.0)
{
$this->tokenizer = $tokenizer;
@ -49,17 +44,11 @@ class TokenCountVectorizer implements Transformer
$this->frequencies = [];
}
/**
* @param array $samples
*/
public function fit(array $samples)
{
$this->buildVocabulary($samples);
}
/**
* @param array $samples
*/
public function transform(array &$samples)
{
foreach ($samples as &$sample) {
@ -69,17 +58,11 @@ class TokenCountVectorizer implements Transformer
$this->checkDocumentFrequency($samples);
}
/**
* @return array
*/
public function getVocabulary()
public function getVocabulary() : array
{
return array_flip($this->vocabulary);
}
/**
* @param array $samples
*/
private function buildVocabulary(array &$samples)
{
foreach ($samples as $index => $sample) {
@ -90,9 +73,6 @@ class TokenCountVectorizer implements Transformer
}
}
/**
* @param string $sample
*/
private function transformSample(string &$sample)
{
$counts = [];
@ -122,8 +102,6 @@ class TokenCountVectorizer implements Transformer
}
/**
* @param string $token
*
* @return int|bool
*/
private function getTokenIndex(string $token)
@ -135,9 +113,6 @@ class TokenCountVectorizer implements Transformer
return $this->vocabulary[$token] ?? false;
}
/**
* @param string $token
*/
private function addTokenToVocabulary(string $token)
{
if ($this->isStopWord($token)) {
@ -149,19 +124,11 @@ class TokenCountVectorizer implements Transformer
}
}
/**
* @param string $token
*
* @return bool
*/
private function isStopWord(string $token): bool
{
return $this->stopWords && $this->stopWords->isStopWord($token);
}
/**
* @param string $token
*/
private function updateFrequency(string $token)
{
if (!isset($this->frequencies[$token])) {
@ -171,9 +138,6 @@ class TokenCountVectorizer implements Transformer
++$this->frequencies[$token];
}
/**
* @param array $samples
*/
private function checkDocumentFrequency(array &$samples)
{
if ($this->minDF > 0) {
@ -184,10 +148,6 @@ class TokenCountVectorizer implements Transformer
}
}
/**
* @param array $sample
* @param array $beyondMinimum
*/
private function resetBeyondMinimum(array &$sample, array $beyondMinimum)
{
foreach ($beyondMinimum as $index) {
@ -195,12 +155,7 @@ class TokenCountVectorizer implements Transformer
}
}
/**
* @param int $samplesCount
*
* @return array
*/
private function getBeyondMinimumIndexes(int $samplesCount)
private function getBeyondMinimumIndexes(int $samplesCount) : array
{
$indexes = [];
foreach ($this->frequencies as $token => $frequency) {

View File

@ -27,9 +27,6 @@ trait OneVsRest
/**
* Train a binary classifier in the OvR style
*
* @param array $samples
* @param array $targets
*/
public function train(array $samples, array $targets)
{
@ -39,13 +36,6 @@ trait OneVsRest
$this->trainBylabel($samples, $targets);
}
/**
* @param array $samples
* @param array $targets
* @param array $allLabels All training set labels
*
* @return void
*/
protected function trainByLabel(array $samples, array $targets, array $allLabels = [])
{
// Overwrites the current value if it exist. $allLabels must be provided for each partialTrain run.
@ -122,12 +112,11 @@ trait OneVsRest
* $targets is not passed by reference nor contains objects so this method
* changes will not affect the caller $targets array.
*
* @param array $targets
* @param mixed $label
*
* @return array Binarized targets and target's labels
*/
private function binarizeTargets($targets, $label)
private function binarizeTargets(array $targets, $label) : array
{
$notLabel = "not_$label";
foreach ($targets as $key => $target) {
@ -140,8 +129,6 @@ trait OneVsRest
}
/**
* @param array $sample
*
* @return mixed
*/
protected function predictSample(array $sample)
@ -163,10 +150,6 @@ trait OneVsRest
/**
* Each classifier should implement this method instead of train(samples, targets)
*
* @param array $samples
* @param array $targets
* @param array $labels
*/
abstract protected function trainBinary(array $samples, array $targets, array $labels);
@ -181,9 +164,6 @@ trait OneVsRest
* Each classifier that make use of OvR approach should be able to
* return a probability for a sample to belong to the given label.
*
* @param array $sample
* @param string $label
*
* @return mixed
*/
abstract protected function predictProbability(array $sample, string $label);
@ -191,8 +171,6 @@ trait OneVsRest
/**
* Each classifier should implement this method instead of predictSample()
*
* @param array $sample
*
* @return mixed
*/
abstract protected function predictSampleBinary(array $sample);

View File

@ -20,11 +20,10 @@ class ConjugateGradient extends GD
/**
* @param array $samples
* @param array $targets
* @param \Closure $gradientCb
*
* @return array
*/
public function runOptimization(array $samples, array $targets, \Closure $gradientCb)
public function runOptimization(array $samples, array $targets, \Closure $gradientCb) : array
{
$this->samples = $samples;
$this->targets = $targets;
@ -65,12 +64,8 @@ class ConjugateGradient extends GD
/**
* Executes the callback function for the problem and returns
* sum of the gradient for all samples & targets.
*
* @param array $theta
*
* @return array
*/
protected function gradient(array $theta)
protected function gradient(array $theta) : array
{
list(, $gradient) = parent::gradient($theta);
@ -79,12 +74,8 @@ class ConjugateGradient extends GD
/**
* Returns the value of f(x) for given solution
*
* @param array $theta
*
* @return float
*/
protected function cost(array $theta)
protected function cost(array $theta) : float
{
list($cost) = parent::gradient($theta);
@ -104,12 +95,8 @@ class ConjugateGradient extends GD
* b) Probe a larger alpha (0.01) and calculate cost function
* b-1) If cost function decreases, continue enlarging alpha
* b-2) If cost function increases, take the midpoint and try again
*
* @param float $d
*
* @return float
*/
protected function getAlpha(float $d)
protected function getAlpha(float $d) : float
{
$small = 0.0001 * $d;
$large = 0.01 * $d;
@ -153,13 +140,8 @@ class ConjugateGradient extends GD
* gradient direction.
*
* θ(k+1) = θ(k) + α.d
*
* @param float $alpha
* @param array $d
*
* @return array
*/
protected function getNewTheta(float $alpha, array $d)
protected function getNewTheta(float $alpha, array $d) : array
{
$theta = $this->theta;
@ -187,12 +169,8 @@ class ConjugateGradient extends GD
*
* See:
* R. Fletcher and C. M. Reeves, "Function minimization by conjugate gradients", Comput. J. 7 (1964), 149154.
*
* @param array $newTheta
*
* @return float
*/
protected function getBeta(array $newTheta)
protected function getBeta(array $newTheta) : float
{
$dNew = array_sum($this->gradient($newTheta));
$dOld = array_sum($this->gradient($this->theta)) + 1e-100;
@ -204,14 +182,8 @@ class ConjugateGradient extends GD
* Calculates the new conjugate direction
*
* d(k+1) =∇f(x(k+1)) + β(k).d(k)
*
* @param array $theta
* @param float $beta
* @param array $d
*
* @return array
*/
protected function getNewDirection(array $theta, float $beta, array $d)
protected function getNewDirection(array $theta, float $beta, array $d) : array
{
$grad = $this->gradient($theta);
@ -227,13 +199,8 @@ class mp
{
/**
* Element-wise <b>multiplication</b> of two vectors of the same size
*
* @param array $m1
* @param array $m2
*
* @return array
*/
public static function mul(array $m1, array $m2)
public static function mul(array $m1, array $m2) : array
{
$res = [];
foreach ($m1 as $i => $val) {
@ -245,13 +212,8 @@ class mp
/**
* Element-wise <b>division</b> of two vectors of the same size
*
* @param array $m1
* @param array $m2
*
* @return array
*/
public static function div(array $m1, array $m2)
public static function div(array $m1, array $m2) : array
{
$res = [];
foreach ($m1 as $i => $val) {
@ -263,14 +225,8 @@ class mp
/**
* Element-wise <b>addition</b> of two vectors of the same size
*
* @param array $m1
* @param array $m2
* @param int $mag
*
* @return array
*/
public static function add(array $m1, array $m2, int $mag = 1)
public static function add(array $m1, array $m2, int $mag = 1) : array
{
$res = [];
foreach ($m1 as $i => $val) {
@ -282,26 +238,16 @@ class mp
/**
* Element-wise <b>subtraction</b> of two vectors of the same size
*
* @param array $m1
* @param array $m2
*
* @return array
*/
public static function sub(array $m1, array $m2)
public static function sub(array $m1, array $m2) : array
{
return self::add($m1, $m2, -1);
}
/**
* Element-wise <b>multiplication</b> of a vector with a scalar
*
* @param array $m1
* @param float $m2
*
* @return array
*/
public static function muls(array $m1, float $m2)
public static function muls(array $m1, float $m2) : array
{
$res = [];
foreach ($m1 as $val) {
@ -313,13 +259,8 @@ class mp
/**
* Element-wise <b>division</b> of a vector with a scalar
*
* @param array $m1
* @param float $m2
*
* @return array
*/
public static function divs(array $m1, float $m2)
public static function divs(array $m1, float $m2) : array
{
$res = [];
foreach ($m1 as $val) {
@ -331,14 +272,8 @@ class mp
/**
* Element-wise <b>addition</b> of a vector with a scalar
*
* @param array $m1
* @param float $m2
* @param int $mag
*
* @return array
*/
public static function adds(array $m1, float $m2, int $mag = 1)
public static function adds(array $m1, float $m2, int $mag = 1) : array
{
$res = [];
foreach ($m1 as $val) {
@ -350,13 +285,8 @@ class mp
/**
* Element-wise <b>subtraction</b> of a vector with a scalar
*
* @param array $m1
* @param float $m2
*
* @return array
*/
public static function subs(array $m1, float $m2)
public static function subs(array $m1, float $m2) : array
{
return self::adds($m1, $m2, -1);
}

View File

@ -17,14 +17,7 @@ class GD extends StochasticGD
*/
protected $sampleCount = null;
/**
* @param array $samples
* @param array $targets
* @param \Closure $gradientCb
*
* @return array
*/
public function runOptimization(array $samples, array $targets, \Closure $gradientCb)
public function runOptimization(array $samples, array $targets, \Closure $gradientCb) : array
{
$this->samples = $samples;
$this->targets = $targets;
@ -57,12 +50,8 @@ class GD extends StochasticGD
/**
* Calculates gradient, cost function and penalty term for each sample
* then returns them as an array of values
*
* @param array $theta
*
* @return array
*/
protected function gradient(array $theta)
protected function gradient(array $theta) : array
{
$costs = [];
$gradient = [];
@ -84,10 +73,6 @@ class GD extends StochasticGD
return [$costs, $gradient, $totalPenalty];
}
/**
* @param array $updates
* @param float $penalty
*/
protected function updateWeightsWithUpdates(array $updates, float $penalty)
{
// Updates all weights at once
@ -110,8 +95,6 @@ class GD extends StochasticGD
/**
* Clears the optimizer internal vars after the optimization process.
*
* @return void
*/
protected function clear()
{

View File

@ -22,8 +22,6 @@ abstract class Optimizer
/**
* Inits a new instance of Optimizer for the given number of dimensions
*
* @param int $dimensions
*/
public function __construct(int $dimensions)
{
@ -39,8 +37,6 @@ abstract class Optimizer
/**
* Sets the weights manually
*
* @param array $theta
*
* @return $this
*
* @throws \Exception
@ -59,10 +55,6 @@ abstract class Optimizer
/**
* Executes the optimization with the given samples & targets
* and returns the weights
*
* @param array $samples
* @param array $targets
* @param \Closure $gradientCb
*/
abstract public function runOptimization(array $samples, array $targets, \Closure $gradientCb);
}

View File

@ -76,8 +76,6 @@ class StochasticGD extends Optimizer
/**
* Initializes the SGD optimizer for the given number of dimensions
*
* @param int $dimensions
*/
public function __construct(int $dimensions)
{
@ -94,8 +92,6 @@ class StochasticGD extends Optimizer
* If change in the theta is less than given value then the
* algorithm will stop training
*
* @param float $threshold
*
* @return $this
*/
public function setChangeThreshold(float $threshold = 1e-5)
@ -109,8 +105,6 @@ class StochasticGD extends Optimizer
* Enable/Disable early stopping by checking at each iteration
* whether changes in theta or cost value are not large enough
*
* @param bool $enable
*
* @return $this
*/
public function setEarlyStop(bool $enable = true)
@ -121,8 +115,6 @@ class StochasticGD extends Optimizer
}
/**
* @param float $learningRate
*
* @return $this
*/
public function setLearningRate(float $learningRate)
@ -133,8 +125,6 @@ class StochasticGD extends Optimizer
}
/**
* @param int $maxIterations
*
* @return $this
*/
public function setMaxIterations(int $maxIterations)
@ -150,14 +140,8 @@ class StochasticGD extends Optimizer
*
* The cost function to minimize and the gradient of the function are to be
* handled by the callback function provided as the third parameter of the method.
*
* @param array $samples
* @param array $targets
* @param \Closure $gradientCb
*
* @return array
*/
public function runOptimization(array $samples, array $targets, \Closure $gradientCb)
public function runOptimization(array $samples, array $targets, \Closure $gradientCb) : array
{
$this->samples = $samples;
$this->targets = $targets;
@ -197,10 +181,7 @@ class StochasticGD extends Optimizer
return $this->theta = $bestTheta;
}
/**
* @return float
*/
protected function updateTheta()
protected function updateTheta() : float
{
$jValue = 0.0;
$theta = $this->theta;
@ -231,12 +212,8 @@ class StochasticGD extends Optimizer
/**
* Checks if the optimization is not effective enough and can be stopped
* in case large enough changes in the solution do not happen
*
* @param array $oldTheta
*
* @return boolean
*/
protected function earlyStop($oldTheta)
protected function earlyStop(array $oldTheta): bool
{
// Check for early stop: No change larger than threshold (default 1e-5)
$diff = array_map(
@ -263,18 +240,14 @@ class StochasticGD extends Optimizer
/**
* Returns the list of cost values for each iteration executed in
* last run of the optimization
*
* @return array
*/
public function getCostValues()
public function getCostValues() : array
{
return $this->costValues;
}
/**
* Clears the optimizer internal vars after the optimization process.
*
* @return void
*/
protected function clear()
{

View File

@ -9,12 +9,6 @@ use Phpml\Exception\InvalidArgumentException;
class Comparison
{
/**
* @param mixed $a
* @param mixed $b
* @param string $operator
*
* @return bool
*
* @throws InvalidArgumentException
*/
public static function compare($a, $b, string $operator): bool

View File

@ -9,8 +9,6 @@ interface Distance
/**
* @param array $a
* @param array $b
*
* @return float
*/
public function distance(array $a, array $b): float;
public function distance(array $a, array $b) : float;
}

View File

@ -10,14 +10,9 @@ use Phpml\Math\Distance;
class Chebyshev implements Distance
{
/**
* @param array $a
* @param array $b
*
* @return float
*
* @throws InvalidArgumentException
*/
public function distance(array $a, array $b): float
public function distance(array $a, array $b) : float
{
if (count($a) !== count($b)) {
throw InvalidArgumentException::arraySizeNotMatch();

View File

@ -10,14 +10,9 @@ use Phpml\Math\Distance;
class Euclidean implements Distance
{
/**
* @param array $a
* @param array $b
*
* @return float
*
* @throws InvalidArgumentException
*/
public function distance(array $a, array $b): float
public function distance(array $a, array $b) : float
{
if (count($a) !== count($b)) {
throw InvalidArgumentException::arraySizeNotMatch();
@ -34,13 +29,8 @@ class Euclidean implements Distance
/**
* Square of Euclidean distance
*
* @param array $a
* @param array $b
*
* @return float
*/
public function sqDistance(array $a, array $b): float
public function sqDistance(array $a, array $b) : float
{
return $this->distance($a, $b) ** 2;
}

View File

@ -10,14 +10,9 @@ use Phpml\Math\Distance;
class Manhattan implements Distance
{
/**
* @param array $a
* @param array $b
*
* @return float
*
* @throws InvalidArgumentException
*/
public function distance(array $a, array $b): float
public function distance(array $a, array $b) : float
{
if (count($a) !== count($b)) {
throw InvalidArgumentException::arraySizeNotMatch();

View File

@ -14,23 +14,15 @@ class Minkowski implements Distance
*/
private $lambda;
/**
* @param float $lambda
*/
public function __construct(float $lambda = 3.0)
{
$this->lambda = $lambda;
}
/**
* @param array $a
* @param array $b
*
* @return float
*
* @throws InvalidArgumentException
*/
public function distance(array $a, array $b): float
public function distance(array $a, array $b) : float
{
if (count($a) !== count($b)) {
throw InvalidArgumentException::arraySizeNotMatch();

View File

@ -14,9 +14,6 @@ class RBF implements Kernel
*/
private $gamma;
/**
* @param float $gamma
*/
public function __construct(float $gamma)
{
$this->gamma = $gamma;
@ -25,8 +22,6 @@ class RBF implements Kernel
/**
* @param array $a
* @param array $b
*
* @return float
*/
public function compute($a, $b)
{

View File

@ -835,7 +835,6 @@ class EigenvalueDecomposition
/**
* Return the eigenvector matrix
*
*
* @return array
*/
public function getEigenvectors()

View File

@ -2,25 +2,25 @@
declare(strict_types=1);
/**
* @package JAMA
* @package JAMA
*
* For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
* unit lower triangular matrix L, an n-by-n upper triangular matrix U,
* and a permutation vector piv of length m so that A(piv,:) = L*U.
* If m < n, then L is m-by-m and U is m-by-n.
* For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
* unit lower triangular matrix L, an n-by-n upper triangular matrix U,
* and a permutation vector piv of length m so that A(piv,:) = L*U.
* If m < n, then L is m-by-m and U is m-by-n.
*
* The LU decompostion with pivoting always exists, even if the matrix is
* singular, so the constructor will never fail. The primary use of the
* LU decomposition is in the solution of square systems of simultaneous
* linear equations. This will fail if isNonsingular() returns false.
* The LU decompostion with pivoting always exists, even if the matrix is
* singular, so the constructor will never fail. The primary use of the
* LU decomposition is in the solution of square systems of simultaneous
* linear equations. This will fail if isNonsingular() returns false.
*
* @author Paul Meagher
* @author Bartosz Matosiuk
* @author Michael Bommarito
* @author Paul Meagher
* @author Bartosz Matosiuk
* @author Michael Bommarito
*
* @version 1.1
* @version 1.1
*
* @license PHP v3.0
* @license PHP v3.0
*
* Slightly changed to adapt the original code to PHP-ML library
* @date 2017/04/24
@ -30,43 +30,43 @@ declare(strict_types=1);
namespace Phpml\Math\LinearAlgebra;
use Phpml\Math\Matrix;
use Phpml\Exception\MatrixException;
use Phpml\Math\Matrix;
class LUDecomposition
{
/**
* Decomposition storage
* Decomposition storage
*
* @var array
* @var array
*/
private $LU = [];
/**
* Row dimension.
* Row dimension.
*
* @var int
* @var int
*/
private $m;
/**
* Column dimension.
* Column dimension.
*
* @var int
* @var int
*/
private $n;
/**
* Pivot sign.
* Pivot sign.
*
* @var int
* @var int
*/
private $pivsign;
/**
* Internal storage of pivot vector.
* Internal storage of pivot vector.
*
* @var array
* @var array
*/
private $piv = [];
@ -142,7 +142,7 @@ class LUDecomposition
*
* @return Matrix Lower triangular factor
*/
public function getL()
public function getL() : Matrix
{
$L = [];
for ($i = 0; $i < $this->m; ++$i) {
@ -165,7 +165,7 @@ class LUDecomposition
*
* @return Matrix Upper triangular factor
*/
public function getU()
public function getU() : Matrix
{
$U = [];
for ($i = 0; $i < $this->n; ++$i) {
@ -186,7 +186,7 @@ class LUDecomposition
*
* @return array Pivot vector
*/
public function getPivot()
public function getPivot() : array
{
return $this->piv;
}
@ -247,7 +247,7 @@ class LUDecomposition
*
* @throws MatrixException
*/
public function solve(Matrix $B)
public function solve(Matrix $B) : array
{
if ($B->getRows() != $this->m) {
throw MatrixException::notSquareMatrix();
@ -283,15 +283,7 @@ class LUDecomposition
return $X;
}
/**
* @param array $matrix
* @param array $RL
* @param int $j0
* @param int $jF
*
* @return array
*/
protected function getSubMatrix(array $matrix, array $RL, int $j0, int $jF)
protected function getSubMatrix(array $matrix, array $RL, int $j0, int $jF) : array
{
$m = count($RL);
$n = $jF - $j0;

View File

@ -4,9 +4,9 @@ declare(strict_types=1);
namespace Phpml\Math;
use Phpml\Math\LinearAlgebra\LUDecomposition;
use Phpml\Exception\InvalidArgumentException;
use Phpml\Exception\MatrixException;
use Phpml\Math\LinearAlgebra\LUDecomposition;
class Matrix
{
@ -31,9 +31,6 @@ class Matrix
private $determinant;
/**
* @param array $matrix
* @param bool $validate
*
* @throws InvalidArgumentException
*/
public function __construct(array $matrix, bool $validate = true)
@ -59,12 +56,7 @@ class Matrix
$this->matrix = $matrix;
}
/**
* @param array $array
*
* @return Matrix
*/
public static function fromFlatArray(array $array)
public static function fromFlatArray(array $array) : Matrix
{
$matrix = [];
foreach ($array as $value) {
@ -74,46 +66,30 @@ class Matrix
return new self($matrix);
}
/**
* @return array
*/
public function toArray()
public function toArray() : array
{
return $this->matrix;
}
/**
* @return float
*/
public function toScalar()
public function toScalar() : float
{
return $this->matrix[0][0];
}
/**
* @return int
*/
public function getRows()
public function getRows(): int
{
return $this->rows;
}
/**
* @return int
*/
public function getColumns()
public function getColumns(): int
{
return $this->columns;
}
/**
* @param $column
*
* @return array
*
* @throws MatrixException
*/
public function getColumnValues($column)
public function getColumnValues($column) : array
{
if ($column >= $this->columns) {
throw MatrixException::columnOutOfRange();
@ -142,18 +118,12 @@ class Matrix
return $this->determinant = $lu->det();
}
/**
* @return bool
*/
public function isSquare()
public function isSquare(): bool
{
return $this->columns === $this->rows;
}
/**
* @return Matrix
*/
public function transpose()
public function transpose() : Matrix
{
if ($this->rows == 1) {
$matrix = array_map(function ($el) {
@ -166,14 +136,7 @@ class Matrix
return new self($matrix, false);
}
/**
* @param Matrix $matrix
*
* @return Matrix
*
* @throws InvalidArgumentException
*/
public function multiply(Matrix $matrix)
public function multiply(Matrix $matrix) : Matrix
{
if ($this->columns != $matrix->getRows()) {
throw InvalidArgumentException::inconsistentMatrixSupplied();
@ -194,12 +157,7 @@ class Matrix
return new self($product, false);
}
/**
* @param $value
*
* @return Matrix
*/
public function divideByScalar($value)
public function divideByScalar($value) : Matrix
{
$newMatrix = [];
for ($i = 0; $i < $this->rows; ++$i) {
@ -211,12 +169,7 @@ class Matrix
return new self($newMatrix, false);
}
/**
* @param $value
*
* @return Matrix
*/
public function multiplyByScalar($value)
public function multiplyByScalar($value) : Matrix
{
$newMatrix = [];
for ($i = 0; $i < $this->rows; ++$i) {
@ -230,37 +183,24 @@ class Matrix
/**
* Element-wise addition of the matrix with another one
*
* @param Matrix $other
*
* @return Matrix
*/
public function add(Matrix $other)
public function add(Matrix $other) : Matrix
{
return $this->_add($other);
}
/**
* Element-wise subtracting of another matrix from this one
*
* @param Matrix $other
*
* @return Matrix
*/
public function subtract(Matrix $other)
public function subtract(Matrix $other) : Matrix
{
return $this->_add($other, -1);
}
/**
* Element-wise addition or substraction depending on the given sign parameter
*
* @param Matrix $other
* @param int $sign
*
* @return Matrix
*/
protected function _add(Matrix $other, $sign = 1)
protected function _add(Matrix $other, int $sign = 1) : Matrix
{
$a1 = $this->toArray();
$a2 = $other->toArray();
@ -275,12 +215,7 @@ class Matrix
return new self($newMatrix, false);
}
/**
* @return Matrix
*
* @throws MatrixException
*/
public function inverse()
public function inverse() : Matrix
{
if (!$this->isSquare()) {
throw MatrixException::notSquareMatrix();
@ -295,10 +230,8 @@ class Matrix
/**
* Returns diagonal identity matrix of the same size of this matrix
*
* @return Matrix
*/
protected function getIdentity()
protected function getIdentity() : Matrix
{
$array = array_fill(0, $this->rows, array_fill(0, $this->columns, 0));
for ($i = 0; $i < $this->rows; ++$i) {
@ -308,13 +241,7 @@ class Matrix
return new self($array, false);
}
/**
* @param int $row
* @param int $column
*
* @return Matrix
*/
public function crossOut(int $row, int $column)
public function crossOut(int $row, int $column) : Matrix
{
$newMatrix = [];
$r = 0;
@ -334,9 +261,6 @@ class Matrix
return new self($newMatrix, false);
}
/**
* @return bool
*/
public function isSingular() : bool
{
return 0 == $this->getDeterminant();
@ -344,12 +268,8 @@ class Matrix
/**
* Returns the transpose of given array
*
* @param array $array
*
* @return array
*/
public static function transposeArray(array $array)
public static function transposeArray(array $array) : array
{
return (new self($array, false))->transpose()->toArray();
}
@ -357,13 +277,8 @@ class Matrix
/**
* Returns the dot product of two arrays<br>
* Matrix::dot(x, y) ==> x.y'
*
* @param array $array1
* @param array $array2
*
* @return array
*/
public static function dot(array $array1, array $array2)
public static function dot(array $array1, array $array2) : array
{
$m1 = new self($array1, false);
$m2 = new self($array2, false);

View File

@ -21,11 +21,6 @@ class Set implements \IteratorAggregate
/**
* Creates the union of A and B.
*
* @param Set $a
* @param Set $b
*
* @return Set
*/
public static function union(Set $a, Set $b) : Set
{
@ -34,11 +29,6 @@ class Set implements \IteratorAggregate
/**
* Creates the intersection of A and B.
*
* @param Set $a
* @param Set $b
*
* @return Set
*/
public static function intersection(Set $a, Set $b) : Set
{
@ -47,11 +37,6 @@ class Set implements \IteratorAggregate
/**
* Creates the difference of A and B.
*
* @param Set $a
* @param Set $b
*
* @return Set
*/
public static function difference(Set $a, Set $b) : Set
{
@ -61,9 +46,6 @@ class Set implements \IteratorAggregate
/**
* Creates the Cartesian product of A and B.
*
* @param Set $a
* @param Set $b
*
* @return Set[]
*/
public static function cartesian(Set $a, Set $b) : array
@ -82,8 +64,6 @@ class Set implements \IteratorAggregate
/**
* Creates the power set of A.
*
* @param Set $a
*
* @return Set[]
*/
public static function power(Set $a) : array
@ -115,8 +95,6 @@ class Set implements \IteratorAggregate
/**
* @param string|int|float $element
*
* @return Set
*/
public function add($element) : Set
{
@ -125,8 +103,6 @@ class Set implements \IteratorAggregate
/**
* @param string[]|int[]|float[] $elements
*
* @return Set
*/
public function addAll(array $elements) : Set
{
@ -137,8 +113,6 @@ class Set implements \IteratorAggregate
/**
* @param string|int|float $element
*
* @return Set
*/
public function remove($element) : Set
{
@ -147,8 +121,6 @@ class Set implements \IteratorAggregate
/**
* @param string[]|int[]|float[] $elements
*
* @return Set
*/
public function removeAll(array $elements) : Set
{
@ -159,8 +131,6 @@ class Set implements \IteratorAggregate
/**
* @param string|int|float $element
*
* @return bool
*/
public function contains($element) : bool
{
@ -169,8 +139,6 @@ class Set implements \IteratorAggregate
/**
* @param string[]|int[]|float[] $elements
*
* @return bool
*/
public function containsAll(array $elements) : bool
{
@ -185,25 +153,16 @@ class Set implements \IteratorAggregate
return $this->elements;
}
/**
* @return \ArrayIterator
*/
public function getIterator() : \ArrayIterator
{
return new \ArrayIterator($this->elements);
}
/**
* @return bool
*/
public function isEmpty() : bool
{
return $this->cardinality() == 0;
}
/**
* @return int
*/
public function cardinality() : int
{
return count($this->elements);

View File

@ -12,11 +12,9 @@ class Correlation
* @param array|int[]|float[] $x
* @param array|int[]|float[] $y
*
* @return float
*
* @throws InvalidArgumentException
*/
public static function pearson(array $x, array $y)
public static function pearson(array $x, array $y) : float
{
if (count($x) !== count($y)) {
throw InvalidArgumentException::arraySizeNotMatch();

View File

@ -11,17 +11,9 @@ class Covariance
/**
* Calculates covariance from two given arrays, x and y, respectively
*
* @param array $x
* @param array $y
* @param bool $sample
* @param float $meanX
* @param float $meanY
*
* @return float
*
* @throws InvalidArgumentException
*/
public static function fromXYArrays(array $x, array $y, $sample = true, float $meanX = null, float $meanY = null)
public static function fromXYArrays(array $x, array $y, bool $sample = true, float $meanX = null, float $meanY = null) : float
{
if (empty($x) || empty($y)) {
throw InvalidArgumentException::arrayCantBeEmpty();
@ -56,19 +48,10 @@ class Covariance
/**
* Calculates covariance of two dimensions, i and k in the given data.
*
* @param array $data
* @param int $i
* @param int $k
* @param bool $sample
* @param float $meanX
* @param float $meanY
*
* @return float
*
* @throws InvalidArgumentException
* @throws \Exception
*/
public static function fromDataset(array $data, int $i, int $k, bool $sample = true, float $meanX = null, float $meanY = null)
public static function fromDataset(array $data, int $i, int $k, bool $sample = true, float $meanX = null, float $meanY = null) : float
{
if (empty($data)) {
throw InvalidArgumentException::arrayCantBeEmpty();
@ -127,12 +110,9 @@ class Covariance
/**
* Returns the covariance matrix of n-dimensional data
*
* @param array $data
* @param array|null $means
*
* @return array
*/
public static function covarianceMatrix(array $data, array $means = null)
public static function covarianceMatrix(array $data, array $means = null) : array
{
$n = count($data[0]);

View File

@ -16,10 +16,6 @@ class Gaussian
*/
protected $std;
/**
* @param float $mean
* @param float $std
*/
public function __construct(float $mean, float $std)
{
$this->mean = $mean;
@ -29,8 +25,6 @@ class Gaussian
/**
* Returns probability density of the given <i>$value</i>
*
* @param float $value
*
* @return float|int
*/
public function pdf(float $value)
@ -46,14 +40,8 @@ class Gaussian
/**
* Returns probability density value of the given <i>$value</i> based on
* given standard deviation and the mean
*
* @param float $mean
* @param float $std
* @param float $value
*
* @return float
*/
public static function distributionPdf(float $mean, float $std, float $value)
public static function distributionPdf(float $mean, float $std, float $value) : float
{
$normal = new self($mean, $std);

View File

@ -11,11 +11,9 @@ class Mean
/**
* @param array $numbers
*
* @return float
*
* @throws InvalidArgumentException
*/
public static function arithmetic(array $numbers)
public static function arithmetic(array $numbers) : float
{
self::checkArrayLength($numbers);

View File

@ -10,13 +10,10 @@ class StandardDeviation
{
/**
* @param array|float[] $a
* @param bool $sample
*
* @return float
*
* @throws InvalidArgumentException
*/
public static function population(array $a, $sample = true)
public static function population(array $a, bool $sample = true) : float
{
if (empty($a)) {
throw InvalidArgumentException::arrayCantBeEmpty();

View File

@ -31,10 +31,6 @@ class ClassificationReport
*/
private $average = [];
/**
* @param array $actualLabels
* @param array $predictedLabels
*/
public function __construct(array $actualLabels, array $predictedLabels)
{
$truePositive = $falsePositive = $falseNegative = $this->support = self::getLabelIndexedArray($actualLabels, $predictedLabels);
@ -55,51 +51,31 @@ class ClassificationReport
$this->computeAverage();
}
/**
* @return array
*/
public function getPrecision()
public function getPrecision() : array
{
return $this->precision;
}
/**
* @return array
*/
public function getRecall()
public function getRecall() : array
{
return $this->recall;
}
/**
* @return array
*/
public function getF1score()
public function getF1score() : array
{
return $this->f1score;
}
/**
* @return array
*/
public function getSupport()
public function getSupport() : array
{
return $this->support;
}
/**
* @return array
*/
public function getAverage()
public function getAverage() : array
{
return $this->average;
}
/**
* @param array $truePositive
* @param array $falsePositive
* @param array $falseNegative
*/
private function computeMetrics(array $truePositive, array $falsePositive, array $falseNegative)
{
foreach ($truePositive as $label => $tp) {
@ -122,9 +98,6 @@ class ClassificationReport
}
/**
* @param int $truePositive
* @param int $falsePositive
*
* @return float|string
*/
private function computePrecision(int $truePositive, int $falsePositive)
@ -137,9 +110,6 @@ class ClassificationReport
}
/**
* @param int $truePositive
* @param int $falseNegative
*
* @return float|string
*/
private function computeRecall(int $truePositive, int $falseNegative)
@ -151,13 +121,7 @@ class ClassificationReport
return $truePositive / $divider;
}
/**
* @param float $precision
* @param float $recall
*
* @return float
*/
private function computeF1Score(float $precision, float $recall): float
private function computeF1Score(float $precision, float $recall) : float
{
if (0 == ($divider = $precision + $recall)) {
return 0.0;
@ -172,7 +136,7 @@ class ClassificationReport
*
* @return array
*/
private static function getLabelIndexedArray(array $actualLabels, array $predictedLabels): array
private static function getLabelIndexedArray(array $actualLabels, array $predictedLabels) : array
{
$labels = array_values(array_unique(array_merge($actualLabels, $predictedLabels)));
sort($labels);

View File

@ -13,7 +13,7 @@ class ConfusionMatrix
*
* @return array
*/
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);
$matrix = self::generateMatrixWithZeros($labels);
@ -43,7 +43,7 @@ class ConfusionMatrix
*
* @return array
*/
private static function generateMatrixWithZeros(array $labels): array
private static function generateMatrixWithZeros(array $labels) : array
{
$count = count($labels);
$matrix = [];
@ -60,7 +60,7 @@ class ConfusionMatrix
*
* @return array
*/
private static function getUniqueLabels(array $labels): array
private static function getUniqueLabels(array $labels) : array
{
$labels = array_values(array_unique($labels));
sort($labels);

View File

@ -4,18 +4,11 @@ declare(strict_types=1);
namespace Phpml;
use Phpml\Exception\SerializeException;
use Phpml\Exception\FileException;
use Phpml\Exception\SerializeException;
class ModelManager
{
/**
* @param Estimator $estimator
* @param string $filepath
*
* @throws FileException
* @throws SerializeException
*/
public function saveToFile(Estimator $estimator, string $filepath)
{
if (!is_writable(dirname($filepath))) {
@ -33,14 +26,6 @@ class ModelManager
}
}
/**
* @param string $filepath
*
* @return Estimator
*
* @throws FileException
* @throws SerializeException
*/
public function restoreFromFile(string $filepath) : Estimator
{
if (!file_exists($filepath) || !is_readable($filepath)) {

View File

@ -8,8 +8,6 @@ interface ActivationFunction
{
/**
* @param float|int $value
*
* @return float
*/
public function compute($value): float;
public function compute($value) : float;
}

View File

@ -10,10 +10,8 @@ class BinaryStep implements ActivationFunction
{
/**
* @param float|int $value
*
* @return float
*/
public function compute($value): float
public function compute($value) : float
{
return $value >= 0 ? 1.0 : 0.0;
}

View File

@ -10,10 +10,8 @@ class Gaussian implements ActivationFunction
{
/**
* @param float|int $value
*
* @return float
*/
public function compute($value): float
public function compute($value) : float
{
return exp(-pow($value, 2));
}

View File

@ -13,20 +13,15 @@ class HyperbolicTangent implements ActivationFunction
*/
private $beta;
/**
* @param float $beta
*/
public function __construct($beta = 1.0)
public function __construct(float $beta = 1.0)
{
$this->beta = $beta;
}
/**
* @param float|int $value
*
* @return float
*/
public function compute($value): float
public function compute($value) : float
{
return tanh($this->beta * $value);
}

View File

@ -13,20 +13,15 @@ class PReLU implements ActivationFunction
*/
private $beta;
/**
* @param float $beta
*/
public function __construct($beta = 0.01)
public function __construct(float $beta = 0.01)
{
$this->beta = $beta;
}
/**
* @param float|int $value
*
* @return float
*/
public function compute($value): float
public function compute($value) : float
{
return $value >= 0 ? $value : $this->beta * $value;
}

View File

@ -13,20 +13,15 @@ class Sigmoid implements ActivationFunction
*/
private $beta;
/**
* @param float $beta
*/
public function __construct($beta = 1.0)
public function __construct(float $beta = 1.0)
{
$this->beta = $beta;
}
/**
* @param float|int $value
*
* @return float
*/
public function compute($value): float
public function compute($value) : float
{
return 1 / (1 + exp(-$this->beta * $value));
}

View File

@ -13,20 +13,15 @@ class ThresholdedReLU implements ActivationFunction
*/
private $theta;
/**
* @param float $theta
*/
public function __construct($theta = 1.0)
public function __construct(float $theta = 1.0)
{
$this->theta = $theta;
}
/**
* @param float|int $value
*
* @return float
*/
public function compute($value): float
public function compute($value) : float
{
return $value > $this->theta ? $value : 0.0;
}

View File

@ -15,10 +15,6 @@ class Layer
private $nodes = [];
/**
* @param int $nodesNumber
* @param string $nodeClass
* @param ActivationFunction|null $activationFunction
*
* @throws InvalidArgumentException
*/
public function __construct(int $nodesNumber = 0, string $nodeClass = Neuron::class, ActivationFunction $activationFunction = null)
@ -33,7 +29,6 @@ class Layer
}
/**
* @param string $nodeClass
* @param ActivationFunction|null $activationFunction
*
* @return Neuron
@ -47,9 +42,6 @@ class Layer
return new $nodeClass();
}
/**
* @param Node $node
*/
public function addNode(Node $node)
{
$this->nodes[] = $node;
@ -58,7 +50,7 @@ class Layer
/**
* @return Node[]
*/
public function getNodes()
public function getNodes() : array
{
return $this->nodes;
}

View File

@ -16,15 +16,12 @@ interface Network
/**
* @return array
*/
public function getOutput(): array;
public function getOutput() : array;
/**
* @param Layer $layer
*/
public function addLayer(Layer $layer);
/**
* @return Layer[]
*/
public function getLayers(): array;
public function getLayers() : array;
}

View File

@ -16,9 +16,6 @@ abstract class LayeredNetwork implements Network
*/
protected $layers;
/**
* @param Layer $layer
*/
public function addLayer(Layer $layer)
{
$this->layers[] = $layer;
@ -27,22 +24,16 @@ abstract class LayeredNetwork implements Network
/**
* @return Layer[]
*/
public function getLayers(): array
public function getLayers() : array
{
return $this->layers;
}
/**
* @return void
*/
public function removeLayers()
{
unset($this->layers);
}
/**
* @return Layer
*/
public function getOutputLayer(): Layer
{
return $this->layers[count($this->layers) - 1];
@ -51,7 +42,7 @@ abstract class LayeredNetwork implements Network
/**
* @return array
*/
public function getOutput(): array
public function getOutput() : array
{
$result = [];
foreach ($this->getOutputLayer()->getNodes() as $neuron) {

View File

@ -5,16 +5,16 @@ declare(strict_types=1);
namespace Phpml\NeuralNetwork\Network;
use Phpml\Estimator;
use Phpml\IncrementalEstimator;
use Phpml\Exception\InvalidArgumentException;
use Phpml\NeuralNetwork\Training\Backpropagation;
use Phpml\Helper\Predictable;
use Phpml\IncrementalEstimator;
use Phpml\NeuralNetwork\ActivationFunction;
use Phpml\NeuralNetwork\Layer;
use Phpml\NeuralNetwork\Node\Bias;
use Phpml\NeuralNetwork\Node\Input;
use Phpml\NeuralNetwork\Node\Neuron;
use Phpml\NeuralNetwork\Node\Neuron\Synapse;
use Phpml\Helper\Predictable;
use Phpml\NeuralNetwork\Training\Backpropagation;
abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator, IncrementalEstimator
{
@ -56,13 +56,6 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
protected $backpropagation = null;
/**
* @param int $inputLayerFeatures
* @param array $hiddenLayers
* @param array $classes
* @param int $iterations
* @param ActivationFunction|null $activationFunction
* @param int $theta
*
* @throws InvalidArgumentException
*/
public function __construct(int $inputLayerFeatures, array $hiddenLayers, array $classes, int $iterations = 10000, ActivationFunction $activationFunction = null, int $theta = 1)
@ -85,9 +78,6 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
$this->initNetwork();
}
/**
* @return void
*/
private function initNetwork()
{
$this->addInputLayer($this->inputLayerFeatures);
@ -100,10 +90,6 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
$this->backpropagation = new Backpropagation($this->theta);
}
/**
* @param array $samples
* @param array $targets
*/
public function train(array $samples, array $targets)
{
$this->reset();
@ -112,10 +98,6 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
}
/**
* @param array $samples
* @param array $targets
* @param array $classes
*
* @throws InvalidArgumentException
*/
public function partialTrain(array $samples, array $targets, array $classes = [])
@ -131,38 +113,25 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
}
/**
* @param array $sample
* @param mixed $target
*/
abstract protected function trainSample(array $sample, $target);
/**
* @param array $sample
*
* @return mixed
*/
abstract protected function predictSample(array $sample);
/**
* @return void
*/
protected function reset()
{
$this->removeLayers();
}
/**
* @param int $nodes
*/
private function addInputLayer(int $nodes)
{
$this->addLayer(new Layer($nodes, Input::class));
}
/**
* @param array $layers
* @param ActivationFunction|null $activationFunction
*/
private function addNeuronLayers(array $layers, ActivationFunction $activationFunction = null)
{
foreach ($layers as $neurons) {
@ -188,10 +157,6 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
}
}
/**
* @param Layer $nextLayer
* @param Layer $currentLayer
*/
private function generateLayerSynapses(Layer $nextLayer, Layer $currentLayer)
{
foreach ($nextLayer->getNodes() as $nextNeuron) {
@ -201,10 +166,6 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
}
}
/**
* @param Layer $currentLayer
* @param Neuron $nextNeuron
*/
private function generateNeuronSynapses(Layer $currentLayer, Neuron $nextNeuron)
{
foreach ($currentLayer->getNodes() as $currentNeuron) {
@ -212,10 +173,6 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
}
}
/**
* @param array $samples
* @param array $targets
*/
private function trainSamples(array $samples, array $targets)
{
foreach ($targets as $key => $target) {

View File

@ -6,8 +6,5 @@ namespace Phpml\NeuralNetwork;
interface Node
{
/**
* @return float
*/
public function getOutput(): float;
public function getOutput() : float;
}

View File

@ -8,10 +8,7 @@ use Phpml\NeuralNetwork\Node;
class Bias implements Node
{
/**
* @return float
*/
public function getOutput(): float
public function getOutput() : float
{
return 1.0;
}

View File

@ -13,25 +13,16 @@ class Input implements Node
*/
private $input;
/**
* @param float $input
*/
public function __construct(float $input = 0.0)
{
$this->input = $input;
}
/**
* @return float
*/
public function getOutput(): float
public function getOutput() : float
{
return $this->input;
}
/**
* @param float $input
*/
public function setInput(float $input)
{
$this->input = $input;

View File

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Phpml\NeuralNetwork\Node;
use Phpml\NeuralNetwork\ActivationFunction;
use Phpml\NeuralNetwork\Node\Neuron\Synapse;
use Phpml\NeuralNetwork\Node;
use Phpml\NeuralNetwork\Node\Neuron\Synapse;
class Neuron implements Node
{
@ -25,9 +25,6 @@ class Neuron implements Node
*/
protected $output;
/**
* @param ActivationFunction|null $activationFunction
*/
public function __construct(ActivationFunction $activationFunction = null)
{
$this->activationFunction = $activationFunction ?: new ActivationFunction\Sigmoid();
@ -35,9 +32,6 @@ class Neuron implements Node
$this->output = 0;
}
/**
* @param Synapse $synapse
*/
public function addSynapse(Synapse $synapse)
{
$this->synapses[] = $synapse;
@ -51,10 +45,7 @@ class Neuron implements Node
return $this->synapses;
}
/**
* @return float
*/
public function getOutput(): float
public function getOutput() : float
{
if (0 === $this->output) {
$sum = 0;

View File

@ -28,42 +28,27 @@ class Synapse
$this->weight = $weight ?: $this->generateRandomWeight();
}
/**
* @return float
*/
protected function generateRandomWeight(): float
protected function generateRandomWeight() : float
{
return 1 / random_int(5, 25) * (random_int(0, 1) ? -1 : 1);
}
/**
* @return float
*/
public function getOutput(): float
public function getOutput() : float
{
return $this->weight * $this->node->getOutput();
}
/**
* @param float $delta
*/
public function changeWeight($delta)
public function changeWeight(float $delta)
{
$this->weight += $delta;
}
/**
* @return float
*/
public function getWeight()
public function getWeight() : float
{
return $this->weight;
}
/**
* @return Node
*/
public function getNode()
public function getNode(): Node
{
return $this->node;
}

View File

@ -24,16 +24,12 @@ class Backpropagation
*/
private $prevSigmas = null;
/**
* @param int $theta
*/
public function __construct(int $theta)
{
$this->theta = $theta;
}
/**
* @param array $layers
* @param mixed $targetClass
*/
public function backpropagate(array $layers, $targetClass)
@ -59,15 +55,7 @@ class Backpropagation
$this->prevSigmas = null;
}
/**
* @param Neuron $neuron
* @param int $targetClass
* @param int $key
* @param bool $lastLayer
*
* @return float
*/
private function getSigma(Neuron $neuron, int $targetClass, int $key, bool $lastLayer): float
private function getSigma(Neuron $neuron, int $targetClass, int $key, bool $lastLayer) : float
{
$neuronOutput = $neuron->getOutput();
$sigma = $neuronOutput * (1 - $neuronOutput);
@ -87,12 +75,7 @@ class Backpropagation
return $sigma;
}
/**
* @param Neuron $neuron
*
* @return float
*/
private function getPrevSigma(Neuron $neuron): float
private function getPrevSigma(Neuron $neuron) : float
{
$sigma = 0.0;

View File

@ -18,38 +18,23 @@ class Sigma
*/
private $sigma;
/**
* @param Neuron $neuron
* @param float $sigma
*/
public function __construct(Neuron $neuron, $sigma)
public function __construct(Neuron $neuron, float $sigma)
{
$this->neuron = $neuron;
$this->sigma = $sigma;
}
/**
* @return Neuron
*/
public function getNeuron()
public function getNeuron(): Neuron
{
return $this->neuron;
}
/**
* @return float
*/
public function getSigma()
public function getSigma() : float
{
return $this->sigma;
}
/**
* @param Neuron $neuron
*
* @return float
*/
public function getSigmaForNeuron(Neuron $neuron): float
public function getSigmaForNeuron(Neuron $neuron) : float
{
$sigma = 0.0;

View File

@ -29,17 +29,11 @@ class Pipeline implements Estimator
$this->estimator = $estimator;
}
/**
* @param Transformer $transformer
*/
public function addTransformer(Transformer $transformer)
{
$this->transformers[] = $transformer;
}
/**
* @param Estimator $estimator
*/
public function setEstimator(Estimator $estimator)
{
$this->estimator = $estimator;
@ -48,15 +42,12 @@ class Pipeline implements Estimator
/**
* @return array|Transformer[]
*/
public function getTransformers()
public function getTransformers() : array
{
return $this->transformers;
}
/**
* @return Estimator
*/
public function getEstimator()
public function getEstimator(): Estimator
{
return $this->estimator;
}

View File

@ -81,7 +81,7 @@ class Imputer implements Preprocessor
*
* @return array
*/
private function getAxis(int $column, array $currentSample): array
private function getAxis(int $column, array $currentSample) : array
{
if (self::AXIS_ROW === $this->axis) {
return array_diff($currentSample, [$this->missingValue]);

View File

@ -4,17 +4,15 @@ declare(strict_types=1);
namespace Phpml\Preprocessing\Imputer\Strategy;
use Phpml\Preprocessing\Imputer\Strategy;
use Phpml\Math\Statistic\Mean;
use Phpml\Preprocessing\Imputer\Strategy;
class MeanStrategy implements Strategy
{
/**
* @param array $currentAxis
*
* @return float
*/
public function replaceValue(array $currentAxis)
public function replaceValue(array $currentAxis) : float
{
return Mean::arithmetic($currentAxis);
}

View File

@ -4,17 +4,15 @@ declare(strict_types=1);
namespace Phpml\Preprocessing\Imputer\Strategy;
use Phpml\Preprocessing\Imputer\Strategy;
use Phpml\Math\Statistic\Mean;
use Phpml\Preprocessing\Imputer\Strategy;
class MedianStrategy implements Strategy
{
/**
* @param array $currentAxis
*
* @return float
*/
public function replaceValue(array $currentAxis)
public function replaceValue(array $currentAxis) : float
{
return Mean::median($currentAxis);
}

View File

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Phpml\Preprocessing\Imputer\Strategy;
use Phpml\Preprocessing\Imputer\Strategy;
use Phpml\Math\Statistic\Mean;
use Phpml\Preprocessing\Imputer\Strategy;
class MostFrequentStrategy implements Strategy
{

View File

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Phpml\Preprocessing;
use Phpml\Exception\NormalizerException;
use Phpml\Math\Statistic\StandardDeviation;
use Phpml\Math\Statistic\Mean;
use Phpml\Math\Statistic\StandardDeviation;
class Normalizer implements Preprocessor
{
@ -35,8 +35,6 @@ class Normalizer implements Preprocessor
private $mean;
/**
* @param int $norm
*
* @throws NormalizerException
*/
public function __construct(int $norm = self::NORM_L2)

View File

@ -30,10 +30,6 @@ class LeastSquares implements Regression
*/
private $coefficients;
/**
* @param array $samples
* @param array $targets
*/
public function train(array $samples, array $targets)
{
$this->samples = array_merge($this->samples, $samples);
@ -43,8 +39,6 @@ class LeastSquares implements Regression
}
/**
* @param array $sample
*
* @return mixed
*/
public function predictSample(array $sample)
@ -57,18 +51,12 @@ class LeastSquares implements Regression
return $result;
}
/**
* @return array
*/
public function getCoefficients()
public function getCoefficients() : array
{
return $this->coefficients;
}
/**
* @return float
*/
public function getIntercept()
public function getIntercept() : float
{
return $this->intercept;
}
@ -90,10 +78,8 @@ class LeastSquares implements Regression
/**
* Add one dimension for intercept calculation.
*
* @return Matrix
*/
private function getSamplesMatrix()
private function getSamplesMatrix() : Matrix
{
$samples = [];
foreach ($this->samples as $sample) {
@ -104,10 +90,7 @@ class LeastSquares implements Regression
return new Matrix($samples);
}
/**
* @return Matrix
*/
private function getTargetsMatrix()
private function getTargetsMatrix() : Matrix
{
if (is_array($this->targets[0])) {
return new Matrix($this->targets);

View File

@ -10,17 +10,6 @@ use Phpml\SupportVectorMachine\Type;
class SVR extends SupportVectorMachine implements Regression
{
/**
* @param int $kernel
* @param int $degree
* @param float $epsilon
* @param float $cost
* @param float|null $gamma
* @param float $coef0
* @param float $tolerance
* @param int $cacheSize
* @param bool $shrinking
*/
public function __construct(
int $kernel = Kernel::RBF,
int $degree = 3,

View File

@ -6,13 +6,6 @@ namespace Phpml\SupportVectorMachine;
class DataTransformer
{
/**
* @param array $samples
* @param array $labels
* @param bool $targets
*
* @return string
*/
public static function trainingSet(array $samples, array $labels, bool $targets = false): string
{
$set = '';
@ -27,11 +20,6 @@ class DataTransformer
return $set;
}
/**
* @param array $samples
*
* @return string
*/
public static function testSet(array $samples): string
{
if (!is_array($samples[0])) {
@ -46,13 +34,7 @@ class DataTransformer
return $set;
}
/**
* @param string $rawPredictions
* @param array $labels
*
* @return array
*/
public static function predictions(string $rawPredictions, array $labels): array
public static function predictions(string $rawPredictions, array $labels) : array
{
$numericLabels = self::numericLabels($labels);
$results = [];
@ -65,12 +47,7 @@ class DataTransformer
return $results;
}
/**
* @param array $labels
*
* @return array
*/
public static function numericLabels(array $labels): array
public static function numericLabels(array $labels) : array
{
$numericLabels = [];
foreach ($labels as $label) {
@ -84,11 +61,6 @@ class DataTransformer
return $numericLabels;
}
/**
* @param array $sample
*
* @return string
*/
private static function sampleRow(array $sample): string
{
$row = [];

View File

@ -91,20 +91,6 @@ class SupportVectorMachine
*/
private $targets = [];
/**
* @param int $type
* @param int $kernel
* @param float $cost
* @param float $nu
* @param int $degree
* @param float|null $gamma
* @param float $coef0
* @param float $epsilon
* @param float $tolerance
* @param int $cacheSize
* @param bool $shrinking
* @param bool $probabilityEstimates
*/
public function __construct(
int $type,
int $kernel,
@ -138,11 +124,6 @@ class SupportVectorMachine
$this->varPath = $rootPath.'var'.DIRECTORY_SEPARATOR;
}
/**
* @param string $binPath
*
* @throws InvalidArgumentException
*/
public function setBinPath(string $binPath)
{
$this->ensureDirectorySeparator($binPath);
@ -151,11 +132,6 @@ class SupportVectorMachine
$this->binPath = $binPath;
}
/**
* @param string $varPath
*
* @throws InvalidArgumentException
*/
public function setVarPath(string $varPath)
{
if (!is_writable($varPath)) {
@ -166,10 +142,6 @@ class SupportVectorMachine
$this->varPath = $varPath;
}
/**
* @param array $samples
* @param array $targets
*/
public function train(array $samples, array $targets)
{
$this->samples = array_merge($this->samples, $samples);
@ -189,17 +161,12 @@ class SupportVectorMachine
unlink($modelFileName);
}
/**
* @return string
*/
public function getModel()
public function getModel(): string
{
return $this->model;
}
/**
* @param array $samples
*
* @return array
*/
public function predict(array $samples)
@ -232,10 +199,7 @@ class SupportVectorMachine
return $predictions;
}
/**
* @return string
*/
private function getOSExtension()
private function getOSExtension(): string
{
$os = strtoupper(substr(PHP_OS, 0, 3));
if ($os === 'WIN') {
@ -247,12 +211,6 @@ class SupportVectorMachine
return '';
}
/**
* @param string $trainingSetFileName
* @param string $modelFileName
*
* @return string
*/
private function buildTrainCommand(string $trainingSetFileName, string $modelFileName): string
{
return sprintf(
@ -276,9 +234,6 @@ class SupportVectorMachine
);
}
/**
* @param string $path
*/
private function ensureDirectorySeparator(string &$path)
{
if (substr($path, -1) !== DIRECTORY_SEPARATOR) {
@ -286,11 +241,6 @@ class SupportVectorMachine
}
}
/**
* @param string $path
*
* @throws InvalidArgumentException
*/
private function verifyBinPath(string $path)
{
if (!is_dir($path)) {

View File

@ -6,10 +6,5 @@ namespace Phpml\Tokenization;
interface Tokenizer
{
/**
* @param string $text
*
* @return array
*/
public function tokenize(string $text): array;
public function tokenize(string $text) : array;
}

View File

@ -6,12 +6,7 @@ namespace Phpml\Tokenization;
class WhitespaceTokenizer implements Tokenizer
{
/**
* @param string $text
*
* @return array
*/
public function tokenize(string $text): array
public function tokenize(string $text) : array
{
return preg_split('/[\pZ\pC]+/u', $text, -1, PREG_SPLIT_NO_EMPTY);
}

View File

@ -6,12 +6,7 @@ namespace Phpml\Tokenization;
class WordTokenizer implements Tokenizer
{
/**
* @param string $text
*
* @return array
*/
public function tokenize(string $text): array
public function tokenize(string $text) : array
{
$tokens = [];
preg_match_all('/\w\w+/u', $text, $tokens);

View File

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace tests\Phpml\Classification\Ensemble;
use Phpml\Classification\Ensemble\Bagging;
use Phpml\Classification\DecisionTree;
use Phpml\Classification\Ensemble\Bagging;
use Phpml\Classification\NaiveBayes;
use Phpml\ModelManager;
use PHPUnit\Framework\TestCase;

View File

@ -4,8 +4,8 @@ declare(strict_types=1);
namespace tests\Phpml\Classification\Ensemble;
use Phpml\Classification\Ensemble\RandomForest;
use Phpml\Classification\DecisionTree;
use Phpml\Classification\Ensemble\RandomForest;
use Phpml\Classification\NaiveBayes;
class RandomForestTest extends BaggingTest

View File

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace tests\Phpml\Classification;
use Phpml\Classification\MLPClassifier;
use Phpml\NeuralNetwork\Node\Neuron;
use Phpml\ModelManager;
use Phpml\NeuralNetwork\Node\Neuron;
use PHPUnit\Framework\TestCase;
class MLPClassifierTest extends TestCase
@ -194,7 +194,7 @@ class MLPClassifierTest extends TestCase
*
* @return array
*/
private function getSynapsesNodes(array $synapses): array
private function getSynapsesNodes(array $synapses) : array
{
$nodes = [];
foreach ($synapses as $synapse) {

View File

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace tests\Phpml\Classification;
use Phpml\Classification\SVC;
use Phpml\SupportVectorMachine\Kernel;
use Phpml\ModelManager;
use Phpml\SupportVectorMachine\Kernel;
use PHPUnit\Framework\TestCase;
class SVCTest extends TestCase

Some files were not shown because too many files have changed in this diff Show More