メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

testcholdout

2 つの分類モデルの予測精度を比較

説明

testcholdout は、2 つの分類モデルの精度を統計的に評価します。この関数では、予測したラベルを真のラベルに対して比較してから、誤分類率の違いが統計的に有意であるかどうかを調べます。

複数の分類モデルの精度が異なるかどうかや、ある分類モデルの性能が別のモデルより優れているかどうかを評価できます。testcholdout では、漸近検定、厳密条件検定、mid-p 値検定など、いくつかのマクネマー検定のバリエーションを実行できます。コストを考慮する評価については、カイ二乗検定 (Optimization Toolbox™ のライセンスが必要) や尤度比検定などの検定を行うことできます。

h = testcholdout(YHat1,YHat2,Y) は、mid-pマクネマー検定を行い、予測したクラス ラベル YHat1 および YHat2 は真のクラス ラベル Y を予測する精度が等しいという帰無仮説を検定した結果を返します。対立仮説は「ラベルの精度は等しくない」です。

h = 1 の場合、帰無仮説は 5% の有意水準で棄却されます。h = 0 の場合、帰無仮説は 5% の水準では棄却されません。

h = testcholdout(YHat1,YHat2,Y,Name,Value) は、1 つ以上の Name,Value ペア引数で指定された追加オプションを適用して行った仮説検定の結果を返します。たとえば、対立仮説のタイプ、検定のタイプ、コスト行列を指定できます。

[h,p,e1,e2] = testcholdout(___) は、前の構文の入力引数のいずれかを使用して、仮説検定の p 値 (p) と、予測したクラス ラベルの各集合に対応する分類損失 (e1e2) を返します。

すべて折りたたむ

異なるアルゴリズムを使用して 2 つの分類モデルを学習させます。ホールドアウト セットに対する 2 つのモデルの誤分類率を比較する統計検定を実行します。

ionosphere データ セットを読み込みます。

load ionosphere

データを学習セットとテスト セットに均等に分割します。

rng(1);                             % For reproducibility
CVP = cvpartition(Y,'holdout',0.5);
idxTrain = training(CVP);           % Training-set indices 
idxTest = test(CVP);                % Test-set indices

CVP は、学習セットとテスト セットを指定する交差検証分割オブジェクトです。

SVM モデルと、バギング分類木が 100 本あるアンサンブルを学習させます。SVM モデルについては、放射基底関数カーネルとヒューリスティック手法を使用してカーネル スケールを決定するように指定します。

MdlSVM = fitcsvm(X(idxTrain,:),Y(idxTrain),'Standardize',true,...
    'KernelFunction','RBF','KernelScale','auto');
t = templateTree('Reproducible',true);  % For reproducibility of random predictor selections
MdlBag = fitcensemble(X(idxTrain,:),Y(idxTrain),'Method','Bag','Learners',t);

MdlSVM は学習済みの ClassificationSVM モデルです。MdlBag は学習済みの ClassificationBaggedEnsemble モデルです。

学習済みのモデルを使用して、テスト セットの観測値にラベルを付けます。

YhatSVM = predict(MdlSVM,X(idxTest,:));
YhatBag = predict(MdlBag,X(idxTest,:));

YhatSVMYhatBag は、対応するモデルで予測したクラス ラベルが格納されているベクトルです。

2 つのモデルの予測精度が同じであるかどうかを検定します。

h = testcholdout(YhatSVM,YhatBag,Y(idxTest))
h = logical
   0

h = 0 なので、2 つのモデルの予測精度が等しいという帰無仮説は棄却できません。

同じアルゴリズムを使用して 2 つの分類モデルを学習させます。ただし、ハイパーパラメーターを調整してアルゴリズムをより複雑にします。複雑なモデルより単純なモデルの方が、ホールドアウト データにおける精度が優れているかどうかを評価する統計検定を実行します。

ionosphere データ セットを読み込みます。

load ionosphere;

データを学習セットとテスト セットに均等に分割します。

rng(1);                             % For reproducibility
CVP = cvpartition(Y,'holdout',0.5);
idxTrain = training(CVP);           % Training-set indices 
idxTest = test(CVP);                % Test-set indices

