Trenowanie modelu regresji za pomocą rozwiązania AutoML i języka Python (zestaw SDK w wersji 1)
DOTYCZY:Zestaw SDK języka Python w wersji 1
Z tego artykułu dowiesz się, jak wytrenować model regresji za pomocą zestawu SDK języka Python usługi Azure Machine Learning przy użyciu zautomatyzowanego uczenia maszynowego azure Machine Learning. Ten model regresji przewiduje taryfy taksówek NYC.
Ten proces akceptuje dane treningowe i ustawienia konfiguracji i automatycznie wykonuje iterację za pomocą kombinacji różnych metod normalizacji/standaryzacji funkcji, modeli i ustawień hiperparametrów w celu uzyskania najlepszego modelu.
W tym artykule napiszesz kod przy użyciu zestawu SDK języka Python. Poznasz następujące zadania:
- Pobieranie, przekształcanie i czyszczenie danych przy użyciu usługi Azure Open Datasets
- Trenowanie modelu regresji zautomatyzowanego uczenia maszynowego
- Obliczanie dokładności modelu
W przypadku automatycznego uczenia maszynowego bez kodu wypróbuj następujące samouczki:
Wymagania wstępne
Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto. Wypróbuj bezpłatną lub płatną wersję usługi Azure Machine Learning dzisiaj.
- Ukończ przewodnik Szybki start: rozpocznij pracę z usługą Azure Machine Learning, jeśli nie masz jeszcze obszaru roboczego usługi Azure Machine Learning ani wystąpienia obliczeniowego.
- Po ukończeniu przewodnika Szybki start:
- Wybierz pozycję Notesy w programie Studio.
- Wybierz kartę Przykłady .
- Otwórz notes SDK w wersji 1/tutorials/regression-automl-nyc-taxi-data/regression-automated-ml.ipynb .
- Aby uruchomić każdą komórkę w samouczku, wybierz pozycję Sklonuj ten notes
Ten artykuł jest również dostępny w witrynie GitHub , jeśli chcesz uruchomić go we własnym środowisku lokalnym. Aby uzyskać wymagane pakiety,
- Zainstaluj pełnego
automl
klienta. - Uruchom polecenie ,
pip install azureml-opendatasets azureml-widgets
aby pobrać wymagane pakiety.
Pobieranie i przygotowywanie danych
Zaimportuj niezbędne pakiety. Pakiet Open Datasets zawiera klasę reprezentującą każde źródło danych (NycTlcGreen
na przykład), aby łatwo filtrować parametry daty przed pobraniem.
from azureml.opendatasets import NycTlcGreen
import pandas as pd
from datetime import datetime
from dateutil.relativedelta import relativedelta
Zacznij od utworzenia ramki danych do przechowywania danych taksówek. Podczas pracy w środowisku spoza platformy Spark platforma Open Datasets umożliwia pobieranie tylko jednego miesiąca danych w danym momencie z określonymi klasami w celu uniknięcia MemoryError
dużych zestawów danych.
Aby pobrać dane taksówek, iteracyjne pobierać jeden miesiąc w danym momencie, a przed dołączeniem go do green_taxi_df
losowo próbki 2000 rekordów z każdego miesiąca, aby uniknąć wydmuchania ramki danych. Następnie wyświetl podgląd danych.
green_taxi_df = pd.DataFrame([])
start = datetime.strptime("1/1/2015","%m/%d/%Y")
end = datetime.strptime("1/31/2015","%m/%d/%Y")
for sample_month in range(12):
temp_df_green = NycTlcGreen(start + relativedelta(months=sample_month), end + relativedelta(months=sample_month)) \
.to_pandas_dataframe()
green_taxi_df = green_taxi_df.append(temp_df_green.sample(2000))
green_taxi_df.head(10)
Vendorid | lpepPickupDatetime | lpepDropoffDatetime | pasażerCount | tripDistance | puLocationId | doLocationId | pickupLongitude | pickupLatitude | dropoffLongitude | ... | paymentType | fareAmount | Dodatkowych | mtaTax | improvementSurcharge | tipAmount | tollsAmount | ehailFee | totalAmount | tripType |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
131969 | 2 | 2015-01-11 05:34:44 | 2015-01-11 05:45:03 | 3 | 4.84 | Brak | Brak | -73.88 | 40.84 | -73.94 | ... | 2 | 15.00 | 0,50 | 0,50 | 0.3 | 0,00 | 0,00 | Nan | 16.30 |
1129817 | 2 | 2015-01-20 16:26:29 | 2015-01-20 16:30:26 | 1 | 0.69 | Brak | Brak | -73.96 | 40.81 | -73.96 | ... | 2 | 4.50 | 1,00 | 0,50 | 0.3 | 0,00 | 0,00 | Nan | 6.30 |
1278620 | 2 | 2015-01-01 05:58:10 | 2015-01-01 06:00:55 | 1 | 0,45 | Brak | Brak | -73.92 | 40.76 | -73.91 | ... | 2 | 4,00 | 0,00 | 0,50 | 0.3 | 0,00 | 0,00 | Nan | 4,80 |
348430 | 2 | 2015-01-17 02:20:50 | 2015-01-17 02:41:38 | 1 | 0,00 | Brak | Brak | -73.81 | 40.70 | -73.82 | ... | 2 | 12.50 | 0,50 | 0,50 | 0.3 | 0,00 | 0,00 | Nan | 13.80 |
1269627 | 1 | 2015-01-01 05:04:10 | 2015-01-01 05:06:23 | 1 | 0,50 | Brak | Brak | -73.92 | 40.76 | -73.92 | ... | 2 | 4,00 | 0,50 | 0,50 | 0 | 0,00 | 0,00 | Nan | 5,00 |
811755 | 1 | 2015-01-04 19:57:51 | 2015-01-04 20:05:45 | 2 | 1.10 | Brak | Brak | -73.96 | 40.72 | -73.95 | ... | 2 | 6.50 | 0,50 | 0,50 | 0.3 | 0,00 | 0,00 | Nan | 7,80 |
737281 | 1 | 2015-01-03 12:27:31 | 2015-01-03 12:33:52 | 1 | 0,90 | Brak | Brak | -73.88 | 40.76 | -73.87 | ... | 2 | 6.00 | 0,00 | 0,50 | 0.3 | 0,00 | 0,00 | Nan | 6.80 |
113951 | 1 | 2015-01-09 23:25:51 | 2015-01-09 23:39:52 | 1 | 3.30 | Brak | Brak | -73.96 | 40.72 | -73.91 | ... | 2 | 12.50 | 0,50 | 0,50 | 0.3 | 0,00 | 0,00 | Nan | 13.80 |
150436 | 2 | 2015-01-11 17:15:14 | 2015-01-11 17:22:57 | 1 | 1.19 | Brak | Brak | -73.94 | 40.71 | -73.95 | ... | 1 | 7.00 | 0,00 | 0,50 | 0.3 | 1,75 | 0,00 | Nan | 9.55 |
432136 | 2 | 2015-01-22 23:16:33 2015-01-22 23:20:13 1 0.65 | Brak | Brak | -73.94 | 40.71 | -73.94 | ... | 2 | 5,00 | 0,50 | 0,50 | 0.3 | 0,00 | 0,00 | Nan | 6.30 |
Usuń niektóre kolumny, których nie potrzebujesz do trenowania ani dodatkowego kompilowania funkcji. Automatyzacja uczenia maszynowego będzie automatycznie obsługiwać funkcje oparte na czasie, takie jak lpepPickupDatetime.
columns_to_remove = ["lpepDropoffDatetime", "puLocationId", "doLocationId", "extra", "mtaTax",
"improvementSurcharge", "tollsAmount", "ehailFee", "tripType", "rateCodeID",
"storeAndFwdFlag", "paymentType", "fareAmount", "tipAmount"
]
for col in columns_to_remove:
green_taxi_df.pop(col)
green_taxi_df.head(5)
Oczyszczanie danych
Uruchom funkcję w describe()
nowej ramce danych, aby wyświetlić podsumowanie statystyk dla każdego pola.
green_taxi_df.describe()
Vendorid | pasażerCount | tripDistance | pickupLongitude | pickupLatitude | dropoffLongitude | dropoffLatitude | totalAmount | month_num day_of_month | day_of_week | hour_of_day |
---|---|---|---|---|---|---|---|---|---|---|
count | 48000.00 | 48000.00 | 48000.00 | 48000.00 | 48000.00 | 48000.00 | 48000.00 | 48000.00 | 48000.00 | 48000.00 |
średnia | 1.78 | 1,37 | 2,87 | -73.83 | 40.69 | -73.84 | 40.70 | 14.75 | 6.50 | 15.13 |
odchylenie standardowe | 0,41 | 1,04 | 2,93 | 2.76 | 1,52 | 2.61 | 1.44 | 12.08 | 3.45 | 8.45 |
min | 1,00 | 0,00 | 0,00 | -74.66 | 0,00 | -74.66 | 0,00 | -300.00 | 1,00 | 1,00 |
25% | 2,00 | 1,00 | 1.06 | -73.96 | 40.70 | -73.97 | 40.70 | 7,80 | 3,75 | 8.00 |
50% | 2,00 | 1,00 | 1.90 | -73.94 | 40.75 | -73.94 | 40.75 | 11.30 | 6.50 | 15.00 |
75% | 2,00 | 1,00 | 3,60 | -73.92 | 40.80 | -73.91 | 40.79 | 17.80 | 9.25 | 22.00 |
max | 2,00 | 9.00 | 97.57 | 0,00 | 41.93 | 0,00 | 41.94 | 450.00 | 12.00 | 30.00 |
Na podstawie statystyk podsumowania widać, że istnieje kilka pól, które mają wartości odstające lub wartości, które zmniejszają dokładność modelu. Najpierw odfiltruj pola lat/długie, aby mieściły się w granicach obszaru Manhattan. Spowoduje to odfiltrowanie dłuższych przejazdów taksówką lub przejazdów odstających w odniesieniu do ich relacji z innymi funkcjami.
Dodatkowo odfiltruj tripDistance
pole, aby było większe niż zero, ale mniejsze niż 31 mil (odległość między dwiema parami lat/long). Eliminuje to długie przejazdy odstające, które mają niespójne koszty podróży.
Na koniec totalAmount
pole ma ujemne wartości taryf taksówek, które nie mają sensu w kontekście naszego modelu, a passengerCount
pole zawiera nieprawidłowe dane z minimalnymi wartościami równymi zero.
Odfiltruj te anomalie przy użyciu funkcji zapytań, a następnie usuń kilka ostatnich kolumn niepotrzebnych do trenowania.
final_df = green_taxi_df.query("pickupLatitude>=40.53 and pickupLatitude<=40.88")
final_df = final_df.query("pickupLongitude>=-74.09 and pickupLongitude<=-73.72")
final_df = final_df.query("tripDistance>=0.25 and tripDistance<31")
final_df = final_df.query("passengerCount>0 and totalAmount>0")
columns_to_remove_for_training = ["pickupLongitude", "pickupLatitude", "dropoffLongitude", "dropoffLatitude"]
for col in columns_to_remove_for_training:
final_df.pop(col)
Ponownie wywołaj describe()
dane, aby upewnić się, że czyszczenie działa zgodnie z oczekiwaniami. Masz teraz przygotowany i oczyszczony zestaw danych dotyczących taksówek, wakacji i pogody do użycia na potrzeby trenowania modelu uczenia maszynowego.
final_df.describe()
Konfigurowanie obszaru roboczego
Utwórz obiekt obszaru roboczego na podstawie istniejącego obszaru roboczego. Obszar roboczy to klasa, która akceptuje informacje o subskrypcji i zasobie platformy Azure. Tworzy ona również zasób w chmurze służący do monitorowania i śledzenia przebiegów modelu. Workspace.from_config()
Odczytuje plik config.json i ładuje szczegóły uwierzytelniania do obiektu o nazwie ws
. ws
jest używany w pozostałej części kodu w tym artykule.
from azureml.core.workspace import Workspace
ws = Workspace.from_config()
Podział danych na zestawy treningowe i testowe
Podziel dane na zestawy treningowe i testowe przy użyciu train_test_split
funkcji w bibliotece scikit-learn
. Ta funkcja dzieli dane na zestaw danych x (funkcje) na potrzeby trenowania modelu oraz zestaw danych y (wartości do przewidywania) na potrzeby testowania.
Parametr test_size
określa procent danych przydzielanych do testowania. Parametr random_state
ustawia inicjator do generatora losowego, dzięki czemu podziały testów pociągu są deterministyczne.
from sklearn.model_selection import train_test_split
x_train, x_test = train_test_split(final_df, test_size=0.2, random_state=223)
Celem tego etapu jest uzyskanie punktów danych do przetestowania ukończono modelu, które nie były używane do jego wytrenowania. Pozwoli to zmierzyć rzeczywistą dokładność.
Innymi słowy, dobrze wytrenowany model powinien umożliwiać dokładne prognozowanie na podstawie danych, które jeszcze się nie pojawiły. Masz teraz dane przygotowane do automatycznego trenowania modelu uczenia maszynowego.
Automatyczne trenowanie modelu
Aby przeprowadzić automatyczne trenowanie modelu, wykonaj następujące czynności:
- Zdefiniuj ustawienia przebiegu eksperymentu. Dołącz do konfiguracji dane treningowe i zmodyfikuj ustawienia, które sterują procesem treningu.
- Prześlij eksperyment do strojenia modelu. Po przesłaniu eksperymentu proces wykonuje iterację z użyciem różnych algorytmów uczenia maszynowego i ustawień hiperparametrycznych z uwzględnieniem zdefiniowanych ograniczeń. Na podstawie zoptymalizowanej metryki dokładności jest wybierany model o najlepszym dopasowaniu.
Definiowanie ustawień trenowania
Zdefiniuj parametr eksperymentu i ustawienia modelu na potrzeby trenowania. Wyświetl pełną listę ustawień. Przesłanie eksperymentu z tymi ustawieniami domyślnymi zajmie około 5–20 minut, ale jeśli chcesz skrócić czas wykonywania, zmniejsz experiment_timeout_hours
parametr .
Właściwość | Wartość w tym artykule | Opis |
---|---|---|
iteration_timeout_minutes | 10 | Limit czasu w minutach dla każdej iteracji. Zwiększ tę wartość w przypadku większych zestawów danych, które wymagają więcej czasu dla każdej iteracji. |
experiment_timeout_hours | 0.3 | Maksymalna ilość czasu w godzinach, przez jaką wszystkie połączone iteracji mogą potrwać przed zakończeniem eksperymentu. |
enable_early_stopping | Prawda | Flaga umożliwiająca wczesne zakończenie, jeśli wynik nie jest poprawiany w krótkim okresie. |
primary_metric | spearman_correlation | Metryka, który ma być optymalizowana. Na podstawie tej metryki zostanie wybrany model o najlepszym dopasowaniu. |
cechowanie | auto | Dzięki automatycznemu eksperymentowi można wstępnie przetworzyć dane wejściowe (obsługa brakujących danych, konwertowanie tekstu na liczbowe itp.) |
verbosity | logging.INFO | Steruje poziomem rejestrowania. |
n_cross_validations | 5 | Liczba podziałów krzyżowego sprawdzania poprawności w przypadku nieokreślenia danych weryfikacji. |
import logging
automl_settings = {
"iteration_timeout_minutes": 10,
"experiment_timeout_hours": 0.3,
"enable_early_stopping": True,
"primary_metric": 'spearman_correlation',
"featurization": 'auto',
"verbosity": logging.INFO,
"n_cross_validations": 5
}
Użyj zdefiniowanych ustawień trenowania jako **kwargs
parametru AutoMLConfig
do obiektu. Ponadto określ dane treningowe i typ modelu — w tym przypadku regression
.
from azureml.train.automl import AutoMLConfig
automl_config = AutoMLConfig(task='regression',
debug_log='automated_ml_errors.log',
training_data=x_train,
label_column_name="totalAmount",
**automl_settings)
Uwaga
Zautomatyzowane kroki przetwarzania wstępnego uczenia maszynowego (normalizacja funkcji, obsługa brakujących danych, konwertowanie tekstu na liczbę itp.) stają się częścią podstawowego modelu. W przypadku korzystania z modelu przewidywania te same kroki przetwarzania wstępnego stosowane podczas trenowania są automatycznie stosowane do danych wejściowych.
Trenowanie automatycznego modelu regresji
Utwórz obiekt eksperymentu w obszarze roboczym. Eksperyment działa jako kontener dla poszczególnych zadań. Przekaż zdefiniowany automl_config
obiekt do eksperymentu i ustaw dane wyjściowe, aby wyświetlić True
postęp podczas zadania.
Po uruchomieniu eksperymentu dane wyjściowe wyświetlane są na żywo w miarę uruchamiania eksperymentu. W każdej iteracji widać typ modelu, czas trwania i dokładność treningu. Pole BEST
umożliwia śledzenie najlepszego wyniku w uruchomionym treningu na podstawie typu metryki.
from azureml.core.experiment import Experiment
experiment = Experiment(ws, "Tutorial-NYCTaxi")
local_run = experiment.submit(automl_config, show_output=True)
Running on local machine
Parent Run ID: AutoML_1766cdf7-56cf-4b28-a340-c4aeee15b12b
Current status: DatasetFeaturization. Beginning to featurize the dataset.
Current status: DatasetEvaluation. Gathering dataset statistics.
Current status: FeaturesGeneration. Generating features for the dataset.
Current status: DatasetFeaturizationCompleted. Completed featurizing the dataset.
Current status: DatasetCrossValidationSplit. Generating individually featurized CV splits.
Current status: ModelSelection. Beginning model selection.
****************************************************************************************************
ITERATION: The iteration being evaluated.
PIPELINE: A summary description of the pipeline being evaluated.
DURATION: Time taken for the current iteration.
METRIC: The result of computing score on the fitted pipeline.
BEST: The best observed score thus far.
****************************************************************************************************
ITERATION PIPELINE DURATION METRIC BEST
0 StandardScalerWrapper RandomForest 0:00:16 0.8746 0.8746
1 MinMaxScaler RandomForest 0:00:15 0.9468 0.9468
2 StandardScalerWrapper ExtremeRandomTrees 0:00:09 0.9303 0.9468
3 StandardScalerWrapper LightGBM 0:00:10 0.9424 0.9468
4 RobustScaler DecisionTree 0:00:09 0.9449 0.9468
5 StandardScalerWrapper LassoLars 0:00:09 0.9440 0.9468
6 StandardScalerWrapper LightGBM 0:00:10 0.9282 0.9468
7 StandardScalerWrapper RandomForest 0:00:12 0.8946 0.9468
8 StandardScalerWrapper LassoLars 0:00:16 0.9439 0.9468
9 MinMaxScaler ExtremeRandomTrees 0:00:35 0.9199 0.9468
10 RobustScaler ExtremeRandomTrees 0:00:19 0.9411 0.9468
11 StandardScalerWrapper ExtremeRandomTrees 0:00:13 0.9077 0.9468
12 StandardScalerWrapper LassoLars 0:00:15 0.9433 0.9468
13 MinMaxScaler ExtremeRandomTrees 0:00:14 0.9186 0.9468
14 RobustScaler RandomForest 0:00:10 0.8810 0.9468
15 StandardScalerWrapper LassoLars 0:00:55 0.9433 0.9468
16 StandardScalerWrapper ExtremeRandomTrees 0:00:13 0.9026 0.9468
17 StandardScalerWrapper RandomForest 0:00:13 0.9140 0.9468
18 VotingEnsemble 0:00:23 0.9471 0.9471
19 StackEnsemble 0:00:27 0.9463 0.9471
Eksplorowanie wyników
Zapoznaj się z wynikami automatycznego trenowania za pomocą widżetu Jupyter. Widżet umożliwia wyświetlenie wykresu i tabeli wszystkich iteracji poszczególnych zadań wraz z metrykami dokładności trenowania i metadanymi. Ponadto można filtrować różne metryki dokładności niż podstawowa metryka za pomocą selektora listy rozwijanej.
from azureml.widgets import RunDetails
RunDetails(local_run).show()
Szczegóły
Pobieranie najlepszego modelu
Wybierz najlepszy model z iteracji. Funkcja get_output
zwraca najlepszy przebieg i dopasowany model dla ostatniego wywołania dopasowania. Za pomocą przeciążeń w systemie get_output
można pobrać najlepszy przebieg i dopasowany model dla dowolnej zarejestrowanej metryki lub określonej iteracji.
best_run, fitted_model = local_run.get_output()
print(best_run)
print(fitted_model)
Testowanie dokładności najlepszego modelu
Użyj najlepszego modelu, aby uruchomić przewidywania na zestawie danych testowych, aby przewidzieć opłaty za taksówkę. predict
Funkcja używa najlepszego modelu i przewiduje wartości y, koszt podróży z x_test
zestawu danych. Wyświetl pierwsze 10 wartości przewidywanego kosztu z zestawu y_predict
.
y_test = x_test.pop("totalAmount")
y_predict = fitted_model.predict(x_test)
print(y_predict[:10])
Oblicz wartość root mean squared error
dla wyników. Przekonwertuj ramkę y_test
danych na listę w celu porównania z przewidywanymi wartościami. Funkcja mean_squared_error
pobiera dwie tablice wartości i oblicza średnią wartość błędu kwadratowego między nimi. Wyciągnięcie pierwiastka kwadratowego z wyniku powoduje błąd w tych samych jednostkach co zmienna y koszt. Wskazuje w przybliżeniu, jak daleko przewidywania taryf taksówek pochodzą z rzeczywistych taryf.
from sklearn.metrics import mean_squared_error
from math import sqrt
y_actual = y_test.values.flatten().tolist()
rmse = sqrt(mean_squared_error(y_actual, y_predict))
rmse
Uruchom następujący kod, aby obliczyć średni błąd procentu bezwzględnego (MAPE) przy użyciu pełnych y_actual
zestawów danych.y_predict
Ta metryka oblicza wartości bezwzględne różnic między poszczególnymi wartościami przewidywanymi i rzeczywistymi oraz sumuje wszystkie różnice. Następnie wyraża tę sumę jako procent sumy wartości rzeczywistych.
sum_actuals = sum_errors = 0
for actual_val, predict_val in zip(y_actual, y_predict):
abs_error = actual_val - predict_val
if abs_error < 0:
abs_error = abs_error * -1
sum_errors = sum_errors + abs_error
sum_actuals = sum_actuals + actual_val
mean_abs_percent_error = sum_errors / sum_actuals
print("Model MAPE:")
print(mean_abs_percent_error)
print()
print("Model Accuracy:")
print(1 - mean_abs_percent_error)
Model MAPE:
0.14353867606052823
Model Accuracy:
0.8564613239394718
Z dwóch metryk dokładności przewidywania widać, że model jest dość dobry w przewidywaniu taryf taksówek z funkcji zestawu danych, zazwyczaj w zakresie +- 4,00 USD i około 15% błędów.
Tradycyjny proces opracowywania modelu uczenia maszynowego intensywnie korzysta z zasobów. Wymaga dużej wiedzy o danej dziedzinie oraz czasu, który trzeba poświęcić na uruchamianie kilkudziesięciu modeli i porównywanie ich wyników. Użycie automatycznego uczenia maszynowego jest doskonałym sposobem na szybkie przetestowanie wielu różnych modeli w danym scenariuszu.
Czyszczenie zasobów
Nie należy wykonywać tej sekcji, jeśli planujesz uruchamianie innych samouczków usługi Azure Machine Learning.
Zatrzymywanie wystąpienia obliczeniowego
Jeśli użyto wystąpienia obliczeniowego, zatrzymaj maszynę wirtualną, gdy nie używasz jej, aby zmniejszyć koszty.
W obszarze roboczym wybierz pozycję Obliczenia.
Z listy wybierz nazwę wystąpienia obliczeniowego.
Wybierz pozycję Zatrzymaj.
Gdy wszystko będzie gotowe do ponownego użycia serwera, wybierz pozycję Uruchom.
Usuń wszystko
Jeśli nie planujesz korzystać z utworzonych zasobów, usuń je, aby nie ponosić żadnych opłat.
- W witrynie Azure Portal na końcu z lewej strony wybierz pozycję Grupy zasobów.
- Wybierz utworzoną grupę zasobów z listy.
- Wybierz pozycję Usuń grupę zasobów.
- Wpisz nazwę grupy zasobów. Następnie wybierz pozycję Usuń.
Możesz też zachować grupę zasobów i usunąć jeden obszar roboczy. Wyświetl właściwości obszaru roboczego i wybierz pozycję Usuń.
Następne kroki
W tym artykule dotyczącym zautomatyzowanego uczenia maszynowego wykonaliśmy następujące zadania:
- Skonfigurowano obszar roboczy i przygotowano dane do eksperymentu.
- Przeprowadzono trenowanie przy użyciu zautomatyzowanego modelu regresji lokalnie z użyciem niestandardowych parametrów.
- Zbadano i przejrzano wyniki trenowania.