3

私は行列(MatLabでは構造体と呼んでいると思います)またはデータ構造を持っています:

  data: [150x4 double]
labels: [150x1 double]

これが私のmatrix.dataで、matrixという名前のファイルをロードすると仮定したように見えます。

5.1000    3.5000    1.4000    0.2000
4.9000    3.0000    1.4000    0.2000
4.7000    3.2000    1.3000    0.2000
4.6000    3.1000    1.5000    0.2000
5.0000    3.6000    1.4000    0.2000
5.4000    3.9000    1.7000    0.4000
4.6000    3.4000    1.4000    0.3000
5.0000    3.4000    1.5000    0.2000
4.4000    2.9000    1.4000    0.2000
4.9000    3.1000    1.5000    0.1000
5.4000    3.7000    1.5000    0.2000
4.8000    3.4000    1.6000    0.2000
4.8000    3.0000    1.4000    0.1000
4.3000    3.0000    1.1000    0.1000
5.8000    4.0000    1.2000    0.2000
5.7000    4.4000    1.5000    0.4000
5.4000    3.9000    1.3000    0.4000
5.1000    3.5000    1.4000    0.3000
5.7000    3.8000    1.7000    0.3000
5.1000    3.8000    1.5000    0.3000

そして、これが私のmatrix.labelsのようになります

 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1
 1

MatLabの既存の関数を使用せずに、10個のクロスフォールド検証を作成しようとしていますが、MatLabの知識が非常に限られているため、自分が持っているものから先に進むのに問題があります。どんな助けでも素晴らしいでしょう。

これは私がこれまでに持っているものであり、これはおそらくmatlabの方法ではないと確信していますが、私はmatlabに非常に慣れていません。

function[output] = fisher(dataFile, number_of_folds)
    data = load(dataFile);
    %create random permutation indx
    idx = randperm(150);
    output = data.data(idx(1:15),:);
end
4

2 に答える 2

5

これが、この相互検証に対する私の見解です。magic(10)を使用してダミーデータを作成し、ランダムにラベルを作成します。アイデアは次のとおりです。データとラベルを取得し、それらをランダムな列と組み合わせます。次のダミーコードを検討してください。

>> data = magic(4)

data =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

>> dataRowNumber = size(data,1)

dataRowNumber =

     4

>> randomColumn = rand(dataRowNumber,1)

randomColumn =

    0.8147
    0.9058
    0.1270
    0.9134


>> X = [ randomColumn data]

X =

    0.8147   16.0000    2.0000    3.0000   13.0000
    0.9058    5.0000   11.0000   10.0000    8.0000
    0.1270    9.0000    7.0000    6.0000   12.0000
    0.9134    4.0000   14.0000   15.0000    1.0000

Xを列1に従って並べ替えると、データがランダムに並べ替えられます。これにより、交差検定のランダム性が得られます。次に、交差検定のパーセンテージに従ってXを除算します。1つのケースでこれを達成するのは簡単です。%75%がトレインケースで、%25%がテストケースであると考えてみましょう。ここでのサイズは4で、3/4 =%75、1/4は%25です。

testDataset = X(1,:)
trainDataset = X(2:4,:)

しかし、これをNクロスフォールドで達成するのは少し難しいです。これをN回作る必要があるので。これにはforループが必要です。5つのクロスフォールド用。私は、最初のfで取得します

  1. 1回目:テスト用に1 2、電車用に3:10
  2. 2つ目:テストの場合は3 4、電車の場合は1 25:10
  3. 3つ目:テストの場合は5 6、電車の場合は1:47:10
  4. 4つ目:テストの場合は7 8、電車の場合は1:69:10
  5. 5倍:テストの場合は9 10、電車の場合は1:8

次のコードは、このプロセスの例です。

data = magic(10);
dataRowNumber = size(data,1);
labels= rand(dataRowNumber,1) > 0.5;
randomColumn = rand(dataRowNumber,1);

X = [ randomColumn data labels];


SortedData = sort(X,1);

crossValidationFolds = 5;
numberOfRowsPerFold = dataRowNumber / crossValidationFolds;