CVP は、学習セットとテスト セットを指定する交差検証分割オブジェクトです。

線形カーネル (バイナリ分類の既定) を使用する SVM モデルと放射基底関数カーネルを使用する SVM モデルを学習させます。カーネル スケールには、既定値の 1 を使用します。

MdlLinear = fitcsvm(X(idxTrain,:),Y(idxTrain),'Standardize',true);
MdlRBF = fitcsvm(X(idxTrain,:),Y(idxTrain),'Standardize',true,...
    'KernelFunction','RBF');

MdlLinearMdlRBF は学習済みの ClassificationSVM モデルです。

学習済みのモデルを使用して、テスト セットの観測値にラベルを付けます。

YhatLinear = predict(MdlLinear,X(idxTest,:));
YhatRBF = predict(MdlRBF,X(idxTest,:));

YhatLinearYhatRBF は、対応するモデルで予測したクラス ラベルが格納されているベクトルです。

単純なモデル (MdlLinear) の精度は複雑なモデル (MdlRBF) の精度と同程度であるという帰無仮説を検定します。テスト セットのサイズが大きいので、漸近マクネマー検定を実行し、mid-p 値検定 (コストを考慮しない検定の既定) で結果を比較します。p 値と誤分類率を返すように指定します。

Asymp = zeros(4,1); % Preallocation
MidP = zeros(4,1); 

[Asymp(1),Asymp(2),Asymp(3),Asymp(4)] = testcholdout(YhatLinear,YhatRBF,Y(idxTest),...
    'Alternative','greater','Test','asymptotic');
[MidP(1),MidP(2),MidP(3),MidP(4)] = testcholdout(YhatLinear,YhatRBF,Y(idxTest),...
    'Alternative','greater');
table(Asymp,MidP,'RowNames',{'h' 'p' 'e1' 'e2'})
ans=4×2 table
            Asymp          MidP   
          __________    __________

    h              1             1
    p     7.2801e-09    2.7649e-10
    e1       0.13714       0.13714
    e2       0.33143       0.33143

両方の検定で p 値がゼロに近いので、単純なモデルの精度が複雑なモデルの精度より低いという帰無仮説を棄却するだけの十分な証拠が得られました。どの検定を指定しても、testcholdout は両方のモデルについて同じタイプの誤分類尺度を返します。

データ セットのクラスの表現が不均衡である場合や、偽陽性のコストと偽陰性のコストが不均衡である場合、コスト行列を分析に含めることにより、2 つの分類モデルの予測性能を統計的に比較できます。

arrhythmia データ セットを読み込みます。データのクラス表現を判別します。

load arrhythmia;
Y = categorical(Y);
tabulate(Y);
  Value    Count   Percent
      1      245     54.20%
      2       44      9.73%
      3       15      3.32%
      4       15      3.32%
      5       13      2.88%
      6       25      5.53%
      7        3      0.66%
      8        2      0.44%
      9        9      1.99%
     10       50     11.06%
     14        4      0.88%
     15        5      1.11%
     16       22      4.87%

16 個のクラスがありますが、一部はデータ セットで表現されていません (たとえば、クラス 13)。ほとんどの観測値は不整脈がないものとして分類されています (クラス 1)。このデータ セットは非常に離散的であり、クラスが不均衡です。

不整脈があるすべての観測値 (クラス 2 ~ 15) を 1 つのクラスに結合します。不整脈の状況 (クラス 16) が不明である観測値をデータ セットから削除します。

idx = (Y ~= '16');
Y = Y(idx);
X = X(idx,:);
Y(Y ~= '1') = 'WithArrhythmia';
Y(Y == '1') = 'NoArrhythmia';
Y = removecats(Y);

データを学習セットとテスト セットに均等に分割します。

rng(1);                             % For reproducibility
CVP = cvpartition(Y,'holdout',0.5);
idxTrain = training(CVP);           % Training-set indices 
idxTest = test(CVP);                % Test-set indices

CVP は、学習セットとテスト セットを指定する交差検証分割オブジェクトです。

