diff --git a/CHANGELOG.md b/CHANGELOG.md
index 12a9c3a7..1c1e0970 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@ This changelog references the relevant changes done in PHP-ML library.
     * fix SVM locale (non-locale aware) (#288)
     * typo, tests, code styles and documentation fixes (#265, #261, #254, #253, #251, #250, #248, #245, #243)
     * change [MLPClassifier] return labels in output (#315)
+    * enhancement Update phpstan to 0.10.5 (#320)
 
 * 0.6.2 (2018-02-22)
     * Fix Apriori array keys (#238)
diff --git a/composer.json b/composer.json
index 7b1cbb65..1604bbfd 100644
--- a/composer.json
+++ b/composer.json
@@ -24,9 +24,9 @@
     },
     "require-dev": {
         "phpbench/phpbench": "^0.14.0",
-        "phpstan/phpstan-phpunit": "^0.9.4",
-        "phpstan/phpstan-shim": "^0.9",
-        "phpstan/phpstan-strict-rules": "^0.9.0",
+        "phpstan/phpstan-phpunit": "^0.10",
+        "phpstan/phpstan-shim": "^0.10",
+        "phpstan/phpstan-strict-rules": "^0.10",
         "phpunit/phpunit": "^7.0.0",
         "symplify/coding-standard": "^5.1",
         "symplify/easy-coding-standard": "^5.1"
diff --git a/composer.lock b/composer.lock
index fa22470d..70324ee0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "content-hash": "cb4240c977f956be78a7fa686c77d0f2",
+    "content-hash": "9ec1ca6b843d05e0870bd777026d7a8b",
     "packages": [],
     "packages-dev": [
         {
@@ -1511,83 +1511,42 @@
             ],
             "time": "2018-08-05T17:53:17+00:00"
         },
-        {
-            "name": "phpstan/phpdoc-parser",
-            "version": "0.3",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/phpstan/phpdoc-parser.git",
-                "reference": "ed3223362174b8067729930439e139794e9e514a"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ed3223362174b8067729930439e139794e9e514a",
-                "reference": "ed3223362174b8067729930439e139794e9e514a",
-                "shasum": ""
-            },
-            "require": {
-                "php": "~7.1"
-            },
-            "require-dev": {
-                "consistence/coding-standard": "^2.0.0",
-                "jakub-onderka/php-parallel-lint": "^0.9.2",
-                "phing/phing": "^2.16.0",
-                "phpstan/phpstan": "^0.10@dev",
-                "phpunit/phpunit": "^6.3",
-                "slevomat/coding-standard": "^3.3.0",
-                "symfony/process": "^3.4 || ^4.0"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "0.3-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "PHPStan\\PhpDocParser\\": [
-                        "src/"
-                    ]
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "description": "PHPDoc parser with support for nullable, intersection and generic types",
-            "time": "2018-06-20T17:48:01+00:00"
-        },
         {
             "name": "phpstan/phpstan-phpunit",
-            "version": "0.9.4",
+            "version": "0.10",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpstan/phpstan-phpunit.git",
-                "reference": "852411f841a37aeca2fa5af0002b0272c485c9bf"
+                "reference": "6feecc7faae187daa6be44140cd0f1ba210e6aa0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/852411f841a37aeca2fa5af0002b0272c485c9bf",
-                "reference": "852411f841a37aeca2fa5af0002b0272c485c9bf",
+                "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/6feecc7faae187daa6be44140cd0f1ba210e6aa0",
+                "reference": "6feecc7faae187daa6be44140cd0f1ba210e6aa0",
                 "shasum": ""
             },
             "require": {
-                "php": "~7.0",
-                "phpstan/phpstan": "^0.9.1",
-                "phpunit/phpunit": "^6.3 || ~7.0"
+                "nikic/php-parser": "^4.0",
+                "php": "~7.1",
+                "phpstan/phpstan": "^0.10"
+            },
+            "conflict": {
+                "phpunit/phpunit": "<7.0"
             },
             "require-dev": {
-                "consistence/coding-standard": "^2.0",
-                "jakub-onderka/php-parallel-lint": "^0.9.2",
+                "consistence/coding-standard": "^3.0.1",
+                "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
+                "jakub-onderka/php-parallel-lint": "^1.0",
                 "phing/phing": "^2.16.0",
-                "phpstan/phpstan-strict-rules": "^0.9",
+                "phpstan/phpstan-strict-rules": "^0.10",
+                "phpunit/phpunit": "^7.0",
                 "satooshi/php-coveralls": "^1.0",
-                "slevomat/coding-standard": "^3.3.0"
+                "slevomat/coding-standard": "^4.5.2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "0.9-dev"
+                    "dev-master": "0.10-dev"
                 }
             },
             "autoload": {
@@ -1600,26 +1559,28 @@
                 "MIT"
             ],
             "description": "PHPUnit extensions and rules for PHPStan",
-            "time": "2018-02-02T09:45:47+00:00"
+            "time": "2018-06-22T18:12:17+00:00"
         },
         {
             "name": "phpstan/phpstan-shim",
-            "version": "0.9.2",
+            "version": "0.10.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpstan/phpstan-shim.git",
-                "reference": "e4720fb2916be05de02869780072253e7e0e8a75"
+                "reference": "a274185548d140a7f48cc1eed5b94f3a9068c674"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpstan-shim/zipball/e4720fb2916be05de02869780072253e7e0e8a75",
-                "reference": "e4720fb2916be05de02869780072253e7e0e8a75",
+                "url": "https://api.github.com/repos/phpstan/phpstan-shim/zipball/a274185548d140a7f48cc1eed5b94f3a9068c674",
+                "reference": "a274185548d140a7f48cc1eed5b94f3a9068c674",
                 "shasum": ""
             },
             "require": {
-                "php": "~7.0"
+                "php": "~7.1"
             },
             "replace": {
+                "nikic/php-parser": "^4.0.2",
+                "phpstan/phpdoc-parser": "^0.3",
                 "phpstan/phpstan": "self.version"
             },
             "bin": [
@@ -1629,46 +1590,53 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "0.9-dev"
+                    "dev-master": "0.10-dev"
                 }
             },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
             "description": "PHPStan Phar distribution",
-            "time": "2018-01-28T14:29:27+00:00"
+            "time": "2018-10-20T17:45:03+00:00"
         },
         {
             "name": "phpstan/phpstan-strict-rules",
-            "version": "0.9",
+            "version": "0.10.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpstan/phpstan-strict-rules.git",
-                "reference": "15be9090622c6b85c079922308f831018d8d9e23"
+                "reference": "18c0b6e8899606b127c680402ab473a7b67166db"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/15be9090622c6b85c079922308f831018d8d9e23",
-                "reference": "15be9090622c6b85c079922308f831018d8d9e23",
+                "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/18c0b6e8899606b127c680402ab473a7b67166db",
+                "reference": "18c0b6e8899606b127c680402ab473a7b67166db",
                 "shasum": ""
             },
             "require": {
-                "php": "~7.0",
-                "phpstan/phpstan": "^0.9"
+                "nikic/php-parser": "^4.0",
+                "php": "~7.1",
+                "phpstan/phpstan": "^0.10"
             },
             "require-dev": {
-                "consistence/coding-standard": "^2.0.0",
-                "jakub-onderka/php-parallel-lint": "^0.9.2",
+                "consistence/coding-standard": "^3.0.1",
+                "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
+                "jakub-onderka/php-parallel-lint": "^1.0",
                 "phing/phing": "^2.16.0",
-                "phpstan/phpstan-phpunit": "^0.9",
-                "phpunit/phpunit": "^6.4",
-                "slevomat/coding-standard": "^3.3.0"
+                "phpstan/phpstan-phpunit": "^0.10",
+                "phpunit/phpunit": "^7.0",
+                "slevomat/coding-standard": "^4.5.2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "0.9-dev"
+                    "dev-master": "0.10-dev"
                 }
             },
             "autoload": {
@@ -1681,7 +1649,7 @@
                 "MIT"
             ],
             "description": "Extra strict and opinionated rules for PHPStan",