crossValidationTrainData = [];
crossValidationTestData = [];
for startOfRow = 1:numberOfRowsPerFold:dataRowNumber
    testRows = startOfRow:startOfRow+numberOfRowsPerFold-1;
    if (startOfRow == 1)
        trainRows = [max(testRows)+1:dataRowNumber];
        else
        trainRows = [1:startOfRow-1 max(testRows)+1:dataRowNumber];
    end
    crossValidationTrainData = [crossValidationTrainData ; SortedData(trainRows ,:)];
    crossValidationTestData = [crossValidationTestData ;SortedData(testRows ,:)];

end
于 2012-09-27T22:41:35.957 に答える
3

ハハハ申し訳ありませんが、解決策はありません。現在MATLABを使用していないため、コードのエラーをチェックできません。しかし、ここに一般的な考え方があります:

  1. k(この場合は10)サブサンプルを生成します
    1. 1から2つのカウンターを開始し、新しいマトリックスを事前に割り当てます。index = 1; subsample = 1; newmat = zeros("150","6")<150はサンプル数、6=4ワイドデータ+1ワイドラベル+1後で使用します
    2. あなたがまだデータを持っている間:while ( length(labels) > 0 )
    3. 残っているデータ量の範囲内で乱数を生成しrandNum = randi(length(labels))ます。これは、1からラベル配列のサイズまでのランダムな整数だと思います(0の場合もあります。ドキュメントを確認してください。そうである場合は、簡単な計算を行って1 <rand <lengthにします)
    4. その行をラベル付きの新しいデータセットに追加します。newmat(index,:) = [data(randNum,:) labels(randNum) subsample]<その最後の列は1〜10のサブサンプル番号です
    5. データとラベルから行を削除します。data(randNum,:) = []; same for labels<これにより、行列から行が物理的に削除されることに注意してください。そのため、forループと単純なインデックスではなく、whileループを使用して、長さが0より大きいかどうかを確認する必要があります。
    6. インクリメントカウンター:index = index + 1; subsample = subsample + 1;
    7. subsample = 11の場合は、もう一度1にします。

この最後に、元のデータとほぼ同じように見えるが、ランダムに「折り畳みラベル」が割り当てられた大きなデータマトリックスが作成されます。

  1. これらすべてと実行中のコードをk(10)回ループします。

編集:よりアクセスしやすい方法で配置されたコード。それはまだ疑似yコードであり、完全ではないことに注意してください!また、これはまったく最も効率的な方法ではありませんが、matlab関数を使用できない場合でもそれほど悪くはないことに注意してください。

for k = 1:10

index = 1; subsample = 1; newmat = zeros("150","6");
while ( length(labels) > 0 )
    randNum = randi(length(labels));
    newmat(index,:) = [data(randNum,:) labels(randNum) subsample];
    data(randNum,:) = []; same for labels
    index = index + 1; subsample = subsample + 1;
    if ( subsample == 11 )
        subsample = 1;
    end
end

% newmat is complete, now run code here using the sampled data 
%(ie pick a random number from 1:10 and use that as your validation fold. the rest for training

end

回答#2の編集:

別の言い方をすれば、データセットと同じ長さのベクトルを作成することです

foldLabels = zeros("150",1);

次に、その長い(150)ループして、ランダムなインデックスにラベルを割り当てます。

foldL = 1;
numAssigned = 0;
while ( numAssigned < 150 )
    idx = randi(150);
    % no need to reassign a given label, so check if is still 0
    if ( foldLabels(idx) == 0 )
        foldLabels(idx) = foldL;
        numAssigned++; % not matlab code, just got lazy. you get it
        foldL++;
        if ( foldL > 10 )
            foldL = 1;
        end
    end
end

回答#2.5の編集

foldLabels = zeros("150",1);
for i = 1:150
    notChosenLabels = [notChosenLabels i];
end
foldL = 1;
numAssigned = 0;
while ( length(notChosenLabels) > 0 )
    labIdx = randi(length(notChosenLabels));
    idx = notChosenLabels(labIdx);
    foldLabels(idx) = foldL;
    numAssigned++; % not matlab code, just got lazy. you get it
    foldL++;
    if ( foldL > 10 )
        foldL = 1;
    end
    notChosenLabels(labIdx) = [];
end

RANDPERMの編集

randpermでインデックスを生成する

idxs = randperm(150);

今すぐ割り当てます

foldLabels = zeros(150,1);
for i = 1:150
    foldLabels(idxs(i)) = sampleLabel;
    sampleLabel = sampleLabel + 1;
    if ( sampleLabel > 10 )
       sampleLabel = 1;
    end
end
于 2012-09-27T21:58:09.227 に答える