コスト行列を作成します。不整脈がある患者を不整脈なしのクラスに誤分類した場合はコストを高くし、不整脈がない患者を不整脈ありのクラスに誤分類した場合の 5 倍にします。正しく分類した場合、コストは発生しません。行は真のクラスを、列は予測したクラスを表します。コストを考慮する分析を実行するときは、クラスの順序を指定することをお勧めします。

Cost = [0 1;5 0];
ClassNames = {'NoArrhythmia','WithArrhythmia'};

50 本の分類木がある 2 つのブースティング アンサンブルに学習をさせます。一方では AdaBoostM1 を、もう一方では LogitBoost を使用します。データ セットには欠損値が含まれているので、代理分岐を使用するよう指定します。コスト行列を使用してモデルを学習させます。

t = templateTree('Surrogate','on');
numTrees = 50;
MdlAda = fitcensemble(X(idxTrain,:),Y(idxTrain),'Method','AdaBoostM1',...
    'NumLearningCycles',numTrees,'Learners',t,...
    'Cost',Cost,'ClassNames',ClassNames);
MdlLogit = fitcensemble(X(idxTrain,:),Y(idxTrain),'Method','LogitBoost',...
    'NumLearningCycles',numTrees,'Learners',t,...
    'Cost',Cost,'ClassNames',ClassNames);

MdlAdaMdlLogit は学習済みの ClassificationEnsemble モデルです。

学習済みのモデルを使用して、テスト セットの観測値にラベルを付けます。

YhatAda = predict(MdlAda,X(idxTest,:));
YhatLogit = predict(MdlLogit,X(idxTest,:));

YhatLinearYhatRBF は、対応するモデルで予測したクラス ラベルが格納されているベクトルです。

AdaBoostM1 アンサンブル (MdlAda) と LogitBoost アンサンブル (MdlLogit) で予測精度が等しいかどうかを検定します。コスト行列を渡します。コストを考慮する漸近的な尤度比検定 (コスト行列を渡す場合の既定) を実行します。p 値と誤分類コストを返すように指定します。

[h,p,e1,e2] = testcholdout(YhatAda,YhatLogit,Y(idxTest), ...
    'Cost',Cost,'ClassNames',ClassNames)
h = logical
   0

p = 
0.1180
e1 = 
0.6698
e2 = 
0.8093

h = 0 なので、2 つのモデルの予測精度が等しいという帰無仮説は棄却できません。

入力引数

すべて折りたたむ

1 番目の分類モデルで予測したクラス ラベル。categorical 配列、文字配列、string 配列、logical ベクトル、数値ベクトル、または文字ベクトルの cell 配列を指定します。

YHat1 が文字配列の場合、各要素は配列の 1 つの行に対応しなければなりません。

YHat1YHat2 および Y は長さが同じでなければなりません。

YHat1YHat2 および Y を同じデータ型にすることをお勧めします。

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

2 番目の分類モデルで予測したクラス ラベル。categorical 配列、文字配列、string 配列、logical ベクトル、数値ベクトル、または文字ベクトルの cell 配列を指定します。

YHat2 が文字配列の場合、各要素は配列の 1 つの行に対応しなければなりません。

YHat1YHat2 および Y は長さが同じでなければなりません。

YHat1YHat2 および Y を同じデータ型にすることをお勧めします。

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

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

Y が文字配列の場合、各要素は配列の 1 つの行に対応しなければなりません。

YHat1YHat2 および Y は長さが同じでなければなりません。

YHat1YHat2 および Y を同じデータ型にすることをお勧めします。

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

名前と値の引数

すべて折りたたむ

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

R2021a より前では、名前と値をそれぞれコンマを使って区切り、Name を引用符で囲みます。

例: 'Alternative','greater','Test','asymptotic','Cost',[0 2;1 0] を指定すると、予測したクラス ラベルの 1 番目のセットが 2 番目のセットより正確であるかどうかが検定されます。漸近的なマクネマー検定を実行すると、真のラベル ClassNames{1} をもつ観測値を誤分類した場合は、真のラベル ClassNames{2} をもつ観測値を誤分類した場合より、ペナルティが 2 倍になります。

