## 4 Model and Methods  
Before feeding data into the LSTM network, comprehensive preprocessing steps were undertaken. The data used in the research were PSG collected from 58 patients sampled in the sleep medicine laboratory, SleepLab, University Hospital of Split, and saved in.EDF format. Initially, we analyzed data from 16 patients, each with 8-9 h of recordings and an average of 300 events, including hypopnea, obstructive apnea, mixed apnea, and central apnea. In the final phase, data from 58 patients were used, showing similar recording durations but greater variability in the number of events with many patients having fewer than 100 events and some fewer than 10. The data were first downsampled from 500 Hz to 1 sample per second and reduced from float64 to float32 to optimize computational efficiency. Before implementation, an analysis of variance was conducted to ensure that there was no significant loss of information when transitioning to 1 Hz and converting to float32. The input data of the network includes key physiological signals such as  
Figure 2: The web application interface is developed using React.js. In the menu, the user inputs the patient ID and sends a request, which is handled by Node.js. The request triggers the execution of Python code to generate graphs as shown in the image. SpO2, heart rate, airflow channel 0, and airflow channel 1. During data processing and preparation for further use, some artifacts were detected primarily at the beginning and end of the patient recordings. Additionally, a few artifacts were present during the recordings. The approach applied was to remove sequences with missing data to ensure data quality. In addition to PSG data file, different types of events that occurred during the night were also collected. Each event is associated with a sleep stage, the time it occurred, the epoch number, the body position, and event validity. Please note that a standard epoch in PSG is typically 30 s long and is chosen because it balances detailed signal resolution with manageable data chunks for manual or automated scoring. For this reason, the recorded data were cut into fixed length chunks, each 30 s long, and assigned with a label indicating whether an apnea event occurred. Figure 3 shows the distribution of apneas and hypappneas by sleep stage for a single patient. Due to the simplicity of our model, apnea (central, mixed, obstructive) or hypopnea events were marked as 1, while other events were marked as 0, based on the SpO2 signal processing, as shown in Figure 4.  
Figure 4: SpO2 with label of one patient, 1 denoting detected apnea, and 0 no apneic event. Figure 3: Distribution of apnoeas event by sleep stage for a single patient. The dataset was then divided into training, validation and testing sets. Specifically, 15% of the data was allocated for validation, 15% for testing, and the remaining 70% for training. This split was repeated for each patient using random sampling with segments from different parts of the night assigned as 15% validation, 15% test, and the rest for training. To ensure balanced sampling during training, a Weighted Random Sampler was used due to class imbalances in event labels. A patient-based data split was tested during the data division process; however, due to the limited number of samples and the variability in patients' clinical conditions--some exhibiting better health and others more severe cases--it was necessary to adopt a random sampling approach. Data designated for testing, training, and validation were scaled to a range of 0-1 or \(-1\) to 1. Various scaling methods including MinMaxScaler, StandardScaler, and RobustScaler were tested, with implementation options explored on a per-sequence or per-patient basis, or as specified in a configuration file. As an optional feature, a unique, encoded ID was assigned to each patient, providing the model with an additional feature for patient-specific insights. To enhance model performance, several features were engineered to provide additional context for the model.