-            "time": "2017-11-26T20:12:30+00:00"
+            "time": "2018-07-06T20:36:44+00:00"
         },
         {
             "name": "phpunit/php-code-coverage",
diff --git a/phpstan.neon b/phpstan.neon
index 7eaee1c8..7a676fa0 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -2,14 +2,13 @@ includes:
     - vendor/phpstan/phpstan-strict-rules/rules.neon
     - vendor/phpstan/phpstan-phpunit/extension.neon
     - vendor/phpstan/phpstan-phpunit/rules.neon
-    - vendor/phpstan/phpstan-phpunit/strictRules.neon
 
 parameters:
     ignoreErrors:
+        - '#Property Phpml\\Clustering\\KMeans\\Cluster\:\:\$points \(iterable\<Phpml\\Clustering\\KMeans\\Point\>\&SplObjectStorage\) does not accept SplObjectStorage#'
         - '#Phpml\\Dataset\\FilesDataset::__construct\(\) does not call parent constructor from Phpml\\Dataset\\ArrayDataset#'
 
         # wide range cases
-        - '#Call to function count\(\) with argument type array<int>\|Phpml\\Clustering\\KMeans\\Point will always result in number 1#'
         - '#Parameter \#1 \$coordinates of class Phpml\\Clustering\\KMeans\\Point constructor expects array, array<int>\|Phpml\\Clustering\\KMeans\\Point given#'
 
         # probably known value
diff --git a/src/Association/Apriori.php b/src/Association/Apriori.php
index 2d09dd7b..201bfbf0 100644
--- a/src/Association/Apriori.php
+++ b/src/Association/Apriori.php
@@ -64,11 +64,11 @@ public function __construct(float $support = 0.0, float $confidence = 0.0)
      */
     public function getRules(): array
     {
-        if (empty($this->large)) {
+        if (count($this->large) === 0) {
             $this->large = $this->apriori();
         }
 
-        if (!empty($this->rules)) {
+        if (count($this->rules) > 0) {
             return $this->rules;
         }
 
@@ -89,7 +89,7 @@ public function apriori(): array
         $L = [];
 
         $items = $this->frequent($this->items());
-        for ($k = 1; !empty($items); ++$k) {
+        for ($k = 1; isset($items[0]); ++$k) {
             $L[$k] = $items;
             $items = $this->frequent($this->candidates($items));
         }
@@ -118,7 +118,7 @@ protected function predictSample(array $sample): array
      */
     private function generateAllRules(): void
     {
-        for ($k = 2; !empty($this->large[$k]); ++$k) {
+        for ($k = 2; isset($this->large[$k]); ++$k) {
             foreach ($this->large[$k] as $frequent) {
                 $this->generateRules($frequent);
             }
@@ -241,7 +241,7 @@ private function candidates(array $samples): array
                     continue;
                 }
 
-                foreach ((array) $this->samples as $sample) {
+                foreach ($this->samples as $sample) {
                     if ($this->subset($sample, $candidate)) {
                         $candidates[] = $candidate;
 
@@ -316,7 +316,7 @@ private function contains(array $system, array $set): bool
      */
     private function subset(array $set, array $subset): bool
     {
-        return !array_diff($subset, array_intersect($subset, $set));
+        return count(array_diff($subset, array_intersect($subset, $set))) === 0;
     }
 
     /**
diff --git a/src/Classification/DecisionTree.php b/src/Classification/DecisionTree.php
index 13a79754..d8010f02 100644
--- a/src/Classification/DecisionTree.php
+++ b/src/Classification/DecisionTree.php
@@ -249,7 +249,7 @@ protected function getSplitLeaf(array $records, int $depth = 0): DecisionTreeLea
         foreach ($records as $recordNo) {
             // Check if the previous record is the same with the current one
             $record = $this->samples[$recordNo];
-            if ($prevRecord && $prevRecord != $record) {
+            if ($prevRecord !== null && $prevRecord != $record) {
                 $allSame = false;
             }
 
@@ -275,13 +275,13 @@ protected function getSplitLeaf(array $records, int $depth = 0): DecisionTreeLea
         if ($allSame || $depth >= $this->maxDepth || count($remainingTargets) === 1) {
             $split->isTerminal = true;
             arsort($remainingTargets);
-            $split->classValue = key($remainingTargets);
+            $split->classValue = (string) key($remainingTargets);
         } else {
-            if (!empty($leftRecords)) {
+            if (isset($leftRecords[0])) {
                 $split->leftLeaf = $this->getSplitLeaf($leftRecords, $depth + 1);
             }
 
-            if (!empty($rightRecords)) {
+            if (isset($rightRecords[0])) {
                 $split->rightLeaf = $this->getSplitLeaf($rightRecords, $depth + 1);
             }
         }
@@ -292,8 +292,10 @@ protected function getSplitLeaf(array $records, int $depth = 0): DecisionTreeLea
     protected function getBestSplit(array $records): DecisionTreeLeaf
     {
         $targets = array_intersect_key($this->targets, array_flip($records));
-        $samples = array_intersect_key($this->samples, array_flip($records));
-        $samples = array_combine($records, $this->preprocess($samples));
+        $samples = (array) array_combine(
+            $records,
+            $this->preprocess(array_intersect_key($this->samples, array_flip($records)))
+        );
         $bestGiniVal = 1;
         $bestSplit = null;
         $features = $this->getSelectedFeatures();
@@ -306,6 +308,10 @@ protected function getBestSplit(array $records): DecisionTreeLeaf
             $counts = array_count_values($colValues);
             arsort($counts);
             $baseValue = key($counts);
+            if ($baseValue === null) {
+                continue;
+            }
+
             $gini = $this->getGiniIndex($baseValue, $colValues, $targets);
             if ($bestSplit === null || $bestGiniVal > $gini) {
                 $split = new DecisionTreeLeaf();
@@ -349,11 +355,11 @@ protected function getBestSplit(array $records): DecisionTreeLeaf
     protected function getSelectedFeatures(): array
     {
         $allFeatures = range(0, $this->featureCount - 1);
-        if ($this->numUsableFeatures === 0 && empty($this->selectedFeatures)) {
+        if ($this->numUsableFeatures === 0 && count($this->selectedFeatures) === 0) {
             return $allFeatures;
         }
 
-        if (!empty($this->selectedFeatures)) {
+        if (count($this->selectedFeatures) > 0) {
             return $this->selectedFeatures;
         }
 
@@ -406,7 +412,7 @@ protected static function isCategoricalColumn(array $columnValues): bool
         //	  all values in that column (Lower than or equal to %20 of all values)
         $numericValues = array_filter($columnValues, 'is_numeric');
         $floatValues = array_filter($columnValues, 'is_float');
-        if (!empty($floatValues)) {
+        if (count($floatValues) > 0) {
             return false;
         }
 
@@ -463,7 +469,7 @@ protected function predictSample(array $sample)
         $node = $this->tree;
         do {
             if ($node->isTerminal) {
-                break;
+                return $node->classValue;
             }
 
             if ($node->evaluate($sample)) {
@@ -473,6 +479,6 @@ protected function predictSample(array $sample)
             }
         } while ($node);
 
-        return $node !== null ? $node->classValue : $this->labels[0];
+        return $this->labels[0];
     }
 }
diff --git a/src/Classification/DecisionTree/DecisionTreeLeaf.php b/src/Classification/DecisionTree/DecisionTreeLeaf.php
index 649c7433..04af3d62 100644
--- a/src/Classification/DecisionTree/DecisionTreeLeaf.php
+++ b/src/Classification/DecisionTree/DecisionTreeLeaf.php
@@ -119,7 +119,7 @@ public function getNodeImpurityDecrease(int $parentRecordCount): float
     /**
      * Returns HTML representation of the node including children nodes
      */
-    public function getHTML($columnNames = null): string
+    public function getHTML(?array $columnNames = null): string
     {
         if ($this->isTerminal) {
             $value = "<b>${this}->classValue</b>";
@@ -131,7 +131,7 @@ public function getHTML($columnNames = null): string
                 $col = "col_$this->columnIndex";
             }
 
-            if (!preg_match('/^[<>=]{1,2}/', (string) $value)) {
+            if ((bool) preg_match('/^[<>=]{1,2}/', (string) $value) === false) {
                 $value = "=${value}";
             }
 
diff --git a/src/Classification/Ensemble/AdaBoost.php b/src/Classification/Ensemble/AdaBoost.php
index 3859295a..fdaeb63e 100644
--- a/src/Classification/Ensemble/AdaBoost.php
+++ b/src/Classification/Ensemble/AdaBoost.php
@@ -100,7 +100,7 @@ public function train(array $samples, array $targets): void
     {
         // Initialize usual variables
         $this->labels = array_keys(array_count_values($targets));
-        if (count($this->labels) != 2) {
+        if (count($this->labels) !== 2) {
             throw new InvalidArgumentException('AdaBoost is a binary classifier and can classify between two classes only');
         }
 
@@ -159,13 +159,10 @@ public function predictSample(array $sample)
     protected function getBestClassifier(): Classifier
     {
         $ref = new ReflectionClass($this->baseClassifier);
-        if (!empty($this->classifierOptions)) {
-            $classifier = $ref->newInstanceArgs($this->classifierOptions);
-        } else {
-            $classifier = $ref->newInstance();
-        }
+        /** @var Classifier $classifier */
+        $classifier = count($this->classifierOptions) === 0 ? $ref->newInstance() : $ref->newInstanceArgs($this->classifierOptions);
 
-        if (is_subclass_of($classifier, WeightedClassifier::class)) {
+        if ($classifier instanceof WeightedClassifier) {
             $classifier->setSampleWeights($this->weights);
             $classifier->train($this->samples, $this->targets);
         } else {
diff --git a/src/Classification/Ensemble/Bagging.php b/src/Classification/Ensemble/Bagging.php
index b73a1d39..26cc7a6d 100644
--- a/src/Classification/Ensemble/Bagging.php
+++ b/src/Classification/Ensemble/Bagging.php
@@ -51,16 +51,6 @@ class Bagging implements Classifier
      */
     protected $subsetRatio = 0.7;
 
-    /**
-     * @var array
-     */
-    private $targets = [];
-
-    /**
-     * @var array
-     */
-    private $samples = [];
-
     /**
      * Creates an ensemble classifier with given number of base classifiers
      * Default number of base classifiers is 50.
@@ -146,11 +136,8 @@ protected function initClassifiers(): array
         $classifiers = [];
         for ($i = 0; $i < $this->numClassifier; ++$i) {
             $ref = new ReflectionClass($this->classifier);
-            if (!empty($this->classifierOptions)) {
-                $obj = $ref->newInstanceArgs($this->classifierOptions);
-            } else {
-                $obj = $ref->newInstance();
-            }
+            /** @var Classifier $obj */
+            $obj = count($this->classifierOptions) === 0 ? $ref->newInstance() : $ref->newInstanceArgs($this->classifierOptions);
 
             $classifiers[] = $this->initSingleClassifier($obj);
         }
diff --git a/src/Classification/KNearestNeighbors.php b/src/Classification/KNearestNeighbors.php
index cac54163..9b78baa8 100644
--- a/src/Classification/KNearestNeighbors.php
+++ b/src/Classification/KNearestNeighbors.php
@@ -45,8 +45,7 @@ public function __construct(int $k = 3, ?Distance $distanceMetric = null)
     protected function predictSample(array $sample)
     {
         $distances = $this->kNeighborsDistances($sample);
-
-        $predictions = array_combine(array_values($this->targets), array_fill(0, count($this->targets), 0));
+        $predictions = (array) array_combine(array_values($this->targets), array_fill(0, count($this->targets), 0));
 
         foreach (array_keys($distances) as $index) {
             ++$predictions[$this->targets[$index]];
diff --git a/src/Classification/Linear/Adaline.php b/src/Classification/Linear/Adaline.php
index a1337328..797cdc9c 100644
--- a/src/Classification/Linear/Adaline.php
+++ b/src/Classification/Linear/Adaline.php
@@ -55,7 +55,7 @@ public function __construct(
      * Adapts the weights with respect to given samples and targets
      * by use of gradient descent learning rule
      */
-    protected function runTraining(array $samples, array $targets)
+    protected function runTraining(array $samples, array $targets): void
     {
         // The cost function is the sum of squares
         $callback = function ($weights, $sample, $target) {
@@ -70,6 +70,6 @@ protected function runTraining(array $samples, array $targets)
 
         $isBatch = $this->trainingType == self::BATCH_TRAINING;
 
-        return parent::runGradientDescent($samples, $targets, $callback, $isBatch);
+        parent::runGradientDescent($samples, $targets, $callback, $isBatch);
     }
 }
diff --git a/src/Classification/Linear/DecisionStump.php b/src/Classification/Linear/DecisionStump.php
index c83d339e..258939e3 100644
--- a/src/Classification/Linear/DecisionStump.php
+++ b/src/Classification/Linear/DecisionStump.php
@@ -119,13 +119,13 @@ protected function trainBinary(array $samples, array $targets, array $labels): v
 
         // Check the size of the weights given.
         // If none given, then assign 1 as a weight to each sample
-        if (!empty($this->weights)) {
+        if (count($this->weights) === 0) {
+            $this->weights = array_fill(0, count($samples), 1);
+        } else {
             $numWeights = count($this->weights);
-            if ($numWeights != count($samples)) {
+            if ($numWeights !== count($samples)) {
                 throw new InvalidArgumentException('Number of sample weights does not match with number of samples');
             }
-        } else {
-            $this->weights = array_fill(0, count($samples), 1);
         }
 
         // Determine type of each column as either "continuous" or "nominal"
@@ -134,7 +134,7 @@ protected function trainBinary(array $samples, array $targets, array $labels): v
         // Try to find the best split in the columns of the dataset
         // by calculating error rate for each split point in each column
         $columns = range(0, count($samples[0]) - 1);
-        if ($this->givenColumnIndex != self::AUTO_SELECT) {
+        if ($this->givenColumnIndex !== self::AUTO_SELECT) {
             $columns = [$this->givenColumnIndex];
         }
 
@@ -184,7 +184,7 @@ protected function getBestNumericalSplit(array $samples, array $targets, int $co
             // the average value for the cut point
             $threshold = array_sum($values) / (float) count($values);
             [$errorRate, $prob] = $this->calculateErrorRate($targets, $threshold, $operator, $values);
-            if ($split === [] || $errorRate < $split['trainingErrorRate']) {
+            if (!isset($split['trainingErrorRate']) || $errorRate < $split['trainingErrorRate']) {
                 $split = [
                     'value' => $threshold,
                     'operator' => $operator,
@@ -224,8 +224,7 @@ protected function getBestNominalSplit(array $samples, array $targets, int $col)
         foreach (['=', '!='] as $operator) {
             foreach ($distinctVals as $val) {
                 [$errorRate, $prob] = $this->calculateErrorRate($targets, $val, $operator, $values);
-
-                if ($split === [] || $split['trainingErrorRate'] < $errorRate) {
+                if (!isset($split['trainingErrorRate']) || $split['trainingErrorRate'] < $errorRate) {
                     $split = [
                         'value' => $val,
                         'operator' => $operator,
diff --git a/src/Classification/Linear/Perceptron.php b/src/Classification/Linear/Perceptron.php
index adc6b36a..36cd4d1f 100644
--- a/src/Classification/Linear/Perceptron.php
+++ b/src/Classification/Linear/Perceptron.php
@@ -60,11 +60,6 @@ class Perceptron implements Classifier, IncrementalEstimator
      */
     protected $enableEarlyStop = true;
 
-    /**
-     * @var array
-     */
-    protected $costValues = [];
-
     /**
      * Initalize a perceptron classifier with given learning rate and maximum
      * number of iterations used while training the perceptron
@@ -156,7 +151,7 @@ protected function resetBinary(): void
      * Trains the perceptron model with Stochastic Gradient Descent optimization
      * to get the correct set of weights
      */
-    protected function runTraining(array $samples, array $targets)
+    protected function runTraining(array $samples, array $targets): void
     {
         // The cost function is the sum of squares
         $callback = function ($weights, $sample, $target) {
@@ -176,7 +171,7 @@ protected function runTraining(array $samples, array $targets)
      * Executes a Gradient Descent algorithm for
      * the given cost function
      */
-    protected function runGradientDescent(array $samples, array $targets, Closure $gradientFunc, bool $isBatch = false)
+    protected function runGradientDescent(array $samples, array $targets, Closure $gradientFunc, bool $isBatch = false): void
     {
         $class = $isBatch ? GD::class : StochasticGD::class;
 
diff --git a/src/Clustering/FuzzyCMeans.php b/src/Clustering/FuzzyCMeans.php
index 5e6fa0c0..db42fe94 100644
--- a/src/Clustering/FuzzyCMeans.php
+++ b/src/Clustering/FuzzyCMeans.php
@@ -108,8 +108,7 @@ public function cluster(array $samples): array
             $column = array_column($this->membership, $k);
             arsort($column);
             reset($column);
-            $i = key($column);
-            $cluster = $this->clusters[$i];
+            $cluster = $this->clusters[key($column)];
             $cluster->attach(new Point($this->samples[$k]));
         }
 
@@ -152,7 +151,7 @@ protected function generateRandomMembership(int $rows, int $cols): void
     protected function updateClusters(): void
     {
         $dim = $this->space->getDimension();
-        if (empty($this->clusters)) {
+        if (count($this->clusters) === 0) {
             for ($i = 0; $i < $this->clustersNumber; ++$i) {
                 $this->clusters[] = new Cluster($this->space, array_fill(0, $dim, 0.0));
             }
@@ -171,11 +170,11 @@ protected function updateClusters(): void
         }
     }
 
-    protected function getMembershipRowTotal(int $row, int $col, bool $multiply)
+    protected function getMembershipRowTotal(int $row, int $col, bool $multiply): float
     {
         $sum = 0.0;
         for ($k = 0; $k < $this->sampleCount; ++$k) {
-            $val = pow($this->membership[$row][$k], $this->fuzziness);
+            $val = $this->membership[$row][$k] ** $this->fuzziness;
             if ($multiply) {
                 $val *= $this->samples[$k][$col];
             }
@@ -211,7 +210,7 @@ protected function getDistanceCalc(int $row, int $col): float
                 $this->samples[$col]
             );
 
-            $val = pow($dist1 / $dist2, 2.0 / ($this->fuzziness - 1));
+            $val = ($dist1 / $dist2) ** 2.0 / ($this->fuzziness - 1);
             $sum += $val;
         }
 
@@ -223,7 +222,7 @@ protected function getDistanceCalc(int $row, int $col): float
      * and all cluster centers. This method returns the summation of all
      * these distances
      */
-    protected function getObjective()
+    protected function getObjective(): float
     {
         $sum = 0.0;
         $distance = new Euclidean();
diff --git a/src/Clustering/KMeans/Cluster.php b/src/Clustering/KMeans/Cluster.php
index 731d79c4..fa73e4bb 100644
--- a/src/Clustering/KMeans/Cluster.php
+++ b/src/Clustering/KMeans/Cluster.php
@@ -4,12 +4,11 @@
 
 namespace Phpml\Clustering\KMeans;
 
-use Countable;
 use IteratorAggregate;
 use LogicException;
 use SplObjectStorage;
 
-class Cluster extends Point implements IteratorAggregate, Countable
+class Cluster extends Point implements IteratorAggregate
 {
     /**
      * @var Space
@@ -32,10 +31,10 @@ public function getPoints(): array
     {
         $points = [];
         foreach ($this->points as $point) {
-            if (!empty($point->label)) {
-                $points[$point->label] = $point->toArray();
-            } else {
+            if (count($point->label) === 0) {
                 $points[] = $point->toArray();
+            } else {
+                $points[$point->label] = $point->toArray();
             }
         }
 
@@ -106,10 +105,7 @@ public function getIterator()
         return $this->points;
     }
 
-    /**
-     * @return mixed
-     */
-    public function count()
+    public function count(): int
     {
         return count($this->points);
     }
diff --git a/src/Clustering/KMeans/Point.php b/src/Clustering/KMeans/Point.php
index 7d41093c..f6ad3f57 100644
--- a/src/Clustering/KMeans/Point.php
+++ b/src/Clustering/KMeans/Point.php
@@ -6,7 +6,7 @@
 
 use ArrayAccess;
 
-class Point implements ArrayAccess
+class Point implements ArrayAccess, \Countable
 {
     /**
      * @var int
@@ -23,6 +23,9 @@ class Point implements ArrayAccess
      */
     protected $label;
 
+    /**
+     * @param mixed $label
+     */
     public function __construct(array $coordinates, $label = null)
     {
         $this->dimension = count($coordinates);
@@ -36,7 +39,7 @@ public function toArray(): array
     }
 
     /**
-     * @return int|mixed
+     * @return float|int
      */
     public function getDistanceWith(self $point, bool $precise = true)
     {
@@ -50,9 +53,9 @@ public function getDistanceWith(self $point, bool $precise = true)
     }
 
     /**
-     * @return mixed
+     * @param Point[] $points
      */
-    public function getClosest(array $points)
+    public function getClosest(array $points): ?self
     {
         $minPoint = null;
 
@@ -114,4 +117,9 @@ public function offsetUnset($offset): void
     {
         unset($this->coordinates[$offset]);
     }
+
+    public function count(): int
+    {
+        return count($this->coordinates);
+    }
 }
diff --git a/src/Clustering/KMeans/Space.php b/src/Clustering/KMeans/Space.php
index aa60eb3c..566d691d 100644
--- a/src/Clustering/KMeans/Space.php
+++ b/src/Clustering/KMeans/Space.php
@@ -28,6 +28,8 @@ public function __construct(int $dimension)
     public function toArray(): array
     {
         $points = [];
+
+        /** @var Point $point */
         foreach ($this as $point) {
             $points[] = $point->toArray();
         }
@@ -35,9 +37,12 @@ public function toArray(): array
         return ['points' => $points];
     }
 
+    /**
+     * @param mixed $label
+     */
     public function newPoint(array $coordinates, $label = null): Point
     {
-        if (count($coordinates) != $this->dimension) {
+        if (count($coordinates) !== $this->dimension) {
             throw new LogicException('('.implode(',', $coordinates).') is not a point of this space');
         }
 
@@ -45,7 +50,8 @@ public function newPoint(array $coordinates, $label = null): Point
     }
 
     /**
-     * @param null $data
+     * @param mixed $label
+     * @param mixed $data
      */
     public function addPoint(array $coordinates, $label = null, $data = null): void
     {
@@ -53,8 +59,8 @@ public function addPoint(array $coordinates, $label = null, $data = null): void
     }
 
     /**
-     * @param Point $point
-     * @param null  $data
+     * @param object $point
+     * @param mixed  $data
      */
     public function attach($point, $data = null): void
     {
@@ -82,10 +88,16 @@ public function getBoundaries()
         $min = $this->newPoint(array_fill(0, $this->dimension, null));
         $max = $this->newPoint(array_fill(0, $this->dimension, null));
 
+        /** @var self $point */
         foreach ($this as $point) {
             for ($n = 0; $n < $this->dimension; ++$n) {
-                ($min[$n] > $point[$n] || $min[$n] === null) && $min[$n] = $point[$n];
-                ($max[$n] < $point[$n] || $max[$n] === null) && $max[$n] = $point[$n];
+                if ($min[$n] === null || $min[$n] > $point[$n]) {
+                    $min[$n] = $point[$n];
+                }
+
+                if ($max[$n] === null || $max[$n] < $point[$n]) {
+                    $max[$n] = $point[$n];
+                }
             }
         }
 
@@ -141,7 +153,10 @@ protected function initializeClusters(int $clustersNumber, int $initMethod): arr
         return $clusters;
     }
 
-    protected function iterate($clusters): bool
+    /**
+     * @param Cluster[] $clusters
+     */
+    protected function iterate(array $clusters): bool
     {
         $convergence = true;
 
@@ -164,10 +179,12 @@ protected function iterate($clusters): bool
             }
         }
 
+        /** @var Cluster $cluster */
         foreach ($attach as $cluster) {
             $cluster->attachAll($attach[$cluster]);
         }
 
+        /** @var Cluster $cluster */
         foreach ($detach as $cluster) {
             $cluster->detachAll($detach[$cluster]);
         }
@@ -179,23 +196,36 @@ protected function iterate($clusters): bool
         return $convergence;
     }
 
+    /**
+     * @return Cluster[]
+     */
     protected function initializeKMPPClusters(int $clustersNumber): array
     {
         $clusters = [];
         $this->rewind();
 
-        $clusters[] = new Cluster($this, $this->current()->getCoordinates());
+        /** @var Point $current */
+        $current = $this->current();
+
+        $clusters[] = new Cluster($this, $current->getCoordinates());
 
         $distances = new SplObjectStorage();
 
         for ($i = 1; $i < $clustersNumber; ++$i) {
             $sum = 0;
+            /** @var Point $point */
             foreach ($this as $point) {
-                $distance = $point->getDistanceWith($point->getClosest($clusters));
+                $closest = $point->getClosest($clusters);
+                if ($closest === null) {
+                    continue;
+                }
+
+                $distance = $point->getDistanceWith($closest);
                 $sum += $distances[$point] = $distance;
             }
 
             $sum = random_int(0, (int) $sum);
+            /** @var Point $point */
             foreach ($this as $point) {
                 $sum -= $distances[$point];
 
@@ -212,6 +242,9 @@ protected function initializeKMPPClusters(int $clustersNumber): array
         return $clusters;
     }
 
+    /**
+     * @return Cluster[]
+     */
     private function initializeRandomClusters(int $clustersNumber): array
     {
         $clusters = [];
diff --git a/src/CrossValidation/Split.php b/src/CrossValidation/Split.php
index bffb59aa..e9d401c4 100644
--- a/src/CrossValidation/Split.php
+++ b/src/CrossValidation/Split.php
@@ -60,7 +60,7 @@ public function getTestLabels(): array
         return $this->testLabels;
     }
 
-    abstract protected function splitDataset(Dataset $dataset, float $testSize);
+    abstract protected function splitDataset(Dataset $dataset, float $testSize): void;
 
     protected function seedGenerator(?int $seed = null): void
     {
diff --git a/src/CrossValidation/StratifiedRandomSplit.php b/src/CrossValidation/StratifiedRandomSplit.php
index 85dd5d13..4974d4ce 100644
--- a/src/CrossValidation/StratifiedRandomSplit.php
+++ b/src/CrossValidation/StratifiedRandomSplit.php
@@ -27,6 +27,7 @@ private function splitByTarget(Dataset $dataset): array
         $samples = $dataset->getSamples();
 
         $uniqueTargets = array_unique($targets);
+        /** @var array $split */
         $split = array_combine($uniqueTargets, array_fill(0, count($uniqueTargets), []));
 
         foreach ($samples as $key => $sample) {
diff --git a/src/Dataset/CsvDataset.php b/src/Dataset/CsvDataset.php
index 631c6a6e..cdd387fb 100644
--- a/src/Dataset/CsvDataset.php
+++ b/src/Dataset/CsvDataset.php
@@ -29,14 +29,14 @@ public function __construct(string $filepath, int $features, bool $headingRow =
 
         if ($headingRow) {
             $data = fgetcsv($handle, $maxLineLength, $delimiter);
-            $this->columnNames = array_slice($data, 0, $features);
+            $this->columnNames = array_slice((array) $data, 0, $features);
         } else {
             $this->columnNames = range(0, $features - 1);
         }
 
         $samples = $targets = [];
         while (($data = fgetcsv($handle, $maxLineLength, $delimiter)) !== false) {
-            $samples[] = array_slice($data, 0, $features);
+            $samples[] = array_slice((array) $data, 0, $features);
             $targets[] = $data[$features];
         }
 
diff --git a/src/Dataset/SvmDataset.php b/src/Dataset/SvmDataset.php
index e5f2a86e..334ec6c2 100644
--- a/src/Dataset/SvmDataset.php
+++ b/src/Dataset/SvmDataset.php
@@ -23,8 +23,8 @@ private static function readProblem(string $filePath): array
         $samples = [];
         $targets = [];
         $maxIndex = 0;
-        while (($line = fgets($handle)) !== false) {
-            [$sample, $target, $maxIndex] = self::processLine($line, $maxIndex);
+        while (false !== $line = fgets($handle)) {
+            [$sample, $target, $maxIndex] = self::processLine((string) $line, $maxIndex);
             $samples[] = $sample;
             $targets[] = $target;
         }
@@ -38,6 +38,9 @@ private static function readProblem(string $filePath): array
         return [$samples, $targets];
     }
 
+    /**
+     * @return resource
+     */
     private static function openFile(string $filePath)
     {
         if (!file_exists($filePath)) {
diff --git a/src/DimensionReduction/KernelPCA.php b/src/DimensionReduction/KernelPCA.php
index 29deb4c4..41c7340f 100644
--- a/src/DimensionReduction/KernelPCA.php
+++ b/src/DimensionReduction/KernelPCA.php
@@ -5,7 +5,6 @@
 namespace Phpml\DimensionReduction;
 
 use Closure;
-use Exception;
 use Phpml\Exception\InvalidArgumentException;
 use Phpml\Exception\InvalidOperationException;
 use Phpml\Math\Distance\Euclidean;
@@ -59,8 +58,7 @@ class KernelPCA extends PCA
      */
     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, true)) {
+        if (!in_array($kernel, [self::KERNEL_RBF, self::KERNEL_SIGMOID, self::KERNEL_LAPLACIAN, self::KERNEL_LINEAR], true)) {
             throw new InvalidArgumentException('KernelPCA can be initialized with the following kernels only: Linear, RBF, Sigmoid and Laplacian');
         }
 
@@ -190,7 +188,7 @@ protected function getKernel(): Closure
                 return function ($x, $y) {
                     $res = Matrix::dot($x, $y)[0] + 1.0;
 
-                    return tanh($this->gamma * $res);
+                    return tanh((float) $this->gamma * $res);
                 };
 
             case self::KERNEL_LAPLACIAN:
@@ -203,7 +201,7 @@ protected function getKernel(): Closure
 
             default:
                 // Not reached
-                throw new Exception(sprintf('KernelPCA initialized with invalid kernel: %d', $this->kernel));
+                throw new InvalidArgumentException(sprintf('KernelPCA initialized with invalid kernel: %d', $this->kernel));
         }
     }
 
diff --git a/src/DimensionReduction/PCA.php b/src/DimensionReduction/PCA.php
index fa651da9..5556558f 100644
--- a/src/DimensionReduction/PCA.php
+++ b/src/DimensionReduction/PCA.php
@@ -115,7 +115,7 @@ protected function calculateMeans(array $data, int $n): void
      */
     protected function normalize(array $data, int $n): array
     {
-        if (empty($this->means)) {
+        if (count($this->means) === 0) {
             $this->calculateMeans($data, $n);
         }
 
diff --git a/src/Estimator.php b/src/Estimator.php
index b4268896..a0541089 100644
--- a/src/Estimator.php
+++ b/src/Estimator.php
@@ -6,7 +6,7 @@
 
 interface Estimator
 {
-    public function train(array $samples, array $targets);
+    public function train(array $samples, array $targets): void;
 
     /**
      * @return mixed
diff --git a/src/FeatureExtraction/TfIdfTransformer.php b/src/FeatureExtraction/TfIdfTransformer.php
index 4a478c30..d1ac35db 100644
--- a/src/FeatureExtraction/TfIdfTransformer.php
+++ b/src/FeatureExtraction/TfIdfTransformer.php
@@ -15,7 +15,7 @@ class TfIdfTransformer implements Transformer
 
     public function __construct(array $samples = [])
     {
-        if (!empty($samples)) {
+        if (count($samples) > 0) {
             $this->fit($samples);
         }
     }
diff --git a/src/FeatureSelection/SelectKBest.php b/src/FeatureSelection/SelectKBest.php
index b0ff6449..36b4245a 100644
--- a/src/FeatureSelection/SelectKBest.php
+++ b/src/FeatureSelection/SelectKBest.php
@@ -43,7 +43,7 @@ public function __construct(int $k = 10, ?ScoringFunction $scoringFunction = nul
 
     public function fit(array $samples, ?array $targets = null): void
     {
-        if ($targets === null || empty($targets)) {
+        if ($targets === null || count($targets) === 0) {
             throw new InvalidArgumentException('The array has zero elements');
         }
 
diff --git a/src/Helper/OneVsRest.php b/src/Helper/OneVsRest.php
index e68b10d0..691fb643 100644
--- a/src/Helper/OneVsRest.php
+++ b/src/Helper/OneVsRest.php
@@ -51,18 +51,13 @@ public function reset(): void
     protected function trainByLabel(array $samples, array $targets, array $allLabels = []): void
     {
         // Overwrites the current value if it exist. $allLabels must be provided for each partialTrain run.
-        if (!empty($allLabels)) {
-            $this->allLabels = $allLabels;
-        } else {
-            $this->allLabels = array_keys(array_count_values($targets));
-        }
-
+        $this->allLabels = count($allLabels) === 0 ? array_keys(array_count_values($targets)) : $allLabels;
         sort($this->allLabels, SORT_STRING);
 
         // If there are only two targets, then there is no need to perform OvR
-        if (count($this->allLabels) == 2) {
+        if (count($this->allLabels) === 2) {
             // Init classifier if required.
-            if (empty($this->classifiers)) {
+            if (count($this->classifiers) === 0) {
                 $this->classifiers[0] = $this->getClassifierCopy();
             }
 
@@ -72,7 +67,7 @@ protected function trainByLabel(array $samples, array $targets, array $allLabels
 
             foreach ($this->allLabels as $label) {
                 // Init classifier if required.
-                if (empty($this->classifiers[$label])) {
+                if (!isset($this->classifiers[$label])) {
                     $this->classifiers[$label] = $this->getClassifierCopy();
                 }
 
@@ -92,10 +87,8 @@ protected function trainByLabel(array $samples, array $targets, array $allLabels
 
     /**
      * Returns an instance of the current class after cleaning up OneVsRest stuff.
-     *
-     * @return Classifier|OneVsRest
      */
-    protected function getClassifierCopy()
+    protected function getClassifierCopy(): Classifier
     {
         // Clone the current classifier, so that
         // we don't mess up its variables while training
@@ -111,7 +104,7 @@ protected function getClassifierCopy()
      */
     protected function predictSample(array $sample)
     {
-        if (count($this->allLabels) == 2) {
+        if (count($this->allLabels) === 2) {
             return $this->classifiers[0]->predictSampleBinary($sample);
         }
 
diff --git a/src/Helper/Optimizer/ConjugateGradient.php b/src/Helper/Optimizer/ConjugateGradient.php
index 67210abd..d7c064f1 100644
--- a/src/Helper/Optimizer/ConjugateGradient.php
+++ b/src/Helper/Optimizer/ConjugateGradient.php
@@ -91,7 +91,7 @@ protected function cost(array $theta): float
     {
         [$cost] = parent::gradient($theta);
 
-        return array_sum($cost) / $this->sampleCount;
+        return array_sum($cost) / (int) $this->sampleCount;
     }
 
     /**
diff --git a/src/Helper/Optimizer/GD.php b/src/Helper/Optimizer/GD.php
index 11577c9d..28320329 100644
--- a/src/Helper/Optimizer/GD.php
+++ b/src/Helper/Optimizer/GD.php
@@ -5,6 +5,7 @@
 namespace Phpml\Helper\Optimizer;
 
 use Closure;
+use Phpml\Exception\InvalidOperationException;
 
 /**
  * Batch version of Gradient Descent to optimize the weights
@@ -59,6 +60,10 @@ protected function gradient(array $theta): array
         $gradient = [];
         $totalPenalty = 0;
 
+        if ($this->gradientCb === null) {
+            throw new InvalidOperationException('Gradient callback is not defined');
+        }
+
         foreach ($this->samples as $index => $sample) {
             $target = $this->targets[$index];
 
diff --git a/src/Helper/Optimizer/Optimizer.php b/src/Helper/Optimizer/Optimizer.php
index dba0cd06..99a82ab3 100644
--- a/src/Helper/Optimizer/Optimizer.php
+++ b/src/Helper/Optimizer/Optimizer.php
@@ -37,9 +37,9 @@ public function __construct(int $dimensions)
         }
     }
 
-    public function setTheta(array $theta)
+    public function setTheta(array $theta): self
     {
-        if (count($theta) != $this->dimensions) {
+        if (count($theta) !== $this->dimensions) {
             throw new InvalidArgumentException(sprintf('Number of values in the weights array should be %s', $this->dimensions));
         }
 
@@ -52,5 +52,5 @@ public function setTheta(array $theta)
      * Executes the optimization with the given samples & targets
      * and returns the weights
      */
-    abstract public function runOptimization(array $samples, array $targets, Closure $gradientCb);
+    abstract public function runOptimization(array $samples, array $targets, Closure $gradientCb): array;
 }
diff --git a/src/Helper/Optimizer/StochasticGD.php b/src/Helper/Optimizer/StochasticGD.php
index c4fabd33..9927c3f2 100644
--- a/src/Helper/Optimizer/StochasticGD.php
+++ b/src/Helper/Optimizer/StochasticGD.php
@@ -6,6 +6,7 @@
 
 use Closure;
 use Phpml\Exception\InvalidArgumentException;
+use Phpml\Exception\InvalidOperationException;
 
 /**
  * Stochastic Gradient Descent optimization method
@@ -34,7 +35,7 @@ class StochasticGD extends Optimizer
      *
      * @var \Closure|null
      */
-    protected $gradientCb = null;
+    protected $gradientCb;
 
     /**
      * Maximum number of iterations used to train the model
@@ -89,9 +90,9 @@ public function __construct(int $dimensions)
         $this->dimensions = $dimensions;
     }
 
-    public function setTheta(array $theta)
+    public function setTheta(array $theta): Optimizer
     {
-        if (count($theta) != $this->dimensions + 1) {
+        if (count($theta) !== $this->dimensions + 1) {
             throw new InvalidArgumentException(sprintf('Number of values in the weights array should be %s', $this->dimensions + 1));
         }
 
@@ -156,7 +157,7 @@ public function setMaxIterations(int $maxIterations)
      * 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.
      */
-    public function runOptimization(array $samples, array $targets, Closure $gradientCb): ?array
+    public function runOptimization(array $samples, array $targets, Closure $gradientCb): array
     {
         $this->samples = $samples;
         $this->targets = $targets;
@@ -175,7 +176,7 @@ public function runOptimization(array $samples, array $targets, Closure $gradien
 
             // Save the best theta in the "pocket" so that
             // any future set of theta worse than this will be disregarded
-            if ($bestTheta == null || $cost <= $bestScore) {
+            if ($bestTheta === null || $cost <= $bestScore) {
                 $bestTheta = $theta;
                 $bestScore = $cost;
             }
@@ -210,6 +211,10 @@ protected function updateTheta(): float
         $jValue = 0.0;
         $theta = $this->theta;
 
+        if ($this->gradientCb === null) {
+            throw new InvalidOperationException('Gradient callback is not defined');
+        }
+
         foreach ($this->samples as $index => $sample) {
             $target = $this->targets[$index];
 
@@ -254,7 +259,7 @@ function ($w1, $w2) {
 
         // Check if the last two cost values are almost the same
         $costs = array_slice($this->costValues, -2);
-        if (count($costs) == 2 && abs($costs[1] - $costs[0]) < $this->threshold) {
+        if (count($costs) === 2 && abs($costs[1] - $costs[0]) < $this->threshold) {
             return true;
         }
 
diff --git a/src/IncrementalEstimator.php b/src/IncrementalEstimator.php
index e356be01..600bfbb2 100644
--- a/src/IncrementalEstimator.php
+++ b/src/IncrementalEstimator.php
@@ -6,5 +6,5 @@
 
 interface IncrementalEstimator
 {
-    public function partialTrain(array $samples, array $targets, array $labels = []);
+    public function partialTrain(array $samples, array $targets, array $labels = []): void;
 }
diff --git a/src/Math/Comparison.php b/src/Math/Comparison.php
index d9ad00cc..d1330a98 100644
--- a/src/Math/Comparison.php
+++ b/src/Math/Comparison.php
@@ -9,6 +9,9 @@
 class Comparison
 {
     /**
+     * @param mixed $a
+     * @param mixed $b
+     *
      * @throws InvalidArgumentException
      */
     public static function compare($a, $b, string $operator): bool
diff --git a/src/Math/LinearAlgebra/EigenvalueDecomposition.php b/src/Math/LinearAlgebra/EigenvalueDecomposition.php
index 3d7484dc..e0f16397 100644
--- a/src/Math/LinearAlgebra/EigenvalueDecomposition.php
+++ b/src/Math/LinearAlgebra/EigenvalueDecomposition.php
@@ -3,25 +3,25 @@
 declare(strict_types=1);
 
 /**
- *	Class to obtain eigenvalues and eigenvectors of a real matrix.
+ * Class to obtain eigenvalues and eigenvectors of a real matrix.
  *
- *	If A is symmetric, then A = V*D*V' where the eigenvalue matrix D
- *	is diagonal and the eigenvector matrix V is orthogonal (i.e.
- *	A = V.times(D.times(V.transpose())) and V.times(V.transpose())
- *	equals the identity matrix).
+ * If A is symmetric, then A = V*D*V' where the eigenvalue matrix D
+ * is diagonal and the eigenvector matrix V is orthogonal (i.e.
+ * A = V.times(D.times(V.transpose())) and V.times(V.transpose())
+ * equals the identity matrix).
  *
- *	If A is not symmetric, then the eigenvalue matrix D is block diagonal
- *	with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
- *	lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda].  The
- *	columns of V represent the eigenvectors in the sense that A*V = V*D,
- *	i.e. A.times(V) equals V.times(D).  The matrix V may be badly
- *	conditioned, or even singular, so the validity of the equation
- *	A = V*D*inverse(V) depends upon V.cond().
+ * If A is not symmetric, then the eigenvalue matrix D is block diagonal
+ * with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
+ * lambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda].  The
+ * columns of V represent the eigenvectors in the sense that A*V = V*D,
+ * i.e. A.times(V) equals V.times(D).  The matrix V may be badly
+ * conditioned, or even singular, so the validity of the equation
+ * A = V*D*inverse(V) depends upon V.cond().
  *
- *	@author Paul Meagher
- *	@license PHP v3.0
+ * @author Paul Meagher
+ * @license PHP v3.0
  *
- *	@version 1.1
+ * @version 1.1
  *
  *  Slightly changed to adapt the original code to PHP-ML library
  *  @date 2017/04/11
@@ -36,83 +36,79 @@
 class EigenvalueDecomposition
 {
     /**
-     *	Row and column dimension (square matrix).
+     * Row and column dimension (square matrix).
      *
-     *	@var int
+     * @var int
      */
     private $n;
 
     /**
-     *	Internal symmetry flag.
+     * Arrays for internal storage of eigenvalues.
      *
-     *	@var bool
+     * @var array
      */
-    private $symmetric;
+    private $d = [];
 
     /**
-     *	Arrays for internal storage of eigenvalues.
-     *
-     *	@var array
+     * @var array
      */
-    private $d = [];
-
     private $e = [];
 
     /**
-     *	Array for internal storage of eigenvectors.
+     * Array for internal storage of eigenvectors.
      *
-     *	@var array
+     * @var array
      */
     private $V = [];
 
     /**
-     *	Array for internal storage of nonsymmetric Hessenberg form.
+     * Array for internal storage of nonsymmetric Hessenberg form.
      *
-     *	@var array
+     * @var array
      */
     private $H = [];
 
     /**
-     *	Working storage for nonsymmetric algorithm.
+     * Working storage for nonsymmetric algorithm.
      *
-     *	@var array
+     * @var array
      */
     private $ort = [];
 
     /**
-     *	Used for complex scalar division.
+     * Used for complex scalar division.
      *
-     *	@var float
+     * @var float
      */
     private $cdivr;
 
+    /**
+     * @var float
+     */
     private $cdivi;
 
-    private $A;
-
     /**
-     *	Constructor: Check for symmetry, then construct the eigenvalue decomposition
+     * Constructor: Check for symmetry, then construct the eigenvalue decomposition
      */
-    public function __construct(array $Arg)
+    public function __construct(array $arg)
     {
-        $this->A = $Arg;
-        $this->n = count($Arg[0]);
-        $this->symmetric = true;
+        $this->n = count($arg[0]);
+        $symmetric = true;
 
-        for ($j = 0; ($j < $this->n) & $this->symmetric; ++$j) {
-            for ($i = 0; ($i < $this->n) & $this->symmetric; ++$i) {
-                $this->symmetric = ($this->A[$i][$j] == $this->A[$j][$i]);
+        for ($j = 0; ($j < $this->n) & $symmetric; ++$j) {
+            for ($i = 0; ($i < $this->n) & $symmetric; ++$i) {
+                $symmetric = $arg[$i][$j] == $arg[$j][$i];
             }
         }
 
-        if ($this->symmetric) {
-            $this->V = $this->A;
+        if ($symmetric) {
+            $this->V = $arg;
             // Tridiagonalize.
             $this->tred2();
             // Diagonalize.
             $this->tql2();
         } else {
-            $this->H = $this->A;
+            $this->H = $arg;
             $this->ort = [];
             // Reduce to Hessenberg form.
             $this->orthes();
@@ -148,7 +144,7 @@ public function getEigenvectors(): array
     }
 
     /**
-     *	Return the real parts of the eigenvalues<br>
+     * Return the real parts of the eigenvalues<br>
      *  d = real(diag(D));
      */
     public function getRealEigenvalues(): array
@@ -157,7 +153,7 @@ public function getRealEigenvalues(): array
     }
 
     /**
-     *	Return the imaginary parts of the eigenvalues <br>
+     * Return the imaginary parts of the eigenvalues <br>
      *  d = imag(diag(D))
      */
     public function getImagEigenvalues(): array
@@ -166,7 +162,7 @@ public function getImagEigenvalues(): array
     }
 
     /**
-     *	Return the block diagonal eigenvalue matrix
+     * Return the block diagonal eigenvalue matrix
      */
     public function getDiagonalEigenvalues(): array
     {
@@ -187,7 +183,7 @@ public function getDiagonalEigenvalues(): array
     }
 
     /**
-     *	Symmetric Householder reduction to tridiagonal form.
+     * Symmetric Householder reduction to tridiagonal form.
      */
     private function tred2(): void
     {
@@ -308,12 +304,12 @@ private function tred2(): void
     }
 
     /**
-     *	Symmetric tridiagonal QL algorithm.
+     * Symmetric tridiagonal QL algorithm.
      *
-     *	This is derived from the Algol procedures tql2, by
-     *	Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
-     *	Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
-     *	Fortran subroutine in EISPACK.
+     * This is derived from the Algol procedures tql2, by
+     * Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+     * Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+     * Fortran subroutine in EISPACK.
      */
     private function tql2(): void
     {
@@ -341,10 +337,7 @@ private function tql2(): void
             // If m == l, $this->d[l] is an eigenvalue,
             // otherwise, iterate.
             if ($m > $l) {
-                $iter = 0;
                 do {
-                    // Could check iteration count here.
-                    ++$iter;
                     // Compute implicit shift
                     $g = $this->d[$l];
                     $p = ($this->d[$l + 1] - $g) / (2.0 * $this->e[$l]);
@@ -423,12 +416,12 @@ private function tql2(): void
     }
 
     /**
-     *	Nonsymmetric reduction to Hessenberg form.
+     * Nonsymmetric reduction to Hessenberg form.
      *
-     *	This is derived from the Algol procedures orthes and ortran,
-     *	by Martin and Wilkinson, Handbook for Auto. Comp.,
-     *	Vol.ii-Linear Algebra, and the corresponding
-     *	Fortran subroutines in EISPACK.
+     * This is derived from the Algol procedures orthes and ortran,
+     * by Martin and Wilkinson, Handbook for Auto. Comp.,
+     * Vol.ii-Linear Algebra, and the corresponding
+     * Fortran subroutines in EISPACK.
      */
     private function orthes(): void
     {
@@ -541,12 +534,12 @@ private function cdiv($xr, $xi, $yr, $yi): void
     }
 
     /**
-     *	Nonsymmetric reduction from Hessenberg to real Schur form.
+     * Nonsymmetric reduction from Hessenberg to real Schur form.
      *
-     *	Code is derived from the Algol procedure hqr2,
-     *	by Martin and Wilkinson, Handbook for Auto. Comp.,
-     *	Vol.ii-Linear Algebra, and the corresponding
-     *	Fortran subroutine in EISPACK.
+     * Code is derived from the Algol procedure hqr2,
+     * by Martin and Wilkinson, Handbook for Auto. Comp.,
+     * Vol.ii-Linear Algebra, and the corresponding
+     * Fortran subroutine in EISPACK.
      */
     private function hqr2(): void
     {
@@ -911,7 +904,7 @@ private function hqr2(): void
                             $y = $this->H[$i + 1][$i];
                             $vr = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i] - $q * $q;
                             $vi = ($this->d[$i] - $p) * 2.0 * $q;
-                            if ($vr == 0.0 & $vi == 0.0) {
+                            if ($vr == 0.0 && $vi == 0.0) {
                                 $vr = $eps * $norm * (abs($w) + abs($q) + abs($x) + abs($y) + abs($z));
                             }
 
@@ -943,7 +936,7 @@ private function hqr2(): void
 
         // Vectors of isolated roots
         for ($i = 0; $i < $nn; ++$i) {
-            if ($i < $low | $i > $high) {
+            if ($i < $low || $i > $high) {
                 for ($j = $i; $j < $nn; ++$j) {
                     $this->V[$i][$j] = $this->H[$i][$j];
                 }
diff --git a/src/Math/LinearAlgebra/LUDecomposition.php b/src/Math/LinearAlgebra/LUDecomposition.php
index f9e7300a..61f7c3f2 100644
--- a/src/Math/LinearAlgebra/LUDecomposition.php
+++ b/src/Math/LinearAlgebra/LUDecomposition.php
@@ -80,7 +80,7 @@ class LUDecomposition
      */
     public function __construct(Matrix $A)
     {
-        if ($A->getRows() != $A->getColumns()) {
+        if ($A->getRows() !== $A->getColumns()) {
             throw new MatrixException('Matrix is not square matrix');
         }
 
@@ -118,7 +118,7 @@ public function __construct(Matrix $A)
             // Find pivot and exchange if necessary.
             $p = $j;
             for ($i = $j + 1; $i < $this->m; ++$i) {
-                if (abs($LUcolj[$i]) > abs($LUcolj[$p])) {
+                if (abs($LUcolj[$i] ?? 0) > abs($LUcolj[$p] ?? 0)) {
                     $p = $i;
                 }
             }
@@ -204,7 +204,7 @@ public function getPivot(): array
      *
      * @see getPivot
      */
-    public function getDoublePivot()
+    public function getDoublePivot(): array
     {
         return $this->getPivot();
     }
diff --git a/src/Math/Matrix.php b/src/Math/Matrix.php
index 840d7469..a511f558 100644
--- a/src/Math/Matrix.php
+++ b/src/Math/Matrix.php
@@ -89,7 +89,7 @@ public function getColumns(): int
     /**
      * @throws MatrixException
      */
-    public function getColumnValues($column): array
+    public function getColumnValues(int $column): array
     {
         if ($column >= $this->columns) {
             throw new MatrixException('Column out of range');
@@ -125,7 +125,7 @@ public function isSquare(): bool
 
     public function transpose(): self
     {
-        if ($this->rows == 1) {
+        if ($this->rows === 1) {
             $matrix = array_map(function ($el) {
                 return [$el];
             }, $this->matrix[0]);
@@ -138,7 +138,7 @@ public function transpose(): self
 
     public function multiply(self $matrix): self
     {
-        if ($this->columns != $matrix->getRows()) {
+        if ($this->columns !== $matrix->getRows()) {
             throw new InvalidArgumentException('Inconsistent matrix supplied');
         }
 
@@ -166,6 +166,9 @@ public function multiply(self $matrix): self
         return new self($product, false);
     }
 
+    /**
+     * @param float|int $value
+     */
     public function divideByScalar($value): self
     {
         $newMatrix = [];
@@ -178,6 +181,9 @@ public function divideByScalar($value): self
         return new self($newMatrix, false);
     }
 
+    /**
+     * @param float|int $value
+     */
     public function multiplyByScalar($value): self
     {
         $newMatrix = [];
diff --git a/src/Math/Product.php b/src/Math/Product.php
index ab1e75a9..78f36931 100644
--- a/src/Math/Product.php
+++ b/src/Math/Product.php
@@ -14,7 +14,7 @@ public static function scalar(array $a, array $b)
         $product = 0;
         foreach ($a as $index => $value) {
             if (is_numeric($value) && is_numeric($b[$index])) {
-                $product += $value * $b[$index];
+                $product += (float) $value * (float) $b[$index];
             }
         }
 
diff --git a/src/Math/Set.php b/src/Math/Set.php
index fab2923a..b22d2f81 100644
--- a/src/Math/Set.php
+++ b/src/Math/Set.php
@@ -131,7 +131,7 @@ public function contains($element): bool
      */
     public function containsAll(array $elements): bool
     {
-        return !array_diff($elements, $this->elements);
+        return count(array_diff($elements, $this->elements)) === 0;
     }
 
     /**
@@ -149,7 +149,7 @@ public function getIterator(): ArrayIterator
 
     public function isEmpty(): bool
     {
-        return $this->cardinality() == 0;
+        return $this->cardinality() === 0;
     }
 
     public function cardinality(): int
diff --git a/src/Math/Statistic/ANOVA.php b/src/Math/Statistic/ANOVA.php
index 0118347e..f7b01c7e 100644
--- a/src/Math/Statistic/ANOVA.php
+++ b/src/Math/Statistic/ANOVA.php
@@ -31,7 +31,7 @@ public static function oneWayF(array $samples): array
         $samplesPerClass = array_map(function (array $class): int {
             return count($class);
         }, $samples);
-        $allSamples = array_sum($samplesPerClass);
+        $allSamples = (int) array_sum($samplesPerClass);
         $ssAllSamples = self::sumOfSquaresPerFeature($samples);
         $sumSamples = self::sumOfFeaturesPerClass($samples);
         $squareSumSamples = self::sumOfSquares($sumSamples);
diff --git a/src/Math/Statistic/Covariance.php b/src/Math/Statistic/Covariance.php
index 4ed07764..52cac5e4 100644
--- a/src/Math/Statistic/Covariance.php
+++ b/src/Math/Statistic/Covariance.php
@@ -15,11 +15,11 @@ class Covariance
      */
     public static function fromXYArrays(array $x, array $y, bool $sample = true, ?float $meanX = null, ?float $meanY = null): float
     {
-        if (empty($x) || empty($y)) {
+        $n = count($x);
+        if ($n === 0 || count($y) === 0) {
             throw new InvalidArgumentException('The array has zero elements');
         }
 
-        $n = count($x);
         if ($sample && $n === 1) {
             throw new InvalidArgumentException('The array must have at least 2 elements');
         }
@@ -53,7 +53,7 @@ public static function fromXYArrays(array $x, array $y, bool $sample = true, ?fl
      */
     public static function fromDataset(array $data, int $i, int $k, bool $sample = true, ?float $meanX = null, ?float $meanY = null): float
     {
-        if (empty($data)) {
+        if (count($data) === 0) {
             throw new InvalidArgumentException('The array has zero elements');
         }
 
@@ -87,7 +87,7 @@ public static function fromDataset(array $data, int $i, int $k, bool $sample = t
             // with a slight cost of CPU utilization.
             $sum = 0.0;
             foreach ($data as $row) {
-                $val = [];
+                $val = [0, 0];
                 foreach ($row as $index => $col) {
                     if ($index == $i) {
                         $val[0] = $col - $meanX;
diff --git a/src/Math/Statistic/Mean.php b/src/Math/Statistic/Mean.php
index 6b6d555a..2ae55aa8 100644
--- a/src/Math/Statistic/Mean.php
+++ b/src/Math/Statistic/Mean.php
@@ -58,7 +58,7 @@ public static function mode(array $numbers)
      */
     private static function checkArrayLength(array $array): void
     {
-        if (empty($array)) {
+        if (count($array) === 0) {
             throw new InvalidArgumentException('The array has zero elements');
         }
     }
diff --git a/src/Math/Statistic/StandardDeviation.php b/src/Math/Statistic/StandardDeviation.php
index f1eae8a8..170a9ee7 100644
--- a/src/Math/Statistic/StandardDeviation.php
+++ b/src/Math/Statistic/StandardDeviation.php
@@ -13,12 +13,11 @@ class StandardDeviation
      */
     public static function population(array $numbers, bool $sample = true): float
     {
-        if (empty($numbers)) {
+        $n = count($numbers);
+        if ($n === 0) {
             throw new InvalidArgumentException('The array has zero elements');
         }
 
-        $n = count($numbers);
-
         if ($sample && $n === 1) {
             throw new InvalidArgumentException('The array must have at least 2 elements');
         }
@@ -33,7 +32,7 @@ public static function population(array $numbers, bool $sample = true): float
             --$n;
         }
 
-        return sqrt((float) ($carry / $n));
+        return sqrt($carry / $n);
     }
 
     /**
@@ -44,7 +43,7 @@ public static function population(array $numbers, bool $sample = true): float
      */
     public static function sumOfSquares(array $numbers): float
     {
-        if (empty($numbers)) {
+        if (count($numbers) === 0) {
             throw new InvalidArgumentException('The array has zero elements');
         }
 
diff --git a/src/Metric/ClassificationReport.php b/src/Metric/ClassificationReport.php
index 969dcc6d..6263a525 100644
--- a/src/Metric/ClassificationReport.php
+++ b/src/Metric/ClassificationReport.php
@@ -142,9 +142,9 @@ private function computeAverage(int $average): void
 
     private function computeMicroAverage(): void
     {
-        $truePositive = array_sum($this->truePositive);
-        $falsePositive = array_sum($this->falsePositive);
-        $falseNegative = array_sum($this->falseNegative);
+        $truePositive = (int) array_sum($this->truePositive);
+        $falsePositive = (int) array_sum($this->falsePositive);
+        $falseNegative = (int) array_sum($this->falseNegative);
 
         $precision = $this->computePrecision($truePositive, $falsePositive);
         $recall = $this->computeRecall($truePositive, $falseNegative);
@@ -227,6 +227,6 @@ private static function getLabelIndexedArray(array $actualLabels, array $predict
         $labels = array_values(array_unique(array_merge($actualLabels, $predictedLabels)));
         sort($labels);
 
-        return array_combine($labels, array_fill(0, count($labels), 0));
+        return (array) array_combine($labels, array_fill(0, count($labels), 0));
     }
 }
diff --git a/src/Metric/ConfusionMatrix.php b/src/Metric/ConfusionMatrix.php
index 5fd3ac59..5b8021cb 100644
--- a/src/Metric/ConfusionMatrix.php
+++ b/src/Metric/ConfusionMatrix.php
@@ -8,13 +8,13 @@ class ConfusionMatrix
 {
     public static function compute(array $actualLabels, array $predictedLabels, array $labels = []): array
     {
-        $labels = !empty($labels) ? array_flip($labels) : self::getUniqueLabels($actualLabels);
+        $labels = count($labels) === 0 ? self::getUniqueLabels($actualLabels) : array_flip($labels);
         $matrix = self::generateMatrixWithZeros($labels);
 
         foreach ($actualLabels as $index => $actual) {
             $predicted = $predictedLabels[$index];
 
-            if (!isset($labels[$actual]) || !isset($labels[$predicted])) {
+            if (!isset($labels[$actual], $labels[$predicted])) {
                 continue;
             }
 
diff --git a/src/ModelManager.php b/src/ModelManager.php
index 36e8e2c1..057e0ead 100644
--- a/src/ModelManager.php
+++ b/src/ModelManager.php
@@ -16,7 +16,7 @@ public function saveToFile(Estimator $estimator, string $filepath): void
         }
 
         $serialized = serialize($estimator);
-        if (empty($serialized)) {
+        if (!isset($serialized[0])) {
             throw new SerializeException(sprintf('Class "%s" can not be serialized.', gettype($estimator)));
         }
 
@@ -32,7 +32,7 @@ public function restoreFromFile(string $filepath): Estimator
             throw new FileException(sprintf('File "%s" can\'t be open.', basename($filepath)));
         }
 
-        $object = unserialize(file_get_contents($filepath));
+        $object = unserialize((string) file_get_contents($filepath), [Estimator::class]);
         if ($object === false) {
             throw new SerializeException(sprintf('"%s" can not be unserialized.', basename($filepath)));
         }
diff --git a/src/NeuralNetwork/Network.php b/src/NeuralNetwork/Network.php
index c2248a64..0b0ce651 100644
--- a/src/NeuralNetwork/Network.php
+++ b/src/NeuralNetwork/Network.php
@@ -13,7 +13,7 @@ public function setInput($input): self;
 
     public function getOutput(): array;
 
-    public function addLayer(Layer $layer);
+    public function addLayer(Layer $layer): void;
 
     /**
      * @return Layer[]
diff --git a/src/NeuralNetwork/Network/MultilayerPerceptron.php b/src/NeuralNetwork/Network/MultilayerPerceptron.php
index 8ff49bc6..7fe08e14 100644
--- a/src/NeuralNetwork/Network/MultilayerPerceptron.php
+++ b/src/NeuralNetwork/Network/MultilayerPerceptron.php
@@ -61,7 +61,7 @@ abstract class MultilayerPerceptron extends LayeredNetwork implements Estimator,
      */
     public function __construct(int $inputLayerFeatures, array $hiddenLayers, array $classes, int $iterations = 10000, ?ActivationFunction $activationFunction = null, float $learningRate = 1)
     {
-        if (empty($hiddenLayers)) {
+        if (count($hiddenLayers) === 0) {
             throw new InvalidArgumentException('Provide at least 1 hidden layer');
         }
 
@@ -95,7 +95,7 @@ public function train(array $samples, array $targets): void
      */
     public function partialTrain(array $samples, array $targets, array $classes = []): void
     {
-        if (!empty($classes) && array_values($classes) !== $this->classes) {
+        if (count($classes) > 0 && array_values($classes) !== $this->classes) {
             // We require the list of classes in the constructor.
             throw new InvalidArgumentException(
                 'The provided classes don\'t match the classes provided in the constructor'
@@ -126,7 +126,7 @@ public function getOutput(): array
     /**
      * @param mixed $target
      */
-    abstract protected function trainSample(array $sample, $target);
+    abstract protected function trainSample(array $sample, $target): void;
 
     /**
      * @return mixed
diff --git a/src/NeuralNetwork/Node/Neuron/Synapse.php b/src/NeuralNetwork/Node/Neuron/Synapse.php
index 08899bf7..0a6e0f8c 100644
--- a/src/NeuralNetwork/Node/Neuron/Synapse.php
+++ b/src/NeuralNetwork/Node/Neuron/Synapse.php
@@ -49,6 +49,6 @@ public function getNode(): Node
 
     protected function generateRandomWeight(): float
     {
-        return 1 / random_int(5, 25) * (random_int(0, 1) ? -1 : 1);
+        return (1 / random_int(5, 25) * random_int(0, 1)) > 0 ? -1 : 1;
     }
 }
diff --git a/src/NeuralNetwork/Training.php b/src/NeuralNetwork/Training.php
deleted file mode 100644
index e699c470..00000000
--- a/src/NeuralNetwork/Training.php
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Phpml\NeuralNetwork;
-
-interface Training
-{
-    public function train(array $samples, array $targets);
-}
diff --git a/src/SupportVectorMachine/DataTransformer.php b/src/SupportVectorMachine/DataTransformer.php
index fcc18f64..0a018f0d 100644
--- a/src/SupportVectorMachine/DataTransformer.php
+++ b/src/SupportVectorMachine/DataTransformer.php
@@ -26,7 +26,7 @@ public static function trainingSet(array $samples, array $labels, bool $targets
 
     public static function testSet(array $samples): string
     {
-        if (empty($samples)) {
+        if (count($samples) === 0) {
             throw new InvalidArgumentException('The array has zero elements');
         }
 
@@ -62,7 +62,7 @@ public static function probabilities(string $rawPredictions, array $labels): arr
         $predictions = explode(PHP_EOL, trim($rawPredictions));
 
         $header = array_shift($predictions);
-        $headerColumns = explode(' ', $header);
+        $headerColumns = explode(' ', (string) $header);
         array_shift($headerColumns);
 
         $columnLabels = [];
diff --git a/src/SupportVectorMachine/SupportVectorMachine.php b/src/SupportVectorMachine/SupportVectorMachine.php
index 4c2f87b9..e320567b 100644
--- a/src/SupportVectorMachine/SupportVectorMachine.php
+++ b/src/SupportVectorMachine/SupportVectorMachine.php
@@ -165,7 +165,7 @@ public function train(array $samples, array $targets): void
             );
         }
 
-        $this->model = file_get_contents($modelFileName);
+        $this->model = (string) file_get_contents($modelFileName);
 
         unlink($modelFileName);
     }
@@ -241,7 +241,7 @@ private function runSvmPredict(array $samples, bool $probabilityEstimates): stri
 
         unlink($testSetFileName);
         unlink($modelFileName);
-        $predictions = file_get_contents($outputFileName);
+        $predictions = (string) file_get_contents($outputFileName);
 
         unlink($outputFileName);
 
diff --git a/src/Tokenization/WhitespaceTokenizer.php b/src/Tokenization/WhitespaceTokenizer.php
index 5b071b8e..4c0ae60d 100644
--- a/src/Tokenization/WhitespaceTokenizer.php
+++ b/src/Tokenization/WhitespaceTokenizer.php
@@ -4,10 +4,17 @@
 
 namespace Phpml\Tokenization;
 
+use Phpml\Exception\InvalidArgumentException;
+
 class WhitespaceTokenizer implements Tokenizer
 {
     public function tokenize(string $text): array
     {
-        return preg_split('/[\pZ\pC]+/u', $text, -1, PREG_SPLIT_NO_EMPTY);
+        $substrings = preg_split('/[\pZ\pC]+/u', $text, -1, PREG_SPLIT_NO_EMPTY);
+        if ($substrings === false) {
+            throw new InvalidArgumentException('preg_split failed on: '.$text);
+        }
+
+        return $substrings;
     }
 }
diff --git a/tests/Association/AprioriTest.php b/tests/Association/AprioriTest.php
index 81a6ce68..bec58f90 100644
--- a/tests/Association/AprioriTest.php
+++ b/tests/Association/AprioriTest.php
@@ -11,6 +11,9 @@
 
 class AprioriTest extends TestCase
 {
+    /**
+     * @var array
+     */
     private $sampleGreek = [
         ['alpha', 'beta', 'epsilon'],
         ['alpha', 'beta', 'theta'],
@@ -18,6 +21,9 @@ class AprioriTest extends TestCase
         ['alpha', 'beta', 'theta'],
     ];
 
+    /**
+     * @var array
+     */
     private $sampleChars = [
         ['E', 'D', 'N', 'E+N', 'EN'],
         ['E', 'R', 'N', 'E+R', 'E+N', 'ER', 'EN'],
@@ -31,6 +37,9 @@ class AprioriTest extends TestCase
         ['N'],
     ];
 
+    /**
+     * @var array
+     */
     private $sampleBasket = [
         [1, 2, 3, 4],
         [1, 2, 4],
@@ -48,16 +57,16 @@ public function testGreek(): void
 
         $predicted = $apriori->predict([['alpha', 'epsilon'], ['beta', 'theta']]);
 
-        $this->assertCount(2, $predicted);
-        $this->assertEquals([['beta']], $predicted[0]);
-        $this->assertEquals([['alpha']], $predicted[1]);
+        self::assertCount(2, $predicted);
+        self::assertEquals([['beta']], $predicted[0]);
+        self::assertEquals([['alpha']], $predicted[1]);
     }
 
     public function testPowerSet(): void
     {
         $apriori = new Apriori();
 
-        $this->assertCount(8, self::invoke($apriori, 'powerSet', [['a', 'b', 'c']]));
+        self::assertCount(8, self::invoke($apriori, 'powerSet', [['a', 'b', 'c']]));
     }
 
     public function testApriori(): void
@@ -67,13 +76,13 @@ public function testApriori(): void
 
         $L = $apriori->apriori();
 
-        $this->assertCount(4, $L[2]);
-        $this->assertTrue(self::invoke($apriori, 'contains', [$L[2], [1, 2]]));
-        $this->assertFalse(self::invoke($apriori, 'contains', [$L[2], [1, 3]]));
-        $this->assertFalse(self::invoke($apriori, 'contains', [$L[2], [1, 4]]));
-        $this->assertTrue(self::invoke($apriori, 'contains', [$L[2], [2, 3]]));
-        $this->assertTrue(self::invoke($apriori, 'contains', [$L[2], [2, 4]]));
-        $this->assertTrue(self::invoke($apriori, 'contains', [$L[2], [3, 4]]));
+        self::assertCount(4, $L[2]);
+        self::assertTrue(self::invoke($apriori, 'contains', [$L[2], [1, 2]]));
+        self::assertFalse(self::invoke($apriori, 'contains', [$L[2], [1, 3]]));
+        self::assertFalse(self::invoke($apriori, 'contains', [$L[2], [1, 4]]));
+        self::assertTrue(self::invoke($apriori, 'contains', [$L[2], [2, 3]]));
+        self::assertTrue(self::invoke($apriori, 'contains', [$L[2], [2, 4]]));
+        self::assertTrue(self::invoke($apriori, 'contains', [$L[2], [3, 4]]));
     }
 
     public function testAprioriEmpty(): void
@@ -85,7 +94,7 @@ public function testAprioriEmpty(): void
 
         $L = $apriori->apriori();
 
-        $this->assertEmpty($L);
+        self::assertEmpty($L);
     }
 
     public function testAprioriSingleItem(): void
@@ -97,8 +106,8 @@ public function testAprioriSingleItem(): void
 
         $L = $apriori->apriori();
 
-        $this->assertEquals([1], array_keys($L));
-        $this->assertEquals([['a']], $L[1]);
+        self::assertEquals([1], array_keys($L));
+        self::assertEquals([['a']], $L[1]);
     }
 
     public function testAprioriL3(): void
@@ -110,7 +119,7 @@ public function testAprioriL3(): void
 
         $L = $apriori->apriori();
 
-        $this->assertEquals([['a', 'b', 'c']], $L[3]);
+        self::assertEquals([['a', 'b', 'c']], $L[3]);
     }
 
     public function testGetRules(): void
@@ -118,7 +127,7 @@ public function testGetRules(): void
         $apriori = new Apriori(0.4, 0.8);
         $apriori->train($this->sampleChars, []);
 
-        $this->assertCount(19, $apriori->getRules());
+        self::assertCount(19, $apriori->getRules());
     }
 
     public function testGetRulesSupportAndConfidence(): void
@@ -130,14 +139,14 @@ public function testGetRulesSupportAndConfidence(): void
 
         $rules = $apriori->getRules();
 
-        $this->assertCount(4, $rules);
-        $this->assertContains([
+        self::assertCount(4, $rules);
+        self::assertContains([
             Apriori::ARRAY_KEY_ANTECEDENT => ['a'],
             Apriori::ARRAY_KEY_CONSEQUENT => ['b'],
             Apriori::ARRAY_KEY_SUPPORT => 0.5,
             Apriori::ARRAY_KEY_CONFIDENCE => 0.5,
         ], $rules);
-        $this->assertContains([
+        self::assertContains([
             Apriori::ARRAY_KEY_ANTECEDENT => ['b'],
             Apriori::ARRAY_KEY_CONSEQUENT => ['a'],
             Apriori::ARRAY_KEY_SUPPORT => 0.5,
@@ -149,14 +158,14 @@ public function testAntecedents(): void
     {
         $apriori = new Apriori();
 
-        $this->assertCount(6, self::invoke($apriori, 'antecedents', [['a', 'b', 'c']]));
+        self::assertCount(6, self::invoke($apriori, 'antecedents', [['a', 'b', 'c']]));
     }
 
     public function testItems(): void
     {
         $apriori = new Apriori();
         $apriori->train($this->sampleGreek, []);
-        $this->assertCount(4, self::invoke($apriori, 'items', []));
+        self::assertCount(4, self::invoke($apriori, 'items', []));
     }
 
     public function testFrequent(): void
@@ -164,8 +173,8 @@ public function testFrequent(): void
         $apriori = new Apriori(0.51);
         $apriori->train($this->sampleGreek, []);
 
-        $this->assertCount(0, self::invoke($apriori, 'frequent', [[['epsilon'], ['theta']]]));
-        $this->assertCount(2, self::invoke($apriori, 'frequent', [[['alpha'], ['beta']]]));
+        self::assertCount(0, self::invoke($apriori, 'frequent', [[['epsilon'], ['theta']]]));
+        self::assertCount(2, self::invoke($apriori, 'frequent', [[['alpha'], ['beta']]]));
     }
 
     public function testCandidates(): void
@@ -175,10 +184,10 @@ public function testCandidates(): void
 
         $candidates = self::invoke($apriori, 'candidates', [[['alpha'], ['beta'], ['theta']]]);
 
-        $this->assertCount(3, $candidates);
-        $this->assertEquals(['alpha', 'beta'], $candidates[0]);
-        $this->assertEquals(['alpha', 'theta'], $candidates[1]);
-        $this->assertEquals(['beta', 'theta'], $candidates[2]);
+        self::assertCount(3, $candidates);
+        self::assertEquals(['alpha', 'beta'], $candidates[0]);
+        self::assertEquals(['alpha', 'theta'], $candidates[1]);
+        self::assertEquals(['beta', 'theta'], $candidates[2]);
     }
 
     public function testConfidence(): void
@@ -186,8 +195,8 @@ public function testConfidence(): void
         $apriori = new Apriori();
         $apriori->train($this->sampleGreek, []);
 
-        $this->assertEquals(0.5, self::invoke($apriori, 'confidence', [['alpha', 'beta', 'theta'], ['alpha', 'beta']]));
-        $this->assertEquals(1, self::invoke($apriori, 'confidence', [['alpha', 'beta'], ['alpha']]));
+        self::assertEquals(0.5, self::invoke($apriori, 'confidence', [['alpha', 'beta', 'theta'], ['alpha', 'beta']]));
+        self::assertEquals(1, self::invoke($apriori, 'confidence', [['alpha', 'beta'], ['alpha']]));
     }
 
     public function testSupport(): void
@@ -195,8 +204,8 @@ public function testSupport(): void
         $apriori = new Apriori();
         $apriori->train($this->sampleGreek, []);
 
-        $this->assertEquals(1.0, self::invoke($apriori, 'support', [['alpha', 'beta']]));
-        $this->assertEquals(0.5, self::invoke($apriori, 'support', [['epsilon']]));
+        self::assertEquals(1.0, self::invoke($apriori, 'support', [['alpha', 'beta']]));
+        self::assertEquals(0.5, self::invoke($apriori, 'support', [['epsilon']]));
     }
 
     public function testFrequency(): void
@@ -204,35 +213,35 @@ public function testFrequency(): void
         $apriori = new Apriori();
         $apriori->train($this->sampleGreek, []);
 
-        $this->assertEquals(4, self::invoke($apriori, 'frequency', [['alpha', 'beta']]));
-        $this->assertEquals(2, self::invoke($apriori, 'frequency', [['epsilon']]));
+        self::assertEquals(4, self::invoke($apriori, 'frequency', [['alpha', 'beta']]));
+        self::assertEquals(2, self::invoke($apriori, 'frequency', [['epsilon']]));
     }
 
     public function testContains(): void
     {
         $apriori = new Apriori();
 
-        $this->assertTrue(self::invoke($apriori, 'contains', [[['a'], ['b']], ['a']]));
-        $this->assertTrue(self::invoke($apriori, 'contains', [[[1, 2]], [1, 2]]));
-        $this->assertFalse(self::invoke($apriori, 'contains', [[['a'], ['b']], ['c']]));
+        self::assertTrue(self::invoke($apriori, 'contains', [[['a'], ['b']], ['a']]));
+        self::assertTrue(self::invoke($apriori, 'contains', [[[1, 2]], [1, 2]]));
+        self::assertFalse(self::invoke($apriori, 'contains', [[['a'], ['b']], ['c']]));
     }
 
     public function testSubset(): void
     {
         $apriori = new Apriori();
 
-        $this->assertTrue(self::invoke($apriori, 'subset', [['a', 'b'], ['a']]));
-        $this->assertTrue(self::invoke($apriori, 'subset', [['a'], ['a']]));
-        $this->assertFalse(self::invoke($apriori, 'subset', [['a'], ['a', 'b']]));
+        self::assertTrue(self::invoke($apriori, 'subset', [['a', 'b'], ['a']]));
+        self::assertTrue(self::invoke($apriori, 'subset', [['a'], ['a']]));
+        self::assertFalse(self::invoke($apriori, 'subset', [['a'], ['a', 'b']]));
     }
 
     public function testEquals(): void
     {
         $apriori = new Apriori();
 
-        $this->assertTrue(self::invoke($apriori, 'equals', [['a'], ['a']]));
-        $this->assertFalse(self::invoke($apriori, 'equals', [['a'], []]));
-        $this->assertFalse(self::invoke($apriori, 'equals', [['a'], ['b', 'a']]));
+        self::assertTrue(self::invoke($apriori, 'equals', [['a'], ['a']]));
+        self::assertFalse(self::invoke($apriori, 'equals', [['a'], []]));
+        self::assertFalse(self::invoke($apriori, 'equals', [['a'], ['b', 'a']]));
     }
 
     public function testSaveAndRestore(): void
@@ -243,14 +252,14 @@ public function testSaveAndRestore(): void
         $testSamples = [['alpha', 'epsilon'], ['beta', 'theta']];
         $predicted = $classifier->predict($testSamples);
 
-        $filename = 'apriori-test-'.random_int(100, 999).'-'.uniqid();
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filename = 'apriori-test-'.random_int(100, 999).'-'.uniqid('', false);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 
     /**
@@ -261,7 +270,7 @@ public function testSaveAndRestore(): void
      *
      * @return mixed
      */
-    private static function invoke(&$object, string $method, array $params = [])
+    private static function invoke(Apriori $object, string $method, array $params = [])
     {
         $reflection = new ReflectionClass(get_class($object));
         $method = $reflection->getMethod($method);
diff --git a/tests/Classification/DecisionTree/DecisionTreeLeafTest.php b/tests/Classification/DecisionTree/DecisionTreeLeafTest.php
index e6948782..05139eea 100644
--- a/tests/Classification/DecisionTree/DecisionTreeLeafTest.php
+++ b/tests/Classification/DecisionTree/DecisionTreeLeafTest.php
@@ -21,7 +21,10 @@ public function testHTMLOutput(): void
 
         $leaf->rightLeaf = $rightLeaf;
 
-        $this->assertEquals('<table ><tr><td colspan=3 align=center style=\'border:1px solid;\'><b>col_0 =1</b><br>Gini: 0.00</td></tr><tr><td></td><td>&nbsp;</td><td valign=top align=right><b>No |</b><br><table ><tr><td colspan=3 align=center style=\'border:1px solid;\'><b>col_1 <= 2</b><br>Gini: 0.00</td></tr></table></td></tr></table>', $leaf->getHTML());
+        self::assertEquals(
+            '<table ><tr><td colspan=3 align=center style=\'border:1px solid;\'><b>col_0 =1</b><br>Gini: 0.00</td></tr><tr><td></td><td>&nbsp;</td><td valign=top align=right><b>No |</b><br><table ><tr><td colspan=3 align=center style=\'border:1px solid;\'><b>col_1 <= 2</b><br>Gini: 0.00</td></tr></table></td></tr></table>',
+            $leaf->getHTML()
+        );
     }
 
     public function testNodeImpurityDecreaseShouldBeZeroWhenLeafIsTerminal(): void
@@ -29,7 +32,7 @@ public function testNodeImpurityDecreaseShouldBeZeroWhenLeafIsTerminal(): void
         $leaf = new DecisionTreeLeaf();
         $leaf->isTerminal = true;
 
-        $this->assertEquals(0.0, $leaf->getNodeImpurityDecrease(1));
+        self::assertEquals(0.0, $leaf->getNodeImpurityDecrease(1));
     }
 
     public function testNodeImpurityDecrease(): void
@@ -45,6 +48,6 @@ public function testNodeImpurityDecrease(): void
         $leaf->rightLeaf->records = [];
         $leaf->rightLeaf->giniIndex = 0.3;
 
-        $this->assertSame(0.75, $leaf->getNodeImpurityDecrease(2));
+        self::assertSame(0.75, $leaf->getNodeImpurityDecrease(2));
     }
 }
diff --git a/tests/Classification/DecisionTreeTest.php b/tests/Classification/DecisionTreeTest.php
index 9478a2ac..3f0a7636 100644
--- a/tests/Classification/DecisionTreeTest.php
+++ b/tests/Classification/DecisionTreeTest.php
@@ -10,6 +10,9 @@
 
 class DecisionTreeTest extends TestCase
 {
+    /**
+     * @var array
+     */
     private $data = [
         ['sunny',       85,    85,    'false',    'Dont_play'],
         ['sunny',       80,    90,    'true',     'Dont_play'],
@@ -27,26 +30,27 @@ class DecisionTreeTest extends TestCase
         ['rain',        71,    80,    'true',     'Dont_play'],
     ];
 
+    /**
+     * @var array
+     */
     private $extraData = [
         ['scorching',   90,     95,     'false',   'Dont_play'],
         ['scorching',  100,     93,     'true',    'Dont_play'],
     ];
 
-    public function testPredictSingleSample()
+    public function testPredictSingleSample(): void
     {
         [$data, $targets] = $this->getData($this->data);
         $classifier = new DecisionTree(5);
         $classifier->train($data, $targets);
-        $this->assertEquals('Dont_play', $classifier->predict(['sunny', 78, 72, 'false']));
-        $this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
-        $this->assertEquals('Dont_play', $classifier->predict(['rain', 60, 60, 'true']));
+        self::assertEquals('Dont_play', $classifier->predict(['sunny', 78, 72, 'false']));
+        self::assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
+        self::assertEquals('Dont_play', $classifier->predict(['rain', 60, 60, 'true']));
 
         [$data, $targets] = $this->getData($this->extraData);
         $classifier->train($data, $targets);
-        $this->assertEquals('Dont_play', $classifier->predict(['scorching', 95, 90, 'true']));
-        $this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
-
-        return $classifier;
+        self::assertEquals('Dont_play', $classifier->predict(['scorching', 95, 90, 'true']));
+        self::assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
     }
 
     public function testSaveAndRestore(): void
@@ -58,14 +62,14 @@ public function testSaveAndRestore(): void
         $testSamples = [['sunny', 78, 72, 'false'], ['overcast', 60, 60, 'false']];
         $predicted = $classifier->predict($testSamples);
 
-        $filename = 'decision-tree-test-'.random_int(100, 999).'-'.uniqid();
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filename = 'decision-tree-test-'.random_int(100, 999).'-'.uniqid('', false);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 
     public function testTreeDepth(): void
@@ -73,10 +77,10 @@ public function testTreeDepth(): void
         [$data, $targets] = $this->getData($this->data);
         $classifier = new DecisionTree(5);
         $classifier->train($data, $targets);
-        $this->assertTrue($classifier->actualDepth <= 5);
+        self::assertTrue($classifier->actualDepth <= 5);
     }
 
-    private function getData($input)
+    private function getData(array $input): array
     {
         $targets = array_column($input, 4);
         array_walk($input, function (&$v): void {
diff --git a/tests/Classification/Ensemble/AdaBoostTest.php b/tests/Classification/Ensemble/AdaBoostTest.php
index 095cde03..173df6ce 100644
--- a/tests/Classification/Ensemble/AdaBoostTest.php
+++ b/tests/Classification/Ensemble/AdaBoostTest.php
@@ -37,27 +37,27 @@ public function testPredictSingleSample(): void
         $targets = [0, 0, 0, 1, 1, 1];
         $classifier = new AdaBoost();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.2]));
-        $this->assertEquals(0, $classifier->predict([0.1, 0.99]));
-        $this->assertEquals(1, $classifier->predict([1.1, 0.8]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.2]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.99]));
+        self::assertEquals(1, $classifier->predict([1.1, 0.8]));
 
         // OR problem
         $samples = [[0, 0], [0.1, 0.2], [0.2, 0.1], [1, 0], [0, 1], [1, 1]];
         $targets = [0, 0, 0, 1, 1, 1];
         $classifier = new AdaBoost();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.2]));
-        $this->assertEquals(1, $classifier->predict([0.1, 0.99]));
-        $this->assertEquals(1, $classifier->predict([1.1, 0.8]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.2]));
+        self::assertEquals(1, $classifier->predict([0.1, 0.99]));
+        self::assertEquals(1, $classifier->predict([1.1, 0.8]));
 
         // XOR problem
         $samples = [[0.1, 0.2], [1., 1.], [0.9, 0.8], [0., 1.], [1., 0.], [0.2, 0.8]];
         $targets = [0, 0, 0, 1, 1, 1];
         $classifier = new AdaBoost(5);
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.1]));
-        $this->assertEquals(1, $classifier->predict([0, 0.999]));
-        $this->assertEquals(0, $classifier->predict([1.1, 0.8]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.1]));
+        self::assertEquals(1, $classifier->predict([0, 0.999]));
+        self::assertEquals(0, $classifier->predict([1.1, 0.8]));
     }
 
     public function testSaveAndRestore(): void
@@ -70,13 +70,13 @@ public function testSaveAndRestore(): void
         $testSamples = [[0, 1], [1, 1], [0.2, 0.1]];
         $predicted = $classifier->predict($testSamples);
 
-        $filename = 'adaboost-test-'.random_int(100, 999).'-'.uniqid();
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filename = 'adaboost-test-'.random_int(100, 999).'-'.uniqid('', false);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 }
diff --git a/tests/Classification/Ensemble/BaggingTest.php b/tests/Classification/Ensemble/BaggingTest.php
index 5b2e47bf..9738ce73 100644
--- a/tests/Classification/Ensemble/BaggingTest.php
+++ b/tests/Classification/Ensemble/BaggingTest.php
@@ -4,6 +4,7 @@
 
 namespace Phpml\Tests\Classification\Ensemble;
 
+use Phpml\Classification\Classifier;
 use Phpml\Classification\DecisionTree;
 use Phpml\Classification\Ensemble\Bagging;
 use Phpml\Classification\NaiveBayes;
@@ -13,6 +14,9 @@
 
 class BaggingTest extends TestCase
 {
+    /**
+     * @var array
+     */
     private $data = [
         ['sunny',       85,    85,    'false',    'Dont_play'],
         ['sunny',       80,    90,    'true',     'Dont_play'],
@@ -30,6 +34,9 @@ class BaggingTest extends TestCase
         ['rain',        71,    80,    'true',     'Dont_play'],
     ];
 
+    /**
+     * @var array
+     */
     private $extraData = [
         ['scorching',  90,     95,    'false',    'Dont_play'],
         ['scorching',   0,      0,    'false',    'Dont_play'],
@@ -49,14 +56,14 @@ public function testPredictSingleSample(): void
         $classifier = $this->getClassifier();
         // Testing with default options
         $classifier->train($data, $targets);
-        $this->assertEquals('Dont_play', $classifier->predict(['sunny', 78, 72, 'false']));
-        $this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
-        $this->assertEquals('Dont_play', $classifier->predict(['rain', 60, 60, 'true']));
+        self::assertEquals('Dont_play', $classifier->predict(['sunny', 78, 72, 'false']));
+        self::assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
+        self::assertEquals('Dont_play', $classifier->predict(['rain', 60, 60, 'true']));
 
         [$data, $targets] = $this->getData($this->extraData);
         $classifier->train($data, $targets);
-        $this->assertEquals('Dont_play', $classifier->predict(['scorching', 95, 90, 'true']));
-        $this->assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
+        self::assertEquals('Dont_play', $classifier->predict(['scorching', 95, 90, 'true']));
+        self::assertEquals('Play', $classifier->predict(['overcast', 60, 60, 'false']));
     }
 
     public function testSaveAndRestore(): void
@@ -68,14 +75,14 @@ public function testSaveAndRestore(): void
         $testSamples = [['sunny', 78, 72, 'false'], ['overcast', 60, 60, 'false']];
         $predicted = $classifier->predict($testSamples);
 
-        $filename = 'bagging-test-'.random_int(100, 999).'-'.uniqid();
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filename = 'bagging-test-'.random_int(100, 999).'-'.uniqid('', false);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 
     public function testBaseClassifiers(): void
@@ -94,12 +101,15 @@ public function testBaseClassifiers(): void
             foreach ($testData as $test) {
                 $result = $classifier->predict($test);
                 $baseResult = $classifier->predict($test);
-                $this->assertEquals($result, $baseResult);
+                self::assertEquals($result, $baseResult);
             }
         }
     }
 
-    protected function getClassifier($numBaseClassifiers = 50)
+    /**
+     * @return Bagging
+     */
+    protected function getClassifier(int $numBaseClassifiers = 50): Classifier
     {
         $classifier = new Bagging($numBaseClassifiers);
         $classifier->setSubsetRatio(1.0);
@@ -108,7 +118,7 @@ protected function getClassifier($numBaseClassifiers = 50)
         return $classifier;
     }
 
-    protected function getAvailableBaseClassifiers()
+    protected function getAvailableBaseClassifiers(): array
     {
         return [
             DecisionTree::class => ['depth' => 5],
@@ -116,7 +126,7 @@ protected function getAvailableBaseClassifiers()
         ];
     }
 
-    private function getData($input)
+    private function getData(array $input): array
     {
         // Populating input data to a size large enough
         // for base classifiers that they can work with a subset of it
diff --git a/tests/Classification/Ensemble/RandomForestTest.php b/tests/Classification/Ensemble/RandomForestTest.php
index 93353a36..2f21c5ca 100644
--- a/tests/Classification/Ensemble/RandomForestTest.php
+++ b/tests/Classification/Ensemble/RandomForestTest.php
@@ -4,6 +4,7 @@
 
 namespace Phpml\Tests\Classification\Ensemble;
 
+use Phpml\Classification\Classifier;
 use Phpml\Classification\DecisionTree;
 use Phpml\Classification\Ensemble\RandomForest;
 use Phpml\Classification\NaiveBayes;
@@ -47,7 +48,10 @@ public function testThrowExceptionWithInvalidFeatureSubsetRatioString(): void
         $classifier->setFeatureSubsetRatio('pow');
     }
 
-    protected function getClassifier($numBaseClassifiers = 50)
+    /**
+     * @return RandomForest
+     */
+    protected function getClassifier(int $numBaseClassifiers = 50): Classifier
     {
         $classifier = new RandomForest($numBaseClassifiers);
         $classifier->setFeatureSubsetRatio('log');
@@ -55,7 +59,7 @@ protected function getClassifier($numBaseClassifiers = 50)
         return $classifier;
     }
 
-    protected function getAvailableBaseClassifiers()
+    protected function getAvailableBaseClassifiers(): array
     {
         return [DecisionTree::class => ['depth' => 5]];
     }
diff --git a/tests/Classification/KNearestNeighborsTest.php b/tests/Classification/KNearestNeighborsTest.php
index 110d49d8..5be9a3d0 100644
--- a/tests/Classification/KNearestNeighborsTest.php
+++ b/tests/Classification/KNearestNeighborsTest.php
@@ -19,15 +19,15 @@ public function testPredictSingleSampleWithDefaultK(): void
         $classifier = new KNearestNeighbors();
         $classifier->train($samples, $labels);
 
-        $this->assertEquals('b', $classifier->predict([3, 2]));
-        $this->assertEquals('b', $classifier->predict([5, 1]));
-        $this->assertEquals('b', $classifier->predict([4, 3]));
-        $this->assertEquals('b', $classifier->predict([4, -5]));
-
-        $this->assertEquals('a', $classifier->predict([2, 3]));
-        $this->assertEquals('a', $classifier->predict([1, 2]));
-        $this->assertEquals('a', $classifier->predict([1, 5]));
-        $this->assertEquals('a', $classifier->predict([3, 10]));
+        self::assertEquals('b', $classifier->predict([3, 2]));
+        self::assertEquals('b', $classifier->predict([5, 1]));
+        self::assertEquals('b', $classifier->predict([4, 3]));
+        self::assertEquals('b', $classifier->predict([4, -5]));
+
+        self::assertEquals('a', $classifier->predict([2, 3]));
+        self::assertEquals('a', $classifier->predict([1, 2]));
+        self::assertEquals('a', $classifier->predict([1, 5]));
+        self::assertEquals('a', $classifier->predict([3, 10]));
     }
 
     public function testPredictArrayOfSamples(): void
@@ -42,7 +42,7 @@ public function testPredictArrayOfSamples(): void
         $classifier->train($trainSamples, $trainLabels);
         $predicted = $classifier->predict($testSamples);
 
-        $this->assertEquals($testLabels, $predicted);
+        self::assertEquals($testLabels, $predicted);
     }
 
     public function testPredictArrayOfSamplesUsingChebyshevDistanceMetric(): void
@@ -57,7 +57,7 @@ public function testPredictArrayOfSamplesUsingChebyshevDistanceMetric(): void
         $classifier->train($trainSamples, $trainLabels);
         $predicted = $classifier->predict($testSamples);
 
-        $this->assertEquals($testLabels, $predicted);
+        self::assertEquals($testLabels, $predicted);
     }
 
     public function testSaveAndRestore(): void
@@ -73,12 +73,12 @@ public function testSaveAndRestore(): void
         $predicted = $classifier->predict($testSamples);
 
         $filename = 'knearest-neighbors-test-'.random_int(100, 999).'-'.uniqid('', false);
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 }
diff --git a/tests/Classification/Linear/AdalineTest.php b/tests/Classification/Linear/AdalineTest.php
index 08ad78aa..7bc8f9df 100644
--- a/tests/Classification/Linear/AdalineTest.php
+++ b/tests/Classification/Linear/AdalineTest.php
@@ -31,18 +31,18 @@ public function testPredictSingleSample(): void
         $targets = [0, 0, 0, 1];
         $classifier = new Adaline();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.2]));
-        $this->assertEquals(0, $classifier->predict([0.1, 0.99]));
-        $this->assertEquals(1, $classifier->predict([1.1, 0.8]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.2]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.99]));
+        self::assertEquals(1, $classifier->predict([1.1, 0.8]));
 
         // OR problem
         $samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
         $targets = [0, 1, 1, 1];
         $classifier = new Adaline();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.2]));
-        $this->assertEquals(1, $classifier->predict([0.1, 0.99]));
-        $this->assertEquals(1, $classifier->predict([1.1, 0.8]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.2]));
+        self::assertEquals(1, $classifier->predict([0.1, 0.99]));
+        self::assertEquals(1, $classifier->predict([1.1, 0.8]));
 
         // By use of One-v-Rest, Adaline can perform multi-class classification
         // The samples should be separable by lines perpendicular to the dimensions
@@ -55,15 +55,15 @@ public function testPredictSingleSample(): void
 
         $classifier = new Adaline();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.5, 0.5]));
-        $this->assertEquals(1, $classifier->predict([6.0, 5.0]));
-        $this->assertEquals(2, $classifier->predict([3.0, 9.5]));
+        self::assertEquals(0, $classifier->predict([0.5, 0.5]));
+        self::assertEquals(1, $classifier->predict([6.0, 5.0]));
+        self::assertEquals(2, $classifier->predict([3.0, 9.5]));
 
         // Extra partial training should lead to the same results.
         $classifier->partialTrain([[0, 1], [1, 0]], [0, 0], [0, 1, 2]);
-        $this->assertEquals(0, $classifier->predict([0.5, 0.5]));
-        $this->assertEquals(1, $classifier->predict([6.0, 5.0]));
-        $this->assertEquals(2, $classifier->predict([3.0, 9.5]));
+        self::assertEquals(0, $classifier->predict([0.5, 0.5]));
+        self::assertEquals(1, $classifier->predict([6.0, 5.0]));
+        self::assertEquals(2, $classifier->predict([3.0, 9.5]));
 
         // Train should clear previous data.
         $samples = [
@@ -73,9 +73,9 @@ public function testPredictSingleSample(): void
         ];
         $targets = [2, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1];
         $classifier->train($samples, $targets);
-        $this->assertEquals(2, $classifier->predict([0.5, 0.5]));
-        $this->assertEquals(0, $classifier->predict([6.0, 5.0]));
-        $this->assertEquals(1, $classifier->predict([3.0, 9.5]));
+        self::assertEquals(2, $classifier->predict([0.5, 0.5]));
+        self::assertEquals(0, $classifier->predict([6.0, 5.0]));
+        self::assertEquals(1, $classifier->predict([3.0, 9.5]));
     }
 
     public function testSaveAndRestore(): void
@@ -89,12 +89,12 @@ public function testSaveAndRestore(): void
         $predicted = $classifier->predict($testSamples);
 
         $filename = 'adaline-test-'.random_int(100, 999).'-'.uniqid('', false);
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 }
diff --git a/tests/Classification/Linear/DecisionStumpTest.php b/tests/Classification/Linear/DecisionStumpTest.php
index 1295ac53..7cd82504 100644
--- a/tests/Classification/Linear/DecisionStumpTest.php
+++ b/tests/Classification/Linear/DecisionStumpTest.php
@@ -23,7 +23,7 @@ public function testTrainThrowWhenSample(): void
         $classifier->train($samples, $targets);
     }
 
-    public function testPredictSingleSample()
+    public function testPredictSingleSample(): void
     {
         // Samples should be separable with a line perpendicular
         // to any dimension given in the dataset
@@ -33,20 +33,20 @@ public function testPredictSingleSample()
         $targets = [0, 0, 1, 1];
         $classifier = new DecisionStump();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.2]));
-        $this->assertEquals(0, $classifier->predict([1.1, 0.2]));
-        $this->assertEquals(1, $classifier->predict([0.1, 0.99]));
-        $this->assertEquals(1, $classifier->predict([1.1, 0.8]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.2]));
+        self::assertEquals(0, $classifier->predict([1.1, 0.2]));
+        self::assertEquals(1, $classifier->predict([0.1, 0.99]));
+        self::assertEquals(1, $classifier->predict([1.1, 0.8]));
 
         // Then: vertical test
         $samples = [[0, 0], [1, 0], [0, 1], [1, 1]];
         $targets = [0, 1, 0, 1];
         $classifier = new DecisionStump();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.2]));
-        $this->assertEquals(0, $classifier->predict([0.1, 1.1]));
-        $this->assertEquals(1, $classifier->predict([1.0, 0.99]));
-        $this->assertEquals(1, $classifier->predict([1.1, 0.1]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.2]));
+        self::assertEquals(0, $classifier->predict([0.1, 1.1]));
+        self::assertEquals(1, $classifier->predict([1.0, 0.99]));
+        self::assertEquals(1, $classifier->predict([1.1, 0.1]));
 
         // By use of One-v-Rest, DecisionStump can perform multi-class classification
         // The samples should be separable by lines perpendicular to the dimensions
@@ -59,11 +59,9 @@ public function testPredictSingleSample()
 
         $classifier = new DecisionStump();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.5, 0.5]));
-        $this->assertEquals(1, $classifier->predict([6.0, 5.0]));
-        $this->assertEquals(2, $classifier->predict([3.5, 9.5]));
-
-        return $classifier;
+        self::assertEquals(0, $classifier->predict([0.5, 0.5]));
+        self::assertEquals(1, $classifier->predict([6.0, 5.0]));
+        self::assertEquals(2, $classifier->predict([3.5, 9.5]));
     }
 
     public function testSaveAndRestore(): void
@@ -76,13 +74,13 @@ public function testSaveAndRestore(): void
         $testSamples = [[0, 1], [1, 1], [0.2, 0.1]];
         $predicted = $classifier->predict($testSamples);
 
-        $filename = 'dstump-test-'.random_int(100, 999).'-'.uniqid();
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filename = 'dstump-test-'.random_int(100, 999).'-'.uniqid('', false);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 }
diff --git a/tests/Classification/Linear/LogisticRegressionTest.php b/tests/Classification/Linear/LogisticRegressionTest.php
index 075e1ead..9573531e 100644
--- a/tests/Classification/Linear/LogisticRegressionTest.php
+++ b/tests/Classification/Linear/LogisticRegressionTest.php
@@ -64,8 +64,8 @@ public function testPredictSingleSample(): void
         $targets = [0, 0, 0, 1, 0, 1];
         $classifier = new LogisticRegression();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.1]));
-        $this->assertEquals(1, $classifier->predict([0.9, 0.9]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.1]));
+        self::assertEquals(1, $classifier->predict([0.9, 0.9]));
     }
 
     public function testPredictSingleSampleWithBatchTraining(): void
@@ -83,8 +83,8 @@ public function testPredictSingleSampleWithBatchTraining(): void
             'L2'
         );
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.1]));
-        $this->assertEquals(1, $classifier->predict([0.9, 0.9]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.1]));
+        self::assertEquals(1, $classifier->predict([0.9, 0.9]));
     }
 
     public function testPredictSingleSampleWithOnlineTraining(): void
@@ -102,8 +102,8 @@ public function testPredictSingleSampleWithOnlineTraining(): void
             ''
         );
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.1]));
-        $this->assertEquals(1, $classifier->predict([0.9, 0.9]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.1]));
+        self::assertEquals(1, $classifier->predict([0.9, 0.9]));
     }
 
     public function testPredictSingleSampleWithSSECost(): void
@@ -118,8 +118,8 @@ public function testPredictSingleSampleWithSSECost(): void
             'L2'
         );
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.1]));
-        $this->assertEquals(1, $classifier->predict([0.9, 0.9]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.1]));
+        self::assertEquals(1, $classifier->predict([0.9, 0.9]));
     }
 
     public function testPredictSingleSampleWithoutPenalty(): void
@@ -134,8 +134,8 @@ public function testPredictSingleSampleWithoutPenalty(): void
             ''
         );
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.1]));
-        $this->assertEquals(1, $classifier->predict([0.9, 0.9]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.1]));
+        self::assertEquals(1, $classifier->predict([0.9, 0.9]));
     }
 
     public function testPredictMultiClassSample(): void
@@ -151,9 +151,9 @@ public function testPredictMultiClassSample(): void
 
         $classifier = new LogisticRegression();
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.5, 0.5]));
-        $this->assertEquals(1, $classifier->predict([6.0, 5.0]));
-        $this->assertEquals(2, $classifier->predict([3.0, 9.5]));
+        self::assertEquals(0, $classifier->predict([0.5, 0.5]));
+        self::assertEquals(1, $classifier->predict([6.0, 5.0]));
+        self::assertEquals(2, $classifier->predict([3.0, 9.5]));
     }
 
     public function testPredictProbabilitySingleSample(): void
@@ -171,13 +171,13 @@ public function testPredictProbabilitySingleSample(): void
 
         $zero = $method->invoke($predictor, [0.1, 0.1], 0);
         $one = $method->invoke($predictor, [0.1, 0.1], 1);
-        $this->assertEquals(1, $zero + $one, '', 1e-6);
-        $this->assertTrue($zero > $one);
+        self::assertEquals(1, $zero + $one, '', 1e-6);
+        self::assertTrue($zero > $one);
 
         $zero = $method->invoke($predictor, [0.9, 0.9], 0);
         $one = $method->invoke($predictor, [0.9, 0.9], 1);
-        $this->assertEquals(1, $zero + $one, '', 1e-6);
-        $this->assertTrue($zero < $one);
+        self::assertEquals(1, $zero + $one, '', 1e-6);
+        self::assertTrue($zero < $one);
     }
 
     public function testPredictProbabilityMultiClassSample(): void
@@ -213,10 +213,10 @@ public function testPredictProbabilityMultiClassSample(): void
         $two = $method->invoke($predictor, [3.0, 9.5], 2);
         $not_two = $method->invoke($predictor, [3.0, 9.5], 'not_2');
 
-        $this->assertEquals(1, $zero + $not_zero, '', 1e-6);
-        $this->assertEquals(1, $one + $not_one, '', 1e-6);
-        $this->assertEquals(1, $two + $not_two, '', 1e-6);
-        $this->assertTrue($zero < $two);
-        $this->assertTrue($one < $two);
+        self::assertEquals(1, $zero + $not_zero, '', 1e-6);
+        self::assertEquals(1, $one + $not_one, '', 1e-6);
+        self::assertEquals(1, $two + $not_two, '', 1e-6);
+        self::assertTrue($zero < $two);
+        self::assertTrue($one < $two);
     }
 }
diff --git a/tests/Classification/Linear/PerceptronTest.php b/tests/Classification/Linear/PerceptronTest.php
index a3958b80..fa118f3d 100644
--- a/tests/Classification/Linear/PerceptronTest.php
+++ b/tests/Classification/Linear/PerceptronTest.php
@@ -33,9 +33,9 @@ public function testPredictSingleSample(): void
         $classifier = new Perceptron(0.001, 5000);
         $classifier->setEarlyStop(false);
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.1, 0.2]));
-        $this->assertEquals(0, $classifier->predict([0, 1]));
-        $this->assertEquals(1, $classifier->predict([1.1, 0.8]));
+        self::assertEquals(0, $classifier->predict([0.1, 0.2]));
+        self::assertEquals(0, $classifier->predict([0, 1]));
+        self::assertEquals(1, $classifier->predict([1.1, 0.8]));
 
         // OR problem
         $samples = [[0.1, 0.1], [0.4, 0.], [0., 0.3], [1, 0], [0, 1], [1, 1]];
@@ -43,9 +43,9 @@ public function testPredictSingleSample(): void
         $classifier = new Perceptron(0.001, 5000, false);
         $classifier->setEarlyStop(false);
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0., 0.]));
-        $this->assertEquals(1, $classifier->predict([0.1, 0.99]));
-        $this->assertEquals(1, $classifier->predict([1.1, 0.8]));
+        self::assertEquals(0, $classifier->predict([0., 0.]));
+        self::assertEquals(1, $classifier->predict([0.1, 0.99]));
+        self::assertEquals(1, $classifier->predict([1.1, 0.8]));
 
         // By use of One-v-Rest, Perceptron can perform multi-class classification
         // The samples should be separable by lines perpendicular to the dimensions
