ドキュメンテーション

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

アンサンブル分類における不均衡データまたは一様ではない誤分類コストの処理

実世界で応用する場合には、データのクラスを非対称的に処理したい場合があります。たとえば、データに、他のどのクラスよりもずっと多くの観測値をもつクラスがあるかもしれません。または、取り組んでいる問題が、1 つのクラスの観測値の分類ミスが、他のクラスの観測値の分類ミスよりも深刻な結果をもたらすようなものかもしれません。そのような状況では、関数 fitcensemblepriorcost の 2 つのオプション パラメーターが使用できます。

prior を使用することによって、優先クラス確率 (つまり、学習に使用されるクラスの確率) を設定します。学習セットに過小または過大に表現されるクラスがある場合に、このオプションを使用します。たとえば、シミュレーションによって学習データを取得するとします。シミュレートするクラス A は、クラス B よりも計算の負荷が高いため、クラス A の観測値は少なめに、また B の観測値は多めに生成される傾向になります。しかし、実世界ではクラス A とクラス B がそれとは異なる比率で混在していると考えられます。このケースでは、実世界で観測される値に近い比率になるように、クラス AB に事前確率を設定します。fitcensemble は事前確率を正規化して、合計 1 になるようにします。すべての事前確率に同じ正因子を乗算しても、分類の結果には影響しません。

学習データでクラスが適切に表現されていても、それらを非対称的に処理したい場合には、cost パラメーターを使用します。癌患者の良性腫瘍と悪性腫瘍を分類したいとします。悪性腫瘍の特定に失敗すること (偽陰性) は、良性を悪性と誤診する (偽陽性) よりも深刻な結果をもたらします。悪性を良性と誤診する場合には高いコストを、良性を悪性と誤診する場合には低いコストを割り当てなければならないはずです。

誤分類のコストは、非負の要素をもつ正方行列として渡さなければなりません。この行列の要素 C(i,j) は、真のクラスが i である場合に、観測値をクラス j に分類するコストを表します。コスト行列 C(i,i) の対角要素は、0 でなければなりません。前の例では、悪性腫瘍をクラス 1、良性腫瘍をクラス 2 として選択できます。この場合、コスト行列は次のように設定できます。

[0c10]

ここで、c > 1 は、悪性腫瘍を良性と誤診した場合のコストを表します。コストは相対値です。すべてのコストに同じ正因子を乗算しても、分類の結果に影響はありません。

クラスが 2 つだけの場合、fitcensemble では i = 1,2 および j ≠ i であるクラスについて P˜i=CijPi を使用して事前確率を調整します。 Pi は、fitcensemble に渡した事前確率または学習データのクラス頻度から計算された事前確率です。P˜i は、調整された事前確率です。次に、fitcensemble は既定のコスト行列を使用します。

[0110]

さらに、これらの調整済みの確率を弱学習器の学習に使用します。つまり、コスト行列の操作は事前確率の操作と等価です。

3 つ以上のクラスを使用する場合も、fitcensemble は入力コストを調整済み事前確率に変換します。この変換はさらに複雑です。まず、fitcensemble は、Zhou と Liu の[51]で説明されている行列方程式を解こうとします。解を求めるのに失敗した場合は、fitcensemble は Breiman などによって説明されている "平均コスト" を適用します。 [11]。詳細は、Zadrozny、Langford および Abe [50] を参照してください。

不均衡な分類コストによるアンサンブルの学習

この例では、不均衡な分類コストを使用して分類木のアンサンブルに学習をさせる方法を示します。この例では、肝炎患者に関するデータを使用して、疾病によって生存するか、または死亡するかを確認します。データセットの説明については、UCI Machine Learning Data Repository を参照してください。

UCI リポジトリから肝炎のデータセットを文字配列として読み込みます。次に、textscan を使用して結果を文字ベクトルの cell 配列に変換します。変数名が格納されている文字ベクトルの cell 配列を指定します。

hepatitis = textscan(urlread(['http://archive.ics.uci.edu/ml/' ...
    'machine-learning-databases/hepatitis/hepatitis.data']),...
    '%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f%f','TreatAsEmpty','?',...
    'Delimiter',',');
size(hepatitis)
VarNames = {'dieOrLive' 'age' 'sex' 'steroid' 'antivirals' 'fatigue' ...
    'malaise' 'anorexia' 'liverBig' 'liverFirm' 'spleen' ...
    'spiders' 'ascites' 'varices' 'bilirubin' 'alkPhosphate' 'sgot' ...
    'albumin' 'protime' 'histology'};
ans =

     1    20

hepatitis は 1 行 20 列の文字ベクトルの cell 配列です。セルは応答 (liveOrDie) および 19 の異種混合予測子に対応します。

予測子が格納されている数値行列と、応答カテゴリの 'Die' および 'Live' が格納されている cell ベクトルを指定します。応答は 2 つの値を含みます。1 は患者が亡くなったことを、2 は患者が生存したことを意味します。応答カテゴリを使用して、応答に対応する文字ベクトルの cell 配列を指定します。hepatitis の最初の変数には応答が含まれます。

