Strona korzysta z plików cookies w celu realizacji usług i zgodnie z Polityką Plików Cookies.



01.12.2022

Wyższy poziom programowania

Progress oferuje nowe narzędzia programistyczne: Progress Telerik, Progress Kendo UI i...
01.12.2022

Łączność w podróży

VMware SD-WAN VMware zaprezentował rozwiązanie SD-WAN nowej generacji, w tym nowego...
01.12.2022

Bezpieczne e-maile

Nowa aplikacja firmy Cypherdog Security Inc. umożliwia bezpieczną wymianę maili i...
01.12.2022

Pierwszy w branży

Schneider Electric wprowadza na rynek APC Smart-UPS Ultra. To pierwszy w branży...
01.12.2022

Przełączniki 10G dla MŚP

Nowe urządzenia to przełączniki 10G kompatybilne z systemem Omada SDN.
01.12.2022

Zarządzanie danymi

Firma Synology wprowadziła na rynek czterokieszeniowy DiskStation DS923+.
01.12.2022

Nowatorski system chłodzenia

OVHcloud zaprezentował nową, autorską technologię hybrydowego zanurzeniowego chłodzenia...
01.12.2022

Linia smart routerów

D-Link zaprezentował najnowszą rodzinę routerów Smart Wi-Fi z algorytmami sztucznej...
04.11.2022

Nowa platforma Red Hat

Nowa platforma Red Hat Enterprise Linux (RHEL) w wersjach 8.7 i 9.1 Beta obsługuje...

Analiza predykcji i ocena uczciwości modeli uczenia maszynowego przy użyciu Responsible AI Widgets

Data publikacji: 04-01-2022 Autor: Marcin Szeliga

W poprzedniej części cyklu opisane zostało użycie widżetu ErrorAnalysisDashboard w celu lepszego zrozumienia danych, popełnianych przez model błędów oraz interpretacji predykcji. W tym artykule przyjrzymy się dokładniej kwestii interpretowalności modeli uczenia maszynowego (ML) przy użyciu widżetu ExplanationDashboard i zastanowimy się nad sposobami oceny i poprawy uczciwości (rozumianej jako bezstronność) modeli. Posłuży nam do tego widżet FairnessDashboard. Wszystkie trzy widżety wchodzą w skład zestawu narzędzi Responsible AI Widgets.

 

Z budowanie dobrego, tj. dokładnego modelu uczenia maszynowego, już nie wystarcza. Dziś coraz większy nacisk kładzie się na odpowiedzialność rozumianą jako bezpieczeństwo modeli (niepodatność na ataki), ich bezstronność (niedyskryminowanie pewnych grup użytkowników), interpretowalność (możliwość wyjaśnienia predykcji) oraz poufność danych treningowych i testowych. Zanim wdrożymy nasz model do użycia, powinniśmy mu się dokładnie przyjrzeć i zadbać o najwyższy poziom wszystkich wymienionych czynników.

 

> Modelowanie


Do samodzielnego przeprowadzania opisanego eksperymentu potrzebować będziemy czterech bibliotek Pythona: lightgbm (do zbudowania modelu uczenia maszynowego), fairlearn (do oceny bezstronności modeli), interpret-community (do analizy predykcji) i raiwidgets (to opisywany zestaw narzędzi Responsible AI Widgets). Zainstalujemy je, wykonując poniższe instrukcje:


pip install --upgrade fairlearn
pip install --upgrade interpret-community
pip install --upgrade raiwidgets
pip install --upgrade lightgbm


Model został nauczony na przykładowych – wchodzących w skład biblioteki fairnlear – danych Census (tab. 1). Poniższe instrukcje ładują ten zbiór danych i dzielą go na zmienne wejściowe (X_raw) i wyjściową (y_raw):


from fairlearn.datasets import fetch_adult
dataset = fetch_adult(as_frame=True)
X_raw, y_raw = dataset[‚data’], dataset[‚target’]
X_raw