@@ -59,15 +59,15 @@ public function testPredictSingleSample(): void
         $classifier = new Perceptron();
         $classifier->setEarlyStop(false);
         $classifier->train($samples, $targets);
-        $this->assertEquals(0, $classifier->predict([0.5, 0.5]));
-        $this->assertEquals(1, $classifier->predict([6.0, 5.0]));
-        $this->assertEquals(2, $classifier->predict([3.0, 9.5]));
+        self::assertEquals(0, $classifier->predict([0.5, 0.5]));
+        self::assertEquals(1, $classifier->predict([6.0, 5.0]));
+        self::assertEquals(2, $classifier->predict([3.0, 9.5]));
 
         // Extra partial training should lead to the same results.
         $classifier->partialTrain([[0, 1], [1, 0]], [0, 0], [0, 1, 2]);
-        $this->assertEquals(0, $classifier->predict([0.5, 0.5]));
-        $this->assertEquals(1, $classifier->predict([6.0, 5.0]));
-        $this->assertEquals(2, $classifier->predict([3.0, 9.5]));
+        self::assertEquals(0, $classifier->predict([0.5, 0.5]));
+        self::assertEquals(1, $classifier->predict([6.0, 5.0]));
+        self::assertEquals(2, $classifier->predict([3.0, 9.5]));
 
         // Train should clear previous data.
         $samples = [
@@ -77,9 +77,9 @@ public function testPredictSingleSample(): void
         ];
         $targets = [2, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1];
         $classifier->train($samples, $targets);
