Main Content

cvpartition

交差検証用のデータの分割

説明

cvpartition は、データ セットにおける無作為分割を定義します。この分割は、交差検証を使って統計モデルを検証するためにテスト セットと学習セットを定義するときに使用します。学習インデックスの抽出のために training を使用し、交差検証用にテスト インデックスを抽出するために test を使用します。repartition は、与えられた cvpartition オブジェクトと同じタイプの、新しい無作為分割を定義するために使用します。

作成

説明

c = cvpartition(n,"KFold",k) は、n 個の観測値に対する k 分割交差検証用の無作為な非層化区分を定義する cvpartition オブジェクト c を返します。観測値は、各副標本の観測値の数がほぼ同じになるように、k 個の副標本 (分割) に無作為に分割されます。

c = cvpartition(n,"Holdout",p) は、n 個の観測値に対するホールドアウト検証用の無作為な非層化区分を作成します。観測値は学習セットとテスト (ホールドアウト) セットに分割されます。

c = cvpartition(group,"KFold",k) は、層化 k 分割交差検証用の無作為分割を作成します。各副標本 (分割) の観測値の数およびクラスの比率は group とほぼ同じです。

group を最初の入力引数として指定した場合、cvpartitiongroup の欠損値に対応する観測値の行を破棄します。

c = cvpartition(group,"KFold",k,"Stratify",stratifyOption) は、k 分割交差検証用の無作為分割を定義する cvpartition オブジェクト c を返します。"Stratify",false を指定した場合、cvpartitiongroup のクラス情報を無視し、無作為な非層化区分を作成します。そうでない場合、既定で階層化が実装されます。

c = cvpartition(group,"Holdout",p) は、group のクラス情報を使用して、観測値を階層的に学習セットとテスト (ホールドアウト) セットに無作為に分割します。学習セットとテスト セットはどちらも、クラスの比率が group とほぼ同じになります。

c = cvpartition(group,"Holdout",p,"Stratify",stratifyOption) は、学習セットとテスト (ホールドアウト) セットへの無作為分割を定義するオブジェクト c を返します。"Stratify",false を指定した場合、cvpartition は無作為な非層化区分を作成します。そうでない場合、既定で階層化が実装されます。

c = cvpartition(n,"Leaveout") は、n 個の観測値に対する leave-one-out 交差検証用の無作為分割を作成します。Leave-one-out 法は "KFold" の特別なケースであり、分割数が観測値の個数と等しくなります。

c = cvpartition(n,"Resubstitution") は、データを分割しないオブジェクト c を作成します。学習セットとテスト データのどちらも元の n 個の観測をすべて含みます。

c = cvpartition("CustomPartition",testSets) は、testSets で示されるテスト セットに基づいてデータを分割する cvpartition オブジェクト c を作成します。 (R2023b 以降)

入力引数

すべて展開する

標本データに含まれている観測値の数。正の整数スカラーとして指定します。

例: 100

データ型: single | double

パーティションの分割数。正の整数スカラーとして指定します。k は観測値の総数よりも小さくなければなりません。

例: 5

データ型: single | double

ホールドアウト検証に使用されるテスト セット内の観測値の比率または数。範囲 (0,1) のスカラー、または範囲 [1,n) の整数スカラーとして指定します。ここで、n は観測値の総数です。

  • p が範囲 (0,1) のスカラーの場合、cvpartition はテスト セットとして約 p*n 個の観測値を無作為に選択します。

  • p が範囲 [1,n) の整数スカラーの場合、cvpartition はテスト セットとして p 個の観測値を無作為に選択します。

例: 0.2

例: 50

データ型: single | double

階層化のためのグループ化変数。数値ベクトル、logical ベクトル、categorical 配列、文字配列、string 配列、または各観測値のクラスを示す文字ベクトルの cell 配列として指定します。cvpartition は、group 内の観測値から分割を作成します。

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

階層化のインジケーター。true または false として指定します。

  • cvpartition に対する最初の入力引数が group の場合、cvpartition は既定で階層化を実装します ("Stratify",true)。無作為な非層化区分では、"Stratify",false を指定してください。

  • cvpartition に対する最初の入力引数が n の場合、cvpartition は常に無作為な非層化区分を作成します ("Stratify",false)。この場合、"Stratify",true は指定できません。