X = cell2mat(hepatitis(2:end));
ClassNames = {'Die' 'Live'};
Y = ClassNames(hepatitis{:,1});

X は 19 個の予測子が格納されている数値行列です。Y は応答が格納されている文字ベクトルの cell 配列です。

欠損値についてデータを検査します。

figure;
barh(sum(isnan(X),1)/size(X,1));
h = gca;
h.YTick = 1:numel(VarNames) - 1;
h.YTickLabel = VarNames(2:end);
ylabel 'Predictor';
xlabel 'Fraction of missing values';

ほとんどの予測子に欠損値があり、その 1 つでは 45% 近くが欠損値となっています。そのため、代理分岐をもつ決定木を使用することによって精度を高めます。データセットのサイズが小さいため、代理分岐を使用した場合でも学習時間はそれほど長くはなりません。

代理分岐を使用する分類木のテンプレートを作成します。

rng(0,'twister') % for reproducibility
t = templateTree('surrogate','all');

データまたはデータの説明を検証して、カテゴリカル予測子を特定します。

X(1:5,:)
ans =

  Columns 1 through 7

   30.0000    2.0000    1.0000    2.0000    2.0000    2.0000    2.0000
   50.0000    1.0000    1.0000    2.0000    1.0000    2.0000    2.0000
   78.0000    1.0000    2.0000    2.0000    1.0000    2.0000    2.0000
   31.0000    1.0000       NaN    1.0000    2.0000    2.0000    2.0000
   34.0000    1.0000    2.0000    2.0000    2.0000    2.0000    2.0000

  Columns 8 through 14

    1.0000    2.0000    2.0000    2.0000    2.0000    2.0000    1.0000
    1.0000    2.0000    2.0000    2.0000    2.0000    2.0000    0.9000
    2.0000    2.0000    2.0000    2.0000    2.0000    2.0000    0.7000
    2.0000    2.0000    2.0000    2.0000    2.0000    2.0000    0.7000
    2.0000    2.0000    2.0000    2.0000    2.0000    2.0000    1.0000

  Columns 15 through 19

   85.0000   18.0000    4.0000       NaN    1.0000
  135.0000   42.0000    3.5000       NaN    1.0000
   96.0000   32.0000    4.0000       NaN    1.0000
   46.0000   52.0000    4.0000   80.0000    1.0000
       NaN  200.0000    4.0000       NaN    1.0000

予測子 2 ~ 13 および予測子 19 はカテゴリカルであると考えられます。この推論は、UCI Machine Learning Data Repository のデータセットの説明によって確認できます。

カテゴリカル変数をリストします。

catIdx = [2:13,19];

150 の学習器と GentleBoost アルゴリズムを使用して、交差検証を使用したアンサンブルを作成します。

Ensemble = fitcensemble(X,Y,'Method','GentleBoost', ...
    'NumLearningCycles',150,'Learners',t,'PredictorNames',VarNames(2:end), ...
    'LearnRate',0.1,'CategoricalPredictors',catIdx,'KFold',5);
figure;
plot(kfoldLoss(Ensemble,'Mode','cumulative','LossFun','exponential'));
xlabel('Number of trees');
ylabel('Cross-validated exponential loss');

混同行列を検査して、アンサンブルによって正しく予測された患者を確認します。

[yFit,sFit] = kfoldPredict(Ensemble);
confusionmat(Y,yFit,'Order',ClassNames)
ans =

    19    13
    11   112

生存した 123 名の患者については、アンサンブルが 112 名の生存を正しく予測しています。しかし、肝炎で死亡した 32 名については、実際に肝炎で死亡した患者の約半数がアンサンブルにより正しく予測されただけです。

アンサンブルによる予測で発生する誤差には、次の 2 つのタイプがあります。

  • 患者の生存を予測したにも関わらず、患者が死亡した場合

  • 患者の死亡を予測したにも関わらず、患者が生存した場合

1 番目の誤差は 2 番目の誤差より 5 倍の悪影響をもたらすという前提があるとします。この前提を反映した新しい分類コスト行列を作成します。

cost.ClassNames = ClassNames;
cost.ClassificationCosts = [0 5; 1 0];

誤分類のコストに cost を使用する新しい交差検証アンサンブルを作成して、結果の混同行列を検査します。

EnsembleCost = fitcensemble(X,Y,'Method','GentleBoost', ...
    'NumLearningCycles',150,'Learners',t,'PredictorNames',VarNames(2:end), ...
    'LearnRate',0.1,'CategoricalPredictors',catIdx,'KFold',5,'Cost',cost);
[yFitCost,sFitCost] = kfoldPredict(EnsembleCost);
confusionmat(Y,yFitCost,'Order',ClassNames)
ans =

    20    12
     8   115

予想どおり、新しいアンサンブルでは死亡する患者の分類機能が向上しています。意外なことに、新しいアンサンブルでは生存する患者の分類も向上しています。ただし、これは統計的に有意な改善ではありません。交差検証の結果は無作為であるため、この結果は単なる統計変動です。この結果から、生存する患者の分類はコストにあまり大きい影響を与えないと考えることができます。

参考

| | | |

関連するトピック