-        $this->assertEquals(2, $classifier->predict([0.5, 0.5]));
-        $this->assertEquals(0, $classifier->predict([6.0, 5.0]));
-        $this->assertEquals(1, $classifier->predict([3.0, 9.5]));
+        self::assertEquals(2, $classifier->predict([0.5, 0.5]));
+        self::assertEquals(0, $classifier->predict([6.0, 5.0]));
+        self::assertEquals(1, $classifier->predict([3.0, 9.5]));
     }
 
     public function testSaveAndRestore(): void
@@ -93,12 +93,12 @@ public function testSaveAndRestore(): void
         $predicted = $classifier->predict($testSamples);
 
         $filename = 'perceptron-test-'.random_int(100, 999).'-'.uniqid('', false);
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 }
diff --git a/tests/Classification/MLPClassifierTest.php b/tests/Classification/MLPClassifierTest.php
index ae0871dc..2998ac91 100644
--- a/tests/Classification/MLPClassifierTest.php
+++ b/tests/Classification/MLPClassifierTest.php
@@ -21,21 +21,21 @@ public function testMLPClassifierLayersInitialization(): void
     {
         $mlp = new MLPClassifier(2, [2], [0, 1]);
 
-        $this->assertCount(3, $mlp->getLayers());
+        self::assertCount(3, $mlp->getLayers());
 
         $layers = $mlp->getLayers();
 
         // input layer
-        $this->assertCount(3, $layers[0]->getNodes());
-        $this->assertNotContainsOnly(Neuron::class, $layers[0]->getNodes());
+        self::assertCount(3, $layers[0]->getNodes());
+        self::assertNotContainsOnly(Neuron::class, $layers[0]->getNodes());
 
         // hidden layer
-        $this->assertCount(3, $layers[1]->getNodes());
-        $this->assertNotContainsOnly(Neuron::class, $layers[1]->getNodes());
+        self::assertCount(3, $layers[1]->getNodes());
+        self::assertNotContainsOnly(Neuron::class, $layers[1]->getNodes());
 
         // output layer
-        $this->assertCount(2, $layers[2]->getNodes());
-        $this->assertContainsOnly(Neuron::class, $layers[2]->getNodes());
+        self::assertCount(2, $layers[2]->getNodes());
+        self::assertContainsOnly(Neuron::class, $layers[2]->getNodes());
     }
 
     public function testSynapsesGeneration(): void
@@ -46,11 +46,11 @@ public function testSynapsesGeneration(): void
         foreach ($layers[1]->getNodes() as $node) {
             if ($node instanceof Neuron) {
                 $synapses = $node->getSynapses();
-                $this->assertCount(3, $synapses);
+                self::assertCount(3, $synapses);
 
                 $synapsesNodes = $this->getSynapsesNodes($synapses);
                 foreach ($layers[0]->getNodes() as $prevNode) {
-                    $this->assertContains($prevNode, $synapsesNodes);
+                    self::assertContains($prevNode, $synapsesNodes);
                 }
             }
         }
@@ -65,10 +65,10 @@ public function testBackpropagationLearning(): void
             ['a', 'b', 'a', 'b']
         );
 
-        $this->assertEquals('a', $network->predict([1, 0]));
-        $this->assertEquals('b', $network->predict([0, 1]));
-        $this->assertEquals('a', $network->predict([1, 1]));
-        $this->assertEquals('b', $network->predict([0, 0]));
+        self::assertEquals('a', $network->predict([1, 0]));
+        self::assertEquals('b', $network->predict([0, 1]));
+        self::assertEquals('a', $network->predict([1, 1]));
+        self::assertEquals('b', $network->predict([0, 0]));
     }
 
     public function testBackpropagationTrainingReset(): void
@@ -80,16 +80,16 @@ public function testBackpropagationTrainingReset(): void
             ['a', 'b']
         );
 
-        $this->assertEquals('a', $network->predict([1, 0]));
-        $this->assertEquals('b', $network->predict([0, 1]));
+        self::assertEquals('a', $network->predict([1, 0]));
+        self::assertEquals('b', $network->predict([0, 1]));
 
         $network->train(
             [[1, 0], [0, 1]],
             ['b', 'a']
         );
 
-        $this->assertEquals('b', $network->predict([1, 0]));
-        $this->assertEquals('a', $network->predict([0, 1]));
+        self::assertEquals('b', $network->predict([1, 0]));
+        self::assertEquals('a', $network->predict([0, 1]));
     }
 
     public function testBackpropagationPartialTraining(): void
@@ -101,18 +101,18 @@ public function testBackpropagationPartialTraining(): void
             ['a', 'b']
         );
 
-        $this->assertEquals('a', $network->predict([1, 0]));
-        $this->assertEquals('b', $network->predict([0, 1]));
+        self::assertEquals('a', $network->predict([1, 0]));
+        self::assertEquals('b', $network->predict([0, 1]));
 
         $network->partialTrain(
             [[1, 1], [0, 0]],
             ['a', 'b']
         );
 
-        $this->assertEquals('a', $network->predict([1, 0]));
-        $this->assertEquals('b', $network->predict([0, 1]));
-        $this->assertEquals('a', $network->predict([1, 1]));
-        $this->assertEquals('b', $network->predict([0, 0]));
+        self::assertEquals('a', $network->predict([1, 0]));
+        self::assertEquals('b', $network->predict([0, 1]));
+        self::assertEquals('a', $network->predict([1, 1]));
+        self::assertEquals('b', $network->predict([0, 0]));
     }
 
     public function testBackpropagationLearningMultilayer(): void
@@ -124,10 +124,10 @@ public function testBackpropagationLearningMultilayer(): void
             ['a', 'b', 'a', 'c']
         );
 
-        $this->assertEquals('a', $network->predict([1, 0, 0, 0, 0]));
-        $this->assertEquals('b', $network->predict([0, 1, 1, 0, 0]));
-        $this->assertEquals('a', $network->predict([1, 1, 1, 1, 1]));
-        $this->assertEquals('c', $network->predict([0, 0, 0, 0, 0]));
+        self::assertEquals('a', $network->predict([1, 0, 0, 0, 0]));
+        self::assertEquals('b', $network->predict([0, 1, 1, 0, 0]));
+        self::assertEquals('a', $network->predict([1, 1, 1, 1, 1]));
+        self::assertEquals('c', $network->predict([0, 0, 0, 0, 0]));
     }
 
     public function testBackpropagationLearningMulticlass(): void
@@ -139,11 +139,11 @@ public function testBackpropagationLearningMulticlass(): void
             ['a', 'b', 'a', 'a', 4]
         );
 
