Когато Кас Сънщайн, Даниел Канеман и Оливие Сибони издадоха книгата си „Шум: Грешка в човешката преценка“, те се докоснаха до една неудобна истина: хората са удивително непоследователни хора, които вземат решения. В резюме, публикувано в Harvard Business Review, авторите споделят как преценките на широк кръг от професионалисти, от „оценители в агенции за кредитен рейтинг, лекари в спешни отделения, застрахователи на заеми и застраховки“ са били „силно повлияни от неуместни фактори, като текущото им настроение, времето от последното им хранене и времето“.

Книгата предлага лекарство - разчитайте повече на алгоритми, които са безшумни. И все пак, както запознатите с изчислителните системи знаят, алгоритмите, особено тези, които разчитат на вероятностно машинно обучение, не са нито напълно последователни, нито свободни от пристрастия. Всъщност, когато бъдат разгърнати, алгоритмичните системи често завършват с кодиране и изостряне на съществуващите пристрастия и неравенства в обществото.

Има много добра работа за това как да се измери модел на машинно обучение за отклонение, вижте тук за пример.

Въпреки това, това, което искаме да направим в тази публикация, е да подчертаем друго измерение за смекчаване на пристрастията – как да проектираме готова за производство система, която може надеждно да приведе в действие тези техники за смекчаване на пристрастията. Както е „споменато“ от изследователското звено за изкуствен интелект на FICO:

„Налагането на справедливост за готови за производство ML системи във Fintech изисква специфични инженерни ангажименти на различни етапи от жизнения цикъл на ML системата“

Ще се съсредоточим върху кредитния рейтинг като примерен случай на употреба, въпреки че подобни принципи могат да бъдат приложени и към други случаи на употреба.

Готови за производство етични системи за машинно обучение с Delta, Databricks Feature Store и MLFlow.

Система за машинно обучение в производство, която се стреми да проследява и смекчава пристрастията, трябва да има няколко функции, включени в нея, които сме посочили по-долу. Първо, системата трябва да бъде възпроизводима, за да бъде преразгледана и одитирана в бъдеще. Това означава, че параметрите, кодът, функциите и източниците на данни, необходими за обучение и възпроизвеждане на модела, са достъпни.

Второ, показателите за справедливост трябва да се проследяват и да се използват за информиране дали моделът е готов за внедряване или не. Освен това всички защитени променливи, които са включени, например пол и раса, се наблюдават по подходящ начин. Това гарантира, че разработчиците на модели са напълно наясно с ефекта, който тези променливи имат върху техните модели, и могат да вземат решение за подходящи компромиси между производителността на модела, бизнес печалбите и справедливостта.

И накрая, моделите се внедряват и дори моделите, които са архивирани, трябва да могат да се търсят за целите на одита.

Диаграмата по-долу показва как може да изглежда такава система на Databricks:

Преглед на случая на употреба

За нашия пример ще работим с класификационен модел, изграден с набора от данни за кредитна карта от UCI Machine Learning Repository. Този „набор от данни“ съдържа информация за плащания по подразбиране, демографски фактори, кредитни данни, история на плащанията и извлечения за сметки на клиенти с кредитни карти в Тайван от април 2005 г. до септември 2005 г.

Ще използваме този набор от данни, за да обучим двоичен класификатор, който прогнозира дали клиентът няма да изпълни плащането си с кредитна карта през следващия месец или не. В реалния свят това може да е вид модел, който обикновено би повлиял на процеса на вземане на решение за заем или кредитен рейтинг.

Пълният код на този пример може да бъде намерен от това Хранилище на Github.

Магазин за функции

На този етап вече сме погълнали нашите данни в бронзовия слой и сме извършили известно почистване на данни. Сега ще извлечем две функции от нашия оригинален набор от данни и ще съхраним тези характеристики в таблица за хранилище на функции.