データ型: logical

R2023b 以降

カスタム テスト セット。正の整数ベクトル、logical ベクトル、または logical 行列として指定します。

  • ホールドアウト検証の場合、logical ベクトルを使用してテスト セットの観測値を指定します。値 1 (true) は対応する観測値がテスト セット内にあることを示し、値 0 (false) は対応する観測値が学習セット内にあることを示します。

  • k 分割交差検証の場合、整数ベクトル (値の範囲は [1,k]) または k 列の logical 行列を使用してテスト セットの観測値を指定します。

    • 整数ベクトル — j の値は、対応する観測値がテスト セット j 内にあることを示します。

    • logical 行列 — 行 i の列 j の値は、観測値 i がテスト セット j 内にあるかどうかを示します。

    k のテスト セットのそれぞれに少なくとも 1 つの観測値が含まれていなければなりません。

  • leave-one-out 交差検証の場合、整数ベクトル (値の範囲は [1,n]) または n 行 n 列の logical 行列を使用してテスト セットの観測値を指定します。ここで、n はデータ内の観測値の数です。

    • 整数ベクトル — j の値は、対応する観測値がテスト セット j 内にあることを示します。

    • logical 行列 — 行 i の列 j の値は、観測値 i がテスト セット j 内にあるかどうかを示します。

例: "CustomPartition",[true false true false false] は、1 番目と 3 番目の観測値がテスト セット内にあるホールドアウト検証方式を示します。

例: "CustomPartition",[1 2 2 1 3 3 1 2 3 2] は、1 番目、4 番目、および 7 番目の観測値が 1 番目のテスト セット内にある 3 分割交差検証方式を示します。

データ型: single | double | logical

プロパティ

すべて展開する

R2023b 以降

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

カスタム分割のインジケーター。logical スカラーとして指定します。カスタム分割を使用して作成されたオブジェクトの場合、値は 1 (true) です。それ以外の場合、値は 0 (false) です。

データ型: logical

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

観測値の数 (欠損した group の値をもつ観測値を含む)。正の整数スカラーとして指定します。

データ型: double

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

分割内のテスト セットの総数。分割タイプが 'kfold' または 'leaveout' の場合は分割の数として指定し、分割タイプが 'holdout' または 'resubstitution' の場合は 1 として指定します。

データ型: double

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

各テスト セットのサイズ。分割タイプが 'kfold' または 'leaveout' の場合は正の整数ベクトルとして指定し、分割タイプが 'holdout' または 'resubstitution' の場合は正の整数スカラーとして指定します。

データ型: double

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

各学習セットのサイズ。分割タイプが 'kfold' または 'leaveout' の場合は正の整数ベクトルとして指定し、分割タイプが 'holdout' または 'resubstitution' の場合は正の整数スカラーとして指定します。

データ型: double

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

検証分割のタイプ。'kfold''holdout''leaveout''resubstitution' のいずれかとして指定します。

オブジェクト関数

repartition交差検証のための再分割データ
test交差検証用のテスト インデックス
training交差検証用の学習インデックス

すべて折りたたむ

交差検証の誤分類誤差を使用して、モデルが新しいデータでどのように実行されるかを推定します。

ionosphere データ セットを読み込みます。予測子データ X と応答変数 Y を含むテーブルを作成します。

load ionosphere
tbl = array2table(X);
tbl.Y = Y;

無作為な非層化区分 hpartition を使用し、データを学習データ (tblTrain) と予約されたデータ セット (tblNew) に分割します。データの約 30% を予約します。

rng('default') % For reproducibility
n = length(tbl.Y);
hpartition = cvpartition(n,'Holdout',0.3); % Nonstratified partition
idxTrain = training(hpartition);
tblTrain = tbl(idxTrain,:);
idxNew = test(hpartition);
tblNew = tbl(idxNew,:);

学習データ tblTrain を使用して、サポート ベクター マシン (SVM) 分類モデルに学習させます。学習データの誤分類誤差と分類精度を計算します。

Mdl = fitcsvm(tblTrain,'Y');
trainError = resubLoss(Mdl)
trainError = 0.0569
trainAccuracy = 1-trainError
trainAccuracy = 0.9431