-        $this->assertEquals('a', $network->predict([1, 0, 0, 0, 0]));
-        $this->assertEquals('b', $network->predict([0, 1, 0, 0, 0]));
-        $this->assertEquals('a', $network->predict([0, 0, 1, 1, 0]));
-        $this->assertEquals('a', $network->predict([1, 1, 1, 1, 1]));
-        $this->assertEquals(4, $network->predict([0, 0, 0, 0, 0]));
+        self::assertEquals('a', $network->predict([1, 0, 0, 0, 0]));
+        self::assertEquals('b', $network->predict([0, 1, 0, 0, 0]));
+        self::assertEquals('a', $network->predict([0, 0, 1, 1, 0]));
+        self::assertEquals('a', $network->predict([1, 1, 1, 1, 1]));
+        self::assertEquals(4, $network->predict([0, 0, 0, 0, 0]));
     }
 
     /**
@@ -157,10 +157,10 @@ public function testBackpropagationActivationFunctions(ActivationFunction $activ
             ['a', 'b', 'a', 'a']
         );
 
-        $this->assertEquals('a', $network->predict([1, 0, 0, 0, 0]));
-        $this->assertEquals('b', $network->predict([0, 1, 0, 0, 0]));
-        $this->assertEquals('a', $network->predict([0, 0, 1, 1, 0]));
-        $this->assertEquals('a', $network->predict([1, 1, 1, 1, 1]));
+        self::assertEquals('a', $network->predict([1, 0, 0, 0, 0]));
+        self::assertEquals('b', $network->predict([0, 1, 0, 0, 0]));
+        self::assertEquals('a', $network->predict([0, 0, 1, 1, 0]));
+        self::assertEquals('a', $network->predict([1, 1, 1, 1, 1]));
     }
 
     public function activationFunctionsProvider(): array
@@ -184,13 +184,13 @@ public function testSaveAndRestore(): void
         $predicted = $classifier->predict($testSamples);
 
         $filename = 'perceptron-test-'.random_int(100, 999).'-'.uniqid('', false);
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 
     public function testSaveAndRestoreWithPartialTraining(): void
@@ -201,11 +201,11 @@ public function testSaveAndRestoreWithPartialTraining(): void
             ['a', 'b']
         );
 
-        $this->assertEquals('a', $network->predict([1, 0]));
-        $this->assertEquals('b', $network->predict([0, 1]));
+        self::assertEquals('a', $network->predict([1, 0]));
+        self::assertEquals('b', $network->predict([0, 1]));
 
         $filename = 'perceptron-test-'.random_int(100, 999).'-'.uniqid('', false);
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($network, $filepath);
 
@@ -216,10 +216,10 @@ public function testSaveAndRestoreWithPartialTraining(): void
             ['a', 'b']
         );
 
-        $this->assertEquals('a', $restoredNetwork->predict([1, 0]));
-        $this->assertEquals('b', $restoredNetwork->predict([0, 1]));
-        $this->assertEquals('a', $restoredNetwork->predict([1, 1]));
-        $this->assertEquals('b', $restoredNetwork->predict([0, 0]));
+        self::assertEquals('a', $restoredNetwork->predict([1, 0]));
+        self::assertEquals('b', $restoredNetwork->predict([0, 1]));
+        self::assertEquals('a', $restoredNetwork->predict([1, 1]));
+        self::assertEquals('b', $restoredNetwork->predict([0, 0]));
     }
 
     public function testThrowExceptionOnInvalidLayersNumber(): void
@@ -249,7 +249,7 @@ public function testOutputWithLabels(): void
     {
         $output = (new MLPClassifier(2, [2, 2], ['T', 'F']))->getOutput();
 
-        $this->assertEquals(['T', 'F'], array_keys($output));
+        self::assertEquals(['T', 'F'], array_keys($output));
     }
 
     private function getSynapsesNodes(array $synapses): array
diff --git a/tests/Classification/NaiveBayesTest.php b/tests/Classification/NaiveBayesTest.php
index 434c9205..4e272618 100644
--- a/tests/Classification/NaiveBayesTest.php
+++ b/tests/Classification/NaiveBayesTest.php
@@ -18,9 +18,9 @@ public function testPredictSingleSample(): void
         $classifier = new NaiveBayes();
         $classifier->train($samples, $labels);
 
-        $this->assertEquals('a', $classifier->predict([3, 1, 1]));
-        $this->assertEquals('b', $classifier->predict([1, 4, 1]));
-        $this->assertEquals('c', $classifier->predict([1, 1, 6]));
+        self::assertEquals('a', $classifier->predict([3, 1, 1]));
+        self::assertEquals('b', $classifier->predict([1, 4, 1]));
+        self::assertEquals('c', $classifier->predict([1, 1, 6]));
     }
 
     public function testPredictArrayOfSamples(): void
@@ -35,7 +35,7 @@ public function testPredictArrayOfSamples(): void
         $classifier->train($trainSamples, $trainLabels);
         $predicted = $classifier->predict($testSamples);
 
-        $this->assertEquals($testLabels, $predicted);
+        self::assertEquals($testLabels, $predicted);
 
         // Feed an extra set of training data.
         $samples = [[1, 1, 6]];
@@ -44,7 +44,7 @@ public function testPredictArrayOfSamples(): void
 
         $testSamples = [[1, 1, 6], [5, 1, 1]];
         $testLabels = ['d', 'a'];
-        $this->assertEquals($testLabels, $classifier->predict($testSamples));
+        self::assertEquals($testLabels, $classifier->predict($testSamples));
     }
 
     public function testSaveAndRestore(): void
@@ -59,13 +59,13 @@ public function testSaveAndRestore(): void
         $predicted = $classifier->predict($testSamples);
 
         $filename = 'naive-bayes-test-'.random_int(100, 999).'-'.uniqid('', false);
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 
     public function testPredictSimpleNumericLabels(): void
@@ -76,9 +76,9 @@ public function testPredictSimpleNumericLabels(): void
         $classifier = new NaiveBayes();
         $classifier->train($samples, $labels);
 
-        $this->assertEquals('1996', $classifier->predict([3, 1, 1]));
-        $this->assertEquals('1997', $classifier->predict([1, 4, 1]));
-        $this->assertEquals('1998', $classifier->predict([1, 1, 6]));
+        self::assertEquals('1996', $classifier->predict([3, 1, 1]));
+        self::assertEquals('1997', $classifier->predict([1, 4, 1]));
+        self::assertEquals('1998', $classifier->predict([1, 1, 6]));
     }
 
     public function testPredictArrayOfSamplesNumericalLabels(): void
@@ -93,7 +93,7 @@ public function testPredictArrayOfSamplesNumericalLabels(): void
         $classifier->train($trainSamples, $trainLabels);
         $predicted = $classifier->predict($testSamples);
 
-        $this->assertEquals($testLabels, $predicted);
+        self::assertEquals($testLabels, $predicted);
 
         // Feed an extra set of training data.
         $samples = [[1, 1, 6]];
@@ -102,7 +102,7 @@ public function testPredictArrayOfSamplesNumericalLabels(): void
 
         $testSamples = [[1, 1, 6], [5, 1, 1]];
         $testLabels = ['1999', '1996'];
-        $this->assertEquals($testLabels, $classifier->predict($testSamples));
+        self::assertEquals($testLabels, $classifier->predict($testSamples));
     }
 
     public function testSaveAndRestoreNumericLabels(): void
@@ -117,12 +117,12 @@ public function testSaveAndRestoreNumericLabels(): void
         $predicted = $classifier->predict($testSamples);
 
         $filename = 'naive-bayes-test-'.random_int(100, 999).'-'.uniqid('', false);
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
     }
 }
diff --git a/tests/Classification/SVCTest.php b/tests/Classification/SVCTest.php
index 1ec15418..5fbcff8c 100644
--- a/tests/Classification/SVCTest.php
+++ b/tests/Classification/SVCTest.php
@@ -19,15 +19,15 @@ public function testPredictSingleSampleWithLinearKernel(): void
         $classifier = new SVC(Kernel::LINEAR, $cost = 1000);
         $classifier->train($samples, $labels);
 
-        $this->assertEquals('b', $classifier->predict([3, 2]));
-        $this->assertEquals('b', $classifier->predict([5, 1]));
-        $this->assertEquals('b', $classifier->predict([4, 3]));
-        $this->assertEquals('b', $classifier->predict([4, -5]));
-
-        $this->assertEquals('a', $classifier->predict([2, 3]));
-        $this->assertEquals('a', $classifier->predict([1, 2]));
-        $this->assertEquals('a', $classifier->predict([1, 5]));
-        $this->assertEquals('a', $classifier->predict([3, 10]));
+        self::assertEquals('b', $classifier->predict([3, 2]));
+        self::assertEquals('b', $classifier->predict([5, 1]));
+        self::assertEquals('b', $classifier->predict([4, 3]));
+        self::assertEquals('b', $classifier->predict([4, -5]));
+
+        self::assertEquals('a', $classifier->predict([2, 3]));
+        self::assertEquals('a', $classifier->predict([1, 2]));
+        self::assertEquals('a', $classifier->predict([1, 5]));
+        self::assertEquals('a', $classifier->predict([3, 10]));
     }
 
     public function testPredictArrayOfSamplesWithLinearKernel(): void
@@ -42,7 +42,7 @@ public function testPredictArrayOfSamplesWithLinearKernel(): void
         $classifier->train($trainSamples, $trainLabels);
         $predictions = $classifier->predict($testSamples);
 
-        $this->assertEquals($testLabels, $predictions);
+        self::assertEquals($testLabels, $predictions);
     }
 
     public function testSaveAndRestore(): void
@@ -57,14 +57,14 @@ public function testSaveAndRestore(): void
         $classifier->train($trainSamples, $trainLabels);
         $predicted = $classifier->predict($testSamples);
 
-        $filepath = tempnam(sys_get_temp_dir(), uniqid('svc-test', true));
+        $filepath = (string) tempnam(sys_get_temp_dir(), uniqid('svc-test', true));
         $modelManager = new ModelManager();
         $modelManager->saveToFile($classifier, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($classifier, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
-        $this->assertEquals($predicted, $testLabels);
+        self::assertEquals($classifier, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($predicted, $testLabels);
     }
 
     public function testWithNonDotDecimalLocale(): void
@@ -81,8 +81,8 @@ public function testWithNonDotDecimalLocale(): void
         $classifier = new SVC(Kernel::LINEAR, $cost = 1000);
         $classifier->train($trainSamples, $trainLabels);
 
-        $this->assertEquals($classifier->predict($testSamples), $testLabels);
+        self::assertEquals($classifier->predict($testSamples), $testLabels);
 
-        setlocale(LC_NUMERIC, $currentLocale);
+        setlocale(LC_NUMERIC, (string) $currentLocale);
     }
 }
diff --git a/tests/Clustering/DBSCANTest.php b/tests/Clustering/DBSCANTest.php
index 3c6d08d8..11322036 100644
--- a/tests/Clustering/DBSCANTest.php
+++ b/tests/Clustering/DBSCANTest.php
@@ -19,7 +19,7 @@ public function testDBSCANSamplesClustering(): void
 
         $dbscan = new DBSCAN($epsilon = 2, $minSamples = 3);
 
-        $this->assertEquals($clustered, $dbscan->cluster($samples));
+        self::assertEquals($clustered, $dbscan->cluster($samples));
 
         $samples = [[1, 1], [6, 6], [1, -1], [5, 6], [-1, -1], [7, 8], [-1, 1], [7, 7]];
         $clustered = [
@@ -29,7 +29,7 @@ public function testDBSCANSamplesClustering(): void
 
         $dbscan = new DBSCAN($epsilon = 3, $minSamples = 4);
 
-        $this->assertEquals($clustered, $dbscan->cluster($samples));
+        self::assertEquals($clustered, $dbscan->cluster($samples));
     }
 
     public function testDBSCANSamplesClusteringAssociative(): void
@@ -57,7 +57,7 @@ public function testDBSCANSamplesClusteringAssociative(): void
 
         $dbscan = new DBSCAN($epsilon = 3, $minSamples = 2);
 
-        $this->assertEquals($clustered, $dbscan->cluster($samples));
+        self::assertEquals($clustered, $dbscan->cluster($samples));
     }
 
     public function testClusterEpsilonSmall(): void
@@ -68,7 +68,7 @@ public function testClusterEpsilonSmall(): void
 
         $dbscan = new DBSCAN($epsilon = 0.5, $minSamples = 2);
 
-        $this->assertEquals($clustered, $dbscan->cluster($samples));
+        self::assertEquals($clustered, $dbscan->cluster($samples));
     }
 
     public function testClusterEpsilonBoundary(): void
@@ -79,7 +79,7 @@ public function testClusterEpsilonBoundary(): void
 
         $dbscan = new DBSCAN($epsilon = 1.0, $minSamples = 2);
 
-        $this->assertEquals($clustered, $dbscan->cluster($samples));
+        self::assertEquals($clustered, $dbscan->cluster($samples));
     }
 
     public function testClusterEpsilonLarge(): void
@@ -91,6 +91,6 @@ public function testClusterEpsilonLarge(): void
 
         $dbscan = new DBSCAN($epsilon = 1.5, $minSamples = 2);
 
-        $this->assertEquals($clustered, $dbscan->cluster($samples));
+        self::assertEquals($clustered, $dbscan->cluster($samples));
     }
 }
diff --git a/tests/Clustering/FuzzyCMeansTest.php b/tests/Clustering/FuzzyCMeansTest.php
index b2005a1d..638e99c3 100644
--- a/tests/Clustering/FuzzyCMeansTest.php
+++ b/tests/Clustering/FuzzyCMeansTest.php
@@ -10,40 +10,40 @@
 
 class FuzzyCMeansTest extends TestCase
 {
-    public function testFCMSamplesClustering()
+    public function testFCMSamplesClustering(): void
     {
         $samples = [[1, 1], [8, 7], [1, 2], [7, 8], [2, 1], [8, 9]];
         $fcm = new FuzzyCMeans(2);
         $clusters = $fcm->cluster($samples);
-        $this->assertCount(2, $clusters);
+        self::assertCount(2, $clusters);
         foreach ($samples as $index => $sample) {
             if (in_array($sample, $clusters[0], true) || in_array($sample, $clusters[1], true)) {
                 unset($samples[$index]);
             }
         }
 
-        $this->assertCount(0, $samples);
-
-        return $fcm;
+        self::assertCount(0, $samples);
     }
 
     public function testMembershipMatrix(): void
     {
-        $fcm = $this->testFCMSamplesClustering();
+        $fcm = new FuzzyCMeans(2);
+        $fcm->cluster([[1, 1], [8, 7], [1, 2], [7, 8], [2, 1], [8, 9]]);
+
         $clusterCount = 2;
         $sampleCount = 6;
         $matrix = $fcm->getMembershipMatrix();
-        $this->assertCount($clusterCount, $matrix);
+        self::assertCount($clusterCount, $matrix);
         foreach ($matrix as $row) {
-            $this->assertCount($sampleCount, $row);
+            self::assertCount($sampleCount, $row);
         }
 
         // Transpose of the matrix
         array_unshift($matrix, null);
-        $matrix = call_user_func_array('array_map', $matrix);
+        $matrix = array_map(...$matrix);
         // All column totals should be equal to 1 (100% membership)
         foreach ($matrix as $col) {
-            $this->assertEquals(1, array_sum($col));
+            self::assertEquals(1, array_sum($col));
         }
     }
 
diff --git a/tests/Clustering/KMeans/ClusterTest.php b/tests/Clustering/KMeans/ClusterTest.php
index 80b98373..2b57d0b8 100644
--- a/tests/Clustering/KMeans/ClusterTest.php
+++ b/tests/Clustering/KMeans/ClusterTest.php
@@ -26,7 +26,7 @@ public function testToArray(): void
         $cluster = new Cluster(new Space(2), [1, 2]);
         $cluster->attach(new Point([1, 1]));
 
-        $this->assertSame([
+        self::assertSame([
             'centroid' => [1, 2],
             'points' => [
                 [1, 1],
@@ -42,8 +42,8 @@ public function testDetach(): void
 
         $detachedPoint = $cluster->detach($point);
 
-        $this->assertSame($detachedPoint, $point);
-        $this->assertNotContains($point, $cluster->getPoints());
-        $this->assertCount(1, $cluster);
+        self::assertSame($detachedPoint, $point);
+        self::assertNotContains($point, $cluster->getPoints());
+        self::assertCount(1, $cluster);
     }
 }
diff --git a/tests/Clustering/KMeansTest.php b/tests/Clustering/KMeansTest.php
index ba36bc63..0265f7d5 100644
--- a/tests/Clustering/KMeansTest.php
+++ b/tests/Clustering/KMeansTest.php
@@ -17,7 +17,7 @@ public function testKMeansSamplesClustering(): void
         $kmeans = new KMeans(2);
         $clusters = $kmeans->cluster($samples);
 
-        $this->assertCount(2, $clusters);
+        self::assertCount(2, $clusters);
 
         foreach ($samples as $index => $sample) {
             if (in_array($sample, $clusters[0], true) || in_array($sample, $clusters[1], true)) {
@@ -25,7 +25,7 @@ public function testKMeansSamplesClustering(): void
             }
         }
 
-        $this->assertCount(0, $samples);
+        self::assertCount(0, $samples);
     }
 
     public function testKMeansSamplesLabeledClustering(): void
@@ -42,16 +42,16 @@ public function testKMeansSamplesLabeledClustering(): void
         $kmeans = new KMeans(2);
         $clusters = $kmeans->cluster($samples);
 
-        $this->assertCount(2, $clusters);
+        self::assertCount(2, $clusters);
 
         foreach ($samples as $index => $sample) {
             if (in_array($sample, $clusters[0], true) || in_array($sample, $clusters[1], true)) {
-                $this->assertArrayHasKey($index, $clusters[0] + $clusters[1]);
+                self::assertArrayHasKey($index, $clusters[0] + $clusters[1]);
                 unset($samples[$index]);
             }
         }
 
-        $this->assertCount(0, $samples);
+        self::assertCount(0, $samples);
     }
 
     public function testKMeansInitializationMethods(): void
@@ -71,11 +71,11 @@ public function testKMeansInitializationMethods(): void
 
         $kmeans = new KMeans(4, KMeans::INIT_KMEANS_PLUS_PLUS);
         $clusters = $kmeans->cluster($samples);
-        $this->assertCount(4, $clusters);
+        self::assertCount(4, $clusters);
 
         $kmeans = new KMeans(4, KMeans::INIT_RANDOM);
         $clusters = $kmeans->cluster($samples);
-        $this->assertCount(4, $clusters);
+        self::assertCount(4, $clusters);
     }
 
     public function testThrowExceptionOnInvalidClusterNumber(): void
diff --git a/tests/CrossValidation/RandomSplitTest.php b/tests/CrossValidation/RandomSplitTest.php
index 65e8d8b9..88928cca 100644
--- a/tests/CrossValidation/RandomSplitTest.php
+++ b/tests/CrossValidation/RandomSplitTest.php
@@ -32,13 +32,13 @@ public function testDatasetRandomSplitWithoutSeed(): void
 
         $randomSplit = new RandomSplit($dataset, 0.5);
 
-        $this->assertCount(2, $randomSplit->getTestSamples());
-        $this->assertCount(2, $randomSplit->getTrainSamples());
+        self::assertCount(2, $randomSplit->getTestSamples());
+        self::assertCount(2, $randomSplit->getTrainSamples());
 
         $randomSplit2 = new RandomSplit($dataset, 0.25);
 
-        $this->assertCount(1, $randomSplit2->getTestSamples());
-        $this->assertCount(3, $randomSplit2->getTrainSamples());
+        self::assertCount(1, $randomSplit2->getTestSamples());
+        self::assertCount(3, $randomSplit2->getTrainSamples());
     }
 
     public function testDatasetRandomSplitWithSameSeed(): void
@@ -53,10 +53,10 @@ public function testDatasetRandomSplitWithSameSeed(): void
         $randomSplit1 = new RandomSplit($dataset, 0.5, $seed);
         $randomSplit2 = new RandomSplit($dataset, 0.5, $seed);
 
-        $this->assertEquals($randomSplit1->getTestLabels(), $randomSplit2->getTestLabels());
-        $this->assertEquals($randomSplit1->getTestSamples(), $randomSplit2->getTestSamples());
-        $this->assertEquals($randomSplit1->getTrainLabels(), $randomSplit2->getTrainLabels());
-        $this->assertEquals($randomSplit1->getTrainSamples(), $randomSplit2->getTrainSamples());
+        self::assertEquals($randomSplit1->getTestLabels(), $randomSplit2->getTestLabels());
+        self::assertEquals($randomSplit1->getTestSamples(), $randomSplit2->getTestSamples());
+        self::assertEquals($randomSplit1->getTrainLabels(), $randomSplit2->getTrainLabels());
+        self::assertEquals($randomSplit1->getTrainSamples(), $randomSplit2->getTrainSamples());
     }
 
     public function testDatasetRandomSplitWithDifferentSeed(): void
@@ -69,10 +69,10 @@ public function testDatasetRandomSplitWithDifferentSeed(): void
         $randomSplit1 = new RandomSplit($dataset, 0.5, 4321);
         $randomSplit2 = new RandomSplit($dataset, 0.5, 1234);
 
-        $this->assertNotEquals($randomSplit1->getTestLabels(), $randomSplit2->getTestLabels());
-        $this->assertNotEquals($randomSplit1->getTestSamples(), $randomSplit2->getTestSamples());
-        $this->assertNotEquals($randomSplit1->getTrainLabels(), $randomSplit2->getTrainLabels());
-        $this->assertNotEquals($randomSplit1->getTrainSamples(), $randomSplit2->getTrainSamples());
+        self::assertNotEquals($randomSplit1->getTestLabels(), $randomSplit2->getTestLabels());
+        self::assertNotEquals($randomSplit1->getTestSamples(), $randomSplit2->getTestSamples());
+        self::assertNotEquals($randomSplit1->getTrainLabels(), $randomSplit2->getTrainLabels());
+        self::assertNotEquals($randomSplit1->getTrainSamples(), $randomSplit2->getTrainSamples());
     }
 
     public function testRandomSplitCorrectSampleAndLabelPosition(): void
@@ -84,9 +84,9 @@ public function testRandomSplitCorrectSampleAndLabelPosition(): void
 
         $randomSplit = new RandomSplit($dataset, 0.5);
 
-        $this->assertEquals($randomSplit->getTestSamples()[0][0], $randomSplit->getTestLabels()[0]);
-        $this->assertEquals($randomSplit->getTestSamples()[1][0], $randomSplit->getTestLabels()[1]);
-        $this->assertEquals($randomSplit->getTrainSamples()[0][0], $randomSplit->getTrainLabels()[0]);
-        $this->assertEquals($randomSplit->getTrainSamples()[1][0], $randomSplit->getTrainLabels()[1]);
+        self::assertEquals($randomSplit->getTestSamples()[0][0], $randomSplit->getTestLabels()[0]);
+        self::assertEquals($randomSplit->getTestSamples()[1][0], $randomSplit->getTestLabels()[1]);
+        self::assertEquals($randomSplit->getTrainSamples()[0][0], $randomSplit->getTrainLabels()[0]);
+        self::assertEquals($randomSplit->getTrainSamples()[1][0], $randomSplit->getTrainLabels()[1]);
     }
 }
diff --git a/tests/CrossValidation/StratifiedRandomSplitTest.php b/tests/CrossValidation/StratifiedRandomSplitTest.php
index 5309dc69..909f15fb 100644
--- a/tests/CrossValidation/StratifiedRandomSplitTest.php
+++ b/tests/CrossValidation/StratifiedRandomSplitTest.php
@@ -19,13 +19,13 @@ public function testDatasetStratifiedRandomSplitWithEvenDistribution(): void
 
         $split = new StratifiedRandomSplit($dataset, 0.5);
 
-        $this->assertEquals(2, $this->countSamplesByTarget($split->getTestLabels(), 'a'));
-        $this->assertEquals(2, $this->countSamplesByTarget($split->getTestLabels(), 'b'));
+        self::assertEquals(2, $this->countSamplesByTarget($split->getTestLabels(), 'a'));
+        self::assertEquals(2, $this->countSamplesByTarget($split->getTestLabels(), 'b'));
 
         $split = new StratifiedRandomSplit($dataset, 0.25);
 
-        $this->assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 'a'));
-        $this->assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 'b'));
+        self::assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 'a'));
+        self::assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 'b'));
     }
 
     public function testDatasetStratifiedRandomSplitWithEvenDistributionAndNumericTargets(): void
@@ -37,16 +37,19 @@ public function testDatasetStratifiedRandomSplitWithEvenDistributionAndNumericTa
 
         $split = new StratifiedRandomSplit($dataset, 0.5);
 
-        $this->assertEquals(2, $this->countSamplesByTarget($split->getTestLabels(), 1));
-        $this->assertEquals(2, $this->countSamplesByTarget($split->getTestLabels(), 2));
+        self::assertEquals(2, $this->countSamplesByTarget($split->getTestLabels(), 1));
+        self::assertEquals(2, $this->countSamplesByTarget($split->getTestLabels(), 2));
 
         $split = new StratifiedRandomSplit($dataset, 0.25);
 
-        $this->assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 1));
-        $this->assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 2));
+        self::assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 1));
+        self::assertEquals(1, $this->countSamplesByTarget($split->getTestLabels(), 2));
     }
 
-    private function countSamplesByTarget($splitTargets, $countTarget): int
+    /**
+     * @param string|int $countTarget
+     */
+    private function countSamplesByTarget(array $splitTargets, $countTarget): int
     {
         $count = 0;
         foreach ($splitTargets as $target) {
diff --git a/tests/Dataset/ArrayDatasetTest.php b/tests/Dataset/ArrayDatasetTest.php
index 04319596..98792c71 100644
--- a/tests/Dataset/ArrayDatasetTest.php
+++ b/tests/Dataset/ArrayDatasetTest.php
@@ -23,8 +23,8 @@ public function testArrayDataset(): void
             $labels = ['a', 'a', 'b', 'b']
         );
 
-        $this->assertEquals($samples, $dataset->getSamples());
-        $this->assertEquals($labels, $dataset->getTargets());
+        self::assertEquals($samples, $dataset->getSamples());
+        self::assertEquals($labels, $dataset->getTargets());
     }
 
     public function testRemoveColumns(): void
@@ -35,6 +35,6 @@ public function testRemoveColumns(): void
         );
         $dataset->removeColumns([0, 2]);
 
-        $this->assertEquals([[2, 4], [3, 5], [4, 6], [5, 7]], $dataset->getSamples());
+        self::assertEquals([[2, 4], [3, 5], [4, 6], [5, 7]], $dataset->getSamples());
     }
 }
diff --git a/tests/Dataset/CsvDatasetTest.php b/tests/Dataset/CsvDatasetTest.php
index 90eb1d09..a1787262 100644
--- a/tests/Dataset/CsvDatasetTest.php
+++ b/tests/Dataset/CsvDatasetTest.php
@@ -22,8 +22,8 @@ public function testSampleCsvDatasetWithHeaderRow(): void
 
         $dataset = new CsvDataset($filePath, 2, true);
 
-        $this->assertCount(10, $dataset->getSamples());
-        $this->assertCount(10, $dataset->getTargets());
+        self::assertCount(10, $dataset->getSamples());
+        self::assertCount(10, $dataset->getTargets());
     }
 
     public function testSampleCsvDatasetWithoutHeaderRow(): void
@@ -32,8 +32,8 @@ public function testSampleCsvDatasetWithoutHeaderRow(): void
 
         $dataset = new CsvDataset($filePath, 2, false);
 
-        $this->assertCount(11, $dataset->getSamples());
-        $this->assertCount(11, $dataset->getTargets());
+        self::assertCount(11, $dataset->getSamples());
+        self::assertCount(11, $dataset->getTargets());
     }
 
     public function testLongCsvDataset(): void
@@ -42,7 +42,7 @@ public function testLongCsvDataset(): void
 
         $dataset = new CsvDataset($filePath, 1000, false);
 
-        $this->assertCount(1000, $dataset->getSamples()[0]);
-        $this->assertEquals('label', $dataset->getTargets()[0]);
+        self::assertCount(1000, $dataset->getSamples()[0]);
+        self::assertEquals('label', $dataset->getTargets()[0]);
     }
 }
diff --git a/tests/Dataset/Demo/GlassDatasetTest.php b/tests/Dataset/Demo/GlassDatasetTest.php
index 0d873e65..3ef182a8 100644
--- a/tests/Dataset/Demo/GlassDatasetTest.php
+++ b/tests/Dataset/Demo/GlassDatasetTest.php
@@ -14,10 +14,10 @@ public function testLoadingWineDataset(): void
         $glass = new GlassDataset();
 
         // whole dataset
-        $this->assertCount(214, $glass->getSamples());
-        $this->assertCount(214, $glass->getTargets());
+        self::assertCount(214, $glass->getSamples());
+        self::assertCount(214, $glass->getTargets());
 
         // one sample features count
-        $this->assertCount(9, $glass->getSamples()[0]);
+        self::assertCount(9, $glass->getSamples()[0]);
     }
 }
diff --git a/tests/Dataset/Demo/IrisDatasetTest.php b/tests/Dataset/Demo/IrisDatasetTest.php
index 4fb2ee23..171bc38b 100644
--- a/tests/Dataset/Demo/IrisDatasetTest.php
+++ b/tests/Dataset/Demo/IrisDatasetTest.php
@@ -14,10 +14,10 @@ public function testLoadingIrisDataset(): void
         $iris = new IrisDataset();
 
         // whole dataset
-        $this->assertCount(150, $iris->getSamples());
-        $this->assertCount(150, $iris->getTargets());
+        self::assertCount(150, $iris->getSamples());
+        self::assertCount(150, $iris->getTargets());
 
         // one sample features count
-        $this->assertCount(4, $iris->getSamples()[0]);
+        self::assertCount(4, $iris->getSamples()[0]);
     }
 }
diff --git a/tests/Dataset/Demo/WineDatasetTest.php b/tests/Dataset/Demo/WineDatasetTest.php
index 1b7a982f..01192941 100644
--- a/tests/Dataset/Demo/WineDatasetTest.php
+++ b/tests/Dataset/Demo/WineDatasetTest.php
@@ -14,10 +14,10 @@ public function testLoadingWineDataset(): void
         $wine = new WineDataset();
 
         // whole dataset
-        $this->assertCount(178, $wine->getSamples());
-        $this->assertCount(178, $wine->getTargets());
+        self::assertCount(178, $wine->getSamples());
+        self::assertCount(178, $wine->getTargets());
 
         // one sample features count
-        $this->assertCount(13, $wine->getSamples()[0]);
+        self::assertCount(13, $wine->getSamples()[0]);
     }
 }
diff --git a/tests/Dataset/FilesDatasetTest.php b/tests/Dataset/FilesDatasetTest.php
index 08b568d9..ec30f91b 100644
--- a/tests/Dataset/FilesDatasetTest.php
+++ b/tests/Dataset/FilesDatasetTest.php
@@ -22,22 +22,22 @@ public function testLoadFilesDatasetWithBBCData(): void
 
         $dataset = new FilesDataset($rootPath);
 
-        $this->assertCount(50, $dataset->getSamples());
-        $this->assertCount(50, $dataset->getTargets());
+        self::assertCount(50, $dataset->getSamples());
+        self::assertCount(50, $dataset->getTargets());
 
         $targets = ['business', 'entertainment', 'politics', 'sport', 'tech'];
-        $this->assertEquals($targets, array_values(array_unique($dataset->getTargets())));
+        self::assertEquals($targets, array_values(array_unique($dataset->getTargets())));
 
         $firstSample = file_get_contents($rootPath.'/business/001.txt');
-        $this->assertEquals($firstSample, $dataset->getSamples()[0][0]);
+        self::assertEquals($firstSample, $dataset->getSamples()[0][0]);
 
         $firstTarget = 'business';
-        $this->assertEquals($firstTarget, $dataset->getTargets()[0]);
+        self::assertEquals($firstTarget, $dataset->getTargets()[0]);
 
         $lastSample = file_get_contents($rootPath.'/tech/010.txt');
-        $this->assertEquals($lastSample, $dataset->getSamples()[49][0]);
+        self::assertEquals($lastSample, $dataset->getSamples()[49][0]);
 
         $lastTarget = 'tech';
-        $this->assertEquals($lastTarget, $dataset->getTargets()[49]);
+        self::assertEquals($lastTarget, $dataset->getTargets()[49]);
     }
 }
diff --git a/tests/Dataset/SvmDatasetTest.php b/tests/Dataset/SvmDatasetTest.php
index 700055c8..437e3d20 100644
--- a/tests/Dataset/SvmDatasetTest.php
+++ b/tests/Dataset/SvmDatasetTest.php
@@ -21,8 +21,8 @@ public function testSvmDatasetEmpty(): void
         $expectedTargets = [
         ];
 
-        $this->assertEquals($expectedSamples, $dataset->getSamples());
-        $this->assertEquals($expectedTargets, $dataset->getTargets());
+        self::assertEquals($expectedSamples, $dataset->getSamples());
+        self::assertEquals($expectedTargets, $dataset->getTargets());
     }
 
     public function testSvmDataset1x1(): void
@@ -37,8 +37,8 @@ public function testSvmDataset1x1(): void
             0,
         ];
 
-        $this->assertEquals($expectedSamples, $dataset->getSamples());
-        $this->assertEquals($expectedTargets, $dataset->getTargets());
+        self::assertEquals($expectedSamples, $dataset->getSamples());
+        self::assertEquals($expectedTargets, $dataset->getTargets());
     }
 
     public function testSvmDataset3x1(): void
@@ -57,8 +57,8 @@ public function testSvmDataset3x1(): void
             1,
         ];
 
-        $this->assertEquals($expectedSamples, $dataset->getSamples());
-        $this->assertEquals($expectedTargets, $dataset->getTargets());
+        self::assertEquals($expectedSamples, $dataset->getSamples());
+        self::assertEquals($expectedTargets, $dataset->getTargets());
     }
 
     public function testSvmDataset3x4(): void
@@ -77,8 +77,8 @@ public function testSvmDataset3x4(): void
             0,
         ];
 
-        $this->assertEquals($expectedSamples, $dataset->getSamples());
-        $this->assertEquals($expectedTargets, $dataset->getTargets());
+        self::assertEquals($expectedSamples, $dataset->getSamples());
+        self::assertEquals($expectedTargets, $dataset->getTargets());
     }
 
     public function testSvmDatasetSparse(): void
@@ -95,8 +95,8 @@ public function testSvmDatasetSparse(): void
             1,
         ];
 
-        $this->assertEquals($expectedSamples, $dataset->getSamples());
-        $this->assertEquals($expectedTargets, $dataset->getTargets());
+        self::assertEquals($expectedSamples, $dataset->getSamples());
+        self::assertEquals($expectedTargets, $dataset->getTargets());
     }
 
     public function testSvmDatasetComments(): void
@@ -113,8 +113,8 @@ public function testSvmDatasetComments(): void
             1,
         ];
 
-        $this->assertEquals($expectedSamples, $dataset->getSamples());
-        $this->assertEquals($expectedTargets, $dataset->getTargets());
+        self::assertEquals($expectedSamples, $dataset->getSamples());
+        self::assertEquals($expectedTargets, $dataset->getTargets());
     }
 
     public function testSvmDatasetTabs(): void
@@ -129,8 +129,8 @@ public function testSvmDatasetTabs(): void
             1,
         ];
 
-        $this->assertEquals($expectedSamples, $dataset->getSamples());
-        $this->assertEquals($expectedTargets, $dataset->getTargets());
+        self::assertEquals($expectedSamples, $dataset->getSamples());
+        self::assertEquals($expectedTargets, $dataset->getTargets());
     }
 
     public function testSvmDatasetMissingFile(): void
diff --git a/tests/DimensionReduction/KernelPCATest.php b/tests/DimensionReduction/KernelPCATest.php
index cca0d537..cd04260b 100644
--- a/tests/DimensionReduction/KernelPCATest.php
+++ b/tests/DimensionReduction/KernelPCATest.php
@@ -40,7 +40,7 @@ public function testKernelPCA(): void
         // during the calculation of eigenValues, we have to compare
         // absolute value of the values
         array_map(function ($val1, $val2) use ($epsilon): void {
-            $this->assertEquals(abs($val1), abs($val2), '', $epsilon);
+            self::assertEquals(abs($val1), abs($val2), '', $epsilon);
         }, $transformed, $reducedData);
 
         // Fitted KernelPCA object can also transform an arbitrary sample of the
