Diverse sondaje făcute de Stack Overflow sau Github poziționează Python în topul celor mai utilizate, căutate sau îndrăgite limbaje de programare. Mie nu mi-a plăcut limbajul când am început să îl folosesc și, dacă e să fiu foarte sincer, nu sunt înnebunit după el nici acum. Dar asta nu contează prea mult, întrucât Python face foarte bine ceea ce face.
3ds Max, Paint Shop Pro și multe aplicații folosesc Python pentru a automatiza sau pentru a adăuga funcționalitate. E același tip de utilizare întâlnit la Java Script sau Tcl/Tk.
Inclus în multe distribuții de sistem de operare, Python se pretează foarte bine pentru a scrie diverse utilitare. Un excelent exemplu este installerul de Ubuntu, Ubiquity.
Aceasta e probabil utilizarea cea mai cunoscută și care i-a adus cei mai mulți utilizatori. Python e limbajul principal pentru Scientific Programming, în special Data Science și Artificial Intelligence. Aici Python a înlocuit într-o oarecare măsură limbaje precum Matlab sau R.
Nu voi insista în acest articol despre Machine Learning și AI ci despre activitățile conexe, precum analiza datelor, modelarea problemei sau vizualizarea rezultatelor. Aceste activități sunt aplicabile indiferent de problema ce trebuie rezolvată, nefiind limitată la ML și AI.
Voi exemplifica utilizarea Python pentru a vizualiza, analiza, selecta, filtra sau curăța date. Nu suntem limitați de o implementare sau alta întrucât există librării ce permit citirea și scrierea datelor din și în cele mai diverse formate: SQL, Parquet, Amazon S3, CSV, Excel etc.
Înainte de a mă avânta în subiectul propus, vreau să menționez rapid câteva aspecte privind instalarea și configurarea unui mediu de dezvoltare Python.
Dacă nu aveți Python 3 în distribuția sistemului de operare, îl puteți descărca și instala de pe site-ul oficial.
Notă: recomand să instalați Python 3 și nu una din versiunile precedente.
Instalarea de Python poate deveni extrem de rapid nefuncțională deoarece toate dependințele cerute de aplicațiile Python sunt instalate în același loc. În timp asta duce invariabil la conflicte.
Pentru a evita această problemă, o soluție e utilizarea mai multor medii virtuale Python. Aceasta se face foarte ușor folosind un manager de medii virtuale precum Anaconda. Cu Anaconda veți crea un mediu virtual de Python separat pentru fiecare problemă/tip de probleme, evitând conflictele generate de dependințe sau versiune de dependințe incompatibile.
Pentru a instala Anaconda intrați pe https://docs.anaconda.com/anaconda/install/
Limbajul a fost creat pentru a fi simplu de folosit chiar și de către cei care nu sunt programatori. Simplitatea în utilizare e confirmată și de aplicații precum Jupyter Notebooks. Jupyter Notebooks permite crearea și rularea codului de Python într-un mod vizual, interactiv fără a fi necesară instalarea unui IDE sau cunoștințe de cum se creează, gestionează sau rulează module de cod.
Exemplul de mai jos include crearea unui mediu dezvoltare Python 3.9 folosind Anaconda și apoi instalarea Jupyter Notebook în acel mediu:
conda create -n dataexp python=3.9
conda activate dataexp
pip install jupyter
Notă: puteți încerca Python și Jupyter Notebooks fără a instala nimic pe calculatorul vostru.
Înainte de a porni Jupyter Notebook, trebuie instalat setul de librării pe care îl vom folosi. Am ales câteva din librăriile cel mai frecvent utilizate în analiza datelor: Pandas, Numpy, Matplotlib, Seaborn.
În mod tradițional, modulele Python dorite sunt listate într-un fișier numit requirements.txt
. E recomandat a se specifica și versiunea dorită. Cu cât mai strict e specificatorul de versiune (3.5.1 vs. 3. *), cu atât mai puține probleme veți întâmpina când modulele se actualizează.
matplotlib==3.4. *
numpy==1.19. *
pandas==1.3. *
seaborn==0.11. *
Odată creat requirements.txt
, instalarea dependințelor se face din linia de comandă. E important să avem activ mediul Python dorit:
conda activate dataexp
pip install -r requirements.txt
Tot din linia de comandă se pornește și Jupyter Notebook cu jupyter-notebook
.
Având mediul Python pregătit, putem începe să explorăm date.
Codul sursă pentru exemplele din articol e disponibil la https://github.com/datagridsoftware/practical-ml/tree/main/notebooks/dataexp alături de alte exemple de ML și AI.
Primul pas în analiza datelor e încărcarea lor folosind modulul Pandas. Pandas e modulul cel mai comun, când vine vorba de analiză și prelucrare de date în Python.
În exemplul de față folosesc titanic.csv , un set de date des întâlnit, în exemplele de Machine Learning, vezi Tabelul 1. La fel de bine am fi putut folosi un fișier Excel sau o conexiune la o bază de date SQL.
import pandas as pd
pd.options.display.float_format = '{:,.2f}'.format
titanic_data = pd.read_csv
(r'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv')
titanic_data.head()
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.00 | 1 | 0 | A/5 21171 | 7.25 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence | female | 38.00 | 1 | 0 | PC 17599 | 71.28 | C85 | C |
Briggs Th... | ||||||||||||
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.00 | 0 | 0 | STON/O2. 3101282 | 7.92 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May | female | 35.00 | 1 | 0 | 113803 | 53.10 | C123 | S |
Peel) | ||||||||||||
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.00 | 0 | 0 | 373450 | 8.05 | NaN | S |
Un notebook Jupyter e organizat în celule ce pot fi executate în orice ordine. Tot codul poate fi scris într-o singură celulă însă acest lucru nu e recomandat. Eu prefer să am cât mai puțin cod în fiecare celulă, cod ce face un singur lucru. Analizând codul de mai sus, cele trei celule fac următoarele:
Importă modulele folosite;
Încarcă setul de date de la URL-ul specificat;
Jupyter Notebook va afișa automat valoarea întoarsă de ultima linie din fiecare celulă. De aceea, în celula 3 e suficient să întorc capul setului de date, fără a folosi explicit vreo instrucțiune de tipărire.
Odată încărcate datele, putem obține informații elementare despre acestea:
titanic_data.info(verbose=True)
+------------------------------------------+
| RangeIndex: 891 entries, 0 to 890 |
| Data columns (total 12 columns): |
| # Column Non-Null Count Dtype |
| --- ------ -------------- ----- |
| 0 PassengerId 891 non-null int64 |
| 1 Survived 891 non-null int64 |
| 2 Pclass 891 non-null int64 |
| 3 Name 891 non-null object |
| 4 Sex 891 non-null object |
| 5 Age 714 non-null float64 |
| 6 SibSp 891 non-null int64 |
| 7 Parch 891 non-null int64 |
| 8 Ticket 891 non-null object |
| 9 Fare 891 non-null float64 |
| 10 Cabin 204 non-null object |
| 11 Embarked 889 non-null object dtypes: |
| float64(2), int64(5), object(5) |
| memory usage: 83.7+ KB |
+------------------------------------------+
Putem obține ușor informații statistice precum:
numărul de valori unice, cea mai întâlnită valoare pentru tipurile non-numerice;
titanic_data.describe(exclude="number").transpose()
count | unique | top | freq | |
---|---|---|---|---|
Name | 891 | 891 | Braund, Mr. Owen Harris | 1 |
Sex | 891 | 2 | male | 577 |
Ticket | 891 | 681 | 347082 | 7 |
Cabin | 204 | 147 | B96 B98 | 4 |
Embarked | 889 | 3 | S | 644 |
titanic_data.describe(exclude="object").transpose()
count | mean | std | min | 25% | 50% | 75% | max | |
---|---|---|---|---|---|---|---|---|
PassengerId | 891.00 | 446.00 | 257.35 | 1.00 | 223.50 | 446.00 | 668.50 | 891.00 |
Survived | 891.00 | 0.38 | 0.49 | 0.00 | 0.00 | 0.00 | 1.00 | 1.00 |
Pclass | 891.00 | 2.31 | 0.84 | 1.00 | 2.00 | 3.00 | 3.00 | 3.00 |
Age | 714.00 | 29.70 | 14.53 | 0.42 | 20.12 | 28.00 | 38.00 | 80.00 |
SibSp | 891.00 | 0.52 | 1.10 | 0.00 | 0.00 | 0.00 | 1.00 | 8.00 |
Parch | 891.00 | 0.38 | 0.81 | 0.00 | 0.00 | 0.00 | 0.00 | 6.00 |
Fare | 891.00 | 32.20 | 49.69 | 0.00 | 7.91 | 14.45 | 31.00 | 512.33 |
Librăriile Matplotlib și Seaborn (și altele care nu sunt menționate aici) oferă o multitudine de funcții predefinite pentru vizualizarea datelor. Fiecare tip de vizualizare permite configurarea paletei de culori, a dimensiunii imaginii, a tipului de linie și a altor parametri specifici. Pentru detalii vă recomand să studiați documentația și exemplele:
Primul pas e să importăm librăriile ce le vom folosi mai departe și să configurăm dimensiunea graficelor.
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
sns.set(rc = {'figure.figsize':(15,8)})
Cu o singură linie de cod putem obține histograme pentru coloanele de interes din setul de date.
titanic_data[["Survived", "Pclass", "Age", "SibSp", "Parch"]]
.hist(bins=10,figsize=(15,10),grid=False);
La fel de ușor putem analiza combinații ale datelor, mai precis distribuția vârstei pasagerilor în raport cu clasa cabinei.
sns.kdeplot("Age", hue="Pclass", data=titanic_data, palette="Set2")
plt.show()
Putem folosi Python nu doar pentru a vizualiza dar și pentru a genera date. Spre exemplu, generarea de numere aleatorii cu o distribuție normală:
plt.hist(np.random.randn(10000), color = "m")
plt.title("Normally distributed random numbers")
plt.show()
Ca ultim exemplu propun calculul valorilor și tipărirea graficului funcțiilor sinus și cosinus pe intervalul [-π, π] folosind Numpy. Codul profită de implementarea vectorizată a Numpy pentru o bună performanță la execuție.
Multe din librăriile de Python sunt scrise peste module C ce folosesc algoritmi vectorizați cu performanțe excelente atât pe CPU-uri, cât și pe GPU-uri. Utilizarea de instrucțiuni iterative pentru procesarea de date cu Python împiedică generarea de cod optimizat și de aceea e un mare NU.
def f(x, n):
return np.sin(x)
def g(x):
return np.cos(x)
x = np.arange(-np.pi, np.pi + 0.1, 0.1)
plt.figure(figsize=(12,6))
plt.plot(x, f(x, 2), color="g")
plt.plot(x, g(x), color="r", linestyle="dotted")
plt.xlabel('X')
plt.ylabel('Y')
plt.legend( [ 'f(x) = sin(x)', 'g(x) = cos(x)' ] )
plt.title('Trigonometry 101');
plt.show()
Rulând cele patru celule de cod obținem graficul dorit.
Python nu e un limbaj elegant sau frumos și nici primul limbaj pe care l-aș alege pentru implementarea unui serviciu de back-end. Dar e cu siguranță o unealtă pe care mă bucur să o am la îndemână pentru a analiza, curăța, filtra și vizualiza date. Iar când vine vorba de ML și AI, Python nu poate fi evitat.
În speranța că exemplele de mai sus v-au stârnit interesul, vă recomand să încercați Python pornind de la Jupyter Notebooks. S-ar putea să descoperiți și voi cât de util poate fi acest limbaj, cât și bogata sa colecție de module open source.