通常、学習データの誤分類誤差は、新しいデータの誤分類率を過小評価する可能性があるため、モデルが新しいデータでどのように実行されるかを適切に推定できません。より正確な推定は、交差検証誤差です。

分割されたモデル cvMdl を作成します。10 分割交差検証の誤分類誤差と分類精度を計算します。既定で、crossval では必ず、各分割のクラス比率が応答変数 tblTrain.Y のクラス比率とほぼ同じに維持されます。

cvMdl = crossval(Mdl); % Performs stratified 10-fold cross-validation
cvtrainError = kfoldLoss(cvMdl)
cvtrainError = 0.1220
cvtrainAccuracy = 1-cvtrainError
cvtrainAccuracy = 0.8780

交差検証誤差 cvtrainError が再代入誤差 trainError より大きいことに注意してください。

学習済みの SVM モデルを使用し、tblNew の新しいデータを分類します。新しいデータの分類精度を推定精度 trainAccuracy および cvtrainAccuracy と比較します。

newError = loss(Mdl,tblNew,'Y');
newAccuracy = 1-newError
newAccuracy = 0.8700

交差検証誤差では、再代入誤差と比較して、新しいデータにおけるモデル性能の推定が正確になります。

2 つのモデルの誤分類率を計算するには、5 分割交差検証に同じ層化区分を使用します。

fisheriris データ セットを読み込みます。行列 meas には、150 種類の花についての測定値が格納されています。変数 species には、それぞれの花の種類がリストされています。

load fisheriris

層化 5 分割交差検証用に分割を無作為に作成します。学習セットとテスト セットは、花の種類の割合が species とほぼ同じです。

rng('default') % For reproducibility
c = cvpartition(species,'KFold',5);

c を使用して、分割された判別分析モデルと分割された分類木モデルを作成します。

discrCVModel = fitcdiscr(meas,species,'CVPartition',c);
treeCVModel = fitctree(meas,species,'CVPartition',c);

分割された 2 つのモデルの誤分類率を計算します。

discrRate = kfoldLoss(discrCVModel)
discrRate = 0.0200
treeRate = kfoldLoss(treeCVModel)
treeRate = 0.0333

判別分析モデルでは、交差検証の誤分類率が小さくなります。

fisheriris データの 5 分割された非層化区分でテスト セット (分割) のクラスの比率を観測します。クラスの比率は分割によって異なります。

fisheriris データ セットを読み込みます。変数 species には、それぞれの花 (観測値) に対する種の名前 (クラス) が格納されています。species を変数 categorical に変換します。

load fisheriris
species = categorical(species);

各クラスの観測値の数を求めます。3 つのクラスが同じ比率になっていることに注意してください。

C = categories(species) % Class names
C = 3x1 cell
    {'setosa'    }
    {'versicolor'}
    {'virginica' }

numClasses = size(C,1);
n = countcats(species) % Number of observations in each class
n = 3×1

    50
    50
    50

階層のない 5 つの部分に無作為に分割します。

rng('default') % For reproducibility
cv = cvpartition(species,'KFold',5,'Stratify',false) 
cv = 
K-fold cross validation partition
   NumObservations: 150
       NumTestSets: 5
         TrainSize: 120  120  120  120  120
          TestSize: 30  30  30  30  30
          IsCustom: 0

5 つのテスト セット (分割) のそれぞれで、3 つのクラスが同じ比率で出現しないことを示します。for ループを使用して行列 nTestData を更新し、各エントリ nTestData(i,j) がテスト セット i とクラス C(j) における観測値の数に対応するようにします。nTestData のデータから棒グラフを作成します。

numFolds = cv.NumTestSets;
nTestData = zeros(numFolds,numClasses);
for i = 1:numFolds
    testClasses = species(cv.test(i));
    nCounts = countcats(testClasses); % Number of test set observations in each class
    nTestData(i,:) = nCounts';
end

bar(nTestData)
xlabel('Test Set (Fold)')
ylabel('Number of Observations')
title('Nonstratified Partition')
legend(C)

Figure contains an axes object. The axes object with title Nonstratified Partition, xlabel Test Set (Fold), ylabel Number of Observations contains 3 objects of type bar. These objects represent setosa, versicolor, virginica.