@@ -48,7 +48,7 @@ public function testKernelPCA(): void
         $newData = [1.25, 2.25];
         $newTransformed = [0.18956227539216];
         $newTransformed2 = $kpca->transform($newData);
-        $this->assertEquals(abs($newTransformed[0]), abs($newTransformed2[0]), '', $epsilon);
+        self::assertEquals(abs($newTransformed[0]), abs($newTransformed2[0]), '', $epsilon);
     }
 
     public function testKernelPCAThrowWhenKernelInvalid(): void
diff --git a/tests/DimensionReduction/LDATest.php b/tests/DimensionReduction/LDATest.php
index 79e925f6..101d2f96 100644
--- a/tests/DimensionReduction/LDATest.php
+++ b/tests/DimensionReduction/LDATest.php
@@ -51,7 +51,7 @@ public function testLDA(): void
             // absolute value of the values
             $row1 = array_map('abs', $row1);
             $row2 = array_map('abs', $row2);
-            $this->assertEquals($row1, $row2, '', $epsilon);
+            self::assertEquals($row1, $row2, '', $epsilon);
         };
         array_map($check, $control, $transformed2);
 
diff --git a/tests/DimensionReduction/PCATest.php b/tests/DimensionReduction/PCATest.php
index ba25268b..ebb5b013 100644
--- a/tests/DimensionReduction/PCATest.php
+++ b/tests/DimensionReduction/PCATest.php
@@ -42,7 +42,7 @@ public function testPCA(): void
         // during the calculation of eigenValues, we have to compare
         // absolute value of the values
         array_map(function ($val1, $val2) use ($epsilon): void {
-            $this->assertEquals(abs($val1), abs($val2), '', $epsilon);
+            self::assertEquals(abs($val1), abs($val2), '', $epsilon);
         }, $transformed, $reducedData);
 
         // Test fitted PCA object to transform an arbitrary sample of the
@@ -52,7 +52,7 @@ public function testPCA(): void
             $newRow2 = $pca->transform($row);
 
             array_map(function ($val1, $val2) use ($epsilon): void {
-                $this->assertEquals(abs($val1), abs($val2), '', $epsilon);
+                self::assertEquals(abs($val1), abs($val2), '', $epsilon);
             }, $newRow, $newRow2);
         }
     }
diff --git a/tests/FeatureExtraction/StopWordsTest.php b/tests/FeatureExtraction/StopWordsTest.php
index 5780c393..112fa0f4 100644
--- a/tests/FeatureExtraction/StopWordsTest.php
+++ b/tests/FeatureExtraction/StopWordsTest.php
@@ -14,13 +14,13 @@ public function testCustomStopWords(): void
     {
         $stopWords = new StopWords(['lorem', 'ipsum', 'dolor']);
 
-        $this->assertTrue($stopWords->isStopWord('lorem'));
-        $this->assertTrue($stopWords->isStopWord('ipsum'));
-        $this->assertTrue($stopWords->isStopWord('dolor'));
+        self::assertTrue($stopWords->isStopWord('lorem'));
+        self::assertTrue($stopWords->isStopWord('ipsum'));
+        self::assertTrue($stopWords->isStopWord('dolor'));
 
-        $this->assertFalse($stopWords->isStopWord('consectetur'));
-        $this->assertFalse($stopWords->isStopWord('adipiscing'));
-        $this->assertFalse($stopWords->isStopWord('amet'));
+        self::assertFalse($stopWords->isStopWord('consectetur'));
+        self::assertFalse($stopWords->isStopWord('adipiscing'));
+        self::assertFalse($stopWords->isStopWord('amet'));
     }
 
     public function testThrowExceptionOnInvalidLanguage(): void
@@ -33,23 +33,23 @@ public function testEnglishStopWords(): void
     {
         $stopWords = StopWords::factory('English');
 
-        $this->assertTrue($stopWords->isStopWord('again'));
-        $this->assertFalse($stopWords->isStopWord('strategy'));
+        self::assertTrue($stopWords->isStopWord('again'));
+        self::assertFalse($stopWords->isStopWord('strategy'));
     }
 
     public function testPolishStopWords(): void
     {
         $stopWords = StopWords::factory('Polish');
 
-        $this->assertTrue($stopWords->isStopWord('wam'));
-        $this->assertFalse($stopWords->isStopWord('transhumanizm'));
+        self::assertTrue($stopWords->isStopWord('wam'));
+        self::assertFalse($stopWords->isStopWord('transhumanizm'));
     }
 
     public function testFrenchStopWords(): void
     {
         $stopWords = StopWords::factory('French');
 
-        $this->assertTrue($stopWords->isStopWord('alors'));
-        $this->assertFalse($stopWords->isStopWord('carte'));
+        self::assertTrue($stopWords->isStopWord('alors'));
+        self::assertFalse($stopWords->isStopWord('carte'));
     }
 }
diff --git a/tests/FeatureExtraction/TfIdfTransformerTest.php b/tests/FeatureExtraction/TfIdfTransformerTest.php
index 30bc0e57..b0cf9f63 100644
--- a/tests/FeatureExtraction/TfIdfTransformerTest.php
+++ b/tests/FeatureExtraction/TfIdfTransformerTest.php
@@ -54,6 +54,6 @@ public function testTfIdfTransformation(): void
         $transformer = new TfIdfTransformer($samples);
         $transformer->transform($samples);
 
-        $this->assertEquals($tfIdfSamples, $samples, '', 0.001);
+        self::assertEquals($tfIdfSamples, $samples, '', 0.001);
     }
 }
diff --git a/tests/FeatureExtraction/TokenCountVectorizerTest.php b/tests/FeatureExtraction/TokenCountVectorizerTest.php
index aaba5fc1..dff9436a 100644
--- a/tests/FeatureExtraction/TokenCountVectorizerTest.php
+++ b/tests/FeatureExtraction/TokenCountVectorizerTest.php
@@ -74,10 +74,10 @@ public function testTransformationWithWhitespaceTokenizer(): void
         $vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer());
 
         $vectorizer->fit($samples);
-        $this->assertSame($vocabulary, $vectorizer->getVocabulary());
+        self::assertSame($vocabulary, $vectorizer->getVocabulary());
 
         $vectorizer->transform($samples);
-        $this->assertSame($tokensCounts, $samples);
+        self::assertSame($tokensCounts, $samples);
     }
 
     public function testTransformationWithMinimumDocumentTokenCountFrequency(): void
@@ -132,10 +132,10 @@ public function testTransformationWithMinimumDocumentTokenCountFrequency(): void
         $vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer(), null, 0.5);
 
         $vectorizer->fit($samples);
-        $this->assertSame($vocabulary, $vectorizer->getVocabulary());
+        self::assertSame($vocabulary, $vectorizer->getVocabulary());
 
         $vectorizer->transform($samples);
-        $this->assertSame($tokensCounts, $samples);
+        self::assertSame($tokensCounts, $samples);
 
         // word at least once in all samples
         $samples = [
@@ -184,7 +184,7 @@ public function testTransformationWithMinimumDocumentTokenCountFrequency(): void
         $vectorizer->fit($samples);
         $vectorizer->transform($samples);
 
-        $this->assertSame($tokensCounts, $samples);
+        self::assertSame($tokensCounts, $samples);
     }
 
     public function testTransformationWithStopWords(): void
@@ -246,9 +246,9 @@ public function testTransformationWithStopWords(): void
         $vectorizer = new TokenCountVectorizer(new WhitespaceTokenizer(), $stopWords);
 
         $vectorizer->fit($samples);
-        $this->assertSame($vocabulary, $vectorizer->getVocabulary());
+        self::assertSame($vocabulary, $vectorizer->getVocabulary());
 
         $vectorizer->transform($samples);
-        $this->assertSame($tokensCounts, $samples);
+        self::assertSame($tokensCounts, $samples);
     }
 }
diff --git a/tests/Helper/Optimizer/ConjugateGradientTest.php b/tests/Helper/Optimizer/ConjugateGradientTest.php
index 09c250c8..2080019a 100644
--- a/tests/Helper/Optimizer/ConjugateGradientTest.php
+++ b/tests/Helper/Optimizer/ConjugateGradientTest.php
@@ -33,7 +33,7 @@ public function testRunOptimization(): void
 
         $theta = $optimizer->runOptimization($samples, $targets, $callback);
 
-        $this->assertEquals([-1, 2], $theta, '', 0.1);
+        self::assertEquals([-1, 2], $theta, '', 0.1);
     }
 
     public function testRunOptimizationWithCustomInitialTheta(): void
@@ -61,7 +61,7 @@ public function testRunOptimizationWithCustomInitialTheta(): void
 
         $theta = $optimizer->runOptimization($samples, $targets, $callback);
 
-        $this->assertEquals([-1.087708, 2.212034], $theta, '', 0.000001);
+        self::assertEquals([-1.087708, 2.212034], $theta, '', 0.000001);
     }
 
     public function testRunOptimization2Dim(): void
@@ -89,7 +89,7 @@ public function testRunOptimization2Dim(): void
 
         $theta = $optimizer->runOptimization($samples, $targets, $callback);
 
-        $this->assertEquals([-1, 2, -3], $theta, '', 0.1);
+        self::assertEquals([-1, 2, -3], $theta, '', 0.1);
     }
 
     public function testThrowExceptionOnInvalidTheta(): void
diff --git a/tests/Helper/Optimizer/GDTest.php b/tests/Helper/Optimizer/GDTest.php
index c68e3185..ecbd5152 100644
--- a/tests/Helper/Optimizer/GDTest.php
+++ b/tests/Helper/Optimizer/GDTest.php
@@ -32,7 +32,7 @@ public function testRunOptimization(): void
 
         $theta = $optimizer->runOptimization($samples, $targets, $callback);
 
-        $this->assertEquals([-1, 2], $theta, '', 0.1);
+        self::assertEquals([-1, 2], $theta, '', 0.1);
     }
 
     public function testRunOptimization2Dim(): void
@@ -60,6 +60,6 @@ public function testRunOptimization2Dim(): void
 
         $theta = $optimizer->runOptimization($samples, $targets, $callback);
 
-        $this->assertEquals([-1, 2, -3], $theta, '', 0.1);
+        self::assertEquals([-1, 2, -3], $theta, '', 0.1);
     }
 }
diff --git a/tests/Helper/Optimizer/OptimizerTest.php b/tests/Helper/Optimizer/OptimizerTest.php
index 22efdd22..97af2d24 100644
--- a/tests/Helper/Optimizer/OptimizerTest.php
+++ b/tests/Helper/Optimizer/OptimizerTest.php
@@ -26,9 +26,9 @@ public function testSetTheta(): void
         $optimizer = $this->getMockForAbstractClass(Optimizer::class, [2]);
         $object = $optimizer->setTheta([0.3, 1]);
 
-        $theta = $this->getObjectAttribute($optimizer, 'theta');
+        $theta = self::getObjectAttribute($optimizer, 'theta');
 
-        $this->assertSame($object, $optimizer);
-        $this->assertSame([0.3, 1], $theta);
+        self::assertSame($object, $optimizer);
+        self::assertSame([0.3, 1], $theta);
     }
 }
diff --git a/tests/Helper/Optimizer/StochasticGDTest.php b/tests/Helper/Optimizer/StochasticGDTest.php
index 6f6e469b..ba3430bf 100644
--- a/tests/Helper/Optimizer/StochasticGDTest.php
+++ b/tests/Helper/Optimizer/StochasticGDTest.php
@@ -32,7 +32,7 @@ public function testRunOptimization(): void
 
         $theta = $optimizer->runOptimization($samples, $targets, $callback);
 
-        $this->assertEquals([-1, 2], $theta, '', 0.1);
+        self::assertEquals([-1, 2], $theta, '', 0.1);
     }
 
     public function testRunOptimization2Dim(): void
@@ -60,6 +60,6 @@ public function testRunOptimization2Dim(): void
 
         $theta = $optimizer->runOptimization($samples, $targets, $callback);
 
-        $this->assertEquals([-1, 2, -3], $theta, '', 0.1);
+        self::assertEquals([-1, 2, -3], $theta, '', 0.1);
     }
 }
diff --git a/tests/Math/ComparisonTest.php b/tests/Math/ComparisonTest.php
index 0118ee46..338055b6 100644
--- a/tests/Math/ComparisonTest.php
+++ b/tests/Math/ComparisonTest.php
@@ -20,7 +20,7 @@ public function testResult($a, $b, string $operator, bool $expected): void
     {
         $result = Comparison::compare($a, $b, $operator);
 
-        $this->assertEquals($expected, $result);
+        self::assertEquals($expected, $result);
     }
 
     public function testThrowExceptionWhenOperatorIsInvalid(): void
diff --git a/tests/Math/Distance/ChebyshevTest.php b/tests/Math/Distance/ChebyshevTest.php
index 1a437314..a59edbf9 100644
--- a/tests/Math/Distance/ChebyshevTest.php
+++ b/tests/Math/Distance/ChebyshevTest.php
@@ -36,7 +36,7 @@ public function testCalculateDistanceForOneDimension(): void
         $expectedDistance = 2;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 
     public function testCalculateDistanceForTwoDimensions(): void
@@ -47,7 +47,7 @@ public function testCalculateDistanceForTwoDimensions(): void
         $expectedDistance = 2;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 
     public function testCalculateDistanceForThreeDimensions(): void
@@ -58,6 +58,6 @@ public function testCalculateDistanceForThreeDimensions(): void
         $expectedDistance = 5;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 }
diff --git a/tests/Math/Distance/EuclideanTest.php b/tests/Math/Distance/EuclideanTest.php
index 4be96d31..979a3785 100644
--- a/tests/Math/Distance/EuclideanTest.php
+++ b/tests/Math/Distance/EuclideanTest.php
@@ -36,7 +36,7 @@ public function testCalculateDistanceForOneDimension(): void
         $expectedDistance = 2;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 
     public function testCalculateDistanceForTwoDimensions(): void
@@ -47,7 +47,7 @@ public function testCalculateDistanceForTwoDimensions(): void
         $expectedDistance = 2.2360679774998;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 
     public function testCalculateDistanceForThreeDimensions(): void
@@ -58,6 +58,6 @@ public function testCalculateDistanceForThreeDimensions(): void
         $expectedDistance = 6.7082039324993694;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 }
diff --git a/tests/Math/Distance/ManhattanTest.php b/tests/Math/Distance/ManhattanTest.php
index 1dd5e46a..c189f263 100644
--- a/tests/Math/Distance/ManhattanTest.php
+++ b/tests/Math/Distance/ManhattanTest.php
@@ -36,7 +36,7 @@ public function testCalculateDistanceForOneDimension(): void
         $expectedDistance = 2;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 
     public function testCalculateDistanceForTwoDimensions(): void
@@ -47,7 +47,7 @@ public function testCalculateDistanceForTwoDimensions(): void
         $expectedDistance = 3;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 
     public function testCalculateDistanceForThreeDimensions(): void
@@ -58,6 +58,6 @@ public function testCalculateDistanceForThreeDimensions(): void
         $expectedDistance = 11;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 }
diff --git a/tests/Math/Distance/MinkowskiTest.php b/tests/Math/Distance/MinkowskiTest.php
index 558c31f4..770bf153 100644
--- a/tests/Math/Distance/MinkowskiTest.php
+++ b/tests/Math/Distance/MinkowskiTest.php
@@ -36,7 +36,7 @@ public function testCalculateDistanceForOneDimension(): void
         $expectedDistance = 2;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance);
+        self::assertEquals($expectedDistance, $actualDistance);
     }
 
     public function testCalculateDistanceForTwoDimensions(): void
@@ -47,7 +47,7 @@ public function testCalculateDistanceForTwoDimensions(): void
         $expectedDistance = 2.080;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
+        self::assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
     }
 
     public function testCalculateDistanceForThreeDimensions(): void
@@ -58,7 +58,7 @@ public function testCalculateDistanceForThreeDimensions(): void
         $expectedDistance = 5.819;
         $actualDistance = $this->distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
+        self::assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
     }
 
     public function testCalculateDistanceForThreeDimensionsWithDifferentLambda(): void
@@ -71,6 +71,6 @@ public function testCalculateDistanceForThreeDimensionsWithDifferentLambda(): vo
         $expectedDistance = 5.300;
         $actualDistance = $distanceMetric->distance($a, $b);
 
-        $this->assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
+        self::assertEquals($expectedDistance, $actualDistance, '', $delta = 0.001);
     }
 }
diff --git a/tests/Math/Kernel/RBFTest.php b/tests/Math/Kernel/RBFTest.php
index 08f795d8..bf24aab5 100644
--- a/tests/Math/Kernel/RBFTest.php
+++ b/tests/Math/Kernel/RBFTest.php
@@ -13,14 +13,14 @@ public function testComputeRBFKernelFunction(): void
     {
         $rbf = new RBF($gamma = 0.001);
 
-        $this->assertEquals(1, $rbf->compute([1, 2], [1, 2]));
-        $this->assertEquals(0.97336, $rbf->compute([1, 2, 3], [4, 5, 6]), '', $delta = 0.0001);
-        $this->assertEquals(0.00011, $rbf->compute([4, 5], [1, 100]), '', $delta = 0.0001);
+        self::assertEquals(1, $rbf->compute([1, 2], [1, 2]));
+        self::assertEquals(0.97336, $rbf->compute([1, 2, 3], [4, 5, 6]), '', $delta = 0.0001);
+        self::assertEquals(0.00011, $rbf->compute([4, 5], [1, 100]), '', $delta = 0.0001);
 
         $rbf = new RBF($gamma = 0.2);
 
-        $this->assertEquals(1, $rbf->compute([1, 2], [1, 2]));
-        $this->assertEquals(0.00451, $rbf->compute([1, 2, 3], [4, 5, 6]), '', $delta = 0.0001);
-        $this->assertEquals(0, $rbf->compute([4, 5], [1, 100]));
+        self::assertEquals(1, $rbf->compute([1, 2], [1, 2]));
+        self::assertEquals(0.00451, $rbf->compute([1, 2, 3], [4, 5, 6]), '', $delta = 0.0001);
+        self::assertEquals(0, $rbf->compute([4, 5], [1, 100]));
     }
 }
diff --git a/tests/Math/LinearAlgebra/LUDecompositionTest.php b/tests/Math/LinearAlgebra/LUDecompositionTest.php
index ea96f77d..bd81e2e3 100644
--- a/tests/Math/LinearAlgebra/LUDecompositionTest.php
+++ b/tests/Math/LinearAlgebra/LUDecompositionTest.php
@@ -34,8 +34,7 @@ public function testLowerTriangularFactor(): void
         $lu = new LUDecomposition(new Matrix([[1, 2], [3, 4]]));
         $L = $lu->getL();
 
-        $this->assertInstanceOf(Matrix::class, $L);
-        $this->assertSame([[1.0, 0.0], [0.3333333333333333, 1.0]], $L->toArray());
+        self::assertSame([[1.0, 0.0], [0.3333333333333333, 1.0]], $L->toArray());
     }
 
     public function testUpperTriangularFactor(): void
@@ -43,7 +42,6 @@ public function testUpperTriangularFactor(): void
         $lu = new LUDecomposition(new Matrix([[1, 2], [3, 4]]));
         $U = $lu->getU();
 
-        $this->assertInstanceOf(Matrix::class, $U);
-        $this->assertSame([[3.0, 4.0], [0.0, 0.6666666666666667]], $U->toArray());
+        self::assertSame([[3.0, 4.0], [0.0, 0.6666666666666667]], $U->toArray());
     }
 }
diff --git a/tests/Math/MatrixTest.php b/tests/Math/MatrixTest.php
index 7adde6ce..94d47e28 100644
--- a/tests/Math/MatrixTest.php
+++ b/tests/Math/MatrixTest.php
@@ -22,11 +22,10 @@ public function testCreateMatrixFromFlatArray(): void
         $flatArray = [1, 2, 3, 4];
         $matrix = Matrix::fromFlatArray($flatArray);
 
-        $this->assertInstanceOf(Matrix::class, $matrix);
-        $this->assertEquals([[1], [2], [3], [4]], $matrix->toArray());
-        $this->assertEquals(4, $matrix->getRows());
-        $this->assertEquals(1, $matrix->getColumns());
-        $this->assertEquals($flatArray, $matrix->getColumnValues(0));
+        self::assertEquals([[1], [2], [3], [4]], $matrix->toArray());
+        self::assertEquals(4, $matrix->getRows());
+        self::assertEquals(1, $matrix->getColumns());
+        self::assertEquals($flatArray, $matrix->getColumnValues(0));
     }
 
     public function testThrowExceptionOnInvalidColumnNumber(): void
@@ -51,7 +50,7 @@ public function testGetMatrixDeterminant(): void
             [4, 2, 1],
             [5, 6, 7],
         ]);
-        $this->assertEquals(-3, $matrix->getDeterminant());
+        self::assertEquals(-3, $matrix->getDeterminant());
 
         $matrix = new Matrix([
             [1, 2, 3, 3, 2, 1],
@@ -61,7 +60,7 @@ public function testGetMatrixDeterminant(): void
             [1 / 4, 4, 1, 0, 2, 3 / 7],
             [1, 8, 7, 5, 4, 4 / 5],
         ]);
-        $this->assertEquals(1116.5035, $matrix->getDeterminant(), '', $delta = 0.0001);
+        self::assertEquals(1116.5035, $matrix->getDeterminant(), '', $delta = 0.0001);
     }
 
     public function testMatrixTranspose(): void
@@ -78,7 +77,7 @@ public function testMatrixTranspose(): void
             [3, 1, 7],
         ];
 
-        $this->assertEquals($transposedMatrix, $matrix->transpose()->toArray());
+        self::assertEquals($transposedMatrix, $matrix->transpose()->toArray());
     }
 
     public function testThrowExceptionOnMultiplyWhenInconsistentMatrixSupplied(): void
@@ -107,7 +106,7 @@ public function testMatrixMultiplyByMatrix(): void
             [139, 154],
         ];
 
-        $this->assertEquals($product, $matrix1->multiply($matrix2)->toArray());
+        self::assertEquals($product, $matrix1->multiply($matrix2)->toArray());
     }
 
     public function testDivideByScalar(): void
@@ -122,7 +121,7 @@ public function testDivideByScalar(): void
             [1, 5, 10],
         ];
 
-        $this->assertEquals($quotient, $matrix->divideByScalar(2)->toArray());
+        self::assertEquals($quotient, $matrix->divideByScalar(2)->toArray());
     }
 
     public function testThrowExceptionWhenInverseIfArrayIsNotSquare(): void
@@ -158,7 +157,7 @@ public function testInverseMatrix(): void
             [-1 / 2, 1 / 2, -1 / 2],
         ];
 
-        $this->assertEquals($inverseMatrix, $matrix->inverse()->toArray(), '', $delta = 0.0001);
+        self::assertEquals($inverseMatrix, $matrix->inverse()->toArray(), '', $delta = 0.0001);
     }
 
     public function testCrossOutMatrix(): void
@@ -174,14 +173,14 @@ public function testCrossOutMatrix(): void
             [1, 1],
         ];
 
-        $this->assertEquals($crossOuted, $matrix->crossOut(1, 1)->toArray());
+        self::assertEquals($crossOuted, $matrix->crossOut(1, 1)->toArray());
     }
 
     public function testToScalar(): void
     {
         $matrix = new Matrix([[1, 2, 3], [3, 2, 3]]);
 
-        $this->assertEquals($matrix->toScalar(), 1);
+        self::assertEquals($matrix->toScalar(), 1);
     }
 
     public function testMultiplyByScalar(): void
@@ -196,7 +195,7 @@ public function testMultiplyByScalar(): void
             [-4, -20, -40],
         ];
 
-        $this->assertEquals($result, $matrix->multiplyByScalar(-2)->toArray());
+        self::assertEquals($result, $matrix->multiplyByScalar(-2)->toArray());
     }
 
     public function testAdd(): void
@@ -208,7 +207,7 @@ public function testAdd(): void
         $m1 = new Matrix($array1);
         $m2 = new Matrix($array2);
 
-        $this->assertEquals($result, $m1->add($m2)->toArray()[0]);
+        self::assertEquals($result, $m1->add($m2)->toArray()[0]);
     }
 
     public function testSubtract(): void
@@ -220,7 +219,7 @@ public function testSubtract(): void
         $m1 = new Matrix($array1);
         $m2 = new Matrix($array2);
 
-        $this->assertEquals($result, $m1->subtract($m2)->toArray()[0]);
+        self::assertEquals($result, $m1->subtract($m2)->toArray()[0]);
     }
 
     public function testTransposeArray(): void
@@ -235,7 +234,7 @@ public function testTransposeArray(): void
             [1, 2],
         ];
 
-        $this->assertEquals($transposed, Matrix::transposeArray($array));
+        self::assertEquals($transposed, Matrix::transposeArray($array));
     }
 
     public function testDot(): void
@@ -244,12 +243,12 @@ public function testDot(): void
         $vect2 = [3, 3, 3];
         $dot = [18];
 
-        $this->assertEquals($dot, Matrix::dot($vect1, $vect2));
+        self::assertEquals($dot, Matrix::dot($vect1, $vect2));
 
         $matrix1 = [[1, 1], [2, 2]];
         $matrix2 = [[3, 3], [3, 3], [3, 3]];
         $dot = [6, 12];
-        $this->assertEquals($dot, Matrix::dot($matrix2, $matrix1));
+        self::assertEquals($dot, Matrix::dot($matrix2, $matrix1));
     }
 
     /**
@@ -257,12 +256,10 @@ public function testDot(): void
      */
     public function testFrobeniusNorm(array $matrix, float $norm): void
     {
-        $matrix = new Matrix($matrix);
-
-        $this->assertEquals($norm, $matrix->frobeniusNorm(), '', 0.0001);
+        self::assertEquals($norm, (new Matrix($matrix))->frobeniusNorm(), '', 0.0001);
     }
 
-    public function dataProviderForFrobeniusNorm()
+    public function dataProviderForFrobeniusNorm(): array
     {
         return [
             [
diff --git a/tests/Math/ProductTest.php b/tests/Math/ProductTest.php
index da7450b9..4eaff58c 100644
--- a/tests/Math/ProductTest.php
+++ b/tests/Math/ProductTest.php
@@ -12,11 +12,11 @@ class ProductTest extends TestCase
 {
     public function testScalarProduct(): void
     {
-        $this->assertEquals(10, Product::scalar([2, 3], [-1, 4]));
-        $this->assertEquals(-0.1, Product::scalar([1, 4, 1], [-2, 0.5, -0.1]));
-        $this->assertEquals(8, Product::scalar([2], [4]));
+        self::assertEquals(10, Product::scalar([2, 3], [-1, 4]));
+        self::assertEquals(-0.1, Product::scalar([1, 4, 1], [-2, 0.5, -0.1]));
+        self::assertEquals(8, Product::scalar([2], [4]));
 
         //test for non numeric values
-        $this->assertEquals(0, Product::scalar(['', null, [], new stdClass()], [null]));
+        self::assertEquals(0, Product::scalar(['', null, [], new stdClass()], [null]));
     }
 }
diff --git a/tests/Math/SetTest.php b/tests/Math/SetTest.php
index 2335c73a..1f311564 100644
--- a/tests/Math/SetTest.php
+++ b/tests/Math/SetTest.php
@@ -13,84 +13,79 @@ public function testUnion(): void
     {
         $union = Set::union(new Set([3, 1]), new Set([3, 2, 2]));
 
-        $this->assertInstanceOf(Set::class, $union);
-        $this->assertEquals(new Set([1, 2, 3]), $union);
-        $this->assertEquals(3, $union->cardinality());
+        self::assertEquals(new Set([1, 2, 3]), $union);
+        self::assertEquals(3, $union->cardinality());
     }
 
     public function testIntersection(): void
     {
         $intersection = Set::intersection(new Set(['C', 'A']), new Set(['B', 'C']));
 
-        $this->assertInstanceOf(Set::class, $intersection);
-        $this->assertEquals(new Set(['C']), $intersection);
-        $this->assertEquals(1, $intersection->cardinality());
+        self::assertEquals(new Set(['C']), $intersection);
+        self::assertEquals(1, $intersection->cardinality());
     }
 
     public function testDifference(): void
     {
         $difference = Set::difference(new Set(['C', 'A', 'B']), new Set(['A']));
 
-        $this->assertInstanceOf(Set::class, $difference);
-        $this->assertEquals(new Set(['B', 'C']), $difference);
-        $this->assertEquals(2, $difference->cardinality());
+        self::assertEquals(new Set(['B', 'C']), $difference);
+        self::assertEquals(2, $difference->cardinality());
     }
 
     public function testPower(): void
     {
         $power = Set::power(new Set(['A', 'B']));
 
-        $this->assertInternalType('array', $power);
-        $this->assertEquals([new Set(), new Set(['A']), new Set(['B']), new Set(['A', 'B'])], $power);
-        $this->assertCount(4, $power);
+        self::assertEquals([new Set(), new Set(['A']), new Set(['B']), new Set(['A', 'B'])], $power);
+        self::assertCount(4, $power);
     }
 
     public function testCartesian(): void
     {
         $cartesian = Set::cartesian(new Set(['A']), new Set([1, 2]));
 
-        $this->assertInternalType('array', $cartesian);
-        $this->assertEquals([new Set(['A', 1]), new Set(['A', 2])], $cartesian);
-        $this->assertCount(2, $cartesian);
+        self::assertEquals([new Set(['A', 1]), new Set(['A', 2])], $cartesian);
+        self::assertCount(2, $cartesian);
     }
 
     public function testContains(): void
     {
         $set = new Set(['B', 'A', 2, 1]);
 
-        $this->assertTrue($set->contains('B'));
-        $this->assertTrue($set->containsAll(['A', 'B']));
+        self::assertTrue($set->contains('B'));
+        self::assertTrue($set->containsAll(['A', 'B']));
 
-        $this->assertFalse($set->contains('C'));
-        $this->assertFalse($set->containsAll(['A', 'B', 'C']));
+        self::assertFalse($set->contains('C'));
+        self::assertFalse($set->containsAll(['A', 'B', 'C']));
     }
 
     public function testRemove(): void
     {
         $set = new Set(['B', 'A', 2, 1]);
 
-        $this->assertEquals((new Set([1, 2, 2, 2, 'B']))->toArray(), $set->remove('A')->toArray());
+        self::assertEquals((new Set([1, 2, 2, 2, 'B']))->toArray(), $set->remove('A')->toArray());
     }
 
     public function testAdd(): void
     {
         $set = new Set(['B', 'A', 2, 1]);
         $set->addAll(['foo', 'bar']);
-        $this->assertEquals(6, $set->cardinality());
+        self::assertEquals(6, $set->cardinality());
     }
 
     public function testEmpty(): void
     {
         $set = new Set([1, 2]);
         $set->removeAll([2, 1]);
-        $this->assertEquals(new Set(), $set);
-        $this->assertTrue($set->isEmpty());
+        self::assertEquals(new Set(), $set);
+        self::assertTrue($set->isEmpty());
     }
 
     public function testToArray(): void
     {
         $set = new Set([1, 2, 2, 3, 'A', false, '', 1.1, -1, -10, 'B']);
 
-        $this->assertEquals([-10, '', -1, 'A', 'B', 1, 1.1, 2, 3], $set->toArray());
+        self::assertEquals([-10, '', -1, 'A', 'B', 1, 1.1, 2, 3], $set->toArray());
     }
 }
diff --git a/tests/Math/Statistic/CorrelationTest.php b/tests/Math/Statistic/CorrelationTest.php
index eebb0652..2d0334d2 100644
--- a/tests/Math/Statistic/CorrelationTest.php
+++ b/tests/Math/Statistic/CorrelationTest.php
@@ -16,18 +16,18 @@ public function testPearsonCorrelation(): void
         $delta = 0.001;
         $x = [9300,  10565,  15000,  15000,  17764,  57000,  65940,  73676,  77006,  93739, 146088, 153260];
         $y = [7100, 15500, 4400, 4400, 5900, 4600, 8800, 2000, 2750, 2550,  960, 1025];
-        $this->assertEquals(-0.641, Correlation::pearson($x, $y), '', $delta);
+        self::assertEquals(-0.641, Correlation::pearson($x, $y), '', $delta);
 
         //http://www.statisticshowto.com/how-to-compute-pearsons-correlation-coefficients/
         $delta = 0.001;
         $x = [43, 21, 25, 42, 57, 59];
         $y = [99, 65, 79, 75, 87, 82];
-        $this->assertEquals(0.549, Correlation::pearson($x, $y), '', $delta);
+        self::assertEquals(0.549, Correlation::pearson($x, $y), '', $delta);
 
         $delta = 0.001;
         $x = [60, 61, 62, 63, 65];
         $y = [3.1, 3.6, 3.8, 4, 4.1];
-        $this->assertEquals(0.911, Correlation::pearson($x, $y), '', $delta);
+        self::assertEquals(0.911, Correlation::pearson($x, $y), '', $delta);
     }
 
     public function testThrowExceptionOnInvalidArgumentsForPearsonCorrelation(): void
diff --git a/tests/Math/Statistic/CovarianceTest.php b/tests/Math/Statistic/CovarianceTest.php
index fd7187a3..dd98aeae 100644
--- a/tests/Math/Statistic/CovarianceTest.php
+++ b/tests/Math/Statistic/CovarianceTest.php
@@ -38,18 +38,18 @@ public function testSimpleCovariance(): void
 
         // Calculate only one covariance value: Cov(x, y)
         $cov1 = Covariance::fromDataset($matrix, 0, 0);
-        $this->assertEquals($cov1, $knownCovariance[0][0], '', $epsilon);
+        self::assertEquals($cov1, $knownCovariance[0][0], '', $epsilon);
         $cov1 = Covariance::fromXYArrays($x, $x);
-        $this->assertEquals($cov1, $knownCovariance[0][0], '', $epsilon);
+        self::assertEquals($cov1, $knownCovariance[0][0], '', $epsilon);
 
         $cov2 = Covariance::fromDataset($matrix, 0, 1);
-        $this->assertEquals($cov2, $knownCovariance[0][1], '', $epsilon);
+        self::assertEquals($cov2, $knownCovariance[0][1], '', $epsilon);
         $cov2 = Covariance::fromXYArrays($x, $y);
-        $this->assertEquals($cov2, $knownCovariance[0][1], '', $epsilon);
+        self::assertEquals($cov2, $knownCovariance[0][1], '', $epsilon);
 
         // Second: calculation cov matrix with automatic means for each column
         $covariance = Covariance::covarianceMatrix($matrix);
-        $this->assertEquals($knownCovariance, $covariance, '', $epsilon);
+        self::assertEquals($knownCovariance, $covariance, '', $epsilon);
 
         // Thirdly, CovMatrix: Means are precalculated and given to the method
         $x = array_column($matrix, 0);
@@ -58,7 +58,7 @@ public function testSimpleCovariance(): void
         $meanY = Mean::arithmetic($y);
 
         $covariance = Covariance::covarianceMatrix($matrix, [$meanX, $meanY]);
-        $this->assertEquals($knownCovariance, $covariance, '', $epsilon);
+        self::assertEquals($knownCovariance, $covariance, '', $epsilon);
     }
 
     public function testThrowExceptionOnEmptyX(): void
