## Materials and Methods
### Algorithm Modelling
#### 2.2.2 Implementation  
Classification  
The classifier implementation is done using Python 3 and using scikit-learn [37]. Every user provides 5 signals per visit, from which ND, FD, and SD are calculated. The first and last 5 s are discarded from every signal, obtaining a 60 s signal. From every one of them, 50 R peaks are detected and segmented accordingly to extract the QRS complex. The complex has the R peak on the 101 th position and is formed by 200 points. All complexes get concatenated, summarizing the database into three types of matrixes for every visit: one per type of signal differentiation. Train and test sets are extracted from this data, selecting the differentiation and visit differently based on the type of experiment to carry out. The training matrix, \(X_{train}\), has dimensions \([r_{train}\times c]\) where \(c\) is the number of columns or points in the QRS complex and \(r_{t}rain\) is the number of rows, which corresponds to the number selected complexes. Similarly, testing data, \(X_{test}\), has \([r_{test}\times c]\) dimensions.  
Some of the required hyperparameters for the MLP classifier need to be set to a specific value due to previous knowledge and considerations. Fixing some of the hyperparameters make the hyperparameter tuning easier. The number of hidden layers is set to one because it usually achieves proper results and avoids extra slowdown [38]. Regarding the type of solvers, not only SGD is an option, but also another SGD-based optimizer, adam [39], and L-BFGS, which is a quasi-Newton optimizer. However, among these three solvers, only adam is used due to our preliminary results where SGD and L-BFGS provide very low-performance results. This decision discards the option of applying a specific learning rate formula because it is only applied to SGD solvers. In this case, we only need the size of the step that updates the weights, which is fixed to the default value, 0.0001. Convergence is assumed when the result does not improve significantly in a specific number of iterations, and this hyperparameter is also given by its default value which is 10. Table 3 summarizes the given values to the discussed parameters and their functionality.  
\begin{table}
\begin{tabular}{c c c c} \hline \hline \multicolumn{2}{c}{**Day 1**} & \multicolumn{2}{c}{**Day 2**} \\ \hline
**Visit 1 (R1)** & **Visit 2 (S)** & **Visit 1 (R2)** & **Visit 2 (Ex)** \\ \hline Resting, sitting down & Resting, standing & Resting, sitting down & After exercise (average 130 bpm) \\ \hline \hline \end{tabular}
\end{table}
Table 2: Selected database visit distribution. The four visits are re-named as shown, based on the type of scenario: R1 and R2 for resting while sitting down, S for resting while standing up, and Ex for exercise.  
After fixing the previous values, the remaining hyperparameters need to be fixed to reach an optimal system's performance. Even though there is one hidden layer, the number of nodes in the hidden layer needs to be assessed. The same happens with the activation function which can be any of those in Table 1. This implementation solver optimizes the loss function in Equation (2). This formula has two components: the first summation corresponds to Cross-Entropy, where t indicates whether a class is positive or not, \(p(s)\) is the softmax output implemented by the library in a multiclass case and \(C\) is the number of classes; the latter belongs to L2-regularization, where \(\alpha\) or alpha is the penalty term and \(||W||_{2}\) represent the Euclidean norm of the weight hyperparameters. The value alpha avoids underfitting when it gets a positive value lower than 1 and it needs to be specified.  
\[Loss(W;t,p(s))=-\sum_{i}^{C}t_{i}log(p(s)_{i})+\alpha||W||_{2}^{2}. \tag{2}\]  
Finally, closely related to the convergence assumption, is the tolerance hyperparameter. The tolerance provides the quantity the loss function needs to be improved to keep iterating.