Õppige Scikit-learn Pipeline'ide abil oma masinõppe töövooge sujuvamaks muutma. Automatiseerige andmete eeltöötlus, mudeli treenimine ja hüperparameetrite häälestamine.
Scikit-learn Pipeline: Ülim Juhend Masinõppe Töövoogude Automatiseerimiseks
Masinõppe maailmas kujutatakse mudeli ehitamist sageli kui glamuurset viimast sammu. Kuid kogenud andmeteadlased ja masinõppe insenerid teavad, et teekond robustse mudelini on sillutatud rea oluliste, sageli korduvate ja vigadele altide sammudega: andmete puhastamine, tunnuste skaleerimine, kategooriliste muutujate kodeerimine ja palju muud. Nende sammude eraldi haldamine treening-, valideerimis- ja testimisandmestike jaoks võib kiiresti muutuda logistiliseks õudusunenäoks, mis viib peenete vigade ja, mis kõige ohtlikum, andmelekkeni.
Siin tulebki appi Scikit-learn'i Pipeline. See ei ole lihtsalt mugavusvahend; see on fundamentaalne tööriist professionaalsete, reprodutseeritavate ja tootmisvalmis masinõppesüsteemide ehitamiseks. See põhjalik juhend juhatab teid läbi kõige, mida peate Scikit-learn Pipeline'ide valdamiseks teadma, alates põhimõistetest kuni täiustatud tehnikateni.
Probleem: Käsitsi Tehtav Masinõppe Töövoog
Vaatleme tüüpilist juhendatud õppe ülesannet. Enne kui saate isegi kutsuda välja model.fit(), peate oma andmed ette valmistama. Standardne töövoog võib välja näha selline:
- Andmete jaotamine: Jaotage oma andmestik treening- ja testimisandmestikeks. See on esimene ja kõige kriitilisem samm, et tagada mudeli jõudluse hindamine nägemata andmetel.
- Puuduvate väärtuste käsitlemine: Tuvastage ja asendage puuduvad andmed treeningandmestikus (nt kasutades keskmist, mediaani või konstanti).
- Kategooriliste tunnuste kodeerimine: Teisendage mittenumbrilised veerud nagu 'Riik' või 'Tootekategooria' numbrilisse vormingusse, kasutades tehnikaid nagu One-Hot kodeerimine või Ordinal-kodeerimine.
- Numbriliste tunnuste skaleerimine: Viige kõik numbrilised tunnused sarnasele skaalale, kasutades meetodeid nagu standardimine (
StandardScaler) või normaliseerimine (MinMaxScaler). See on ülioluline paljude algoritmide jaoks, nagu SVM-id, logistiline regressioon ja närvivõrgud. - Mudeli treenimine: Lõpuks sobitage oma valitud masinõppemudel eeltöödeldud treeningandmetele.
Nüüd, kui soovite teha ennustusi oma testimisandmestikul (või uutel, nägemata andmetel), peate kordama täpselt samu eeltöötluse samme. Peate rakendama sama asendusstrateegiat (kasutades treeningandmestikust arvutatud väärtust), sama kodeerimisskeemi ja samu skaleerimisparameetreid. Kõigi nende sobitatud teisendajate käsitsi jälgimine on tüütu ja suur vigade allikas.
Suurim risk siin on andmeleke (data leakage). See tekib siis, kui testimisandmestiku informatsioon lekib tahtmatult treeningprotsessi. Näiteks, kui arvutate asendamiseks keskmise või skaleerimisparameetrid kogu andmestikust enne selle jaotamist, õpib teie mudel kaudselt testimisandmetest. See viib liialt optimistliku jõudlushinnanguni ja mudelini, mis reaalses maailmas haledalt ebaõnnestub.
Tutvustame Scikit-learn Pipeline'i: Automatiseeritud Lahendus
Scikit-learn'i Pipeline on objekt, mis aheldab mitu andmeteisenduse sammu ja lõpliku estimaatori (nagu klassifikaator või regressor) üheks, ühtseks objektiks. Võite seda ette kujutada kui oma andmete konveierliini.
Kui kutsute Pipeline'il välja .fit(), rakendab see järjestikku fit_transform() igale vaheetapile treeningandmetel, edastades ühe etapi väljundi järgmise sisendiks. Lõpuks kutsub see viimasel etapil, estimaatoril, välja .fit(). Kui kutsute Pipeline'il välja .predict() või .transform(), rakendab see uutele andmetele ainult iga vaheetapi .transform() meetodit enne lõpliku estimaatoriga ennustuse tegemist.
Pipeline'ide Kasutamise Peamised Eelised
- Andmelekke Vältimine: See on kõige kriitilisem eelis. Kapseldades kogu eeltöötluse pipeline'i sisse, tagate, et teisendused õpitakse ainult treeningandmetelt ristvalideerimise ajal ja rakendatakse korrektselt valideerimis-/testimisandmetele.
- Lihtsus ja Korraldatus: Kogu teie töövoog, alates toorandmetest kuni treenitud mudelini, on koondatud ühte objekti. See muudab teie koodi puhtamaks, loetavamaks ja lihtsamini hallatavaks.
- Reprodutseeritavus: Pipeline'i objekt kapseldab kogu teie modelleerimisprotsessi. Saate selle ühe objekti hõlpsasti salvestada (nt kasutades `joblib` või `pickle`) ja hiljem ennustuste tegemiseks laadida, tagades, et iga kord järgitakse täpselt samu samme.
- Tõhusus Võrgotsingus (Grid Search): Saate teostada hüperparameetrite häälestamist korraga kogu pipeline'i ulatuses, leides parimad parameetrid nii eeltöötluse sammudele kui ka lõplikule mudelile samaaegselt. Uurime seda võimast funktsiooni hiljem.
Oma Esimese Lihtsa Pipeline'i Ehitamine
Alustame lihtsa näitega. Kujutage ette, et meil on numbriline andmestik ja me tahame andmeid skaleerida enne logistilise regressiooni mudeli treenimist. Siin on, kuidas selleks pipeline'i ehitada.
Kõigepealt seadistame oma keskkonna ja loome mõned näidisandmed.
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score
# Generate some sample data
X, y = np.random.rand(100, 5) * 10, (np.random.rand(100) > 0.5).astype(int)
# Split data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Nüüd defineerime oma pipeline'i. Pipeline luuakse, andes ette nimekirja sammudest. Iga samm on ennik (tuple), mis sisaldab nime (teie valitud string) ja teisendaja või estimaatori objekti ennast.
# Create the pipeline steps
steps = [
('scaler', StandardScaler()),
('classifier', LogisticRegression())
]
# Create the Pipeline object
pipe = Pipeline(steps)
# Now, you can treat the 'pipe' object as if it were a regular model.
# Let's train it on our training data.
pipe.fit(X_train, y_train)
# Make predictions on the test data
y_pred = pipe.predict(X_test)
# Evaluate the model
accuracy = accuracy_score(y_test, y_pred)
print(f"Pipeline Accuracy: {accuracy:.4f}")
See ongi kõik! Vaid mõne reaga oleme kombineerinud skaleerimise ja klassifitseerimise. Scikit-learn tegeleb kogu vaheloogikaga. Kui kutsutakse välja pipe.fit(X_train, y_train), kutsub see kõigepealt välja StandardScaler().fit_transform(X_train) ja edastab seejärel tulemuse meetodile LogisticRegression().fit(). Kui kutsutakse välja pipe.predict(X_test), rakendab see juba sobitatud skaleerijat, kasutades StandardScaler().transform(X_test), enne kui teeb ennustusi logistilise regressiooni mudeliga.
Heterogeensete Andmete Käsitlemine: `ColumnTransformer`
Reaalse maailma andmestikud on harva lihtsad. Need sisaldavad sageli segu erinevatest andmetüüpidest: numbrilised veerud, mis vajavad skaleerimist, kategoorilised veerud, mis vajavad kodeerimist, ja võib-olla tekstiveerud, mis vajavad vektoriseerimist. Lihtne järjestikune pipeline ei ole selleks piisav, kuna peate rakendama erinevaid teisendusi erinevatele veergudele.
Siin särabki ColumnTransformer. See võimaldab teil rakendada erinevaid teisendajaid erinevatele veergude alamhulkadele teie andmetes ja seejärel arukalt tulemused ühendada. See on ideaalne tööriist, mida kasutada eeltöötluse sammuna suuremas pipeline'is.
Näide: Numbriliste ja Kategooriliste Tunnuste Kombineerimine
Loome pandas'e abil realistlikuma andmestiku, mis sisaldab nii numbrilisi kui ka kategoorilisi tunnuseid.
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
# Create a sample DataFrame
data = {
'age': [25, 30, 45, 35, 50, np.nan, 22],
'salary': [50000, 60000, 120000, 80000, 150000, 75000, 45000],
'country': ['USA', 'Canada', 'USA', 'UK', 'Canada', 'USA', 'UK'],
'purchased': [0, 1, 1, 0, 1, 1, 0]
}
df = pd.DataFrame(data)
X = df.drop('purchased', axis=1)
y = df['purchased']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Identify numerical and categorical columns
numerical_features = ['age', 'salary']
categorical_features = ['country']
Meie eeltöötlusstrateegia on järgmine:
- Numbriliste veergude (
age,salary) jaoks: Asendage puuduvad väärtused mediaaniga, seejärel skaleerige need. - Kategooriliste veergude (
country) jaoks: Asendage puuduvad väärtused kõige sagedasema kategooriaga, seejärel tehke neile one-hot kodeerimine.
Saame need sammud defineerida, kasutades kahte eraldi mini-pipeline'i.
# Create a pipeline for numerical features
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
# Create a pipeline for categorical features
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
Nüüd kasutame `ColumnTransformer`'it, et rakendada neid pipeline'e õigetele veergudele.
# Create the preprocessor with ColumnTransformer
preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, numerical_features),
('cat', categorical_transformer, categorical_features)
])
`ColumnTransformer` võtab sisendiks `transformers`'ite nimekirja. Iga transformer on ennik, mis sisaldab nime, transformeri objekti (mis võib olla ka ise pipeline) ja veergude nimede nimekirja, millele seda rakendada.
Lõpuks saame paigutada selle `preprocessor`'i esimese sammuna meie põhipipeline'i, millele järgneb meie lõplik estimaator.
from sklearn.ensemble import RandomForestClassifier
# Create the full pipeline
full_pipeline = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', RandomForestClassifier(random_state=42))
])
# Train and evaluate the full pipeline
full_pipeline.fit(X_train, y_train)
print("Model score on test data:", full_pipeline.score(X_test, y_test))
# You can now make predictions on new raw data
new_data = pd.DataFrame({
'age': [40, 28],
'salary': [90000, 55000],
'country': ['USA', 'Germany'] # 'Germany' is an unknown category
})
predictions = full_pipeline.predict(new_data)
print("Predictions for new data:", predictions)
Pange tähele, kui elegantselt see keerulist töövoogu haldab. Parameeter `handle_unknown='ignore'` `OneHotEncoder`'is on eriti kasulik tootmissüsteemides, kuna see hoiab ära vead, kui andmetesse ilmuvad uued, varem nägemata kategooriad.
Täiustatud Pipeline'i Tehnikad
Pipeline'id pakuvad veelgi rohkem võimsust ja paindlikkust. Uurime mõningaid täiustatud funktsioone, mis on professionaalsete masinõppeprojektide jaoks hädavajalikud.
Kohandatud Teisendajate Loomine
Mõnikord ei piisa sisseehitatud Scikit-learn'i teisendajatest. Teil võib olla vaja teha valdkonnaspetsiifilist teisendust, näiteks tunnuse logaritmi võtmine või kahe tunnuse ühendamine uueks. Saate hõlpsasti luua oma kohandatud teisendajaid, mis integreeruvad sujuvalt pipeline'i.
Selleks loote klassi, mis pärib klassidest `BaseEstimator` ja `TransformerMixin`. Peate implementeerima ainult `fit()` ja `transform()` meetodid (ja vajadusel `__init__()`).
Loome teisendaja, mis lisab uue tunnuse: `salary` ja `age` suhte.
from sklearn.base import BaseEstimator, TransformerMixin
# Define column indices (can also pass names)
age_ix, salary_ix = 0, 1
class FeatureRatioAdder(BaseEstimator, TransformerMixin):
def __init__(self):
pass # No parameters to set
def fit(self, X, y=None):
return self # Nothing to learn during fit, so just return self
def transform(self, X):
salary_age_ratio = X[:, salary_ix] / X[:, age_ix]
return np.c_[X, salary_age_ratio] # Concatenate original X with new feature
Seejärel saate lisada selle kohandatud teisendaja oma numbriliste andmete töötlemise pipeline'i:
numeric_transformer_with_custom = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('ratio_adder', FeatureRatioAdder()), # Our custom transformer
('scaler', StandardScaler())
])
Selline kohandamise tase võimaldab teil kapseldada kogu oma tunnuste loomise loogika pipeline'i sisse, muutes teie töövoo äärmiselt kaasaskantavaks ja reprodutseeritavaks.
Hüperparameetrite Häälestamine Pipeline'idega, Kasutades `GridSearchCV`'d
See on vaieldamatult üks Pipeline'ide võimsamaid rakendusi. Saate otsida parimaid hüperparameetreid kogu oma töövoo jaoks, sealhulgas eeltöötluse sammude ja lõpliku mudeli jaoks, kõik korraga.
Selleks, et määrata, milliseid parameetreid häälestada, kasutate spetsiaalset süntaksit: `sammunimi__parameetrinimi`.
Laiendame oma eelmist näidet ja häälestame hüperparameetrid nii meie eeltöötleja asendaja (imputer) kui ka `RandomForestClassifier`'i jaoks.
from sklearn.model_selection import GridSearchCV
# We use the 'full_pipeline' from the ColumnTransformer example
# Define the parameter grid
param_grid = {
'preprocessor__num__imputer__strategy': ['mean', 'median'],
'classifier__n_estimators': [50, 100, 200],
'classifier__max_depth': [None, 10, 20],
'classifier__min_samples_leaf': [1, 2, 4]
}
# Create the GridSearchCV object
grid_search = GridSearchCV(full_pipeline, param_grid, cv=5, verbose=1, n_jobs=-1)
# Fit it to the data
grid_search.fit(X_train, y_train)
# Print the best parameters and score
print("Best parameters found: ", grid_search.best_params_)
print("Best cross-validation score: ", grid_search.best_score_)
# The best estimator is already refitted on the whole training data
best_model = grid_search.best_estimator_
print("Test set score with best model: ", best_model.score(X_test, y_test))
Vaadake hoolikalt võtmeid `param_grid`'is:
'preprocessor__num__imputer__strategy': See sihib `SimpleImputer`'i sammu `strategy` parameetrit, mis kannab nime `imputer` ja asub numbrilises pipeline'is nimega `num`, mis omakorda on `ColumnTransformer`'i sees nimega `preprocessor`.'classifier__n_estimators': See sihib lõpliku estimaatori `n_estimators` parameetrit, mille nimi on `classifier`.
Seda tehes proovib `GridSearchCV` korrektselt läbi kõik kombinatsioonid ja leiab optimaalse parameetrite komplekti kogu töövoo jaoks, vältides täielikult andmeleket häälestamisprotsessi ajal, kuna kogu eeltöötlus tehakse iga ristvalideerimise voldi sees.
Oma Pipeline'i Visualiseerimine ja Uurimine
Keerulisi pipeline'e võib olla raske mõista. Scikit-learn pakub suurepärast viisi nende visualiseerimiseks. Alates versioonist 0.23 saate interaktiivse HTML-esituse.
from sklearn import set_config
# Set display to 'diagram' to get the visual representation
set_config(display='diagram')
# Now, simply displaying the pipeline object in a Jupyter Notebook or similar environment will render it
full_pipeline
See genereerib diagrammi, mis näitab andmete voogu läbi iga teisendaja ja estimaatori koos nende nimedega. See on uskumatult kasulik silumiseks, oma töö jagamiseks ja mudeli struktuuri mõistmiseks.
Saate ka sobitatud pipeline'i üksikutele sammudele nende nimede kaudu juurde pääseda:
# Access the final classifier of the fitted pipeline
final_classifier = full_pipeline.named_steps['classifier']
print("Feature importances:", final_classifier.feature_importances_)
# Access the OneHotEncoder to see the learned categories
onehot_encoder = full_pipeline.named_steps['preprocessor'].named_transformers_['cat'].named_steps['onehot']
print("Categorical features learned:", onehot_encoder.categories_)
Levinud Lõksud ja Parimad Praktikad
- Sobitamine Valedel Andmetel: Alati, alati sobitage oma pipeline AINULT treeningandmetele. Ärge kunagi sobitage seda kogu andmestikule või testimisandmestikule. See on peamine reegel andmelekke vältimiseks.
- Andmevormingud: Olge teadlik iga sammu poolt oodatavast andmevormingust. Mõned teisendajad (nagu meie kohandatud näites) võivad töötada NumPy massiividega, samas kui teised on mugavamad Pandas DataFrame'idega. Scikit-learn on üldiselt hea sellega toime tulema, kuid see on asi, mida tuleks teada, eriti kohandatud teisendajate puhul.
- Pipeline'ide Salvestamine ja Laadimine: Mudeli kasutuselevõtuks peate salvestama sobitatud pipeline'i. Standardne viis seda teha Pythoni ökosüsteemis on `joblib` või `pickle`. `joblib` on sageli tõhusam objektide jaoks, mis sisaldavad suuri NumPy massiive.
import joblib # Save the pipeline joblib.dump(full_pipeline, 'my_model_pipeline.joblib') # Load the pipeline later loaded_pipeline = joblib.load('my_model_pipeline.joblib') # Make predictions with the loaded model loaded_pipeline.predict(new_data) - Kasutage Kirjeldavaid Nimesid: Andke oma pipeline'i sammudele ja `ColumnTransformer`'i komponentidele selged, kirjeldavad nimed (nt 'numbriline_asendaja', 'kategooriline_kodeerija', 'svm_klassifikaator'). See muudab teie koodi loetavamaks ning lihtsustab hüperparameetrite häälestamist ja silumist.
Kokkuvõte: Miks On Pipeline'id Professionaalse Masinõppe Jaoks Vältimatud
Scikit-learn'i Pipeline'id ei ole lihtsalt tööriist puhtama koodi kirjutamiseks; need esindavad paradigmamuutust käsitsi tehtavast, vigaderohkest skriptimisest süstemaatilisele, robustsele ja reprodutseeritavale lähenemisele masinõppes. Need on usaldusväärsete masinõppe inseneritavade selgroog.
Pipeline'e kasutusele võttes saavutate:
- Robustsus: Kõrvaldate masinõppeprojektide kõige levinuma veaallika – andmelekke.
- Tõhusus: Sujuvamaks muudate kogu oma töövoo, alates tunnuste loomisest kuni hüperparameetrite häälestamiseni, üheks terviklikuks üksuseks.
- Reprodutseeritavus: Loote ühe, serialiseeritava objekti, mis sisaldab kogu teie mudeli loogikat, muutes selle kasutuselevõtu ja jagamise lihtsaks.
Kui suhtute tõsiselt masinõppemudelite ehitamisse, mis töötavad usaldusväärselt reaalses maailmas, siis Scikit-learn'i Pipeline'ide valdamine ei ole valikuline – see on hädavajalik. Alustage nende lisamist oma projektidesse juba täna ja te ehitate paremaid, usaldusväärsemaid mudeleid kiiremini kui kunagi varem.