一部のテスト セットではクラスの比率が異なることに注意してください。たとえば、最初のテスト セットでは、すべての種類の花が 10 本ずつになるのではなく、setosa 種の花が 8 本、versicolor 種の花が 13 本、virginica 種の花が 9 本となっています。cvfisheriris データの無作為な非層化区分なので、各テスト セット (分割) におけるクラス比率は必ずしも species のクラス比率と等しくなるとは限りません。つまり、species とは異なり、各テスト セットでは、クラスの比率が必ずしも等しくなるとは限りません。

tall 配列に対する非層化ホールドアウト分割と層化ホールドアウト分割を作成します。2 つのホールドアウト セットについて、各クラスの観測値の数を比較します。

tall 配列に対する計算を実行する場合、MATLAB® は並列プール (Parallel Computing Toolbox™ がある場合は既定) またはローカルの MATLAB セッションを使用します。Parallel Computing Toolbox がある場合にローカルの MATLAB セッションを使用して例を実行するには、関数 mapreducer を使用してグローバルな実行環境を変更します。

mapreducer(0)

クラス 1 とクラス 2 の比率が 1:10 になるように、2 つのクラスの数値ベクトルを作成します。

group = [ones(20,1);2*ones(200,1)]
group = 220×1

     1
     1
     1
     1
     1
     1
     1
     1
     1
     1
      ⋮

group から tall 配列を作成します。

tgroup = tall(group)
tgroup =

  220x1 tall double column vector

     1
     1
     1
     1
     1
     1
     1
     1
     :
     :

tall 配列がサポートされている cvpartition のオプションは Holdout だけです。非層化ホールドアウト分割を無作為に作成します。

CV0 = cvpartition(tgroup,'Holdout',1/4,'Stratify',false)  
CV0 = 
Hold-out cross validation partition
   NumObservations: [1x1 tall]
       NumTestSets: 1
         TrainSize: [1x1 tall]
          TestSize: [1x1 tall]
          IsCustom: 0

関数 gather を使用して、CV0.test の結果をメモリに取得します。

testIdx0 = gather(CV0.test);
Evaluating tall expression using the Local MATLAB Session:
- Pass 1 of 1: Completed in 0.29 sec
Evaluation completed in 0.4 sec

テスト (ホールドアウト) セットにおける各クラスの出現回数を求めます。

accumarray(group(testIdx0),1) % Number of observations per class in the holdout set
ans = 2×1

     5
    51

cvpartition の結果には無作為性があるので、各クラスの観測値の数はここに示されているものと異なる可能性があります。

CV0 は非層化区分のため、ホールドアウト セットにおけるクラス 1 の観測値とクラス 2 の観測値は必ずしも tgroup と同じ比率になるとは限りません。ただし、cvpartition には無作為性があるので、'Stratify',false を指定した場合でも、ホールドアウト セットにおけるクラスの比率が tgroup と同じになることがあります。学習セットはホールドアウト セットから NaN や欠損している観測値を除いた補完セットであるため、学習セットでも同様の結果を得ることができます。

CV0.training の結果をメモリに取得します。

trainIdx0 = gather(CV0.training);
Evaluating tall expression using the Local MATLAB Session:
- Pass 1 of 1: Completed in 0.097 sec
Evaluation completed in 0.14 sec

学習セットにおける各クラスの発生数を求めます。

accumarray(group(trainIdx0),1) % Number of observations per class in the training set
ans = 2×1

    15
   149

非層化学習セットで出現するクラスの比率は必ずしも tgroup と同じになるとは限りません。

層化ホールドアウト分割を無作為に作成します。

CV1 = cvpartition(tgroup,'Holdout',1/4)  
CV1 = 
Hold-out cross validation partition
   NumObservations: [1x1 tall]
       NumTestSets: 1
         TrainSize: [1x1 tall]
          TestSize: [1x1 tall]
          IsCustom: 0

CV1.test の結果をメモリに取得します。

testIdx1 = gather(CV1.test);
Evaluating tall expression using the Local MATLAB Session:
- Pass 1 of 1: Completed in 0.12 sec
Evaluation completed in 0.15 sec

テスト (ホールドアウト) セットにおける各クラスの出現回数を求めます。

