Main Content

fairnessThresholder

公平性を含めるための分類しきい値の最適化

R2023a 以降

    説明

    fairnessThresholder は、公平性の範囲を満たしながら精度が最大になるように最適なスコアのしきい値を探します。最適なしきい値を下回る臨界領域の観測値については、センシティブ属性の参照グループと非参照グループで公平性の制約が保たれるように関数でラベルが調整されます。fairnessThresholder オブジェクトを作成した後、オブジェクト関数 predictloss を新しいデータで使用して、公平性のラベルの予測と分類損失の計算をそれぞれ行うことができます。

    作成

    説明

    fairnessMdl = fairnessThresholder(Mdl,Tbl,AttributeName,ResponseVarName) は、バイナリ分類器 Mdl のスコアのしきい値を公平性の範囲を満たしながら最適化します。この関数では、検証データ table Tbl 内の観測値を table 変数 ResponseVarName 内のクラス ラベルで分類するしきい値のベクトルについて試行します。最適なしきい値を下回る臨界領域の観測値については、センシティブ属性 AttributeName の参照グループと非参照グループで公平性の制約が保たれるように関数でラベルが調整されます。詳細については、棄却オプションベース分類を参照してください。

    fairnessMdl = fairnessThresholder(Mdl,X,attribute,Y) は、数値予測子データ Xattribute で指定されたセンシティブ属性、および Y で指定された二項反応を使用します。

    fairnessMdl = fairnessThresholder(Mdl,attribute,threshold) は、最適化問題を解く代わりに、指定された threshold をスコアのしきい値として使用します。領域の専門知識に基づく固定のしきい値を選択します。

    fairnessMdl = fairnessThresholder(___,Name=Value) では、前の構文におけるいずれかの入力引数の組み合わせに加えて、1 つ以上の名前と値の引数を使用してオプションを指定します。たとえば、名前と値の引数 BiasMetric を使用してバイアス メトリクスを指定します。

    入力引数

    すべて展開する

    バイナリ分類器。完全またはコンパクトな分類モデル オブジェクトか関数ハンドルとして指定します。

    検証データ セット。table として指定します。Tbl の各行は 1 つの観測値に対応し、各列は 1 つの変数に対応します。Mdl の学習に使用したすべての予測子変数、センシティブ属性、および応答変数を table に含める必要があります。観測値の重みなどの追加の変数も table に含めることができます。文字ベクトルの cell 配列ではない cell 配列と複数列の変数は使用できません。

    データ型: table

    センシティブ属性の名前。Tbl 内の変数の名前として指定します。AttributeName は文字ベクトルまたは string スカラーとして指定しなければなりません。たとえば、センシティブ属性が Tbl.Attribute として格納されている場合、"Attribute" として指定します。

    センシティブ属性は、数値ベクトル、logical ベクトル、文字配列、string 配列、文字ベクトルの cell 配列、または categorical ベクトルでなければなりません。

    データ型: char | string

    応答変数の名前。Tbl 内の変数の名前で指定します。ResponseVarName は文字ベクトルまたは string スカラーとして指定しなければなりません。たとえば、応答変数が Tbl.Y として格納されている場合、"Y" として指定します。

    応答変数は、数値ベクトル、logical ベクトル、文字配列、string 配列、文字ベクトルの cell 配列、または categorical ベクトルでなければなりません。データ型は Mdl の学習に使用した応答変数のデータ型と同じでなければなりません。

    データ型: char | string

    検証予測子データ。数値行列として指定します。X の各行は 1 つの観測値に、各列は 1 つの予測子変数に対応します。

    • Xattribute、および Y の行数は同じでなければなりません。

    • X の列の順序は Mdl の学習に使用した予測子変数と同じでなければなりません。

    データ型: single | double

    センシティブ属性。数値列ベクトル、logical 列ベクトル、文字配列、string 配列、文字ベクトルの cell 配列、または categorical 列ベクトルとして指定します。

    • Xattribute、および Y の行数は同じでなければなりません。

    • attribute が文字配列の場合、配列の各行がセンシティブ属性のグループに対応していなければなりません。

    データ型: single | double | logical | char | string | cell | categorical

    クラス ラベル。数値列ベクトル、logical 列ベクトル、文字配列、string 配列、文字ベクトルの cell 配列、または categorical 列ベクトルとして指定します。

    • Xattribute、および Y の行数は同じでなければなりません。

    • Y が文字配列の場合、配列の各行がクラス ラベルに対応していなければなりません。

    • Y のデータ型は Mdl の学習に使用した応答変数のデータ型と同じでなければなりません。

    • Mdl が分類モデル オブジェクトの場合、Y の各クラスは Mdl.ClassNames のクラスのサブセットでなければなりません。

    データ型: single | double | logical | char | string | cell | categorical

    スコアのしきい値。数値スカラーとして指定します。最大スコアが threshold の値より小さい各観測値のラベルが fairnessThresholder で調整されます。

    • Mdl またはそのオブジェクト関数 predict が事後確率の分類スコアを返す場合、範囲 [0.5, 1]threshold の値を指定します。

    • Mdl のオブジェクト関数 predict が範囲 (–∞,∞) の分類スコアを返す場合、非負の threshold の値を指定します。

    データ型: single | double

    名前と値の引数

    オプションの引数のペアを Name1=Value1,...,NameN=ValueN として指定します。ここで Name は引数名、Value は対応する値です。名前と値の引数は他の引数の後ろにする必要がありますが、ペアの順序は関係ありません。

    例: fairnessThresholder(Mdl,Tbl,"Gender","Smoker",BiasMetric="spd",BiasMetricRange=[–0.1 0.1]) は、センシティブ属性 Gender の非参照グループの統計的均一性差が範囲 [–0.1, 0.1] になるスコアのしきい値を見つけるように指定します。

    しきい値の最適化で公平性の制約として使用するバイアス メトリクス。次の表のメトリクス名のいずれかとして指定します。

    メトリクス名説明
    "DisparateImpact" または "di" (既定の設定)差異の影響 (DI)
    "AverageAbsoluteOddsDifference" または "aaod"平均絶対オッズ差 (AAOD)
    "EqualOpportunityDifference" または "eod"機会均等差 (EOD)
    "StatisticalParityDifference" または "spd"統計的均一性差 (SPD)

    バイアス メトリクスの定義の詳細については、バイアス メトリクスを参照してください。

    関数 fairnessThresholder は、非参照グループ (つまり ReferenceGroups の補数) のバイアス メトリクスを計算し、値がバイアス メトリクスの範囲 (BiasMetricRange) に収まっているかどうかをチェックします。

    例: BiasMetric="spd"

    例: BiasMetric="EqualOpportunityDifference"

    データ型: char | string

    しきい値の最適化で制約として使用するバイアス メトリクスの範囲。2 要素の数値ベクトルとして指定します。次の表に、各バイアス メトリクスについて、サポートされるバイアス メトリクスの値と既定のバイアス メトリクスの範囲を示します。

    メトリクス名サポートされるバイアス メトリクスの値BiasMetricRange の既定値
    "DisparateImpact" または "di"[0, ∞)[0.8, 1.25]
    "AverageAbsoluteOddsDifference" または "aaod"[0, 1][0, 0.05]
    "EqualOpportunityDifference" または "eod"[–1, 1][–0.05, 0.05]
    "StatisticalParityDifference" または "spd"[–1, 1][–0.05, 0.05]

    関数 fairnessThresholder は、非参照グループ (つまり ReferenceGroups の補数) のバイアス メトリクス (BiasMetric) を計算し、値がバイアス メトリクスの範囲に収まっているかどうかをチェックします。

    例: BiasMetricRange=[-0.1 0.1]

    データ型: single | double

    バイアス メトリクスの計算で参照グループとして使用するセンシティブ属性のグループ。スカラーまたはベクトルとして指定します。既定では、fairnessThresholder は、検証データ内の最も頻繁に出現するグループを参照グループとして選択します。ReferenceGroups の値の各要素は、センシティブ属性と同じデータ型でなければなりません。

    この関数では、参照グループと非参照グループを含む二項のセンシティブ属性用に設計された手法を使用します。非参照グループは、ReferenceGroups の値に含まれていないセンシティブ属性のグループで形成されます。

    例: ReferenceGroups=categorical(["Husband","Unmarried"])

    データ型: single | double | logical | char | string | cell | categorical

    陽性クラスのラベル。数値スカラー、logical スカラー、文字ベクトル、string スカラー、1 つの文字ベクトルを含む cell 配列、または categorical スカラーとして指定します。PositiveClass のデータ型は真のクラス ラベルの変数と同じでなければなりません。

    PositiveClass の既定値は、バイナリ ラベルの 2 番目のクラスです。クラスの順序は、真のクラス ラベルの変数に対して関数 unique"sorted" オプションを指定して返される順序になります。

    例: PositiveClass=categorical(">50K")

    データ型: single | double | logical | char | string | cell | categorical

    しきい値の最適化で最小化する損失。"classiferror""classifcost"、または関数ハンドルとして指定します。

    次の表は、使用できる損失関数の一覧です。対応する文字ベクトルまたは string スカラーを使用して、いずれかを指定します。

    説明
    "classifcost"観測誤分類コスト

    L=j=1nC(kj,k^j)I(yjy^j)n

    "classiferror"10 進数の誤分類率

    L=j=1nI(yjy^j)n

    • C は誤分類コスト行列、I はインジケーター関数です。Mdl が分類モデル オブジェクトの場合、誤分類コスト行列は MdlCost プロパティに対応します。Mdl が関数ハンドルの場合は、C は既定のコスト行列であり、"classifcost""classiferror" の損失の値は同じです。

    • yj は観測値 j に対する真のクラス ラベル、yj はクラス kj に属しています。

    • y^j は観測値 j に対して最大の予測スコアをもつクラス ラベル、y^j はクラス k^j に属しています。

    • n は検証データ セット内の観測値の数です。

    カスタム損失関数を指定するには、Mdl を分類モデル オブジェクトとして指定しなければなりません。関数ハンドル表記 (@lossfun) を使用します。関数の形式は次のとおりです。

    lossvalue = lossfun(Class,Score,Cost)

    • 出力引数 lossvalue はスカラーです。

    • 関数名 (lossfun) を指定します。

    • ClassnK 列の logical 行列であり、対応する観測値が属するクラスを各行が示します。nTbl または X 内の観測値の数、K は応答変数内の異なるクラスの数です。列の順序は Mdl.ClassNames のクラスの順序に対応します。各行について観測値 p がクラス q に属する場合は Class(p,q) = 1 を設定することにより、Class を作成します。行 p の他のすべての要素を 0 に設定します。

    • Score は、分類スコアの nK 列の行列です。列の順序は Mdl.ClassNames のクラスの順序に対応します。Score は分類スコアの行列で、predict の出力と同様です。

    • Cost は、誤分類コストの、KK 列の数値行列です。たとえば、Cost = ones(K) – eye(K) は、正しい分類のコストとして 0 を、誤分類のコストとして 1 を指定します。

    例: LossFun="classifcost"

    データ型: char | string | function_handle

    しきい値の最適化で評価するしきい値の最大数。正の整数として指定します。fairnessThresholder は、min(n,MaxNumThresholds) 個のしきい値のベクトルを最適化プロセスの一部として使用します。ここで、n は検証データ内の観測値の数です。

    例: MaxNumThresholds=250

    データ型: single | double

    プロパティ

    すべて展開する

    この プロパティ は読み取り専用です。

    バイナリ分類器。完全またはコンパクトな分類モデル オブジェクトか関数ハンドルとして返されます。

    この プロパティ は読み取り専用です。

    センシティブ属性。変数名、数値列ベクトル、logical 列ベクトル、文字配列、文字ベクトルの cell 配列、または categorical 列ベクトルとして返されます。

    • table を使用して fairnessThresholder オブジェクトを作成する場合、SensitiveAttribute はセンシティブ属性の名前になります。名前は文字ベクトルとして格納されます。

    • 行列を使用して fairnessThresholder オブジェクトを作成する場合、SensitiveAttribute のサイズとデータ型はオブジェクトの作成に使用されるセンシティブ属性と同じになります。(string 配列は文字ベクトルの cell 配列として扱われます)。

    データ型: single | double | logical | char | cell | categorical

    この プロパティ は読み取り専用です。

    参照グループとして使用するセンシティブ属性のグループ。スカラーまたはベクトルとして返されます。(string 配列は文字ベクトルの cell 配列として扱われます)。

    名前と値の引数 ReferenceGroups によってこのプロパティが設定されます。

    データ型: single | double | logical | char | cell | categorical

    この プロパティ は読み取り専用です。

    真のクラス ラベルの変数の名前。応答変数の名前を含む文字ベクトルとして返されます。(string スカラーは文字ベクトルとして扱われます。)

    • 入力引数 ResponseVarName を指定した場合、その値に応じてこのプロパティが決まります。

    • 入力引数 Y を指定した場合、このプロパティの値は 'Y' になります。

    データ型: char

    この プロパティ は読み取り専用です。

    陽性クラスのラベル。数値スカラー、logical スカラー、文字ベクトル、1 つの文字ベクトルを含む cell 配列、または categorical スカラーとして返されます。(string スカラーは文字ベクトルとして扱われます。)

    名前と値の引数 PositiveClass によってこのプロパティが設定されます。

    データ型: single | double | logical | char | cell | categorical

    この プロパティ は読み取り専用です。

    スコアのしきい値。数値スカラーとして返されます。このスコアのしきい値は、fairnessThresolder によって導出された最適なスコアのしきい値か入力引数 threshold の値になります。

    ScoreThreshold プロパティは、元のモデルの予測が既に公平性の制約を満たしている場合やいずれの潜在的なスコアのしきい値も公平性の制約を満たさない場合は空になります。

    データ型: single | double

    この プロパティ は読み取り専用です。

    バイアス メトリクス。文字ベクトルとして返されます。

    名前と値の引数 BiasMetric によってこのプロパティが設定されます。

    データ型: char

    この プロパティ は読み取り専用です。

    非参照グループのバイアス メトリクスの値。数値スカラーとして返されます。非参照グループは、ReferenceGroups の値に含まれていないセンシティブ属性のグループで形成されます。

    fairnessThresholder は、ScoreThreshold の値を使用して調整された検証データ セットの予測を使用してバイアス メトリクスの値を計算します。

    BiasMetricValue プロパティは、元のモデルの予測が既に公平性の制約を満たしている場合やいずれの潜在的なスコアのしきい値も公平性の制約を満たさない場合は空になります。

    データ型: double

    この プロパティ は読み取り専用です。

    バイアス メトリクスの範囲。2 要素の数値ベクトルとして返されます。

    名前と値の引数 BiasMetricRange によってこのプロパティが設定されます。

    データ型: single | double

    この プロパティ は読み取り専用です。

    検証分類損失。数値スカラーとして返されます。fairnessThresholder は、名前と値の引数 LossFun で指定された分類スコアを計算します。ScoreThreshold の値を使用して調整された検証データ セットの予測が関数で使用されます。

    ValidationLoss プロパティは、元のモデルの予測が既に公平性の制約を満たしている場合やいずれの潜在的なスコアのしきい値も公平性の制約を満たさない場合は空になります。

    データ型: double

    オブジェクト関数

    loss公平性のしきい値で調整された分類損失
    predict公平性のしきい値で調整された予測ラベル

    すべて折りたたむ

    バイナリ分類用の木アンサンブルに学習させ、センシティブ属性の各グループについての差異の影響を計算します。非参照グループの差異の影響の値を小さくするために、観測値を分類するスコアのしきい値を調整します。

    データ census1994 を読み込みます。これには、データ セット adultdata とテスト データ セット adulttest が含まれています。このデータ セットは、個人の年収が $50,000 を超えるかどうかを予測するために使用できる、米国国勢調査局の人口統計情報から構成されています。adultdata の最初の数行をプレビューします。

    load census1994
    head(adultdata)
        age       workClass          fnlwgt      education    education_num       marital_status           occupation        relationship     race      sex      capital_gain    capital_loss    hours_per_week    native_country    salary
        ___    ________________    __________    _________    _____________    _____________________    _________________    _____________    _____    ______    ____________    ____________    ______________    ______________    ______
    
        39     State-gov                77516    Bachelors         13          Never-married            Adm-clerical         Not-in-family    White    Male          2174             0                40          United-States     <=50K 
        50     Self-emp-not-inc         83311    Bachelors         13          Married-civ-spouse       Exec-managerial      Husband          White    Male             0             0                13          United-States     <=50K 
        38     Private             2.1565e+05    HS-grad            9          Divorced                 Handlers-cleaners    Not-in-family    White    Male             0             0                40          United-States     <=50K 
        53     Private             2.3472e+05    11th               7          Married-civ-spouse       Handlers-cleaners    Husband          Black    Male             0             0                40          United-States     <=50K 
        28     Private             3.3841e+05    Bachelors         13          Married-civ-spouse       Prof-specialty       Wife             Black    Female           0             0                40          Cuba              <=50K 
        37     Private             2.8458e+05    Masters           14          Married-civ-spouse       Exec-managerial      Wife             White    Female           0             0                40          United-States     <=50K 
        49     Private             1.6019e+05    9th                5          Married-spouse-absent    Other-service        Not-in-family    Black    Female           0             0                16          Jamaica           <=50K 
        52     Self-emp-not-inc    2.0964e+05    HS-grad            9          Married-civ-spouse       Exec-managerial      Husband          White    Male             0             0                45          United-States     >50K  
    

    各行には、成人 1 人の人口統計情報が格納されています。agemarital_statusrelationshipracesex などのセンシティブ属性の情報が含まれます。3 列目の flnwgt に観測値の重みが格納されており、最後の列 salary は個人の年収が $50,000 以下 (<=50K) か $50,000 を超える (>50K) かを示します。

    欠損値を含む観測値を削除します。

    adultdata = rmmissing(adultdata);
    adulttest = rmmissing(adulttest);

    adultdata を学習セットと検証セットに分割します。観測値の 60% を学習セット trainingData に使用し、観測値の 40% を検証セット validationData に使用します。

    rng("default") % For reproducibility
    c = cvpartition(adultdata.salary,"Holdout",0.4);
    trainingIdx = training(c);
    validationIdx = test(c);
    trainingData = adultdata(trainingIdx,:);
    validationData = adultdata(validationIdx,:);

    学習データ セット trainingData を使用して木のブースティング アンサンブルに学習させます。table adultdata 内の変数名を使用して、応答変数、予測子変数、および観測値の重みを指定します。ランダム アンダーサンプリング ブースティングをアンサンブル集約法として使用します。

    predictors = ["capital_gain","capital_loss","education", ...
        "education_num","hours_per_week","occupation","workClass"];
    Mdl = fitcensemble(trainingData,"salary", ...
        PredictorNames=predictors, ...
        Weights="fnlwgt",Method="RUSBoost");

    テスト データ セット adulttest 内の観測値について、給与の値を予測し、分類誤差を計算します。

    labels = predict(Mdl,adulttest);
    L = loss(Mdl,adulttest)
    L = 0.2080
    

    テスト セットの観測値の約 80% について、給与の分類がモデルで正確に予測されています。

    テスト セットのモデル予測を使用して、センシティブ属性 sex についての公平性メトリクスを計算します。特に、sex の各グループについての差異の影響を調べます。fairnessMetrics のオブジェクト関数 reportplot を使用して結果を表示します。

    evaluator = fairnessMetrics(adulttest,"salary", ...
        SensitiveAttributeNames="sex",Predictions=labels, ...
        ModelNames="Ensemble",Weights="fnlwgt");
    evaluator.PositiveClass
    ans = categorical
         >50K 
    
    
    evaluator.ReferenceGroup
    ans = 
    'Male'
    
    report(evaluator,BiasMetrics="DisparateImpact")
    ans=2×4 table
        ModelNames    SensitiveAttributeNames    Groups    DisparateImpact
        __________    _______________________    ______    _______________
    
         Ensemble               sex              Female        0.73792    
         Ensemble               sex              Male                1    
    
    
    plot(evaluator,"DisparateImpact")

    Figure contains an axes object. The axes object with title Disparate Impact, xlabel Fairness Metric Value, ylabel sex contains 2 objects of type bar, constantline.

    差異の影響の値は、非参照グループ (Female) について、そのグループの陽性クラスの値 (>50K) をもつ予測の比率を参照グループ (Male) の陽性クラスの値をもつ予測の比率で除算したものです。差異の影響の値は 1 に近くなるのが理想的です。

    非参照グループの差異の影響の値が改善するか試すために、関数 fairnessThresholder を使用してモデル予測を調整できます。この関数は、検証データを使用して、公平性の範囲を満たしながら精度が最大になる最適なスコアのしきい値を探します。最適なしきい値を下回る臨界領域の観測値については、参照グループと非参照グループで公平性の制約が保たれるように関数でラベルが変更されます。既定では、この関数は非参照グループの差異の影響の値が範囲 [0.8,1.25] になるスコアのしきい値を見つけようとします。

    fairnessMdl = fairnessThresholder(Mdl,validationData,"sex","salary")
    fairnessMdl = 
      fairnessThresholder with properties:
    
                   Learner: [1x1 classreg.learning.classif.CompactClassificationEnsemble]
        SensitiveAttribute: 'sex'
           ReferenceGroups: Male
              ResponseName: 'salary'
             PositiveClass: >50K
            ScoreThreshold: 1.6749
                BiasMetric: 'DisparateImpact'
           BiasMetricValue: 0.9702
           BiasMetricRange: [0.8000 1.2500]
            ValidationLoss: 0.2017
    
    

    fairnessMdlfairnessThresholder モデル オブジェクトです。アンサンブル モデル Mdl の関数 predict が返すスコアは事後確率ではないことに注意してください。スコアの範囲は (-,) であり、各観測値の最大スコアは 0 より大きくなります。最大スコアが新しいスコアのしきい値 (fairnessMdl.ScoreThreshold) より小さい観測値について、fairnessMdl オブジェクトの関数 predict で予測が調整されます。非参照グループの観測値の場合、関数はその観測値を陽性クラスに予測します。参照グループの観測値の場合、関数はその観測値を陰性クラスに予測します。これらの調整の結果として予測ラベルが常に変わるとは限りません。

    新しいスコアのしきい値を使用してテスト セットの予測を調整し、分類誤差を計算します。

    fairnessLabels = predict(fairnessMdl,adulttest);
    fairnessLoss = loss(fairnessMdl,adulttest)
    fairnessLoss = 0.2064
    

    新しい分類誤差は元の分類誤差と同程度です。

    Mdl を使用して計算した元の予測と fairnessMdl を使用して計算した調整後の予測の 2 セットのテストの予測で、それらの差異の影響の値を比較します。

    newEvaluator = fairnessMetrics(adulttest,"salary", ...
        SensitiveAttributeNames="sex",Predictions=[labels,fairnessLabels], ...
        ModelNames=["Original","Adjusted"],Weights="fnlwgt");
    newEvaluator.PositiveClass
    ans = categorical
         >50K 
    
    
    newEvaluator.ReferenceGroup
    ans = 
    'Male'
    
    report(newEvaluator,BiasMetrics="DisparateImpact")
    ans=2×5 table
            Metrics        SensitiveAttributeNames    Groups    Original    Adjusted
        _______________    _______________________    ______    ________    ________
    
        DisparateImpact              sex              Female    0.73792      1.0048 
        DisparateImpact              sex              Male            1           1 
    
    
    plot(newEvaluator,"di")

    Figure contains an axes object. The axes object with title Disparate Impact, xlabel Fairness Metric Value, ylabel sex contains 2 objects of type bar. These objects represent Original, Adjusted.

    調整後の予測を使用した場合の方が、非参照グループ (Female) の差異の影響の値が 1 に近くなっています。

    サポート ベクター マシン (SVM) モデルに学習させ、センシティブ属性の各グループについての統計的均一性差 (SPD) を計算します。非参照グループの SPD の値を小さくするために、観測値を分類するスコアのしきい値を調整します。

    100 人の患者の医療情報を含む patients データ セットを読み込みます。変数 GenderSmokercategorical 変数に変換します。10 の代わりに、SmokerNonsmoker というわかりやすいカテゴリ名を指定します。

    load patients
    Gender = categorical(Gender);
    Smoker = categorical(Smoker,logical([1 0]), ...
        ["Smoker","Nonsmoker"]);

    連続予測子 DiastolicSystolic を含む行列を作成します。センシティブ属性として Gender、応答変数として Smoker を指定します。

    X = [Diastolic,Systolic];
    attribute = Gender;
    Y = Smoker;

    データを学習セットと検証セットに分割します。半分の観測値を学習に使用し、半分の観測値を検証に使用します。

    rng("default") % For reproducibility
    cv = cvpartition(Y,"Holdout",0.5);
    
    trainX = X(training(cv),:);
    trainAttribute = attribute(training(cv));
    trainY = Y(training(cv));
    
    validationX = X(test(cv),:);
    validationAttribute = attribute(test(cv));
    validationY = Y(test(cv));

    学習データでサポート ベクター マシン (SVM) バイナリ分類器に学習させます。モデルを当てはめる前に予測子を標準化します。学習させたモデルを使用してラベルを予測し、検証データ セットのスコアを計算します。

    mdl = fitcsvm(trainX,trainY,Standardize=true);
    [labels,scores] = predict(mdl,validationX);

    検証データ セットについて、センシティブ属性と応答変数の情報を 1 つのグループ化変数 groupTest に結合します。

    groupTest = validationAttribute.*validationY;
    names = string(categories(groupTest))
    names = 4x1 string
        "Female Smoker"
        "Female Nonsmoker"
        "Male Smoker"
        "Male Nonsmoker"
    
    

    SVM モデルで誤分類される検証観測値を見つけます。

    wrongIdx = (validationY ~= labels);
    wrongX = validationX(wrongIdx,:);
    names(5) = "Misclassified";

    検証データをプロットします。各点の色は、その観測値のセンシティブ属性のグループとクラス ラベルを示します。円で囲まれた点は、誤分類された観測値を示します。

    figure
    hold on
    gscatter(validationX(:,1),validationX(:,2), ...
        validationAttribute.*validationY)
    plot(wrongX(:,1),wrongX(:,2), ...
        "ko",MarkerSize=8)
    legend(names)
    xlabel("Diastolic")
    ylabel("Systolic")
    title("Validation Data")
    hold off

    Figure contains an axes object. The axes object with title Validation Data, xlabel Diastolic, ylabel Systolic contains 5 objects of type line. One or more of the lines displays its values using only markers These objects represent Female Smoker, Female Nonsmoker, Male Smoker, Male Nonsmoker, Misclassified.

    モデル予測を使用して、センシティブ属性についての公平性メトリクスを計算します。特に、validationAttribute の各グループについての統計的均一性差 (SPD) を調べます。

    evaluator = fairnessMetrics(validationAttribute,validationY, ...
        Predictions=labels);
    evaluator.ReferenceGroup
    ans = 
    'Female'
    
    evaluator.PositiveClass
    ans = categorical
         Nonsmoker 
    
    
    report(evaluator,BiasMetrics="StatisticalParityDifference")
    ans=2×4 table
        ModelNames    SensitiveAttributeNames    Groups    StatisticalParityDifference
        __________    _______________________    ______    ___________________________
    
          Model1                x1               Female                     0         
          Model1                x1               Male               -0.064412         
    
    
    figure
    plot(evaluator,"StatisticalParityDifference")

    Figure contains an axes object. The axes object with title Statistical Parity Difference, xlabel Fairness Metric Value, ylabel x1 contains 2 objects of type bar, constantline.

    SPD の値は、非参照グループ (Male) において、センシティブ属性の値が Male の場合に患者が陽性クラス (Nonsmoker) になる確率とセンシティブ属性の値が Female の場合に患者が陽性クラスになる確率 (参照グループでの確率) の差です。SPD の値は 0 に近くなるのが理想的です。

    非参照グループの SPD の値が改善するか試すために、関数 fairnessThresholder を使用してモデル予測を調整できます。この関数は、公平性の範囲を満たしながら精度が最大になるように最適なスコアのしきい値を探します。最適なしきい値を下回る臨界領域の観測値については、参照グループと非参照グループで公平性の制約が保たれるように関数でラベルが変更されます。既定では、SPD のバイアス メトリクスを使用する場合、この関数は非参照グループの SPD の値が範囲 [–0.05,0.05] になるスコアのしきい値を見つけようとします。

    fairnessMdl = fairnessThresholder(mdl,validationX, ...
        validationAttribute,validationY, ...
        BiasMetric="StatisticalParityDifference")
    fairnessMdl = 
      fairnessThresholder with properties:
    
                   Learner: [1x1 classreg.learning.classif.CompactClassificationSVM]
        SensitiveAttribute: [50x1 categorical]
           ReferenceGroups: Female
              ResponseName: 'Y'
             PositiveClass: Nonsmoker
            ScoreThreshold: 0.5116
                BiasMetric: 'StatisticalParityDifference'
           BiasMetricValue: -0.0209
           BiasMetricRange: [-0.0500 0.0500]
            ValidationLoss: 0.1200
    
    

    fairnessMdlfairnessThresholder モデル オブジェクトです。

    更新後の方が非参照グループの SPD の値が 0 に近いことに注目してください。

    newNonReferenceSPD = fairnessMdl.BiasMetricValue
    newNonReferenceSPD = -0.0209
    

    新しいスコアのしきい値を使用して検証データの予測を調整します。fairnessMdl オブジェクトの関数 predict で、最大スコアがスコアのしきい値より小さい各観測値の予測が調整されます。非参照グループの観測値の場合、関数はその観測値を陽性クラスに予測します。参照グループの観測値の場合、関数はその観測値を陰性クラスに予測します。これらの調整の結果として予測ラベルが常に変わるとは限りません。

    fairnessLabels = predict(fairnessMdl,validationX, ...
        validationAttribute);

    予測が fairnessMdl で切り替えられた観測値を見つけます。

    differentIdx = (labels ~= fairnessLabels);
    differentX = validationX(differentIdx,:);
    names(5) = "Switched Prediction";

    検証データをプロットします。各点の色は、その観測値のセンシティブ属性のグループとクラス ラベルを示します。四角で囲まれた点は、ラベルが fairnessThresholder モデルで切り替えられた観測値を示します。

    figure
    hold on
    gscatter(validationX(:,1),validationX(:,2), ...
        validationAttribute.*validationY)
    plot(differentX(:,1),differentX(:,2), ...
        "ks",MarkerSize=8)
    legend(names)
    xlabel("Diastolic")
    ylabel("Systolic")
    title("Validation Data")
    hold off

    Figure contains an axes object. The axes object with title Validation Data, xlabel Diastolic, ylabel Systolic contains 5 objects of type line. One or more of the lines displays its values using only markers These objects represent Female Smoker, Female Nonsmoker, Male Smoker, Male Nonsmoker, Switched Prediction.

    関数 fairnessThresholder では、参照グループと非参照グループを含む二項のセンシティブ属性用に設計された手法を使用します。この例では、センシティブ属性に 2 つより多くのグループがある場合の関数の使用方法を示します。

    標本ファイル CreditRating_Historical.dat を table に読み取ります。予測子データには、法人顧客リストの財務比率が格納されています。応答変数には、格付機関が割り当てた信用格付けが格納されています。業種の情報がセンシティブ属性であるとします。

    creditrating = readtable("CreditRating_Historical.dat");

    変数 ID の各値は一意の顧客 ID であるため (つまり、length(unique(creditrating.ID))creditrating に含まれる観測値の数に等しい)、変数 ID は予測子としては適切ではありません。変数 ID を table から削除し、変数 Industrycategorical 変数に変換します。

    creditrating.ID = [];
    creditrating.Industry = categorical(creditrating.Industry);

    応答変数 Rating について、AAAAAA、および BBB の格付けを "good" の格付けのカテゴリに結合し、BBB、および CCC の格付けを "poor" の格付けのカテゴリに結合します。

    Rating = categorical(creditrating.Rating);
    Rating = mergecats(Rating,["AAA","AA","A","BBB"],"good");
    Rating = mergecats(Rating,["BB","B","CCC"],"poor");
    creditrating.Rating = Rating;

    データを学習セット、検証セット、テスト セットに分割します。観測値を約 3 分の 1 ずつ使用して、それぞれのセットを作成します。

    rng("default")
    cv1 = cvpartition(creditrating.Rating,"Holdout",1/3);
    tblNotForTest = creditrating(training(cv1),:);
    tblTest = creditrating(test(cv1),:);
    
    cv2 = cvpartition(tblNotForTest.Rating,"Holdout",1/2);
    tblTrain = tblNotForTest(training(cv2),:);
    tblValidation = tblNotForTest(test(cv2),:);

    この例では、poor の格付けに対する good の格付けの比率が高い業種をセンシティブ属性 Industry の参照グループとします。学習データ セット tblTrain と関数 grpstats を使用して比率を計算します。

    info = grpstats(tblTrain,["Industry","Rating"]);
    goodInfo = info(info.Rating == "good",1:3);
    poorInfo = info(info.Rating == "poor",1:3);
    goodToPoorRatio = goodInfo.GroupCount./poorInfo.GroupCount
    goodToPoorRatio = 12×1
    
        2.0000
        1.5122
        2.1212
        1.3061
        1.7778
        2.5152
        2.4118
        1.9394
        1.4186
        1.1875
          ⋮
    
    

    goodToPoorRatio の値が 2.5 より大きい業種を優良な業種と定義します。goodToPoorRatio の値が最も高い業種を最も優れた業種と見なします。

    wellRatedIndustries = goodInfo.Industry(goodToPoorRatio > 2.5,:)
    wellRatedIndustries = 2x1 categorical
         6 
         11 
    
    
    maximumRatio = max(goodToPoorRatio);
    bestRatedIndustry = goodInfo.Industry(goodToPoorRatio == maximumRatio,:)
    bestRatedIndustry = categorical
         11 
    
    

    学習データを使用して、センシティブ属性についての公平性メトリクスを計算します。特に、Industy の各グループについての統計的均一性差 (SPD) を調べます。good の格付けを陽性クラスとして指定し、最も優れた業種 (11) を参照グループとして指定します。fairnessMetrics のオブジェクト関数 reportplot を使用して結果を表示します。

    dataEvaluator = fairnessMetrics(tblTrain,"Rating", ...
        SensitiveAttributeNames="Industry", ...
        PositiveClass="good",ReferenceGroup=bestRatedIndustry);
    report(dataEvaluator,BiasMetrics="StatisticalParityDifference")
    ans=12×3 table
        SensitiveAttributeNames    Groups    StatisticalParityDifference
        _______________________    ______    ___________________________
    
               Industry              1                -0.075908         
               Industry              2                 -0.14063         
               Industry              3                -0.062963         
               Industry              4                  -0.1762         
               Industry              5                 -0.10257         
               Industry              6                -0.027057         
               Industry              7                -0.035678         
               Industry              8                 -0.08278         
               Industry              9                 -0.15604         
               Industry              10                -0.19972         
               Industry              11                       0         
               Industry              12               -0.058364         
    
    
    plot(dataEvaluator,"StatisticalParityDifference")

    Figure contains an axes object. The axes object with title Statistical Parity Difference, xlabel Fairness Metric Value, ylabel Industry contains 2 objects of type bar, constantline.

    SPD の値は、センシティブ属性の各グループ "g" について、センシティブ属性の値が "g" の場合に陽性クラス (good) になる確率とセンシティブ属性の値が参照グループの値 (11) の場合に陽性クラスになる確率の差です。SPD の値は 0 に近くなるのが理想的です。

    箱ひげ図を使用して SPD の値の分布を可視化します。

    boxchart(dataEvaluator.BiasMetrics.StatisticalParityDifference)
    ylabel("Statistical Parity Difference")
    legend("Training Data")

    Figure contains an axes object. The axes object with ylabel Statistical Parity Difference contains an object of type boxchart. This object represents Training Data.

    SPD の値の中央値は約 –0.08 です。

    学習データ セットを使用して二分木分類器に学習させます。学習させたモデルを使用してラベルを予測し、テスト データ セットで分類誤差を計算します。

    predictorNames = ["WC_TA","RE_TA","EBIT_TA","MVE_BVTD","S_TA"];
    treeMdl = fitctree(tblTrain,"Rating", ...
        PredictorNames=predictorNames);
    treePredictions = predict(treeMdl,tblTest);
    L = loss(treeMdl,tblTest)
    L = 0.1107
    

    関数 fairnessThresholder を使用してモデル予測を調整できます。この関数は、検証データを使用して、公平性の範囲を満たしながら精度が最大になる最適なスコアのしきい値を探します。名前と値の引数 ReferenceGroups を使用して、優良な業種 (6 および 11) を参照グループとして指定します。それ以外のすべての業種で非参照グループが形成されます。バイアス メトリクスを統計的均一性差、バイアス メトリクスの範囲を [–0.005,0.005] と指定します。これらの範囲は、センシティブ属性の個々の業種ではなく、それらをまとめた非参照グループの SPD の値に適用されることに注意してください。

    fairnessMdl = fairnessThresholder(treeMdl,tblValidation, ...
        "Industry","Rating", ...
        PositiveClass="good",ReferenceGroups=wellRatedIndustries, ...
        BiasMetric="StatisticalParityDifference", ...
        BiasMetricRange=[-0.005 0.005])
    fairnessMdl = 
      fairnessThresholder with properties:
    
                   Learner: [1x1 classreg.learning.classif.CompactClassificationTree]
        SensitiveAttribute: 'Industry'
           ReferenceGroups: [2x1 categorical]
              ResponseName: 'Rating'
             PositiveClass: 'good'
            ScoreThreshold: 0.5444
                BiasMetric: 'StatisticalParityDifference'
           BiasMetricValue: 0.0034
           BiasMetricRange: [-0.0050 0.0050]
            ValidationLoss: 0.1198
    
    

    fairnessMdlfairnessThresholder モデル オブジェクトです。

    新しいスコアのしきい値を使用してテスト セットの予測を調整し、分類誤差を計算します。

    newPredictions = predict(fairnessMdl,tblTest);
    newL = loss(fairnessMdl,tblTest)
    newL = 0.1183
    

    新しい分類誤差は元の分類誤差と同程度です。

    treeMdl を使用して計算した元の予測と fairnessMdl を使用して計算した調整後の予測の 2 セットのテストの予測で、それらの SPD の値を比較します。good の格付けを陽性クラスとして指定し、最も優れた業種 (11) を参照グループとして指定します。fairnessMetrics のオブジェクト関数 reportplot を使用して結果を表示します。

    predEvaluator = fairnessMetrics(tblTest,"Rating", ...
        SensitiveAttributeNames="Industry", ...
        Predictions=[treePredictions,newPredictions], ...
        PositiveClass="good", ...
        ModelNames=["Original Model","Adjusted Model"], ...
        ReferenceGroup=bestRatedIndustry);
    report(predEvaluator,BiasMetric="DisparateImpact")
    ans=12×5 table
            Metrics        SensitiveAttributeNames    Groups    Original Model    Adjusted Model
        _______________    _______________________    ______    ______________    ______________
    
        DisparateImpact           Industry              1          0.96499           0.95014    
        DisparateImpact           Industry              2           1.0755            1.0634    
        DisparateImpact           Industry              3          0.94643           0.94643    
        DisparateImpact           Industry              4           1.0541            1.0392    
        DisparateImpact           Industry              5           1.0262            1.0132    
        DisparateImpact           Industry              6           1.0186            1.0186    
        DisparateImpact           Industry              7          0.99692           0.96067    
        DisparateImpact           Industry              8            1.077             1.077    
        DisparateImpact           Industry              9           1.0392            1.0103    
        DisparateImpact           Industry              10          1.0781            1.0635    
        DisparateImpact           Industry              11               1                 1    
        DisparateImpact           Industry              12          1.0392            1.0225    
    
    
    plot(predEvaluator,"spd")

    Figure contains an axes object. The axes object with title Statistical Parity Difference, xlabel Fairness Metric Value, ylabel Industry contains 2 objects of type bar. These objects represent Original Model, Adjusted Model.

    箱ひげ図を使用して SPD の値の 2 つの分布を可視化します。

    boxchart(predEvaluator.BiasMetrics.StatisticalParityDifference, ...
        GroupByColor=predEvaluator.BiasMetrics.ModelNames)
    ylabel("Statistical Parity Difference")
    legend

    Figure contains an axes object. The axes object with ylabel Statistical Parity Difference contains 2 objects of type boxchart. These objects represent Original Model, Adjusted Model.

    元のテスト セットの予測は、SPD の値が 0 に近く、中央値は約 0.02 です。調整後のテスト セットの予測は、SPD の値の中央値がそれよりもさらに少し 0 に近くなっています。

    関数 fitglm を使用してロジスティック回帰モデルに学習させます。観測値を分類するスコアのしきい値を調整するために、そのモデルを fairnessThresholder に関数ハンドルを使用して入力として渡します。

    100 人の患者の医療情報を含む patients データ セットを読み込みます。変数 GenderSmoker をカテゴリカル変数に変換します。10 の代わりに、SmokerNonsmoker というわかりやすいカテゴリ名を指定します。

    load patients
    Gender = categorical(Gender);
    Smoker = categorical(Smoker,logical([1 0]), ...
        ["Smoker","Nonsmoker"]);

    連続予測子 Diastolic および Systolic、センシティブ属性 Gender、応答変数 Smoker を含む table を作成します。

    Tbl = table(Diastolic,Systolic,Gender,Smoker);

    データを学習セットと検証セットに分割します。半分の観測値を学習に使用し、半分の観測値を検証に使用します。

    rng("default") % For reproducibility
    cv = cvpartition(Tbl.Smoker,"Holdout",0.5);
    trainTbl = Tbl(training(cv),:);
    validationTbl = Tbl(test(cv),:);

    学習データ trainTbl と関数 fitglm を使用してロジスティック回帰モデルに学習させます。

    modelspec = "Smoker ~ Diastolic + Systolic";
    glmMdl = fitglm(trainTbl,modelspec,Distribution="binomial")
    glmMdl = 
    Generalized linear regression model:
        logit(P(Smoker='Nonsmoker')) ~ 1 + Diastolic + Systolic
        Distribution = Binomial
    
    Estimated Coefficients:
                       Estimate      SE        tStat      pValue  
                       ________    _______    _______    _________
    
        (Intercept)      116.98     44.939     2.6032    0.0092356
        Diastolic      -0.54261    0.21577    -2.5147     0.011913
        Systolic       -0.57999    0.28697    -2.0211     0.043268
    
    
    50 observations, 47 error degrees of freedom
    Dispersion: 1
    Chi^2-statistic vs. constant model: 54, p-value = 1.89e-12
    

    線形回帰モデルの方程式で示されているように、Nonsmoker が陽性クラスです。つまり、予測スコアが 0.5 より大きい観測値が非喫煙者として予測されます。

    GeneralizedLinearModel オブジェクト glmMdl の関数 predict の関数ハンドルを作成します。

    f = @(T) predict(glmMdl,T);

    関数ハンドル f と検証データ validationTbl を使用して fairnessThresholder オブジェクトを作成します。この関数は、公平性の範囲を満たしながら精度が最大になるように最適なスコアのしきい値を探します。非参照グループの差異の影響の値が範囲 [0.9,1.1] になるようにバイアス メトリクスの範囲を指定します。

    分類モデルを関数ハンドルとして渡すときは、陽性クラスを指定しなければなりません。

    fairnessMdl = fairnessThresholder(f,validationTbl, ...
        "Gender","Smoker", ...
        BiasMetricRange=[0.9 1.1], ...
        PositiveClass=categorical("Nonsmoker"))
    fairnessMdl = 
      fairnessThresholder with properties:
    
                   Learner: @(T)predict(glmMdl,T)
        SensitiveAttribute: 'Gender'
           ReferenceGroups: Female
              ResponseName: 'Smoker'
             PositiveClass: Nonsmoker
            ScoreThreshold: 0.8087
                BiasMetric: 'DisparateImpact'
           BiasMetricValue: 0.9538
           BiasMetricRange: [0.9000 1.1000]
            ValidationLoss: 0.1600
    
    
    omega = fairnessMdl.ScoreThreshold
    omega = 0.8087
    

    fairnessMdlfairnessThresholder モデル オブジェクトです。スコアが範囲 (1–omega,omega) になる各観測値について、fairnessMdl オブジェクトの関数 predict で予測が調整されます。非参照グループ (Male) の観測値の場合、関数はその観測値を陽性クラス (Nonsmoker) に予測します。参照グループ (Female) の観測値の場合、関数はその観測値を陰性クラス (Smoker) に予測します。

    新しいスコアのしきい値を使用して、データ セット Tbl 全体の予測を調整します。

    fairnessLabels = predict(fairnessMdl,Tbl)
    fairnessLabels = 100x1 categorical
         Smoker 
         Nonsmoker 
         Smoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Smoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Smoker 
         Nonsmoker 
         Smoker 
         Smoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Smoker 
         Smoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Nonsmoker 
         Smoker 
          ⋮
    
    

    アルゴリズム

    すべて展開する

    参照

    [1] Kamiran, Faisal, Asim Karim, and Xiangliang Zhang. "Decision Theory for Discrimination-Aware Classification." 2012 IEEE 12th International Conference on Data Mining: 924-929.

    バージョン履歴

    R2023a で導入