仮説検定の有意水準。'Alpha' と (0, 1) の範囲にあるスカラー値をコンマで区切って指定します。

例: 'Alpha',0.1

データ型: single | double

評価する対立仮説。'Alternative' と次の表に記載されている値のいずれかをコンマ区切りのペアとして指定します。

対立仮説
'unequal' (既定の設定)Y の予測について、YHat1YHat2 は精度が等しくない。
'greater'Y の予測について、YHat1YHat2 より精度が高い。
'less'Y の予測について、YHat1YHat2 より精度が低い。

例: 'Alternative','greater'

クラス名。'ClassNames' と categorical 配列、文字配列、string 配列、logical ベクトル、数値ベクトル、または文字ベクトルの cell 配列から構成されるコンマ区切りのペアとして指定します。ClassNamesY のデータ型を使用して設定しなければなりません。

ClassNames が文字配列の場合、各要素は配列の 1 つの行に対応しなければなりません。

ClassNames の使用目的は次のとおりです。

  • クラスの順序に対応する入力引数の次元の順序を指定する。たとえば、Cost の次元の順序を指定するために ClassNames を使用します。

  • 検定用にクラスのサブセットを選択する。たとえば、Y に含まれているすべての異なるクラス名の集合が {'a','b','c'} であるとします。クラス 'a' および 'c' のみの観測値を使用してモデルの学習と検定を行うには、'ClassNames',{'a','c'} を指定します。

既定の設定は、Y に含まれているすべての異なるクラス名の集合です。

例: 'ClassNames',{'b','g'}

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

誤分類のコスト。'Cost' と正方行列または構造体配列をコンマで区切って指定します。

  • 正方行列 Cost を指定する場合、Cost(i,j) は真のクラスが i の点をクラス j に分類するコストです。つまり、行は真のクラスに、列は予測するクラスに対応します。Cost の対応する行および列についてクラスの順序を指定するには、名前と値のペアの引数 ClassNames をさらに指定します。

  • 構造体 S を指定する場合、S には次の 2 つのフィールドが必要です。

    • S.ClassNamesY と同じデータ型の変数としてクラス名を格納します。このフィールドを使用してクラスの順序を指定できます。

    • S.ClassificationCosts。行と列の順序が S.ClassNames と同じであるコスト行列。

Cost を指定した場合、testcholdout では片側検定、厳密検定および mid-p 検定を実行できません。'Alternative','unequal','Test','asymptotic' も指定しなければなりません。コストを考慮する検定のオプションについては、名前と値のペアの引数 CostTest を参照してください。

分類モデルに学習をさせるために使用したものと同じコスト行列を渡すことをお勧めします。

既定値は、i ~= j の場合は Cost(i,j) = 1i = j の場合は Cost(i,j) = 0 です。

例: 'Cost',[0 1 2 ; 1 0 2; 2 2 0]

データ型: single | double | struct

コストを考慮する検定のタイプ。'CostTest''chisquare' または 'likelihood' をコンマ区切りのペアとして指定します。Cost の名前と値のペアの引数を使用してコスト行列を指定しない限り、testcholdout では CostTest が無視されます。

次の表に、コストを考慮する検定で利用できるオプションの概要を示します。

漸近検定のタイプ要件
'chisquare'カイ二乗検定quadprog (Optimization Toolbox) を実装するための Optimization Toolbox のライセンス
'likelihood'尤度比検定なし

詳細は、コストを考慮する検定を参照してください。

例: 'CostTest','chisquare'

実行する検定。'Test''asymptotic''exact' または 'midp' をコンマで区切って指定します。次の表に、コストを考慮しない検定で利用できるオプションの概要を示します。

説明
'asymptotic'漸近的なマクネマー検定
'exact'厳密条件マクネマー検定
'midp' (既定の設定)mid-p 値マクネマー検定

詳細は、マクネマー検定を参照してください。

コストを考慮する検定の場合、Test'asymptotic' でなければなりません。Cost の名前と値のペア引数を指定し、コストを考慮する検定で CostTest の名前と値のペアの引数を使用する場合、'asymptotic' が既定になります。