За колоните PAY_*, (-2=няма кредит за плащане, -1=платете надлежно, 0=покриване на минималното плащане, 1=забавяне на плащането за един месец, 2=забавяне на плащането за два месеца, … 8=забавяне на плащането за осем месеца, 9=забавяне на плащане за девет месеца и повече), ние създаваме функция, наречена num_paym_unmet, която обобщава общия брой пъти за 6 месеца, когато клиент е имал забавено плащане

Ние също така създаваме втора функция, наречена num_paym_met, която обобщава общия брой пъти за 6 месеца, когато клиентът е изпълнил своите задължения за плащане

def num_paym_unmet_fn(df):
  """
  sums up the total number of times, over 6 months, that a customer had a delayed payment
  """
  def count_unmet(col):
    return F.when(F.col(col) > 0, 1).otherwise(0)
  feature_df = df[["USER_ID", "PAY_1", "PAY_2", "PAY_3", "PAY_4", "PAY_5", "PAY_6"]]
  feature_df = feature_df.withColumn("NUM_PAYM_UNMET", reduce(add, [count_unmet(x) for x in silver.columns if x in pay_cols])) \
.select("USER_ID", "NUM_PAYM_UNMET")
  return feature_df

def num_paym_met_fn(df):
  """
  sums up the total number of times, over 6 months, that a customer met their payment obligations
  """
  def count_met(col):
    return F.when(F.col(col) <= 0, 1).otherwise(0)
  feature_df = df[["USER_ID", "PAY_1", "PAY_2", "PAY_3", "PAY_4", "PAY_5", "PAY_6"]]
  feature_df = feature_df.withColumn("NUM_PAYM_MET", reduce(add, [count_met(x) for x in silver.columns if x in pay_cols])) \
.select("USER_ID", "NUM_PAYM_MET")
  return feature_df

num_paym_unmet_feature = num_paym_unmet_fn(silver)
num_paym_met_feature = num_paym_met_fn(silver)

По-късно, чрез регистриране и обслужване на нашия модел като модел на хранилище на функции, същата логика на представяне ще бъде приложена по време на обучение и обслужване, което минимизира риска от изкривяване при обслужване на обучение.

Проследяване на показатели за справедливост

Налични са множество пакети с отворен код за измерване на показателите за справедливост, например Fairlearn на Microsoft и Model Cards на Google. В този пример ще използваме пакета с отворен код Veritas, пуснат от Monetary Authority на Сингапур, тъй като той е пример, показващ как да се включат съображения за справедливост в производствена система въз основа на препоръки и инструменти, създадени от действителен финансов регулатор.

За да използваме този пакет, ние първо дефинираме това, което наричаме защитени променливи, които са входни характеристики, които не трябва да променят неоправдано нашия модел. Тук задаваме ПОЛА и семейното положение на дадено лице като защитени променливи. В рамките на тези защитени променливи ние също избираме кои са привилегированите групи. В случая на променливата SEX това е сегментът „мъж“, а в случая на променливата БРАК това е сегментът „женен“.

p_var = ['SEX', 'MARRIAGE']
p_grp = {'SEX': [1], 'MARRIAGE':[1]}

След инициализиране на mlflow експеримент с mlflow.start_run(), предаваме данните за обучение, защитените променливи и групи и нашия модел в обекта на контейнера на модела. След това уточняваме, че искаме да използваме този обект за оценка на кредитен рейтинг и предаваме показателите, върху които искаме да се фокусираме, в този обект.