accumarray(group(testIdx1),1) % Number of observations per class in the holdout set
ans = 2×1

     5
    51

層化ホールドアウト分割の場合は、ホールドアウト セットと tgroup でクラスの比率が同じ (1:10) になります。

leave-one-out 交差検証用にデータを無作為に分割します。学習セットの平均を計算して比較します。有意に異なる平均値をもつ反復値は、影響力のある観測値が存在することを示唆しています。

1 つだけ非常に大きい値を含むデータ セット X を作成します。

X = [1 2 3 4 5 6 7 8 9 20]';

学習データとテスト データのうち 10 個の観測値と 10 個の反復値をもつ cvpartition オブジェクトを作成します。各反復値について、cvpartition は観測値を 1 つ選択し、学習セットから削除してテスト セットのために予約します。

c = cvpartition(10,'Leaveout')
c = 
Leave-one-out cross validation partition
   NumObservations: 10
       NumTestSets: 10
         TrainSize: 9  9  9  9  9  9  9  9  9  9
          TestSize: 1  1  1  1  1  1  1  1  1  1
          IsCustom: 0

leave-one-out 分割を X に適用し、crossval を使用して反復値ごとに学習観測値の平均を計算します。

values = crossval(@(Xtrain,Xtest)mean(Xtrain),X,'Partition',c)
values = 10×1

    6.5556
    6.4444
    7.0000
    6.3333
    6.6667
    7.1111
    6.8889
    6.7778
    6.2222
    5.0000

ボックス チャート (箱ひげ図) を使用して、学習セットの平均の分布を表示します。プロットでは外れ値が 1 つ表示されます。

boxchart(values)

Figure contains an axes object. The axes object contains an object of type boxchart.

外れ値に対応する反復値を見つけます。その反復値について、テスト セットで観測値を見つけます。

[~,repetitionIdx] = min(values)
repetitionIdx = 10
observationIdx = test(c,repetitionIdx);
influentialObservation = X(observationIdx)
influentialObservation = 20

その観測値を含む学習セットとその観測値を含まない学習セットでは、平均値が大きく異なります。平均値のこのように大きな変化は、X 内の 20 という値が影響力のある観測値であることを示しています。

カスタムの 4 分割交差検証分割を指定して、交差検証済みの回帰木を作成します。

carbig データ セットを読み込みます。応答変数 MPG と予測子変数 AccelerationCylinders などを格納する table Tbl を作成します。

load carbig
Tbl = table(Acceleration,Cylinders,Displacement, ...
    Horsepower,Model_Year,Weight,Origin,MPG);

欠損値を含む観測値を削除します。欠損値がある観測値を削除した後の table のデータのサイズを確認します。

Tbl = rmmissing(Tbl);
dimensions = size(Tbl)
dimensions = 1×2

   392     8

結果の table には 392 個の観測値が含まれています (392/4=98)。

Tbl のデータからカスタムの 4 分割交差検証分割を作成します。最初の 98 個の観測値を 1 番目のテスト セット、次の 98 個の観測値を 2 番目のテスト セットのように順番に配置します。

testSet = ones(98,1);
testIndices = [testSet; 2*testSet; ...
    3*testSet; 4*testSet];
c = cvpartition("CustomPartition",testIndices)
c = 
K-fold cross validation partition
   NumObservations: 392
       NumTestSets: 4
         TrainSize: 294  294  294  294
          TestSize: 98  98  98  98
          IsCustom: 1

カスタム分割 c を使用して、交差検証済みの回帰木に学習させます。モデルの性能を評価するには、交差検証平均二乗誤差 (MSE) を計算します。

cvMdl = fitrtree(Tbl,"MPG","CVPartition",c);
cvMSE = kfoldLoss(cvMdl)
cvMSE = 21.2223

ヒント

  • cvpartition に対する最初の入力引数として group を指定した場合、group の欠損値に対応する観測値の行が破棄されます。

  • cvpartition に対する最初の入力引数として group を指定した場合、既定で階層化が実装されます。"Stratify",false を指定すると、無作為な非層化区分を作成できます。

  • "Stratify",true を指定できるのは、cvpartition に対する最初の入力引数が group である場合だけです。

拡張機能

バージョン履歴

R2008a で導入

すべて展開する