Kodėl Python tapo ML kalbų karaliumi?
Jei kada nors bandėte pasirinkti programavimo kalbą mašininio mokymosi projektui, tikriausiai pastebėjote, kad beveik visur stumia Python. Ir tai nėra atsitiktinumas ar mada. Python atsirado kaip dominuojanti kalba ML srityje dėl kelių labai konkrečių priežasčių, kurios kartu sudaro sunkiai įveikiamą pranašumą.
Pirma, Python sintaksė yra neįtikėtinai skaitoma. Kai rašai ML kodą, dažnai tenka greitai eksperimentuoti, keisti parametrus, testuoti hipotezes. Jei kalba reikalauja daug boilerplate kodo, tai tiesiog trukdo mąstymo procesui. Python leidžia susikoncentruoti į algoritmą, o ne į kalbos taisykles.
Antra, ekosistema. NumPy, pandas, scikit-learn, TensorFlow, PyTorch – visa tai yra Python bibliotekos, kurios buvo kuriamos metų metus ir dabar yra tikrai brandžios. Jei bandytumėte tą patį padaryti su Java ar C++, tikriausiai rastumėte kažką, bet ne tokią integruotą, tokią gerai dokumentuotą ekosistemą.
Trečia, bendruomenė. Stack Overflow, GitHub, Kaggle – visur Python. Kai užstringa, greičiausiai rasite atsakymą su Python kodo pavyzdžiu. Tai sukuria savęs stiprinantį ciklą: daugiau žmonių naudoja Python, todėl daugiau resursų, todėl dar daugiau žmonių renkasi Python.
Nuo ko pradėti: aplinkos sukūrimas be galvos skausmo
Viena dažniausių klaidų, kurią daro pradedantieji – bando tiesiog įdiegti Python ir pradėti. Tai gali veikti, bet labai greitai atsiranda problemų su bibliotekų versijomis, konfliktais, ir galiausiai sistema tampa tokia supainiota, kad lengviau viską ištrinti ir pradėti iš naujo.
Geriausia praktika yra naudoti virtualias aplinkas. Štai kaip tai atrodo praktiškai:
# Sukuriame naują virtualią aplinką
python -m venv ml_projektas
# Aktyvuojame (Linux/Mac)
source ml_projektas/bin/activate
# Aktyvuojame (Windows)
ml_projektas\Scripts\activate
# Įdiegiame pagrindines bibliotekas
pip install numpy pandas scikit-learn matplotlib jupyter
Bet dar geriau – naudoti conda arba mamba. Conda ypač naudinga, nes ji valdo ne tik Python paketus, bet ir sisteminius priklausomybes. Kai dirbate su TensorFlow ar PyTorch, kurie turi CUDA priklausomybes GPU palaikymui, conda dažnai išsprendžia problemas automatiškai, kurias su pip tektų spręsti rankiniu būdu.
Jupyter Notebook arba JupyterLab yra beveik privalomas įrankis ML darbui. Jis leidžia rašyti kodą ląstelėmis, iš karto matyti rezultatus, vizualizacijas, ir tai labai tinka eksperimentiniam darbui. VS Code su Jupyter plėtiniu taip pat puikiai veikia, jei norite pilnesnio IDE funkcionalumo.
Duomenų paruošimas: tas nuobodus darbas, kuris nulemia viską
Yra toks posakis ML bendruomenėje: „garbage in, garbage out”. Jei duomenys yra prasti, modelis bus prastas, nesvarbu, kokį sudėtingą algoritmą naudosite. Ir realybėje duomenų paruošimas užima apie 70-80% viso ML projekto laiko. Tai nėra seksualinga dalis, bet tai yra svarbiausia dalis.
Pandas biblioteka yra pagrindinis įrankis darbui su duomenimis Python ekosistemoje:
import pandas as pd
import numpy as np
# Įkeliame duomenis
df = pd.read_csv('duomenys.csv')
# Pirmas žvilgsnis į duomenis
print(df.head())
print(df.info())
print(df.describe())
# Trūkstamų reikšmių tikrinimas
print(df.isnull().sum())
# Paprastas trūkstamų reikšmių užpildymas vidurkiu
df['amzius'].fillna(df['amzius'].mean(), inplace=True)
# Kategorinių kintamųjų kodavimas
df = pd.get_dummies(df, columns=['miestas'])
Trūkstamų reikšmių problema yra viena dažniausių. Yra kelios strategijos: išmesti eilutes su trūkstamomis reikšmėmis (jei jų nedaug), užpildyti vidurkiu arba mediana (skaitiniams kintamiesiems), užpildyti moda (kategoriniams), arba naudoti sudėtingesnius metodus kaip KNN imputation. Pasirinkimas priklauso nuo konteksto ir nuo to, kiek duomenų prarasite.
Duomenų normalizacija arba standartizacija dažnai yra būtina. Daugelis algoritmų (pvz., SVM, KNN, neural networks) yra jautrūs kintamųjų skalei. Jei vienas kintamasis matuojamas tūkstančiais, o kitas – dešimtimis, algoritmas gali nepagrįstai teikti pirmenybę pirmajam:
from sklearn.preprocessing import StandardScaler, MinMaxScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_train)
# Svarbu: test duomenims naudojame tik transform, ne fit_transform
X_test_scaled = scaler.transform(X_test)
Ši klaida – naudoti fit_transform ir test duomenims – yra labai dažna ir sukelia duomenų nutekėjimą (data leakage). Tai reiškia, kad modelis netiesiogiai „mato” test duomenis treniravimo metu, ir rezultatai bus per optimistiški.
Scikit-learn: ML biblioteka, kuri tiesiog veikia
Scikit-learn yra tikriausiai svarbiausia Python ML biblioteka pradedantiesiems ir vidutinio lygio praktikams. Jos dizainas yra elegantiškas: beveik visi modeliai turi tą patį API – fit(), predict(), score(). Tai reiškia, kad išmokęs dirbti su vienu algoritmu, labai lengvai pereini prie kito.
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix
# Duomenų padalijimas
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Modelio sukūrimas ir treniravimas
modelis = RandomForestClassifier(n_estimators=100, random_state=42)
modelis.fit(X_train, y_train)
# Prognozavimas ir vertinimas
y_pred = modelis.predict(X_test)
print(classification_report(y_test, y_pred))
Random Forest yra puikus pradinis pasirinkimas daugeliui problemų. Jis gerai veikia be daug parametrų derinimo, yra atsparus outlier’iams, gali dirbti su mišriais duomenų tipais, ir suteikia feature importance informaciją, kuri padeda suprasti, kurie kintamieji yra svarbiausi.
Tačiau scikit-learn turi ir ribotumų. Ji nėra skirta giluminio mokymosi (deep learning) modeliams. Taip pat ji nėra optimizuota labai dideliems duomenų rinkiniams, kurie netelpa į RAM. Tokiais atvejais reikia kitų įrankių.
Cross-validation yra dar viena svarbi koncepcija, kurią scikit-learn labai lengvai realizuoja:
from sklearn.model_selection import cross_val_score
rezultatai = cross_val_score(modelis, X, y, cv=5, scoring='accuracy')
print(f"Tikslumas: {rezultatai.mean():.3f} (+/- {rezultatai.std():.3f})")
Vietoj to, kad modelį vertintumėte tik ant vieno test rinkinio, cross-validation padalija duomenis į 5 (arba kiek nurodysite) dalis ir kiekvieną kartą naudoja kitą dalį kaip test rinkinį. Tai suteikia daug patikimesnį modelio veikimo įvertinimą.
Giluminis mokymasis su PyTorch ir TensorFlow
Kai scikit-learn nebepakanka – kai dirbate su vaizdais, tekstu, garsu, arba kai duomenų yra labai daug ir santykiai labai sudėtingi – ateina laikas giluminiam mokymuisi. Python ekosistemoje yra du pagrindiniai žaidėjai: TensorFlow (su Keras) ir PyTorch.
Istoriškai TensorFlow buvo populiaresnis industrijoje, o PyTorch – akademijoje. Bet pastaraisiais metais PyTorch labai išaugo ir dabar yra dominuojantis abiejose srityse. Jo dinaminis computation graph leidžia rašyti intuityvesnį kodą ir lengviau debuginti:
import torch
import torch.nn as nn
import torch.optim as optim
# Paprastas neural network
class ManoModelis(nn.Module):
def __init__(self):
super(ManoModelis, self).__init__()
self.fc1 = nn.Linear(784, 256)
self.fc2 = nn.Linear(256, 128)
self.fc3 = nn.Linear(128, 10)
self.relu = nn.ReLU()
self.dropout = nn.Dropout(0.3)
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.dropout(x)
x = self.relu(self.fc2(x))
x = self.fc3(x)
return x
modelis = ManoModelis()
kriterijus = nn.CrossEntropyLoss()
optimizatorius = optim.Adam(modelis.parameters(), lr=0.001)
GPU palaikymas yra vienas iš pagrindinių giluminio mokymosi privalumų. Treniruoti didelį modelį CPU gali užtrukti dienas, o GPU – valandas. PyTorch tai realizuoja elegantiškai:
# Tikriname, ar GPU prieinamas
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
modelis = modelis.to(device)
# Treniravimo ciklas
for epoch in range(num_epochs):
for batch_X, batch_y in train_loader:
batch_X, batch_y = batch_X.to(device), batch_y.to(device)
optimizatorius.zero_grad()
outputs = modelis(batch_X)
loss = kriterijus(outputs, batch_y)
loss.backward()
optimizatorius.step()
Jei neturite savo GPU, galite naudoti Google Colab, kuris suteikia nemokamą GPU prieigą. Tai puiku eksperimentams ir mokymosi tikslais. Kaggle taip pat suteikia nemokamą GPU laiką savo notebook aplinkoje.
Hiperparametrų derinimas: menas rasti geriausius nustatymus
Kiekvienas ML modelis turi hiperparametrus – nustatymus, kuriuos nurodote prieš treniravimą ir kurie kontroliuoja mokymosi procesą. Random Forest turi n_estimators, max_depth, min_samples_split ir daugelį kitų. Neural network turi learning rate, batch size, sluoksnių skaičių, neuronų skaičių kiekviename sluoksnyje.
Rankinis derinimas yra neefektyvus. Scikit-learn siūlo kelis automatinius metodus:
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
# Grid Search - išbando visas kombinacijas
param_grid = {
'n_estimators': [100, 200, 300],
'max_depth': [None, 10, 20, 30],
'min_samples_split': [2, 5, 10]
}
grid_search = GridSearchCV(
RandomForestClassifier(random_state=42),
param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1 # naudoja visus CPU branduolius
)
grid_search.fit(X_train, y_train)
print(f"Geriausi parametrai: {grid_search.best_params_}")
print(f"Geriausias rezultatas: {grid_search.best_score_:.3f}")
Grid Search yra išsamus, bet lėtas – jis išbando visas galimas kombinacijas. Jei turite daug hiperparametrų, geriau naudoti Randomized Search, kuris atsitiktinai parenka kombinacijas ir dažnai randa gerą sprendimą daug greičiau.
Dar pažangesnis variantas – Bayesian optimization, kurį realizuoja bibliotekos kaip Optuna arba Hyperopt. Šie metodai naudoja ankstesnių bandymų rezultatus, kad protingiau pasirinktų kitus parametrus. Optuna yra ypač patogi naudoti:
import optuna
def objective(trial):
n_estimators = trial.suggest_int('n_estimators', 50, 500)
max_depth = trial.suggest_int('max_depth', 2, 32)
modelis = RandomForestClassifier(
n_estimators=n_estimators,
max_depth=max_depth,
random_state=42
)
return cross_val_score(modelis, X_train, y_train, cv=3).mean()
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
print(f"Geriausi parametrai: {study.best_params}")
MLOps: nuo eksperimento iki produkcijos
Daugelis ML kursų ir vadovėlių sustoja ties modelio sukūrimu ir vertinimu. Bet realybėje tai yra tik pusė darbo. Modelį reikia įdiegti, stebėti, atnaujinti. Tai yra MLOps sritis, ir ji tampa vis svarbesnė.
Eksperimentų sekimas yra pirmasis žingsnis. Kai bandote dešimtis skirtingų modelių ir parametrų kombinacijų, labai lengva prarasti, kas veikė ir kas ne. MLflow yra populiarus įrankis šiai problemai spręsti:
import mlflow
import mlflow.sklearn
with mlflow.start_run():
modelis = RandomForestClassifier(n_estimators=100, max_depth=10)
modelis.fit(X_train, y_train)
tikslumas = modelis.score(X_test, y_test)
# Logginame parametrus ir metrikas
mlflow.log_param("n_estimators", 100)
mlflow.log_param("max_depth", 10)
mlflow.log_metric("tikslumas", tikslumas)
# Išsaugome modelį
mlflow.sklearn.log_model(modelis, "modelis")
Modelio serializacija yra būtina, kad galėtumėte jį panaudoti produkcijoje. Scikit-learn modeliams dažniausiai naudojamas joblib arba pickle:
import joblib
# Išsaugome modelį
joblib.dump(modelis, 'modelis.pkl')
joblib.dump(scaler, 'scaler.pkl')
# Įkeliame ir naudojame
ikeltas_modelis = joblib.load('modelis.pkl')
ikeltas_scaler = joblib.load('scaler.pkl')
nauji_duomenys_scaled = ikeltas_scaler.transform(nauji_duomenys)
prognoze = ikeltas_modelis.predict(nauji_duomenys_scaled)
FastAPI yra puikus pasirinkimas, jei norite sukurti REST API savo ML modeliui. Jis yra greitas, turi automatinę dokumentaciją, ir labai gerai integruojasi su Python ML ekosistema. Paprastas ML API gali atrodyti taip:
from fastapi import FastAPI
from pydantic import BaseModel
import joblib
import numpy as np
app = FastAPI()
modelis = joblib.load('modelis.pkl')
class InputData(BaseModel):
feature1: float
feature2: float
feature3: float
@app.post("/predict")
def predict(data: InputData):
X = np.array([[data.feature1, data.feature2, data.feature3]])
prognoze = modelis.predict(X)
return {"prognoze": int(prognoze[0])}
Kai Python ML tampa gyvenimo būdu: ką toliau?
Machine learning su Python yra ne tik techninis įgūdis – tai mąstymo būdas. Kai pradedi suprasti, kaip algoritmai mokosi iš duomenų, pradedi kitaip žiūrėti į problemas apskritai. Bet kelias nuo „Hello World” iki realių projektų yra ilgas, ir svarbu žinoti, kur eiti toliau.
Praktika yra svarbesnė už teoriją, bent jau pradžioje. Kaggle konkurencijos yra puikus būdas gauti realių duomenų ir pamatyti, kaip kiti žmonės sprendžia tas pačias problemas. Pradėkite nuo Titanic arba House Prices konkurencijų – jos yra klasikinės ir turi daug resursų pradedantiesiems.
Matematinis pagrindas – linijinė algebra, statistika, tikimybių teorija – ilgainiui tampa svarbus. Galite pradėti be jo, bet jei norite suprasti, kodėl algoritmai veikia taip, kaip veikia, ir kaip juos adaptuoti nestandartinėms situacijoms, matematika yra būtina. 3Blue1Brown YouTube kanalas yra nuostabus būdas suprasti linijinę algebrą ir neural networks intuityviai.
Specializacija taip pat verta apsvarstyti. ML yra plati sritis: kompiuterinė rega (computer vision), natūralios kalbos apdorojimas (NLP), rekomenduojančios sistemos, laiko eilučių analizė – kiekviena sritis turi savo metodus, bibliotekas, geriausias praktikas. Geriau būti tikrai gerai vienoje srityje, nei paviršutiniškai visose.
Galiausiai, nepamirškite, kad ML yra priemonė, o ne tikslas. Geriausi ML inžinieriai yra tie, kurie supranta verslo ar mokslinę problemą, kurią sprendžia, ir gali paaiškinti savo modelio rezultatus žmonėms, kurie nežino, kas yra gradient descent. Techninis meistriškumas be gebėjimo komunikuoti ir suprasti kontekstą yra tik pusė reikalingo įgūdžių rinkinio. Python ir jo ekosistema suteikia jums įrankius – ką su jais darysite, priklauso nuo jūsų.