diff --git a/tests/Math/Statistic/GaussianTest.php b/tests/Math/Statistic/GaussianTest.php
index e4627f44..b19c8db6 100644
--- a/tests/Math/Statistic/GaussianTest.php
+++ b/tests/Math/Statistic/GaussianTest.php
@@ -20,9 +20,9 @@ public function testPdf(): void
         $x = [0, 0.1, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0];
         $pdf = [0.3989, 0.3969, 0.3520, 0.2419, 0.1295, 0.0539, 0.0175, 0.0044];
         foreach ($x as $i => $v) {
-            $this->assertEquals($pdf[$i], $g->pdf($v), '', $delta);
+            self::assertEquals($pdf[$i], $g->pdf($v), '', $delta);
 
-            $this->assertEquals($pdf[$i], Gaussian::distributionPdf($mean, $std, $v), '', $delta);
+            self::assertEquals($pdf[$i], Gaussian::distributionPdf($mean, $std, $v), '', $delta);
         }
     }
 }
diff --git a/tests/Math/Statistic/MeanTest.php b/tests/Math/Statistic/MeanTest.php
index 3b980326..6e5d8d78 100644
--- a/tests/Math/Statistic/MeanTest.php
+++ b/tests/Math/Statistic/MeanTest.php
@@ -19,9 +19,9 @@ public function testArithmeticThrowExceptionOnEmptyArray(): void
     public function testArithmeticMean(): void
     {
         $delta = 0.01;
-        $this->assertEquals(3.5, Mean::arithmetic([2, 5]), '', $delta);
-        $this->assertEquals(41.16, Mean::arithmetic([43, 21, 25, 42, 57, 59]), '', $delta);
-        $this->assertEquals(1.7, Mean::arithmetic([0.5, 0.5, 1.5, 2.5, 3.5]), '', $delta);
+        self::assertEquals(3.5, Mean::arithmetic([2, 5]), '', $delta);
+        self::assertEquals(41.16, Mean::arithmetic([43, 21, 25, 42, 57, 59]), '', $delta);
+        self::assertEquals(1.7, Mean::arithmetic([0.5, 0.5, 1.5, 2.5, 3.5]), '', $delta);
     }
 
     public function testMedianThrowExceptionOnEmptyArray(): void
@@ -34,14 +34,14 @@ public function testMedianOnOddLengthArray(): void
     {
         $numbers = [5, 2, 6, 1, 3];
 
-        $this->assertEquals(3, Mean::median($numbers));
+        self::assertEquals(3, Mean::median($numbers));
     }
 
     public function testMedianOnEvenLengthArray(): void
     {
         $numbers = [5, 2, 6, 1, 3, 4];
 
-        $this->assertEquals(3.5, Mean::median($numbers));
+        self::assertEquals(3.5, Mean::median($numbers));
     }
 
     public function testModeThrowExceptionOnEmptyArray(): void
@@ -54,6 +54,6 @@ public function testModeOnArray(): void
     {
         $numbers = [5, 2, 6, 1, 3, 4, 6, 6, 5];
 
-        $this->assertEquals(6, Mean::mode($numbers));
+        self::assertEquals(6, Mean::mode($numbers));
     }
 }
diff --git a/tests/Math/Statistic/StandardDeviationTest.php b/tests/Math/Statistic/StandardDeviationTest.php
index c6fd47e6..e18c374b 100644
--- a/tests/Math/Statistic/StandardDeviationTest.php
+++ b/tests/Math/Statistic/StandardDeviationTest.php
@@ -15,15 +15,15 @@ public function testStandardDeviationOfPopulationSample(): void
         //https://pl.wikipedia.org/wiki/Odchylenie_standardowe
         $delta = 0.001;
         $population = [5, 6, 8, 9];
-        $this->assertEquals(1.825, StandardDeviation::population($population), '', $delta);
+        self::assertEquals(1.825, StandardDeviation::population($population), '', $delta);
 
         //http://www.stat.wmich.edu/s216/book/node126.html
         $delta = 0.5;
         $population = [7100, 15500, 4400, 4400, 5900, 4600, 8800, 2000, 2750, 2550,  960, 1025];
-        $this->assertEquals(4079, StandardDeviation::population($population), '', $delta);
+        self::assertEquals(4079, StandardDeviation::population($population), '', $delta);
 
         $population = [9300,  10565,  15000,  15000,  17764,  57000,  65940,  73676,  77006,  93739, 146088, 153260];
-        $this->assertEquals(50989, StandardDeviation::population($population), '', $delta);
+        self::assertEquals(50989, StandardDeviation::population($population), '', $delta);
     }
 
     public function testThrowExceptionOnEmptyArrayIfNotSample(): void
diff --git a/tests/Math/Statistic/VarianceTest.php b/tests/Math/Statistic/VarianceTest.php
index 19b2cd8a..310acb60 100644
--- a/tests/Math/Statistic/VarianceTest.php
+++ b/tests/Math/Statistic/VarianceTest.php
@@ -17,7 +17,7 @@ public function testVarianceFromInt(array $numbers, float $variance): void
         self::assertEquals($variance, Variance::population($numbers), '', 0.001);
     }
 
-    public function dataProviderForPopulationVariance()
+    public function dataProviderForPopulationVariance(): array
     {
         return [
             [[0, 0, 0, 0, 0, 1], 0.138],
diff --git a/tests/Metric/AccuracyTest.php b/tests/Metric/AccuracyTest.php
index e2260c45..792dd2fb 100644
--- a/tests/Metric/AccuracyTest.php
+++ b/tests/Metric/AccuracyTest.php
@@ -27,7 +27,7 @@ public function testCalculateNormalizedScore(): void
         $actualLabels = ['a', 'b', 'a', 'b'];
         $predictedLabels = ['a', 'a', 'b', 'b'];
 
-        $this->assertEquals(0.5, Accuracy::score($actualLabels, $predictedLabels));
+        self::assertEquals(0.5, Accuracy::score($actualLabels, $predictedLabels));
     }
 
     public function testCalculateNotNormalizedScore(): void
@@ -35,7 +35,7 @@ public function testCalculateNotNormalizedScore(): void
         $actualLabels = ['a', 'b', 'a', 'b'];
         $predictedLabels = ['a', 'b', 'b', 'b'];
 
-        $this->assertEquals(3, Accuracy::score($actualLabels, $predictedLabels, false));
+        self::assertEquals(3, Accuracy::score($actualLabels, $predictedLabels, false));
     }
 
     public function testAccuracyOnDemoDataset(): void
@@ -51,6 +51,6 @@ public function testAccuracyOnDemoDataset(): void
 
         $expected = PHP_VERSION_ID >= 70100 ? 1 : 0.959;
 
-        $this->assertEquals($expected, $accuracy, '', 0.01);
+        self::assertEquals($expected, $accuracy, '', 0.01);
     }
 }
diff --git a/tests/Metric/ClassificationReportTest.php b/tests/Metric/ClassificationReportTest.php
index fa9080b3..3258bc18 100644
--- a/tests/Metric/ClassificationReportTest.php
+++ b/tests/Metric/ClassificationReportTest.php
@@ -45,11 +45,11 @@ public function testClassificationReportGenerateWithStringLabels(): void
             'f1score' => 0.49,  // (2/3 + 0 + 4/5) / 3 = 22/45
         ];
 
-        $this->assertEquals($precision, $report->getPrecision(), '', 0.01);
-        $this->assertEquals($recall, $report->getRecall(), '', 0.01);
-        $this->assertEquals($f1score, $report->getF1score(), '', 0.01);
-        $this->assertEquals($support, $report->getSupport(), '', 0.01);
-        $this->assertEquals($average, $report->getAverage(), '', 0.01);
+        self::assertEquals($precision, $report->getPrecision(), '', 0.01);
+        self::assertEquals($recall, $report->getRecall(), '', 0.01);
+        self::assertEquals($f1score, $report->getF1score(), '', 0.01);
+        self::assertEquals($support, $report->getSupport(), '', 0.01);
+        self::assertEquals($average, $report->getAverage(), '', 0.01);
     }
 
     public function testClassificationReportGenerateWithNumericLabels(): void
@@ -85,11 +85,11 @@ public function testClassificationReportGenerateWithNumericLabels(): void
             'f1score' => 0.49,
         ];
 
-        $this->assertEquals($precision, $report->getPrecision(), '', 0.01);
-        $this->assertEquals($recall, $report->getRecall(), '', 0.01);
-        $this->assertEquals($f1score, $report->getF1score(), '', 0.01);
-        $this->assertEquals($support, $report->getSupport(), '', 0.01);
-        $this->assertEquals($average, $report->getAverage(), '', 0.01);
+        self::assertEquals($precision, $report->getPrecision(), '', 0.01);
+        self::assertEquals($recall, $report->getRecall(), '', 0.01);
+        self::assertEquals($f1score, $report->getF1score(), '', 0.01);
+        self::assertEquals($support, $report->getSupport(), '', 0.01);
+        self::assertEquals($average, $report->getAverage(), '', 0.01);
     }
 
     public function testClassificationReportAverageOutOfRange(): void
@@ -114,7 +114,7 @@ public function testClassificationReportMicroAverage(): void
             'f1score' => 0.6,   // Harmonic mean of precision and recall
         ];
 
-        $this->assertEquals($average, $report->getAverage(), '', 0.01);
+        self::assertEquals($average, $report->getAverage(), '', 0.01);
     }
 
     public function testClassificationReportMacroAverage(): void
@@ -130,7 +130,7 @@ public function testClassificationReportMacroAverage(): void
             'f1score' => 0.49,  // (2/3 + 0 + 4/5) / 3 = 22/45
         ];
 
-        $this->assertEquals($average, $report->getAverage(), '', 0.01);
+        self::assertEquals($average, $report->getAverage(), '', 0.01);
     }
 
     public function testClassificationReportWeightedAverage(): void
@@ -146,7 +146,7 @@ public function testClassificationReportWeightedAverage(): void
             'f1score' => 0.61,  // (2/3 * 1 + 0 * 1 + 4/5 * 3) / 5 = 46/75
         ];
 
-        $this->assertEquals($average, $report->getAverage(), '', 0.01);
+        self::assertEquals($average, $report->getAverage(), '', 0.01);
     }
 
     public function testPreventDivideByZeroWhenTruePositiveAndFalsePositiveSumEqualsZero(): void
@@ -156,7 +156,7 @@ public function testPreventDivideByZeroWhenTruePositiveAndFalsePositiveSumEquals
 
         $report = new ClassificationReport($labels, $predicted);
 
