如何輕松檢查你的機(jī)器學(xué)習(xí)模型是否公平?
譯文【51CTO.com快譯】我們生活在日益分裂的世界。在世界上一些地區(qū),種族和性別之間的差異和不平等現(xiàn)象在加劇。用于建模的數(shù)據(jù)大體上體現(xiàn)了數(shù)據(jù)源。世界可能有偏見(jiàn),因此數(shù)據(jù)和模型可能會(huì)體現(xiàn)這一點(diǎn)。我們提出了一種方法,機(jī)器學(xué)習(xí)工程師可以輕松檢查模型是否有偏見(jiàn)?,F(xiàn)在我們的公平性工具僅適用于分類模型。
案例分析
為了表明dalex公平性模塊(https://dalex.drwhy.ai/)的功能,我們將使用著名的德國(guó)信貸數(shù)據(jù)集(https://archive.ics.uci.edu/ml/datasets/statlog+(german+credit+data)為每個(gè)信貸申請(qǐng)者賦予風(fēng)險(xiǎn)。這個(gè)簡(jiǎn)單的任務(wù)可能需要使用可解釋的決策樹(shù)分類器。
- # imports
- import dalex as dx
- import numpy as np
- from sklearn.compose import ColumnTransformer
- from sklearn.pipeline import Pipeline
- from sklearn.preprocessing import OneHotEncoder
- from sklearn.tree import DecisionTreeClassifier
- # credit data
- data = dx.datasets.load_german()
- # risk is the target
- X = data.drop(columns='risk')
- y = data.risk
- categorical_features = ['sex', 'job', 'housing', 'saving_accounts', "checking_account", 'purpose']
- categorical_transformer = Pipeline(steps=[
- ('onehot', OneHotEncoder(handle_unknown='ignore'))
- ])
- preprocessor = ColumnTransformer(transformers=[
- ('cat', categorical_transformer, categorical_features)
- ])
- clf = Pipeline(steps=[
- ('preprocessor', preprocessor),
- ('classifier', DecisionTreeClassifier(max_depth=7, random_state=123))
- ])
- clf.fit(X, y)
- exp = dx.Explainer(clf, X, y)
一旦有了dx.Explainer,我們需要執(zhí)行方法model_fairness(),以便它可以利用protected矢量來(lái)計(jì)算子組中的所有必要度量,該矢量是一個(gè)數(shù)組或列表,列出了表明每一個(gè)觀察對(duì)象(個(gè)人)的性別、種族或國(guó)籍等方面的敏感屬性。除此之外,我們需要指出哪個(gè)子組(即protected的哪個(gè)獨(dú)特元素)具有最高特權(quán),這可以通過(guò)privileged參數(shù)來(lái)完成,本例中將是較年長(zhǎng)男性。
- # array with values like male_old, female_young, etc.
- protected = data.sex + '_' + np.where(data.age < 25, 'young', 'old')
- privileged = 'male_old'
- fobject = exp.model_fairness(protected = protected, privileged=privileged)
該對(duì)象有許多屬性,我們不會(huì)遍歷每一個(gè)屬性,而是著重介紹一種方法和兩個(gè)圖。
那么,我們的模型是否有偏見(jiàn)?
這個(gè)問(wèn)題很簡(jiǎn)單,但由于偏見(jiàn)的性質(zhì),答案將是要看情況。但是這種方法從不同的視角來(lái)度量偏見(jiàn),因此確保沒(méi)有任何有偏見(jiàn)的模型是漏網(wǎng)之魚(yú)。要檢查公平性,就得使用fairness_check()方法。
- fobject.fairness_check(epsilon = 0.8) # default epsilon
以下內(nèi)容是來(lái)自上述代碼的控制臺(tái)輸出。
- Bias detected in 1 metric: FPR
- Conclusion: your model cannot be called fair because 1 metric score exceeded acceptable limits set by epsilon.
- It does not mean that your model is unfair but it cannot be automatically approved based on these metrics.
- Ratios of metrics, based on 'male_old'. Parameter 'epsilon' was set to 0.8 and therefore metrics should be within (0.8, 1.25)
- TPR ACC PPV FPR STP
- female_old 1.006508 1.027559 1.000000 0.765051 0.927739
- female_young 0.971800 0.937008 0.879594 0.775330 0.860140
- male_young 1.030369 0.929134 0.875792 0.998532 0.986014
FPR(誤報(bào)率)這個(gè)度量發(fā)現(xiàn)了偏見(jiàn)。上述輸出表明無(wú)法自動(dòng)批準(zhǔn)模型(如上述輸出中所述),因此得由用戶來(lái)決定。我認(rèn)為這不是公平的模型。較低的FPR意味著特權(quán)子組比無(wú)特權(quán)子組更容易出現(xiàn)誤報(bào)。
詳述fairness_check()
我們獲得有關(guān)偏見(jiàn)、結(jié)論和度量比率原始DataFrame的信息。有幾個(gè)度量:TPR(正陽(yáng)性率)、ACC(準(zhǔn)確度)、PPV(陽(yáng)性預(yù)測(cè)值)、FPR(假陽(yáng)性率)和STP(統(tǒng)計(jì)奇偶性)。這些度量來(lái)自每個(gè)無(wú)特權(quán)子組的混淆矩陣(https://en.wikipedia.org/wiki/Confusion_matrix),然后除以基于特權(quán)子組的度量值。有三種可能的結(jié)論:
- # not fair
- Conclusion: your model is not fair because 2 or more metric scores exceeded acceptable limits set by epsilon.
- # neither fair or not
- Conclusion: your model cannot be called fair because 1 metric score exceeded acceptable limits set by epsilon.It does not mean that your model is unfair but it cannot be automatically approved based on these metrics.
- # fair
- Conclusion: your model is fair in terms of checked fairness metrics.
DA真正公平模型不會(huì)超出任何度量,但是當(dāng)真實(shí)值(目標(biāo))依賴敏感屬性時(shí),事情會(huì)變得復(fù)雜,并超出本文探討的范圍。簡(jiǎn)而言之,一些度量會(huì)不一樣,但不一定會(huì)超出用戶的閾值。如果您想了解更多,建議您閱讀《公平性和機(jī)器學(xué)習(xí)》一書(shū)(https://fairmlbook.org/),尤其是第二章。
但有人會(huì)問(wèn):為何我們的模型不公平?我們基于什么依據(jù)來(lái)決定?
回答這個(gè)問(wèn)題很棘手,但到目前為止判斷公平性的方法似乎是最佳方法。每個(gè)子組的分?jǐn)?shù)通常應(yīng)接近特權(quán)子組的分?jǐn)?shù)。從數(shù)學(xué)的角度來(lái)看,特權(quán)度量和無(wú)特權(quán)度量的分?jǐn)?shù)之間的比率應(yīng)接近1。該值越接近1,表明模型越公平。但為了稍微放寬該標(biāo)準(zhǔn),這樣表述更合理:
其中ε是介于0和1之間的值,它應(yīng)該是該比率的最小可接受值。默認(rèn)情況下,它是0.8,遵循招聘中常見(jiàn)的五分之四規(guī)則(80%規(guī)則)。很難在度量的公平和歧視差異之間找到一個(gè)非任意邊界;檢查度量的比率是否恰好為1毫無(wú)意義,因?yàn)槿绻嚷蕿?.99會(huì)怎樣? 這就是為什么我們決定選擇0.8作為默認(rèn)的ε,因?yàn)閷?duì)于可接受的歧視程度而言,它是有形閾值的唯一已知值。當(dāng)然,用戶可以根據(jù)需要更改這個(gè)值。
偏見(jiàn)也可以繪出來(lái)
有兩個(gè)偏見(jiàn)檢測(cè)圖可用(不過(guò)有更多的方法可以直觀顯示偏見(jiàn))。
- fairness_check——直觀顯示fairness_check()方法
- metric_scores——直觀顯示metric_scores屬性,它是度量的原始分?jǐn)?shù)。
類型只需傳遞到plot方法的type參數(shù)。
- fbject.plot()
上圖顯示了與公平性檢查輸出相似的內(nèi)容。度量名已改成更標(biāo)準(zhǔn)的公平性等效項(xiàng),但是公式指出了我們引用的度量。上圖很直觀:如果條柱到達(dá)紅色區(qū)域,表示度量超出基于ε的范圍。條柱長(zhǎng)度等效于| 1-M |,其中M是無(wú)特權(quán)度分?jǐn)?shù)除以特權(quán)度量分?jǐn)?shù)(因此就像之前的公平性檢查一樣)。
- fobject.plot(type=’metric_scores’)
度量分?jǐn)?shù)圖輔以公平性檢查很好地表明了度量及其比率。在這里,這些點(diǎn)是原始的度量分?jǐn)?shù)。垂直線表示特權(quán)度量分?jǐn)?shù)。離那條線越近越好。
可以將多個(gè)模型放在一個(gè)圖中,以便輕松相互比較。不妨添加幾個(gè)模型,直觀顯示metric_scores:
- from sklearn.ensemble import RandomForestClassifier
- from sklearn.linear_model import LogisticRegression
- from sklearn.preprocessing import StandardScaler
- # create models
- numeric_features = ['credit_amount', 'duration', 'age']
- numeric_transformer = Pipeline(steps=[
- ('scaler', StandardScaler())])
- categorical_transformer = Pipeline(steps=[
- ('onehot', OneHotEncoder(handle_unknown='ignore'))])
- preprocessor = ColumnTransformer(
- transformers=[
- ('cat', categorical_transformer, categorical_features),
- ('num', numeric_transformer, numeric_features)])
- clf_forest = Pipeline(steps=[('preprocessor', preprocessor),
- ('classifier', RandomForestClassifier(random_state=123, max_depth=4))]).fit(X,y)
- clf_logreg = Pipeline(steps=[('preprocessor', preprocessor),
- ('classifier', LogisticRegression(random_state=123))]).fit(X,y)
- # create Explainer objects
- exp_forest = dx.Explainer(clf_forest, X,y, verbose = False)
- exp_logreg = dx.Explainer(clf_logreg, X,y, verbose = False)
- # create fairness explanations
- fobject_forest = exp_forest.model_fairness(protected, privileged)
- fobject_logreg = exp_logreg.model_fairness(protected, privileged)
- # lets see their metric scores
- fobject.plot(objects=[fobject_forest, fobject_logreg], type = "metric_scores")
上述代碼的輸出。
現(xiàn)在不妨檢查基于fairness_check的圖:
我們可以看到RandomForestClassifier在綠色區(qū)域內(nèi),因此就這些度量而言,它是公平的。另一方面,LogisticRegression在三個(gè)度量方面抵達(dá)紅色區(qū)域,因此不能稱之為公平的。
每個(gè)圖都是交互式的,是使用python可視化包plotly繪制的。
結(jié)語(yǔ)
dalex中的公平性模塊是確保模型公平的統(tǒng)一且可訪問(wèn)的方法。還有其他方法可以直觀顯示模型偏見(jiàn),請(qǐng)務(wù)必查看一下!將來(lái)會(huì)增加緩解偏見(jiàn)的方法。長(zhǎng)期計(jì)劃是增添對(duì) individual fairness和 fairness in regression的支持。
務(wù)必看一下。您可以使用以下命令來(lái)安裝dalex:
- pip install dalex –U
原文標(biāo)題:How to easily check if your Machine Learning model is fair?,作者:Jakub Wiśniewski
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】