Tym razem zmienną wyjściową potraktujemy jako opisującą zgodę lub odmowę na udzielenie danej osobie pożyczki – taka jej interpretacja lepiej pasuje do tematu artykułu. Dodatkowo zdefiniujemy dwie wrażliwe zmienne, tj. zmienne, dla których chcemy ocenić i poprawić bezstronność modelu. Powiedzmy, że chcemy się upewnić, że nasz model nie dyskryminuje osób na podstawie ich płci lub rasy:

 

sensitive_features = X_raw[[‘sex’,’race’]]
sensitive_features


Zmienna wyjściowa musi zostać przekształcona do formatu kompatybilnego z biblioteką uczenia maszynowego, możemy to zrobić następująco:


from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y = le.fit_transform(y_raw)


Ostatnim etapem przygotowania danych jest ich podzielenie na zbiór treningowy (zawierający 90% obserwacji) i testowy (zawierający pozostałe 10% obserwacji). Użyta metoda podziału warstwowego zagwarantuje nam taki sam rozkład wartości zmiennej y w obu podzbiorach:


from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test, sensitive_features_train, sensitive_features_test =
train_test_split(X_raw, y, sensitive_features,
test_size = 0.1, random_state=0, stratify=y)
# Work around indexing bug
X_train = X_train.reset_index(drop=True)
sensitive_features_train = sensitive_features_train.reset_index(drop=True)
X_test= X_test.reset_index(drop=True)
sensitive_features_test = sensitive_features_test.reset_index(drop=True)


Możemy już zdefiniować potok ML. Jego pierwszy krok przygotuje dane (uzupełni brakujące wartości, przeskaluje zmienne numeryczne i zakoduje zmienne kategoryczne), a drugi wytrenuje model maszyny wzmacniania gradientu – ten algorytm i jego hiperparametry zostały wcześniej znalezione przy użyciu biblioteki automatycznego uczenia maszynowego FLAML:


from sklearn.compose import ColumnTransformer, make_column_selector
from sklearn.preprocessing import LabelEncoder,StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
import lightgbm as lgb
numeric_transformer = Pipeline(
steps=[
(“impute”, SimpleImputer()),
(“scaler”, StandardScaler()),
]
)
categorical_transformer = Pipeline(
[
(“impute”, SimpleImputer(strategy=”most_frequent”)),
(“ohe”, OneHotEncoder(handle_unknown=”ignore”)),
]
)
preprocessor = ColumnTransformer(
transformers=[
(“num”, numeric_transformer,
make_column_selector(dtype_exclude=”category”)),
(“cat”, categorical_transformer,
make_column_selector(dtype_include=”category”)),
]
)
model = Pipeline(
steps=[
(“preprocessor”, preprocessor),
(“classifier”, lgb.LGBMClassifier(colsample_bytree=0.6649148062238498,
learning_rate=0.17402065726724145, max_bin=255,
min_child_samples=3, n_estimators=189, num_leaves=20,
reg_alpha=0.0009765625, reg_lambda=0.006761362450996487),
),
]
)


Tak przygotowany model możemy już uczyć. Proszę jednak zwrócić uwagę, że do uczenia używamy oryginalnego zbioru treningowego, ale model uczony jest na danych przekształconych przez pierwszy krok potoku ML:


model.fit(X_train,y_train)

 

> Interpretacja predykcji

 