-        $this->assertEquals([
+        self::assertEquals([
             1 => 0.0,
             2 => 0.5,
         ], $report->getPrecision(), '', 0.01);
@@ -169,7 +169,7 @@ public function testPreventDivideByZeroWhenTruePositiveAndFalseNegativeSumEquals
 
         $report = new ClassificationReport($labels, $predicted);
 
-        $this->assertEquals([
+        self::assertEquals([
             1 => 0.0,
             2 => 1,
             3 => 0,
@@ -183,7 +183,7 @@ public function testPreventDividedByZeroWhenPredictedLabelsAllNotMatch(): void
 
         $report = new ClassificationReport($labels, $predicted);
 
-        $this->assertEquals([
+        self::assertEquals([
             'precision' => 0,
             'recall' => 0,
             'f1score' => 0,
@@ -197,7 +197,7 @@ public function testPreventDividedByZeroWhenLabelsAreEmpty(): void
 
         $report = new ClassificationReport($labels, $predicted);
 
-        $this->assertEquals([
+        self::assertEquals([
             'precision' => 0,
             'recall' => 0,
             'f1score' => 0,
diff --git a/tests/Metric/ConfusionMatrixTest.php b/tests/Metric/ConfusionMatrixTest.php
index 590aff89..36518a33 100644
--- a/tests/Metric/ConfusionMatrixTest.php
+++ b/tests/Metric/ConfusionMatrixTest.php
@@ -20,7 +20,7 @@ public function testComputeConfusionMatrixOnNumericLabels(): void
             [1, 0, 2],
         ];
 
-        $this->assertEquals($confusionMatrix, ConfusionMatrix::compute($actualLabels, $predictedLabels));
+        self::assertEquals($confusionMatrix, ConfusionMatrix::compute($actualLabels, $predictedLabels));
     }
 
     public function testComputeConfusionMatrixOnStringLabels(): void
@@ -34,7 +34,7 @@ public function testComputeConfusionMatrixOnStringLabels(): void
             [1, 0, 2],
         ];
 
-        $this->assertEquals($confusionMatrix, ConfusionMatrix::compute($actualLabels, $predictedLabels));
+        self::assertEquals($confusionMatrix, ConfusionMatrix::compute($actualLabels, $predictedLabels));
     }
 
     public function testComputeConfusionMatrixOnLabelsWithSubset(): void
@@ -48,7 +48,7 @@ public function testComputeConfusionMatrixOnLabelsWithSubset(): void
             [0, 0],
         ];
 
-        $this->assertEquals($confusionMatrix, ConfusionMatrix::compute($actualLabels, $predictedLabels, $labels));
+        self::assertEquals($confusionMatrix, ConfusionMatrix::compute($actualLabels, $predictedLabels, $labels));
 
         $labels = ['bird', 'ant'];
 
@@ -57,6 +57,6 @@ public function testComputeConfusionMatrixOnLabelsWithSubset(): void
             [0, 2],
         ];
 
-        $this->assertEquals($confusionMatrix, ConfusionMatrix::compute($actualLabels, $predictedLabels, $labels));
+        self::assertEquals($confusionMatrix, ConfusionMatrix::compute($actualLabels, $predictedLabels, $labels));
     }
 }
diff --git a/tests/ModelManagerTest.php b/tests/ModelManagerTest.php
index 48ab7479..fab34d7b 100644
--- a/tests/ModelManagerTest.php
+++ b/tests/ModelManagerTest.php
@@ -13,7 +13,7 @@ class ModelManagerTest extends TestCase
 {
     public function testSaveAndRestore(): void
     {
-        $filename = uniqid();
+        $filename = uniqid('', false);
         $filepath = sys_get_temp_dir().DIRECTORY_SEPARATOR.$filename;
 
         $estimator = new LeastSquares();
@@ -21,7 +21,7 @@ public function testSaveAndRestore(): void
         $modelManager->saveToFile($estimator, $filepath);
 
         $restored = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($estimator, $restored);
+        self::assertEquals($estimator, $restored);
     }
 
     public function testRestoreWrongFile(): void
diff --git a/tests/NeuralNetwork/ActivationFunction/BinaryStepTest.php b/tests/NeuralNetwork/ActivationFunction/BinaryStepTest.php
index 4e854786..699c7084 100644
--- a/tests/NeuralNetwork/ActivationFunction/BinaryStepTest.php
+++ b/tests/NeuralNetwork/ActivationFunction/BinaryStepTest.php
@@ -11,12 +11,14 @@ class BinaryStepTest extends TestCase
 {
     /**
      * @dataProvider binaryStepProvider
+     *
+     * @param float|int $value
      */
-    public function testBinaryStepActivationFunction($expected, $value): void
+    public function testBinaryStepActivationFunction(float $expected, $value): void
     {
         $binaryStep = new BinaryStep();
 
-        $this->assertEquals($expected, $binaryStep->compute($value));
+        self::assertEquals($expected, $binaryStep->compute($value));
     }
 
     public function binaryStepProvider(): array
@@ -30,12 +32,14 @@ public function binaryStepProvider(): array
 
     /**
      * @dataProvider binaryStepDerivativeProvider
+     *
+     * @param float|int $value
      */
-    public function testBinaryStepDerivative($expected, $value): void
+    public function testBinaryStepDerivative(float $expected, $value): void
     {
         $binaryStep = new BinaryStep();
         $activatedValue = $binaryStep->compute($value);
-        $this->assertEquals($expected, $binaryStep->differentiate($value, $activatedValue));
+        self::assertEquals($expected, $binaryStep->differentiate($value, $activatedValue));
     }
 
     public function binaryStepDerivativeProvider(): array
diff --git a/tests/NeuralNetwork/ActivationFunction/GaussianTest.php b/tests/NeuralNetwork/ActivationFunction/GaussianTest.php
index aace8bcb..6876fd87 100644
--- a/tests/NeuralNetwork/ActivationFunction/GaussianTest.php
+++ b/tests/NeuralNetwork/ActivationFunction/GaussianTest.php
@@ -11,12 +11,14 @@ class GaussianTest extends TestCase
 {
     /**
      * @dataProvider gaussianProvider
+     *
+     * @param float|int $value
      */
-    public function testGaussianActivationFunction($expected, $value): void
+    public function testGaussianActivationFunction(float $expected, $value): void
     {
         $gaussian = new Gaussian();
 
-        $this->assertEquals($expected, $gaussian->compute($value), '', 0.001);
+        self::assertEquals($expected, $gaussian->compute($value), '', 0.001);
     }
 
     public function gaussianProvider(): array
@@ -32,12 +34,14 @@ public function gaussianProvider(): array
 
     /**
      * @dataProvider gaussianDerivativeProvider
+     *
+     * @param float|int $value
      */
-    public function testGaussianDerivative($expected, $value): void
+    public function testGaussianDerivative(float $expected, $value): void
     {
         $gaussian = new Gaussian();
         $activatedValue = $gaussian->compute($value);
-        $this->assertEquals($expected, $gaussian->differentiate($value, $activatedValue), '', 0.001);
+        self::assertEquals($expected, $gaussian->differentiate($value, $activatedValue), '', 0.001);
     }
 
     public function gaussianDerivativeProvider(): array
diff --git a/tests/NeuralNetwork/ActivationFunction/HyperboliTangentTest.php b/tests/NeuralNetwork/ActivationFunction/HyperboliTangentTest.php
index 629200e9..a6a244ff 100644
--- a/tests/NeuralNetwork/ActivationFunction/HyperboliTangentTest.php
+++ b/tests/NeuralNetwork/ActivationFunction/HyperboliTangentTest.php
@@ -11,12 +11,14 @@ class HyperboliTangentTest extends TestCase
 {
     /**
      * @dataProvider tanhProvider
+     *
+     * @param float|int $value
      */
-    public function testHyperbolicTangentActivationFunction($beta, $expected, $value): void
+    public function testHyperbolicTangentActivationFunction(float $beta, float $expected, $value): void
     {
         $tanh = new HyperbolicTangent($beta);
 
-        $this->assertEquals($expected, $tanh->compute($value), '', 0.001);
+        self::assertEquals($expected, $tanh->compute($value), '', 0.001);
     }
 
     public function tanhProvider(): array
@@ -33,12 +35,14 @@ public function tanhProvider(): array
 
     /**
      * @dataProvider tanhDerivativeProvider
+     *
+     * @param float|int $value
      */
-    public function testHyperbolicTangentDerivative($beta, $expected, $value): void
+    public function testHyperbolicTangentDerivative(float $beta, float $expected, $value): void
     {
         $tanh = new HyperbolicTangent($beta);
         $activatedValue = $tanh->compute($value);
-        $this->assertEquals($expected, $tanh->differentiate($value, $activatedValue), '', 0.001);
+        self::assertEquals($expected, $tanh->differentiate($value, $activatedValue), '', 0.001);
     }
 
     public function tanhDerivativeProvider(): array
diff --git a/tests/NeuralNetwork/ActivationFunction/PReLUTest.php b/tests/NeuralNetwork/ActivationFunction/PReLUTest.php
index c9f565d3..a659204a 100644
--- a/tests/NeuralNetwork/ActivationFunction/PReLUTest.php
+++ b/tests/NeuralNetwork/ActivationFunction/PReLUTest.php
@@ -11,12 +11,14 @@ class PReLUTest extends TestCase
 {
     /**
      * @dataProvider preluProvider
+     *
+     * @param float|int $value
      */
-    public function testPReLUActivationFunction($beta, $expected, $value): void
+    public function testPReLUActivationFunction(float $beta, float $expected, $value): void
     {
         $prelu = new PReLU($beta);
 
-        $this->assertEquals($expected, $prelu->compute($value), '', 0.001);
+        self::assertEquals($expected, $prelu->compute($value), '', 0.001);
     }
 
     public function preluProvider(): array
@@ -32,12 +34,14 @@ public function preluProvider(): array
 
     /**
      * @dataProvider preluDerivativeProvider
+     *
+     * @param float|int $value
      */
-    public function testPReLUDerivative($beta, $expected, $value): void
+    public function testPReLUDerivative(float $beta, float $expected, $value): void
     {
         $prelu = new PReLU($beta);
         $activatedValue = $prelu->compute($value);
-        $this->assertEquals($expected, $prelu->differentiate($value, $activatedValue));
+        self::assertEquals($expected, $prelu->differentiate($value, $activatedValue));
     }
 
     public function preluDerivativeProvider(): array
diff --git a/tests/NeuralNetwork/ActivationFunction/SigmoidTest.php b/tests/NeuralNetwork/ActivationFunction/SigmoidTest.php
index 1028fb3b..d98b39c5 100644
--- a/tests/NeuralNetwork/ActivationFunction/SigmoidTest.php
+++ b/tests/NeuralNetwork/ActivationFunction/SigmoidTest.php
@@ -11,12 +11,14 @@ class SigmoidTest extends TestCase
 {
     /**
      * @dataProvider sigmoidProvider
+     *
+     * @param float|int $value
      */
-    public function testSigmoidActivationFunction($beta, $expected, $value): void
+    public function testSigmoidActivationFunction(float $beta, float $expected, $value): void
     {
         $sigmoid = new Sigmoid($beta);
 
-        $this->assertEquals($expected, $sigmoid->compute($value), '', 0.001);
+        self::assertEquals($expected, $sigmoid->compute($value), '', 0.001);
     }
 
     public function sigmoidProvider(): array
@@ -33,12 +35,14 @@ public function sigmoidProvider(): array
 
     /**
      * @dataProvider sigmoidDerivativeProvider
+     *
+     * @param float|int $value
      */
-    public function testSigmoidDerivative($beta, $expected, $value): void
+    public function testSigmoidDerivative(float $beta, float $expected, $value): void
     {
         $sigmoid = new Sigmoid($beta);
         $activatedValue = $sigmoid->compute($value);
-        $this->assertEquals($expected, $sigmoid->differentiate($value, $activatedValue), '', 0.001);
+        self::assertEquals($expected, $sigmoid->differentiate($value, $activatedValue), '', 0.001);
     }
 
     public function sigmoidDerivativeProvider(): array
diff --git a/tests/NeuralNetwork/ActivationFunction/ThresholdedReLUTest.php b/tests/NeuralNetwork/ActivationFunction/ThresholdedReLUTest.php
index 4db0418e..19b00394 100644
--- a/tests/NeuralNetwork/ActivationFunction/ThresholdedReLUTest.php
+++ b/tests/NeuralNetwork/ActivationFunction/ThresholdedReLUTest.php
@@ -11,12 +11,14 @@ class ThresholdedReLUTest extends TestCase
 {
     /**
      * @dataProvider thresholdProvider
+     *
+     * @param float|int $value
      */
-    public function testThresholdedReLUActivationFunction($theta, $expected, $value): void
+    public function testThresholdedReLUActivationFunction(float $theta, float $expected, $value): void
     {
         $thresholdedReLU = new ThresholdedReLU($theta);
 
-        $this->assertEquals($expected, $thresholdedReLU->compute($value));
+        self::assertEquals($expected, $thresholdedReLU->compute($value));
     }
 
     public function thresholdProvider(): array
@@ -31,12 +33,14 @@ public function thresholdProvider(): array
 
     /**
      * @dataProvider thresholdDerivativeProvider
+     *
+     * @param float|int $value
      */
-    public function testThresholdedReLUDerivative($theta, $expected, $value): void
+    public function testThresholdedReLUDerivative(float $theta, float $expected, $value): void
     {
         $thresholdedReLU = new ThresholdedReLU($theta);
         $activatedValue = $thresholdedReLU->compute($value);
-        $this->assertEquals($expected, $thresholdedReLU->differentiate($value, $activatedValue));
+        self::assertEquals($expected, $thresholdedReLU->differentiate($value, $activatedValue));
     }
 
     public function thresholdDerivativeProvider(): array
diff --git a/tests/NeuralNetwork/LayerTest.php b/tests/NeuralNetwork/LayerTest.php
index baa3f9a3..87809b8c 100644
--- a/tests/NeuralNetwork/LayerTest.php
+++ b/tests/NeuralNetwork/LayerTest.php
@@ -17,16 +17,16 @@ public function testLayerInitialization(): void
     {
         $layer = new Layer();
 
-        $this->assertEquals([], $layer->getNodes());
+        self::assertEquals([], $layer->getNodes());
     }
 
     public function testLayerInitializationWithDefaultNodesType(): void
     {
         $layer = new Layer($number = 5);
 
-        $this->assertCount($number, $layer->getNodes());
+        self::assertCount($number, $layer->getNodes());
         foreach ($layer->getNodes() as $node) {
-            $this->assertInstanceOf(Neuron::class, $node);
+            self::assertInstanceOf(Neuron::class, $node);
         }
     }
 
@@ -34,9 +34,9 @@ public function testLayerInitializationWithExplicitNodesType(): void
     {
         $layer = new Layer($number = 5, $class = Bias::class);
 
-        $this->assertCount($number, $layer->getNodes());
+        self::assertCount($number, $layer->getNodes());
         foreach ($layer->getNodes() as $node) {
-            $this->assertInstanceOf($class, $node);
+            self::assertInstanceOf($class, $node);
         }
     }
 
@@ -52,6 +52,6 @@ public function testAddNodesToLayer(): void
         $layer->addNode($node1 = new Neuron());
         $layer->addNode($node2 = new Neuron());
 
-        $this->assertEquals([$node1, $node2], $layer->getNodes());
+        self::assertEquals([$node1, $node2], $layer->getNodes());
     }
 }
diff --git a/tests/NeuralNetwork/Network/LayeredNetworkTest.php b/tests/NeuralNetwork/Network/LayeredNetworkTest.php
index 2a7e6966..a8658311 100644
--- a/tests/NeuralNetwork/Network/LayeredNetworkTest.php
+++ b/tests/NeuralNetwork/Network/LayeredNetworkTest.php
@@ -20,7 +20,7 @@ public function testLayersSettersAndGetters(): void
         $network->addLayer($layer1 = new Layer());
         $network->addLayer($layer2 = new Layer());
 
-        $this->assertEquals([$layer1, $layer2], $network->getLayers());
+        self::assertEquals([$layer1, $layer2], $network->getLayers());
     }
 
     public function testGetLastLayerAsOutputLayer(): void
@@ -28,10 +28,10 @@ public function testGetLastLayerAsOutputLayer(): void
         $network = $this->getLayeredNetworkMock();
         $network->addLayer($layer1 = new Layer());
 
-        $this->assertEquals($layer1, $network->getOutputLayer());
+        self::assertEquals($layer1, $network->getOutputLayer());
 
         $network->addLayer($layer2 = new Layer());
-        $this->assertEquals($layer2, $network->getOutputLayer());
+        self::assertEquals($layer2, $network->getOutputLayer());
     }
 
     public function testSetInputAndGetOutput(): void
@@ -40,10 +40,10 @@ public function testSetInputAndGetOutput(): void
         $network->addLayer(new Layer(2, Input::class));
 
         $network->setInput($input = [34, 43]);
-        $this->assertEquals($input, $network->getOutput());
+        self::assertEquals($input, $network->getOutput());
 
         $network->addLayer(new Layer(1));
-        $this->assertEquals([0.5], $network->getOutput());
+        self::assertEquals([0.5], $network->getOutput());
     }
 
     public function testSetInputAndGetOutputWithCustomActivationFunctions(): void
@@ -52,7 +52,7 @@ public function testSetInputAndGetOutputWithCustomActivationFunctions(): void
         $network->addLayer(new Layer(2, Input::class, $this->getActivationFunctionMock()));
 
         $network->setInput($input = [34, 43]);
-        $this->assertEquals($input, $network->getOutput());
+        self::assertEquals($input, $network->getOutput());
     }
 
     /**
diff --git a/tests/NeuralNetwork/Network/MultilayerPerceptronTest.php b/tests/NeuralNetwork/Network/MultilayerPerceptronTest.php
index cea2a2f2..d7bf7e55 100644
--- a/tests/NeuralNetwork/Network/MultilayerPerceptronTest.php
+++ b/tests/NeuralNetwork/Network/MultilayerPerceptronTest.php
@@ -55,14 +55,14 @@ public function testLearningRateSetter(): void
             [5, [3], [0, 1], 1000, null, 0.42]
         );
 
-        $this->assertEquals(0.42, $this->readAttribute($mlp, 'learningRate'));
-        $backprop = $this->readAttribute($mlp, 'backpropagation');
-        $this->assertEquals(0.42, $this->readAttribute($backprop, 'learningRate'));
+        self::assertEquals(0.42, self::readAttribute($mlp, 'learningRate'));
+        $backprop = self::readAttribute($mlp, 'backpropagation');
+        self::assertEquals(0.42, self::readAttribute($backprop, 'learningRate'));
 
         $mlp->setLearningRate(0.24);
-        $this->assertEquals(0.24, $this->readAttribute($mlp, 'learningRate'));
-        $backprop = $this->readAttribute($mlp, 'backpropagation');
-        $this->assertEquals(0.24, $this->readAttribute($backprop, 'learningRate'));
+        self::assertEquals(0.24, self::readAttribute($mlp, 'learningRate'));
+        $backprop = self::readAttribute($mlp, 'backpropagation');
+        self::assertEquals(0.24, self::readAttribute($backprop, 'learningRate'));
     }
 
     public function testLearningRateSetterWithCustomActivationFunctions(): void
@@ -75,14 +75,14 @@ public function testLearningRateSetterWithCustomActivationFunctions(): void
             [5, [[3, $activation_function], [5, $activation_function]], [0, 1], 1000, null, 0.42]
         );
 
-        $this->assertEquals(0.42, $this->readAttribute($mlp, 'learningRate'));
-        $backprop = $this->readAttribute($mlp, 'backpropagation');
-        $this->assertEquals(0.42, $this->readAttribute($backprop, 'learningRate'));
+        self::assertEquals(0.42, self::readAttribute($mlp, 'learningRate'));
+        $backprop = self::readAttribute($mlp, 'backpropagation');
+        self::assertEquals(0.42, self::readAttribute($backprop, 'learningRate'));
 
         $mlp->setLearningRate(0.24);
-        $this->assertEquals(0.24, $this->readAttribute($mlp, 'learningRate'));
-        $backprop = $this->readAttribute($mlp, 'backpropagation');
-        $this->assertEquals(0.24, $this->readAttribute($backprop, 'learningRate'));
+        self::assertEquals(0.24, self::readAttribute($mlp, 'learningRate'));
+        $backprop = self::readAttribute($mlp, 'backpropagation');
+        self::assertEquals(0.24, self::readAttribute($backprop, 'learningRate'));
     }
 
     public function testLearningRateSetterWithLayerObject(): void
@@ -95,14 +95,14 @@ public function testLearningRateSetterWithLayerObject(): void
             [5, [new Layer(3, Neuron::class, $activation_function), new Layer(5, Neuron::class, $activation_function)], [0, 1], 1000, null, 0.42]
         );
 
-        $this->assertEquals(0.42, $this->readAttribute($mlp, 'learningRate'));
-        $backprop = $this->readAttribute($mlp, 'backpropagation');
-        $this->assertEquals(0.42, $this->readAttribute($backprop, 'learningRate'));
+        self::assertEquals(0.42, self::readAttribute($mlp, 'learningRate'));
+        $backprop = self::readAttribute($mlp, 'backpropagation');
+        self::assertEquals(0.42, self::readAttribute($backprop, 'learningRate'));
 
         $mlp->setLearningRate(0.24);
-        $this->assertEquals(0.24, $this->readAttribute($mlp, 'learningRate'));
-        $backprop = $this->readAttribute($mlp, 'backpropagation');
-        $this->assertEquals(0.24, $this->readAttribute($backprop, 'learningRate'));
+        self::assertEquals(0.24, self::readAttribute($mlp, 'learningRate'));
+        $backprop = self::readAttribute($mlp, 'backpropagation');
+        self::assertEquals(0.24, self::readAttribute($backprop, 'learningRate'));
     }
 
     /**
diff --git a/tests/NeuralNetwork/Node/BiasTest.php b/tests/NeuralNetwork/Node/BiasTest.php
index e42a737c..bb9650c8 100644
--- a/tests/NeuralNetwork/Node/BiasTest.php
+++ b/tests/NeuralNetwork/Node/BiasTest.php
@@ -13,6 +13,6 @@ public function testBiasOutput(): void
     {
         $bias = new Bias();
 
-        $this->assertEquals(1.0, $bias->getOutput());
+        self::assertEquals(1.0, $bias->getOutput());
     }
 }
diff --git a/tests/NeuralNetwork/Node/InputTest.php b/tests/NeuralNetwork/Node/InputTest.php
index 09ca8319..8304d3e0 100644
--- a/tests/NeuralNetwork/Node/InputTest.php
+++ b/tests/NeuralNetwork/Node/InputTest.php
@@ -12,10 +12,10 @@ class InputTest extends TestCase
     public function testInputInitialization(): void
     {
         $input = new Input();
-        $this->assertEquals(0.0, $input->getOutput());
+        self::assertEquals(0.0, $input->getOutput());
 
         $input = new Input($value = 9.6);
-        $this->assertEquals($value, $input->getOutput());
+        self::assertEquals($value, $input->getOutput());
     }
 
     public function testSetInput(): void
@@ -23,6 +23,6 @@ public function testSetInput(): void
         $input = new Input();
         $input->setInput($value = 6.9);
 
-        $this->assertEquals($value, $input->getOutput());
+        self::assertEquals($value, $input->getOutput());
     }
 }
diff --git a/tests/NeuralNetwork/Node/Neuron/SynapseTest.php b/tests/NeuralNetwork/Node/Neuron/SynapseTest.php
index 973d2161..1e33f348 100644
--- a/tests/NeuralNetwork/Node/Neuron/SynapseTest.php
+++ b/tests/NeuralNetwork/Node/Neuron/SynapseTest.php
@@ -17,13 +17,14 @@ public function testSynapseInitialization(): void
 
         $synapse = new Synapse($node, $weight = 0.75);
 
-        $this->assertEquals($node, $synapse->getNode());
-        $this->assertEquals($weight, $synapse->getWeight());
-        $this->assertEquals($weight * $nodeOutput, $synapse->getOutput());
+        self::assertEquals($node, $synapse->getNode());
+        self::assertEquals($weight, $synapse->getWeight());
+        self::assertEquals($weight * $nodeOutput, $synapse->getOutput());
 
         $synapse = new Synapse($node);
+        $weight = $synapse->getWeight();
 
-        $this->assertInternalType('float', $synapse->getWeight());
+        self::assertTrue($weight === -1. || $weight === 1.);
     }
 
     public function testSynapseWeightChange(): void
@@ -32,11 +33,11 @@ public function testSynapseWeightChange(): void
         $synapse = new Synapse($node, $weight = 0.75);
         $synapse->changeWeight(1.0);
 
-        $this->assertEquals(1.75, $synapse->getWeight());
+        self::assertEquals(1.75, $synapse->getWeight());
 
         $synapse->changeWeight(-2.0);
 
-        $this->assertEquals(-0.25, $synapse->getWeight());
+        self::assertEquals(-0.25, $synapse->getWeight());
     }
 
     /**
diff --git a/tests/NeuralNetwork/Node/NeuronTest.php b/tests/NeuralNetwork/Node/NeuronTest.php
index 03e309d1..b1a77a80 100644
--- a/tests/NeuralNetwork/Node/NeuronTest.php
+++ b/tests/NeuralNetwork/Node/NeuronTest.php
@@ -16,8 +16,8 @@ public function testNeuronInitialization(): void
     {
         $neuron = new Neuron();
 
-        $this->assertEquals([], $neuron->getSynapses());
-        $this->assertEquals(0.5, $neuron->getOutput());
+        self::assertEquals([], $neuron->getSynapses());
+        self::assertEquals(0.5, $neuron->getOutput());
     }
 
     public function testNeuronActivationFunction(): void
@@ -28,7 +28,7 @@ public function testNeuronActivationFunction(): void
 
         $neuron = new Neuron($activationFunction);
 
-        $this->assertEquals($output, $neuron->getOutput());
+        self::assertEquals($output, $neuron->getOutput());
     }
 
     public function testNeuronWithSynapse(): void
@@ -36,8 +36,8 @@ public function testNeuronWithSynapse(): void
         $neuron = new Neuron();
         $neuron->addSynapse($synapse = $this->getSynapseMock());
 
-        $this->assertEquals([$synapse], $neuron->getSynapses());
-        $this->assertEquals(0.88, $neuron->getOutput(), '', 0.01);
+        self::assertEquals([$synapse], $neuron->getSynapses());
+        self::assertEquals(0.88, $neuron->getOutput(), '', 0.01);
     }
 
     public function testNeuronRefresh(): void
@@ -46,11 +46,11 @@ public function testNeuronRefresh(): void
         $neuron->getOutput();
         $neuron->addSynapse($this->getSynapseMock());
 
-        $this->assertEquals(0.5, $neuron->getOutput(), '', 0.01);
+        self::assertEquals(0.5, $neuron->getOutput(), '', 0.01);
 
         $neuron->reset();
 
-        $this->assertEquals(0.88, $neuron->getOutput(), '', 0.01);
+        self::assertEquals(0.88, $neuron->getOutput(), '', 0.01);
     }
 
     /**
diff --git a/tests/PipelineTest.php b/tests/PipelineTest.php
index d72e0c81..0ba91c66 100644
--- a/tests/PipelineTest.php
+++ b/tests/PipelineTest.php
@@ -28,8 +28,8 @@ public function testPipelineConstruction(): void
 
         $pipeline = new Pipeline($transformers, $estimator);
 
-        $this->assertEquals($transformers, $pipeline->getTransformers());
-        $this->assertEquals($estimator, $pipeline->getEstimator());
+        self::assertEquals($transformers, $pipeline->getTransformers());
+        self::assertEquals($estimator, $pipeline->getEstimator());
     }
 
     public function testPipelineEstimatorSetter(): void
@@ -39,7 +39,7 @@ public function testPipelineEstimatorSetter(): void
         $estimator = new SVR();
         $pipeline->setEstimator($estimator);
 
-        $this->assertEquals($estimator, $pipeline->getEstimator());
+        self::assertEquals($estimator, $pipeline->getEstimator());
     }
 
     public function testPipelineWorkflow(): void
@@ -67,7 +67,7 @@ public function testPipelineWorkflow(): void
 
         $predicted = $pipeline->predict([[0, 0, 0]]);
 
-        $this->assertEquals(4, $predicted[0]);
+        self::assertEquals(4, $predicted[0]);
     }
 
     public function testPipelineTransformers(): void
@@ -104,7 +104,7 @@ public function testPipelineTransformers(): void
 
         $predicted = $pipeline->predict(['Hello Max', 'Goodbye Mark']);
 
-        $this->assertEquals($expected, $predicted);
+        self::assertEquals($expected, $predicted);
     }
 
     public function testPipelineTransformersWithTargets(): void
@@ -145,13 +145,13 @@ public function testSaveAndRestore(): void
         $testSamples = ['Hello Max', 'Goodbye Mark'];
         $predicted = $pipeline->predict($testSamples);
 
-        $filepath = tempnam(sys_get_temp_dir(), uniqid('pipeline-test', true));
+        $filepath = (string) tempnam(sys_get_temp_dir(), uniqid('pipeline-test', true));
         $modelManager = new ModelManager();
         $modelManager->saveToFile($pipeline, $filepath);
 
         $restoredClassifier = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($pipeline, $restoredClassifier);
-        $this->assertEquals($predicted, $restoredClassifier->predict($testSamples));
+        self::assertEquals($pipeline, $restoredClassifier);
+        self::assertEquals($predicted, $restoredClassifier->predict($testSamples));
         unlink($filepath);
     }
 }
diff --git a/tests/Preprocessing/ImputerTest.php b/tests/Preprocessing/ImputerTest.php
index 1078e547..dcbb8073 100644
--- a/tests/Preprocessing/ImputerTest.php
+++ b/tests/Preprocessing/ImputerTest.php
@@ -32,7 +32,7 @@ public function testComplementsMissingValuesWithMeanStrategyOnColumnAxis(): void
         $imputer = new Imputer(null, new MeanStrategy(), Imputer::AXIS_COLUMN, $data);
         $imputer->transform($data);
 
-        $this->assertEquals($imputeData, $data, '', $delta = 0.01);
+        self::assertEquals($imputeData, $data, '', $delta = 0.01);
     }
 
     public function testComplementsMissingValuesWithMeanStrategyOnRowAxis(): void
@@ -54,7 +54,7 @@ public function testComplementsMissingValuesWithMeanStrategyOnRowAxis(): void
         $imputer = new Imputer(null, new MeanStrategy(), Imputer::AXIS_ROW, $data);
         $imputer->transform($data);
 
-        $this->assertEquals($imputeData, $data, '', $delta = 0.01);
+        self::assertEquals($imputeData, $data, '', $delta = 0.01);
     }
 
     public function testComplementsMissingValuesWithMediaStrategyOnColumnAxis(): void
@@ -76,7 +76,7 @@ public function testComplementsMissingValuesWithMediaStrategyOnColumnAxis(): voi
         $imputer = new Imputer(null, new MedianStrategy(), Imputer::AXIS_COLUMN, $data);
         $imputer->transform($data);
 
-        $this->assertEquals($imputeData, $data, '', $delta = 0.01);
+        self::assertEquals($imputeData, $data, '', $delta = 0.01);
     }
 
     public function testComplementsMissingValuesWithMediaStrategyOnRowAxis(): void
@@ -98,7 +98,7 @@ public function testComplementsMissingValuesWithMediaStrategyOnRowAxis(): void
         $imputer = new Imputer(null, new MedianStrategy(), Imputer::AXIS_ROW, $data);
         $imputer->transform($data);
 
-        $this->assertEquals($imputeData, $data, '', $delta = 0.01);
+        self::assertEquals($imputeData, $data, '', $delta = 0.01);
     }
 
     public function testComplementsMissingValuesWithMostFrequentStrategyOnColumnAxis(): void
@@ -122,7 +122,7 @@ public function testComplementsMissingValuesWithMostFrequentStrategyOnColumnAxis
         $imputer = new Imputer(null, new MostFrequentStrategy(), Imputer::AXIS_COLUMN, $data);
         $imputer->transform($data);
 
-        $this->assertEquals($imputeData, $data);
+        self::assertEquals($imputeData, $data);
     }
 
     public function testComplementsMissingValuesWithMostFrequentStrategyOnRowAxis(): void
@@ -146,7 +146,7 @@ public function testComplementsMissingValuesWithMostFrequentStrategyOnRowAxis():
         $imputer = new Imputer(null, new MostFrequentStrategy(), Imputer::AXIS_ROW, $data);
         $imputer->transform($data);
 
-        $this->assertEquals($imputeData, $data);
+        self::assertEquals($imputeData, $data);
     }
 
     public function testImputerWorksOnFitSamples(): void
@@ -172,7 +172,7 @@ public function testImputerWorksOnFitSamples(): void
         $imputer = new Imputer(null, new MeanStrategy(), Imputer::AXIS_COLUMN, $trainData);
         $imputer->transform($data);
 
-        $this->assertEquals($imputeData, $data, '', $delta = 0.01);
+        self::assertEquals($imputeData, $data, '', $delta = 0.01);
     }
 
     public function testThrowExceptionWhenTryingToTransformWithoutTrainSamples(): void
diff --git a/tests/Preprocessing/NormalizerTest.php b/tests/Preprocessing/NormalizerTest.php
index ea762da0..53b07d86 100644
--- a/tests/Preprocessing/NormalizerTest.php
+++ b/tests/Preprocessing/NormalizerTest.php
@@ -33,7 +33,7 @@ public function testNormalizeSamplesWithL2Norm(): void
         $normalizer = new Normalizer();
         $normalizer->transform($samples);
 
-        $this->assertEquals($normalized, $samples, '', $delta = 0.01);
+        self::assertEquals($normalized, $samples, '', $delta = 0.01);
     }
 
     public function testNormalizeSamplesWithL1Norm(): void
@@ -53,7 +53,7 @@ public function testNormalizeSamplesWithL1Norm(): void
         $normalizer = new Normalizer(Normalizer::NORM_L1);
         $normalizer->transform($samples);
 
-        $this->assertEquals($normalized, $samples, '', $delta = 0.01);
+        self::assertEquals($normalized, $samples, '', $delta = 0.01);
     }
 
     public function testFitNotChangeNormalizerBehavior(): void
@@ -73,11 +73,11 @@ public function testFitNotChangeNormalizerBehavior(): void
         $normalizer = new Normalizer();
         $normalizer->transform($samples);
 
-        $this->assertEquals($normalized, $samples, '', $delta = 0.01);
+        self::assertEquals($normalized, $samples, '', $delta = 0.01);
 
         $normalizer->fit($samples);
 
-        $this->assertEquals($normalized, $samples, '', $delta = 0.01);
+        self::assertEquals($normalized, $samples, '', $delta = 0.01);
     }
 
     public function testL1NormWithZeroSumCondition(): void
@@ -97,7 +97,7 @@ public function testL1NormWithZeroSumCondition(): void
         $normalizer = new Normalizer(Normalizer::NORM_L1);
         $normalizer->transform($samples);
 
-        $this->assertEquals($normalized, $samples, '', $delta = 0.01);
+        self::assertEquals($normalized, $samples, '', $delta = 0.01);
     }
 
     public function testStandardNorm(): void
@@ -122,7 +122,7 @@ public function testStandardNorm(): void
         $normalizer->transform($samples);
 
         // Values in the vector should be some value between -3 and +3
-        $this->assertCount(10, $samples);
+        self::assertCount(10, $samples);
         foreach ($samples as $sample) {
             $errors = array_filter(
                 $sample,
@@ -130,8 +130,8 @@ function ($element) {
                     return $element < -3 || $element > 3;
                 }
             );
-            $this->assertCount(0, $errors);
-            $this->assertEquals(0, $sample[3]);
+            self::assertCount(0, $errors);
+            self::assertEquals(0, $sample[3]);
         }
     }
 }
diff --git a/tests/Regression/LeastSquaresTest.php b/tests/Regression/LeastSquaresTest.php
index 71215bc6..1142a37e 100644
--- a/tests/Regression/LeastSquaresTest.php
+++ b/tests/Regression/LeastSquaresTest.php
@@ -21,7 +21,7 @@ public function testPredictSingleFeatureSamples(): void
         $regression = new LeastSquares();
         $regression->train($samples, $targets);
 
-        $this->assertEquals(4.06, $regression->predict([64]), '', $delta);
+        self::assertEquals(4.06, $regression->predict([64]), '', $delta);
 
         //http://www.stat.wmich.edu/s216/book/node127.html
         $samples = [[9300], [10565], [15000], [15000], [17764], [57000], [65940], [73676], [77006], [93739], [146088], [153260]];
@@ -30,11 +30,11 @@ public function testPredictSingleFeatureSamples(): void
         $regression = new LeastSquares();
         $regression->train($samples, $targets);
 
-        $this->assertEquals(7659.35, $regression->predict([9300]), '', $delta);
-        $this->assertEquals(5213.81, $regression->predict([57000]), '', $delta);
-        $this->assertEquals(4188.13, $regression->predict([77006]), '', $delta);
-        $this->assertEquals(7659.35, $regression->predict([9300]), '', $delta);
-        $this->assertEquals(278.66, $regression->predict([153260]), '', $delta);
+        self::assertEquals(7659.35, $regression->predict([9300]), '', $delta);
+        self::assertEquals(5213.81, $regression->predict([57000]), '', $delta);
+        self::assertEquals(4188.13, $regression->predict([77006]), '', $delta);
+        self::assertEquals(7659.35, $regression->predict([9300]), '', $delta);
+        self::assertEquals(278.66, $regression->predict([153260]), '', $delta);
     }
 
     public function testPredictSingleFeatureSamplesWithMatrixTargets(): void
@@ -48,7 +48,7 @@ public function testPredictSingleFeatureSamplesWithMatrixTargets(): void
         $regression = new LeastSquares();
         $regression->train($samples, $targets);
 
-        $this->assertEquals(4.06, $regression->predict([64]), '', $delta);
+        self::assertEquals(4.06, $regression->predict([64]), '', $delta);
     }
 
     public function testPredictMultiFeaturesSamples(): void
@@ -62,10 +62,10 @@ public function testPredictMultiFeaturesSamples(): void
         $regression = new LeastSquares();
         $regression->train($samples, $targets);
 
-        $this->assertEquals(-800614.957, $regression->getIntercept(), '', $delta);
-        $this->assertEquals([-0.0327, 404.14], $regression->getCoefficients(), '', $delta);
-        $this->assertEquals(4094.82, $regression->predict([60000, 1996]), '', $delta);
-        $this->assertEquals(5711.40, $regression->predict([60000, 2000]), '', $delta);
+        self::assertEquals(-800614.957, $regression->getIntercept(), '', $delta);
+        self::assertEquals([-0.0327, 404.14], $regression->getCoefficients(), '', $delta);
+        self::assertEquals(4094.82, $regression->predict([60000, 1996]), '', $delta);
+        self::assertEquals(5711.40, $regression->predict([60000, 2000]), '', $delta);
     }
 
     public function testSaveAndRestore(): void
@@ -81,13 +81,13 @@ public function testSaveAndRestore(): void
         $testSamples = [[9300], [10565], [15000]];
         $predicted = $regression->predict($testSamples);
 
-        $filename = 'least-squares-test-'.random_int(100, 999).'-'.uniqid();
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filename = 'least-squares-test-'.random_int(100, 999).'-'.uniqid('', false);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($regression, $filepath);
 
         $restoredRegression = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($regression, $restoredRegression);
-        $this->assertEquals($predicted, $restoredRegression->predict($testSamples));
+        self::assertEquals($regression, $restoredRegression);
+        self::assertEquals($predicted, $restoredRegression->predict($testSamples));
     }
 }
diff --git a/tests/Regression/SVRTest.php b/tests/Regression/SVRTest.php
index d2fdefbb..89099c0b 100644
--- a/tests/Regression/SVRTest.php
+++ b/tests/Regression/SVRTest.php
@@ -21,7 +21,7 @@ public function testPredictSingleFeatureSamples(): void
         $regression = new SVR(Kernel::LINEAR);
         $regression->train($samples, $targets);
 
-        $this->assertEquals(4.03, $regression->predict([64]), '', $delta);
+        self::assertEquals(4.03, $regression->predict([64]), '', $delta);
     }
 
     public function testPredictMultiFeaturesSamples(): void
@@ -34,7 +34,7 @@ public function testPredictMultiFeaturesSamples(): void
         $regression = new SVR(Kernel::LINEAR);
         $regression->train($samples, $targets);
 
-        $this->assertEquals([4109.82, 4112.28], $regression->predict([[60000, 1996], [60000, 2000]]), '', $delta);
+        self::assertEquals([4109.82, 4112.28], $regression->predict([[60000, 1996], [60000, 2000]]), '', $delta);
     }
 
     public function testSaveAndRestore(): void
@@ -48,13 +48,13 @@ public function testSaveAndRestore(): void
         $testSamples = [64];
         $predicted = $regression->predict($testSamples);
 
-        $filename = 'svr-test'.random_int(100, 999).'-'.uniqid();
-        $filepath = tempnam(sys_get_temp_dir(), $filename);
+        $filename = 'svr-test'.random_int(100, 999).'-'.uniqid('', false);
+        $filepath = (string) tempnam(sys_get_temp_dir(), $filename);
         $modelManager = new ModelManager();
         $modelManager->saveToFile($regression, $filepath);
 
         $restoredRegression = $modelManager->restoreFromFile($filepath);
-        $this->assertEquals($regression, $restoredRegression);
-        $this->assertEquals($predicted, $restoredRegression->predict($testSamples));
+        self::assertEquals($regression, $restoredRegression);
+        self::assertEquals($predicted, $restoredRegression->predict($testSamples));
     }
 }
diff --git a/tests/SupportVectorMachine/DataTransformerTest.php b/tests/SupportVectorMachine/DataTransformerTest.php
index df298062..32d7d324 100644
--- a/tests/SupportVectorMachine/DataTransformerTest.php
+++ b/tests/SupportVectorMachine/DataTransformerTest.php
@@ -22,7 +22,7 @@ public function testTransformDatasetToTrainingSet(): void
             '1 1:4.000000 2:5.000000 '.PHP_EOL
         ;
 
-        $this->assertEquals($trainingSet, DataTransformer::trainingSet($samples, $labels));
+        self::assertEquals($trainingSet, DataTransformer::trainingSet($samples, $labels));
     }
 
     public function testTransformSamplesToTestSet(): void
@@ -36,7 +36,7 @@ public function testTransformSamplesToTestSet(): void
             '0 1:4.000000 2:5.000000 '.PHP_EOL
         ;
 
-        $this->assertEquals($testSet, DataTransformer::testSet($samples));
+        self::assertEquals($testSet, DataTransformer::testSet($samples));
     }
 
     public function testPredictions(): void
@@ -46,7 +46,7 @@ public function testPredictions(): void
 
         $predictions = ['a', 'b', 'a', 'a'];
 
-        $this->assertEquals($predictions, DataTransformer::predictions($rawPredictions, $labels));
+        self::assertEquals($predictions, DataTransformer::predictions($rawPredictions, $labels));
     }
 
     public function testProbabilities(): void
@@ -77,7 +77,7 @@ public function testProbabilities(): void
             ],
         ];
 
-        $this->assertEquals($probabilities, DataTransformer::probabilities($rawPredictions, $labels));
+        self::assertEquals($probabilities, DataTransformer::probabilities($rawPredictions, $labels));
     }
 
     public function testThrowExceptionWhenTestSetIsEmpty(): void
diff --git a/tests/SupportVectorMachine/SupportVectorMachineTest.php b/tests/SupportVectorMachine/SupportVectorMachineTest.php
index 088d37b0..e3bbc85c 100644
--- a/tests/SupportVectorMachine/SupportVectorMachineTest.php
+++ b/tests/SupportVectorMachine/SupportVectorMachineTest.php
@@ -35,7 +35,7 @@ public function testTrainCSVCModelWithLinearKernel(): void
         $svm = new SupportVectorMachine(Type::C_SVC, Kernel::LINEAR, 100.0);
         $svm->train($samples, $labels);
 
-        $this->assertEquals($model, $svm->getModel());
+        self::assertEquals($model, $svm->getModel());
     }
 
     public function testTrainCSVCModelWithProbabilityEstimate(): void
@@ -59,8 +59,8 @@ public function testTrainCSVCModelWithProbabilityEstimate(): void
         );
         $svm->train($samples, $labels);
 
-        $this->assertContains(PHP_EOL.'probA ', $svm->getModel());
-        $this->assertContains(PHP_EOL.'probB ', $svm->getModel());
+        self::assertContains(PHP_EOL.'probA ', $svm->getModel());
+        self::assertContains(PHP_EOL.'probB ', $svm->getModel());
     }
 
     public function testPredictSampleWithLinearKernel(): void
@@ -77,9 +77,9 @@ public function testPredictSampleWithLinearKernel(): void
             [4, -5],
         ]);
 
-        $this->assertEquals('b', $predictions[0]);
-        $this->assertEquals('a', $predictions[1]);
-        $this->assertEquals('b', $predictions[2]);
+        self::assertEquals('b', $predictions[0]);
+        self::assertEquals('a', $predictions[1]);
+        self::assertEquals('b', $predictions[2]);
     }
 
     public function testPredictSampleFromMultipleClassWithRbfKernel(): void
@@ -104,9 +104,9 @@ public function testPredictSampleFromMultipleClassWithRbfKernel(): void
             [-4, -3],
         ]);
 
-        $this->assertEquals('a', $predictions[0]);
-        $this->assertEquals('b', $predictions[1]);
-        $this->assertEquals('c', $predictions[2]);
+        self::assertEquals('a', $predictions[0]);
+        self::assertEquals('b', $predictions[1]);
+        self::assertEquals('c', $predictions[2]);
     }
 
     public function testPredictProbability(): void
@@ -136,12 +136,12 @@ public function testPredictProbability(): void
             [4, -5],
         ]);
 
-        $this->assertTrue($predictions[0]['a'] < $predictions[0]['b']);
-        $this->assertTrue($predictions[1]['a'] > $predictions[1]['b']);
-        $this->assertTrue($predictions[2]['a'] < $predictions[2]['b']);
+        self::assertTrue($predictions[0]['a'] < $predictions[0]['b']);
+        self::assertTrue($predictions[1]['a'] > $predictions[1]['b']);
+        self::assertTrue($predictions[2]['a'] < $predictions[2]['b']);
 
         // Should be true because the latter is farther from the decision boundary
-        $this->assertTrue($predictions[0]['b'] < $predictions[2]['b']);
+        self::assertTrue($predictions[0]['b'] < $predictions[2]['b']);
     }
 
     public function testThrowExceptionWhenVarPathIsNotWritable(): void
diff --git a/tests/Tokenization/WhitespaceTokenizerTest.php b/tests/Tokenization/WhitespaceTokenizerTest.php
index 03e8f7ea..d6dd4cf7 100644
--- a/tests/Tokenization/WhitespaceTokenizerTest.php
+++ b/tests/Tokenization/WhitespaceTokenizerTest.php
@@ -21,7 +21,7 @@ public function testTokenizationOnAscii(): void
             'Cras', 'consectetur,', 'dui', 'et', 'lobortis', 'auctor.',
             'Nulla', 'vitae', 'congue', 'lorem.', ];
 
-        $this->assertEquals($tokens, $tokenizer->tokenize($text));
+        self::assertEquals($tokens, $tokenizer->tokenize($text));
     }
 
     public function testTokenizationOnUtf8(): void
@@ -36,6 +36,6 @@ public function testTokenizationOnUtf8(): void
             '剆坲', '煘煓瑐', '鬐鶤鶐', '飹勫嫢', '銪', '餀', '枲柊氠', '鍎鞚韕', '焲犈,',
             '殍涾烰', '齞齝囃', '蹅輶', '鄜,', '孻憵', '擙樲橚', '藒襓謥', '岯岪弨', '蒮', '廞徲', '孻憵懥', '趡趛踠', '槏', ];
 
-        $this->assertEquals($tokens, $tokenizer->tokenize($text));
+        self::assertEquals($tokens, $tokenizer->tokenize($text));
     }
 }
diff --git a/tests/Tokenization/WordTokenizerTest.php b/tests/Tokenization/WordTokenizerTest.php
index 387e0f8b..39448b78 100644
--- a/tests/Tokenization/WordTokenizerTest.php
+++ b/tests/Tokenization/WordTokenizerTest.php
@@ -21,7 +21,7 @@ public function testTokenizationOnAscii(): void
             'Cras', 'consectetur', 'dui', 'et', 'lobortis', 'auctor',
             'Nulla', 'vitae', 'congue', 'lorem', ];
 
-        $this->assertEquals($tokens, $tokenizer->tokenize($text));
+        self::assertEquals($tokens, $tokenizer->tokenize($text));
     }
 
     public function testTokenizationOnUtf8(): void
@@ -36,6 +36,6 @@ public function testTokenizationOnUtf8(): void
             '剆坲', '煘煓瑐', '鬐鶤鶐', '飹勫嫢', '枲柊氠', '鍎鞚韕', '焲犈',
             '殍涾烰', '齞齝囃', '蹅輶', '孻憵', '擙樲橚', '藒襓謥', '岯岪弨', '廞徲', '孻憵懥', '趡趛踠', ];
 
-        $this->assertEquals($tokens, $tokenizer->tokenize($text));
+        self::assertEquals($tokens, $tokenizer->tokenize($text));
     }
 }