Parkinson Risk and Symptom Analysis and Classification
Boac Mihai Cosmin
Simulare Etapa Locală ONIA 2026
1. Introducere
Problema Parkinson Risk and Symptom Analysis and Classification face parte din concursul Simulare Etapa Locală ONIA 2026, desfășurat în data de 17 ianuarie 2026, pe platforma https://platform.olimpiada-ai.ro.
Lucrarea de față descrie soluția mea pentru această problemă.
Setul de date conține informații despre mai mulți pacienți: Age, AlcoholConsumption, BMI, CholesterolHDL, Depression etc.
Pe baza acestor date, se formulează trei sarcini:
- Subtask 1: Calcularea scorului riscului cardiometabolic, dat de formula:
- Subtask 2: Calcularea scorului riscului legat de stilul de viață, dat de formula:
- Subtask 3: Predicția coloanei
Diagnosis, care reprezintă diagnosticul pacientului (0= sănătos,1= Parkinson’s).
În continuare, voi prezenta ideea teoretică, tehnologiile folosite și alternative posibile, apoi voi explica implementarea.
2. Abstract
Această problemă combină preprocesarea datelor, prelucrarea eficientă a acestora și antrenarea unui model cât mai performant.
-
Subtask-rile 1 și 2 reprezintă o problemă simplă de prelucrare a datelor. Vom procesa fiecare linie din dataset în parte și vom calcula
CardiometabolicRiskScoreșiLifestyleRiskIndexfolosind formulele din enunț. -
Subtask-ul 3 este o problemă de clasificare. Pe baza pacienților care au deja coloana
Diagnosiscompletată, cei din dataset-ul de train, antrenăm un model (CatBoostClassifier) care să prezică diagnosticul pentru pacienții din dataset-ul de test.
Fluxul de rezolvare este următorul:
- Citirea datelor din fișierele
train.csvșitest.csv; - Preprocesarea datelor: codificarea coloanelor categorice și scalarea celor numerice;
- Rezolvarea celor 3 cerințe;
- Construirea fișierului
output.csv, care să conțină coloanelePatientID,subtaskIDșiAnswer.
3. Tehnologii folosite, rolul lor și eventuale alternative
Codul folosește următoarele biblioteci:
pandas
import pandas as pdPentru citirea și manipularea dataset-urilor. Pandas oferă DataFrame-uri, filtrare, selecție de coloane etc.
- Alternativă: modulul standard
csvdin Python, însă ar fi mult mai incomod de folosit şi ar necesita cod suplimentar pentru operaţii simple.
scikit-learn
StandardScaler
from sklearn.preprocessing import StandardScalerPentru scalarea coloanelor numerice.
GridSearchCV
from sklearn.model_selection import GridSearchCVPentru hyperparameter tuning.
make_pipeline
from sklearn.pipeline import make_pipelinePentru a combina mai ușor StandardScaler() cu CatBoostClassifier().
catboost
CatBoostClassifier
from catboost import CatBoostClassifierPentru modelul CatBoostClassifier().
4. Prezentarea implementării
Mai jos voi trece prin părțile principale ale codului și logica fiecăreia.
4.1. Citirea datelor
train_df = pd.read_csv("train.csv")test_df = pd.read_csv("test.csv")Bucata de cod de mai sus citește dataset-urile de train și test.
4.2. Preprocesarea datelor
doctors = {}def get_doctors(df): for doctor in df["DoctorInCharge"]: if doctor not in doctors: doctors[doctor] = len(doctors)get_doctors(train_df)get_doctors(test_df)Funcția get_doctors() creează un dicționar care asociază fiecărui doctor o valoare unică.
def preprocess(df): df["DoctorInCharge"] = df["DoctorInCharge"].replace(doctors) df["EyeColor"] = df["EyeColor"].replace({ "Brown": 0, "Blue": 1, "Green": 2, "Hazel": 3, "Gray": 4 }) return dftrain_df = preprocess(train_df)test_df = preprocess(test_df)Funcția preprocess() transformă feature-urile categorice în feature-uri numerice. Pentru coloana DoctorInCharge folosim dicționarul creat mai sus, iar pentru coloana EyeColor scriem un dicționar de mână.
4.3. Subtask-urile 1 și 2
results = []for idx, row in test_df.iterrows(): results.append(( row["PatientID"], "Task1", (row["Hypertension"] == 1) + (row["Diabetes"] == 1) + (row["BMI"] > 30) )) results.append(( row["PatientID"], "Task2", (row["Smoking"] == 1) + (row["AlcoholConsumption"] > 2) + (row["PhysicalActivity"] < 1) ))Pentru a rezolva subtask-urile 1 și 2, iterăm prin liniile dataset-ului de test folosind test_df.iterrows().
Pentru fiecare rând, selectăm coloanele din formulele din enunț, adică Hypertension, Diabetes și BMI pentru subtask-ul 1, respectiv Smoking, AlcoholConsumption și PhysicalActivity pentru subtask-ul 2, și aplicăm formulele.
4.4. Subtask-ul 3
cb_param_grid = { "iterations": [300, 600], "learning_rate": [0.03, 0.1], "depth": [6, 8], "l2_leaf_reg": [3, 7],}cb_grid_search = GridSearchCV( CatBoostClassifier(), cb_param_grid, scoring="roc_auc", n_jobs=-1)cb_grid_search.fit(X_train, y_train)cb_best_params = cb_grid_search.best_params_print(cb_best_params)Pentru a rezolva subtask-ul 3, vom folosi un CatBoostClassifier() cu hyperparameter tuning.
În bucata de cod de mai sus, definim parameter grid-ul pentru tuning, apoi folosim GridSearchCV pentru a găsi cei mai buni parametri.
Rulând codul vom obține parametrii următori:
{ "depth": 6, "iterations": 600, "l2_leaf_reg": 3, "learning_rate": 0.03}X_train = train_df.drop(columns=["PatientID", "Diagnosis"])y_train = train_df["Diagnosis"]X_test = test_df.drop(columns="PatientID")cb = make_pipeline( StandardScaler(), CatBoostClassifier(**cb_best_params))cb.fit(X_train, y_train)y_pred = cb.predict(X_test)În continuare, împărțim dataset-urile de train și test în X_train, y_train și X_test.
Apoi definim un CatBoostClassifier() cu parametrii aflați mai sus, pe care îl combinăm cu StandardScaler() folosind make_pipeline.
În final, dăm fit pe X_train și y_train, iar apoi facem predicția pe X_test.
for (idx, row), label in zip(test_df.iterrows(), y_pred): results.append(( row["PatientID"], "Task3", label ))Folosind aceeași metodă ca la subtask-urile 1 si 2, iterăm prin liniile dataset-ului de test și adăugăm label-urile la răspuns.
4.5. Crearea fișierului de output
output_df = pd.DataFrame( results, columns=["PatientID", "subtaskID", "Answer"])output_df.to_csv("output.csv", index=False)Folosind pandas, creăm un DataFrame cu rezultatele de la cele 3 subtask-uri și cu coloanele specificate în enunț, pe care apoi îl exportăm folosind .to_csv().
5. Concluzii
Soluția prezentată parcurge toate detaliile de implementare, de la preprocesarea datelor până la tunarea hyperparametrilor, pentru rezolvarea celor 3 cerințe ale problemei.
Problema reprezintă, astfel, un bun exercițiu pentru consolidarea cunoștințelor din domeniul inteligenței artificiale.