Passed
Push — master ( c44f3b...492344 )
by Arkadiusz
02:48
created

Adaline::runTraining()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 9

Duplication

Lines 9
Ratio 52.94 %

Importance

Changes 0
Metric Value
dl 9
loc 17
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Phpml\Classification\Linear;
6
7
use Phpml\Classification\Classifier;
8
9
class Adaline extends Perceptron
10
{
11
12
    /**
13
     * Batch training is the default Adaline training algorithm
14
     */
15
    const BATCH_TRAINING    = 1;
16
17
    /**
18
     * Online training: Stochastic gradient descent learning
19
     */
20
    const ONLINE_TRAINING    = 2;
21
22
    /**
23
     * Training type may be either 'Batch' or 'Online' learning
24
     *
25
     * @var string
26
     */
27
    protected $trainingType;
28
29
    /**
30
     * Initalize an Adaline (ADAptive LInear NEuron) classifier with given learning rate and maximum
31
     * number of iterations used while training the classifier <br>
32
     *
33
     * Learning rate should be a float value between 0.0(exclusive) and 1.0 (inclusive) <br>
34
     * Maximum number of iterations can be an integer value greater than 0 <br>
35
     * If normalizeInputs is set to true, then every input given to the algorithm will be standardized
36
     * by use of standard deviation and mean calculation
37
     *
38
     * @param int $learningRate
39
     * @param int $maxIterations
40
     */
41
    public function __construct(float $learningRate = 0.001, int $maxIterations = 1000,
42
        bool $normalizeInputs = true, int $trainingType = self::BATCH_TRAINING)
43
    {
44
        if (! in_array($trainingType, [self::BATCH_TRAINING, self::ONLINE_TRAINING])) {
45
            throw new \Exception("Adaline can only be trained with batch and online/stochastic gradient descent algorithm");
46
        }
47
48
        $this->trainingType = $trainingType;
0 ignored issues
show
Documentation Bug introduced by
The property $trainingType was declared of type string, but $trainingType is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
49
50
        parent::__construct($learningRate, $maxIterations, $normalizeInputs);
51
    }
52
53
    /**
54
     * Adapts the weights with respect to given samples and targets
55
     * by use of gradient descent learning rule
56
     */
57
    protected function runTraining()
58
    {
59
        // The cost function is the sum of squares
60 View Code Duplication
        $callback = function ($weights, $sample, $target) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
61
            $this->weights = $weights;
62
63
            $output = $this->output($sample);
64
            $gradient = $output - $target;
65
            $error = $gradient ** 2;
66
67
            return [$error, $gradient];
68
        };
69
70
        $isBatch = $this->trainingType == self::BATCH_TRAINING;
71
72
        return parent::runGradientDescent($callback, $isBatch);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (runGradientDescent() instead of runTraining()). Are you sure this is correct? If so, you might want to change this to $this->runGradientDescent().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
73
    }
74
}
75