例: 'Test','asymptotic'

メモ

NaN<undefined> 値、空の文字ベクトル ('')、空の string ("")、および <missing> 値は、欠損データ値を示します。testcholdout では次のようになります。

  • YHat1YHat2 の欠損値は、誤分類観測値として扱われます。

  • Y の欠損値と、YHat1 および YHat2 の対応する値が削除されます。

出力引数

すべて折りたたむ

論理値として返される仮説検定の結果。

h = 1 の場合、有意水準 Alpha で帰無仮説が棄却されます。

h = 0 の場合、有意水準 Alpha では帰無仮説を棄却できません。

データ型: logical

検定の p 値。[0,1] の範囲にあるスカラー値として返されます。p は、帰無仮説が真であると仮定した場合に、観測された検定統計量よりも無作為な検定統計量の方が極端な値になる確率です。

testcholdout では、検定のタイプによって異なる検定統計量の分布を使用して p を推定します。マクネマー検定のバリエーションから導き出される検定統計量についての詳細は、マクネマー検定を参照してください。コストを考慮する検定から導き出される検定統計量についての詳細は、コストを考慮する検定を参照してください。

1 番目のクラス ラベルのセット (YHat1) で真のクラス ラベル (Y) を予測する精度を要約した分類損失。スカラー値として返されます。

コストを考慮しない検定の場合、e1 は誤分類率です。つまり、e1 は誤分類した観測値の比率であり、[0,1] の範囲にあるスカラー値になります。

コストを考慮する検定の場合、e1 は誤分類コストです。つまり、e1 は誤分類コストの加重平均です。この場合の重みは、誤分類した観測値についてそれぞれ推定した比率です。

2 番目のクラス ラベルのセット (YHat2) で真のクラス ラベル (Y) を予測する精度を要約した分類損失。スカラー値として返されます。

コストを考慮しない検定の場合、e2 は誤分類率です。つまり、e2 は誤分類した観測値の比率であり、[0,1] の範囲にあるスカラー値になります。

コストを考慮する検定の場合、e2 は誤分類コストです。つまり、e2 は誤分類コストの加重平均です。この場合の重みは、誤分類した観測値についてそれぞれ推定した比率です。

詳細

すべて折りたたむ

ヒント

  • 予測したクラス ラベルを取得するには、学習済みの分類モデルと新しい予測子データを predict メソッドに渡すことをお勧めします。たとえば、SVM モデルで予測したラベルについては、predict を参照してください。

  • コストを考慮する検定では数値を最適化しますが、これには追加の計算リソースが必要です。尤度比検定では、ある区間におけるラグランジュ乗数の根を求めるため間接的に数値を最適化します。データ セットによっては、根が区間の境界付近にある場合、メソッドが失敗する可能性があります。このため、Optimization Toolbox のライセンスがある場合は、コストを考慮するカイ二乗検定を代わりに実行することを検討してください。詳細は、CostTestおよびコストを考慮する検定を参照してください。

参照

[1] Agresti, A. Categorical Data Analysis, 2nd Ed. John Wiley & Sons, Inc.: Hoboken, NJ, 2002.

[2] Fagerlan, M.W., S. Lydersen, and P. Laake. “The McNemar Test for Binary Matched-Pairs Data: Mid-p and Asymptotic Are Better Than Exact Conditional.” BMC Medical Research Methodology. Vol. 13, 2013, pp. 1–8.

[3] Lancaster, H.O. “Significance Tests in Discrete Distributions.” JASA, Vol. 56, Number 294, 1961, pp. 223–234.

[4] McNemar, Q. “Note on the Sampling Error of the Difference Between Correlated Proportions or Percentages.” Psychometrika, Vol. 12, Number 2, 1947, pp. 153–157.

[5] Mosteller, F. “Some Statistical Problems in Measuring the Subjective Response to Drugs.” Biometrics, Vol. 8, Number 3, 1952, pp. 220–226.

バージョン履歴

R2015a で導入

参考

トピック