cre_sco_obj= CreditScoring(model_params = [container], fair_threshold = 0.43, fair_concern = “eligible”, fair_priority = “benefit”, fair_impact = “significant”, perf_metric_name = “balanced_acc”, fair_metric_name = “equal_opportunity”)```

Извикването на метода evaluate на този обект на CreditScoring ще генерира отчети и оценки, ориентирани към справедливост, които можем да запазим като mlflow.artifacts за анализиране по-късно.

cre_sco_obj.evaluate()
cre_sco_obj.tradeoff(output=False)
mlflow.log_artifact("/dbfs/FileStore/fairness_artifacts/cre_sco_obj.pkl")
mlflow.log_dict(cre_sco_obj.fair_conclusion, "fair_conclusion.json")
mlflow.log_dict(cre_sco_obj.get_fair_metrics_results(), "fair_metrics.json")
mlflow.log_dict(cre_sco_obj.get_perf_metrics_results(), "perf_metrics.json")
mlflow.log_dict(get_tradeoff_metrics(cre_sco_obj), "tradeoff.json")

И така, на този етап успяхме да покрием аспекта на възпроизводимостта на готова за производство система за кредитен скоринг. Наличието на възпроизводима система означава, че процесът на обучение на нашия модел е прозрачен и подлежи на одит от регулаторите.

Но процесът на производство не завършва на етапа на обучение на модела. В този момент инженерът по Data Science или Machine Learning обикновено ще прехвърли модел в етапна среда, ще изпълни проверки и валидиране в етапа, преди да прехвърли модела в производство. За нашето приложение искаме да се съсредоточим върху проверките, свързани с честността на нашия модел. Проверката на нашия модел, преди да бъде разгърнат, ни позволява да избегнем неволно прилагане на модел, който поставя в неравностойно положение определени групи.

За да автоматизираме този процес, ние използваме Databricks Model Registry Webhooks

Настройка на работа и HTTP Webhook

Уеб куките за работа ни позволяват да задействаме работа за бележник, когато се направи заявка за преход на модел от регистъра на моделите MLFlow

В нашия случай настройваме HTTP уебкукичка, за да ни даде Slack известие, когато се направи заявка за преход. Ние също така настроихме Job Webhook, който задейства задание за бележник, за да генерира отчет за справедливост

Преход (базиран на UI)

И така, сега сме обучили модел, регистрирали сме го и сме настроили нашите уеб кукички, ще продължим да правим заявка за прехвърляне на модела към ПРОИЗВОДСТВО.

След това това трябва да задейства нашия бележник за валидиране на справедливост да работи като автоматизирана работа.

Сега ще се поставя на мястото на одобряващ модел, който трябва да валидира изхода на тестовия бележник. Например, нашият бележник може да извежда различни показатели за ефективност за оценка.

Работа с бележник за валидиране на справедливост

Така че нека разгледаме малко по-задълбочено какви оценки на справедливостта можем да извършим за нашия модел

Паритет

Можем да анализираме нашия модел въз основа на определени показатели за справедливост, като демографски паритет, равни възможности и равни шансове. Тук разглеждаме разликите в тези показатели за непривилегированата група спрямо привилегированата група.

Наистина, въпреки че сега ръчно оценяваме тази диаграма, част от този процес на валидиране може да бъде автоматизиран. Например задаваме тестове, за да се уверим, че нашите мерки за паритет не надхвърлят определен праг, и запазваме резултатите от този тест като тагове на модела „mlflow“, към които можем да се позоваваме в потребителския интерфейс на регистъра на модела MLFlow

for p in pvars:
  if all(df[df['protected_var']==p]['parity'] > 0.1) == False:
    client.set_model_version_tag(name=dict["model_name"], version=dict["version"], key=f"parity_check_{p}", value=1)
    print("Parity checks passed")
  else:
    client.set_model_version_tag(name=dict["model_name"], version=dict["version"], key=f"parity_check_{p}", value=0)

Компромис между производителност и справедливост

Какви компромиси за производителността можем да очакваме, ако калибрираме нашия модел според ограниченията за справедливост? Това са доклади, които можем да предоставим на нашите бизнес МСП

И накрая, запазваме метаданни около историята на внедряване на нашия модел в отделна таблица, за да можем да проследим тази информация, ако трябва да одитираме модела.

Заключение

Има много методи за измерване и смекчаване на отклоненията в системите за машинно обучение, нещо, което също разгледахме в друга публикация. Все още обаче остават допълнителни предизвикателства. По-специално те включват гарантиране, че показателите за справедливост на системата са количествено определени и внимателно проследени по време на обучението и предварителното внедряване и където целият жизнен цикъл на модела е възпроизводим и подлежи на одит. Само когато тези предизвикателства бъдат адресирани, можем да преминем към системи за машинно обучение, които са справедливи към групите, към които се прилагат.