Modele uczenia maszynowego nie powinny być traktowane jak czarne skrzynki – funkcje, których działania nikt nie rozumie i które zwracają wyniki w sposób magiczny. Niestety modele bywają bardzo skomplikowane, a wyjaśnienie ich wyników w kontekście danych wejściowych bywa trudne. Problem ten rozwiązuje się na dwa sposoby: 1) używając do treningu interpretowalnych algorytmów uczenia maszynowego (szklanych modeli), 2) tworząc interpretatory modeli czarnej skrzynki. Pierwsze rozwiązanie jest szybkie i dostarcza dokładnych interpretacji. Drugie jest elastyczne (możemy korzystać z dowolnych algorytmów uczenia maszynowego), ale jest wolniejsze i daje mniej dokładne interpretacje. My zastosujemy drugie podejście i utworzymy interpretator wytrenowanego modelu (zwróconego przez wyrażenie

 

model.steps[-1][1]):
from interpret.ext.blackbox import MimicExplainer
from interpret.ext.glassbox import LGBMExplainableModel
explainer = MimicExplainer(model.steps[-1][1],
X_train,
LGBMExplainableModel,
features=X_raw.columns,
classes=[‘Rejected’, ‘Approved’],
transformations=preprocessor)


Użyta biblioteka Interpret-Community (bit.ly/3Gt0c3v) zawiera kilka interpretatorów modeli o nieznanej, dowolnej architekturze, w tym dwa najpopularniejsze: Shapely Additive Explanations (SHAP) oraz Local Interpretable Model-Agnostic Explanations (LIME). Pierwszy algorytm został zaimplementowany w module TabularExplainer, drugi – w module MimicExplainer.


Działanie algorytmu SHAP polega na porównywaniu jakości modeli uczonych na wybranych kombinacjach zmiennych wejściowych. Jeżeli usunięcie zmiennej z danych treningowych miało niewielki wpływ na jakość modelu, to przydatność (siła predykcyjna) tej zmiennej była niewielka. Takie podejście sprawdza się najlepiej do wyjaśniania modeli uczonych na niewielkiej liczbie zmiennych wejściowych.


Działanie wybranego w tym wypadku algorytmu LIME (po zakodowaniu zmiennych kategorycznych nasz model był trenowany na ponad 100 zmiennych) polega na zbudowaniu uproszczonego, interpretowalnego modelu, którego predykcje są zbliżone do predykcji wyjaśnianego modelu. W tym celu wybierana jest pewna liczba obserwacji zbliżonych do wyjaśnianej. Wagi tych obserwacji zostają ustalone na podstawie ich odległości od wyjaśnianej obserwacji, odczytywane są predykcje zwrócone przez wyjaśniany model dla tych obserwacji i uczony jest interpretowalny model na tych ważonych obserwacjach.


Następnie obliczony został globalny wpływ zmiennych na predykcje modelu, w tym celu użyto tysiąca obserwacji testowych:


global_explanation = explainer.explain_global(X_test[:1000])
print(‘global importance rank:
{}’.format(global_explanation.get_feature_importance_dict()))
---
global importance rank: {‘marital-status’: 1.373580583366491, ‘age’:
0.522131397533456, ‘education-num’: 0.5198770111388555, ‘capital-gain’:
0.4854105136871302, ‘hours-per-week’: 0.2717721671482566, ‘occupation’: '
0.22331647731828086, ‘capital-loss’: 0.14121049724699203, ‘relationship’: '
0.10204537767350337, ‘sex’: 0.09918709724845973, ‘race’: 0.04508025344908681,
‘fnlwgt’: 0.04487749775618806, ‘workclass’: 0.040517478245184514,
‘native-country’: 0.033797037377133334, ‘education’: 0.006906780485538252}


Okazuje się, że największy wpływ na decyzję o przyznaniu lub odmowie pożyczki mają kolejno: stan cywilny, wiek, wykształcenie i zgromadzony kapitał.

 

[...]

 

Pracownik naukowy Wyższej Szkoły Bankowej w Poznaniu Wydział Zamiejscowy w Chorzowie, jest autorem książek poświęconych analizie danych i posiada tytuł Microsoft Most Valuable Professional.

Pełna treść artykułu jest dostępna w papierowym wydaniu pisma.

prenumerata Numer niedostępny Spis treści

.

Transmisje online zapewnia: StreamOnline

All rights reserved © 2019 Presscom / Miesięcznik \"IT Professional\"