【学習機械学習】モデル評価と選択——matlab版

44512 ワード

モデル評価と選択-matlab
  • 前言
  • 一、訓練セットとテストセットを区分する
  • 1、残し方
  • 2、p回k折交差検証法
  • 3、セルフサービス法
  • 二、性能メトリック
  • 1、MSE
  • 2、エラー率と精度
  • 3、キャリブレーション率とキャリブレーション率
  • 4、F 1指数
  • 5、ROC図を描き、AUC
  • を計算する
  • 三、仮定検査
  • 参考資料:
  • 前言
    金曜日の実験授業は、予想外に完成できないと言えます.前にpythonで書いたときから内容が多すぎると思っていたので、先生がmatlabの基本的な使い方を教えてから、実験をして残す方法だけを要求すればいいのです.次に,アヤメ(iris)データセットを用いて,まずデータ分割の部分を作成した.
    一、訓練セットとテストセットを区分する
    すべての原理の紹介は前回python実装の時に書きましたが、今回matlabを使って再実装したのは、主にこれらの方法の原理をもっと熟知するためです.pythonが直接関数を呼び出すのは実際には区分の具体的な操作が何なのか分からないので、コードだけを話します.matlab処理マトリクスは確かに片手があると言われていますが、かなり便利で、初めて接触してもすぐに上手になりました.モデルの評価と選択に関する内容だけを知りたい場合は、この書いたモデルの評価と選択を見ることができます.
    1、残し方
    法先生が直接例としてmatlabの基本的な文法を説明してくれたので、最後に私が書いたものだけが完璧になりました.
    function [Train_holdout,Test_holdout]=splittraintest(data1)
    Train_holdout=[];
    Test_holdout=[];
    
    f=[50 50 50];
    
    D1=data1(1:50,:);
    D2=data1(51:100,:);
    D3=data1(101:150,:);
    
    D(:,:,1)=D1;	%                
    D(:,:,2)=D2;	%                    
    D(:,:,3)=D3;	%                     
    
    [a,b]=size(f);
    
    [d1,d2]=size(data1);
    
    percent1=0.7;	%     
    
    for j=1:100		%100   
        for i=1:b     
            x=round(f(i)*percent1);     %round    
            s=randperm(f(i));	%      ,       
            s1=s(1:x);
            s2=s((x+1):f(i));
            DD=D(:,:,i);
            train1=DD(s1,:);
            test1=DD(s2,:);
            Train_data(:,:,i)=train1;
            Test_data(:,:,i)=test1;
        end   
        Train1=reshape(Train_data,x*b,d2);    %        
        Test1=reshape(Test_data,d1-x*b,d2);
        Train_holdout=cat(3,Train1,Train_holdout);   % 100             
        Test_holdout=cat(3,Test1,Test_holdout);
    end
    

    このコードの中で私が書いた部分は実は最後の4つの言葉しかありません.上記の注釈に書いてあるように、先生はデータを3次元に分けて均一に選択しますが、私たちのデータは最終的に2次元マトリクス(ある場合)を必要とします.したがって,reshape関数を用いた3次元行列を2次元に変換する必要がある.reshapeの使い方はreshapeの使い方を参考に整理することができます.特に、次元を変換した後も要素の個数を一定に保つ必要があります.つまり、xyz=mnxyz=mnxyz=mn(x、y、zは元の3次元、m、nは新しい2次元)です.ここでは列(n=y n=y n=y n=y)を一定に保ち、2次元マトリクスの中行数m=xz m=xzを要求します.次に,分割は複数回行い,最後にそれぞれ予測して平均化して結果を得る必要があるため,最外層に1サイクルを設けて反復実験(上のjサイクル)を実現する必要がある.ループごとに1対のTrainとTestのデータ分割が得られ、私が考えた保存方法の一つはそれらを「積み重ね」、すなわち3次元に格納することです.ではcat関数(結合関数)を用いた.cat関数の使い方、具体的な内容は後述しませんが、結合の各項目に同じ行数と列数が必要であることに注意してください.この点は後で遭遇します.
    2、p回k折交差検証法
    k折交差検証法の鍵は「1折ごとに区切る」ことであり,k個をグループ化すると,その後の内容はk−1個ずつ並べてセットする問題にすぎない.
    function [Train_kfold,Test_kfold]=repeatedkfold(data1)
    Train_kfold=[];
    Test_kfold=[];
    d_length=length(data1); %150 
    [d1,d2]=size(data1);    %    d1   d2
    
    k=input('   k  k=');    %k p      Txxx_kfold    k*p (k+1*p
    p=input('       p=');
    
    divide=round(d_length/k);   %for n=1:p   % p 
        data_temp=[];
        rowrank = randperm(size(data1, 1)); %       ,   p      
        data_temp=data1(rowrank,:);
    
        division_matrix=[]; %    ,    k     ,    
    
        left_index=1;   %           
        right_index=left_index+divide-1;
    
        while left_index<=d_length   %        
            a=data_temp(left_index:right_index,:);
            left_index=right_index+1;
            right_index=right_index+divide;
    
            if right_index>=d_length       %          
                right_index=d_length;
            end
    
            if length(a)<divide       %0
                a(divide,d2)=0;
            end
            division_matrix=cat(3,a,division_matrix);
        end
    
        [array,column,page]=size(division_matrix); %           page
        Train_temp=[];
        Test_temp=[];
        Train=[];   %     k    ,    
        Test=[];
        
        for i=1:page
            Test_temp=division_matrix(:,:,i);
            for j=1:page
                if j~=i
                    Train_temp=cat(3,division_matrix(:,:,j),Train_temp);
                end
            end
            Train1=reshape(Train_temp,array*(page-1),column);
            Train_temp=[];
            Train=cat(3,Train1,Train);
            Test=cat(3,Test_temp,Test);
        end
         Train_kfold=cat(4,Train,Train_kfold);  %    p k   ,    
         Test_kfold=cat(4,Test,Test_kfold);
    end
    

    上のコードはループに従って分割して、一歩ごとに何をしたかを見ることができます.whileサイクル.whileループはクロス検証法全体の核心内容を行い,分割した.区間左右下標の処理については,注釈を組み合わせて理解するのは難しくないが,最後のステップでは区間長補0に満たない処理があることに気づき,これは主に後連結操作の準備のためである.for i=1:pageサイクル.このforループは実際にはk−1個のパケット統合の動作を行う.しかし、ブログを書いたとき、これは完全に性能を浪費する方法であることに気づきました.訓練セットの取得には、最初から最後まで連結する必要はありません.区分マトリクスからテストセットを削除すればいいです.改善方法を考えてみますが、現在の状況では明らかに任務を遂行することができます.for n=1:p.最外層のサイクルはp回の繰返し分割を実現するためであり,サイクルの初めに元のデータセットの順序を乱し,複数回の繰返しに効果をもたらすことがわかる.p回のk折り曲げの実行が完了すると、4次元マトリクスが得られ、4次元はn回目のk折り曲げを表し、3次元は1回のk折り曲げのi回目のマージを表す.
    3、セルフサービス法
    セルフサービス法は本当に何も言うことはありません.前回pythonで何行か書けば終わりです.matlabの考えも悪くありませんが、今回は繰り返し実験をしました.
    function [Train_bootstrap,Test_bootstrap]=bootstrap(data1)
    Train_bootstrap=[];
    Test_bootstrap=[];
    d_length=length(data1);
    
    for n=1:10  %  n 
        bootstrap=[];
        Train_temp=[];
        Test_temp=[];
    
        for i=1:d_length
            bootstrap(end+1)=round(rand*d_length);  %  m           m 
        end
    
        for i=1:d_length
            if ismember(i,bootstrap)
                Train_temp(end+1,:)=data1(i,:);
            else
                Test_temp(end+1,:)=data1(i,:);
            end
        end
        Train_temp(d_length*0.7,:)=0;   %35%        
        Test_temp(d_length*0.7,:)=0;    %0 0.7*m  
        Train_bootstrap=cat(3,Train_temp,Train_bootstrap);
        Test_bootstrap=cat(3,Test_temp,Test_bootstrap);
    end
    

    二、性能メジャー
    先生は私たちがランダムにいくつかのデータを生成するだけでいいと言っています.そのため、私たちは直接コマンドラインで以下のコードを実行して2分類のデータを生成することができます.
    predict=rand(1,100);	%    100 0-1      
    ground_truth=randi([0,1],1,100); %  100 0 1      
    

    次は数式だけでいいです
    1、MSE
    平均二乗誤差(MSE):E(f;D)=1 mΣi=1 m(f(x i)−y i)2 E(f;D)=cfrac{1}{m}sum_{i=1}^m(f(xi)−yi)^2 E(f;D)=m 1Σi=1 m(f(xi)−yi)2,x i xi xiはテストデータ,f(x i)f(xi)f(xi)は予測値である.
    function [MSE]=calMSE(data1,data2)
    predict=data1;
    truth=data2;
    sum=0;
    for i=1:length(data1)
        sum=sum+(predict(i)-truth(i))^2;
    end
    MSE=sum/length(data1);
    

    2、エラー率と精度
    予測値が正の例を表すか逆の例を表すかで閾値thresholdを設定する必要があると判断し,ここではユーザに直接閾値を入力させる.エラー率:E(f;D)=1 mΣi=1 mII(f(x i)≠y i)E(f;D)=cfrac{1}{m}sum_{i=1}^mII(f(xi)eq yi)E(f;D)=m 1Σi=1 mII(f(xi)=yi)精度:a c(f;D)=1 mΣi=1 mII(f(x i)=y i)=1−E(f;D)acc(f;D)=cfrac{1}{m}sum_{i=1}^m Ⅱ(f(xi)= yi)=1-E(f;D) acc(f;D)=m1​∑i=1m​Ⅱ(f(xi)=yi)=1−E(f;D)
    function [error_rate,accuracy]=calErrorAndAccuracy(data1,data2,threshold)
    predict=data1;
    ground_truth=data2;
    right=0;	%    
    wrong=0;	%    
    for i=1:length(data1)	%        for    
        if predict(i)>threshold
            predict(i)=1;
        else
            predict(i)=0;
        end
    end
    
    for i=1:length(data1)
        if predict(i)==ground_truth(i)
            right=right+1;
        else
            wrong=wrong+1;
        end
    end
    
    error_rate=wrong/length(data1);
    accuracy=right/length(data1);
    

    3、検査基準率と検査全率
    ここから,一連の判定値TP(真例),TN(真反例),FR(偽正例),FN(偽反例)が必要となる.演算を繰り返さないように、これらの値を一緒に残します.キャリブレーション率(Precision):T P T P+F Pcfrac{TP}{TP+FPTPキャリブレーション率(Recall):T P T P+F Ncfrac{TP}{TP+FN}TP+FNTP
    function [TP,FP,TN,FN,precision,recall]=calPrecisionAndRecall(data1,data2,threshold)
    predict=data1;
    ground_truth=data2;
    TP=0;   %   
    FP=0;   %   
    TN=0;   %   
    FN=0;   %   
    for i=1:length(data1)
        if((predict(i)>threshold)&&(ground_truth(i)==1))
            TP=TP+1;
        elseif((predict(i)>threshold)&&(ground_truth(i)==0))
            FP=FP+1;
        elseif((predict(i)<=threshold)&&(ground_truth(i)==0))
            TN=TN+1;
        elseif((predict(i)<=threshold)&&(ground_truth(i)==1))
            FN=FN+1;
        end
    end
    
    precision=TP/(TP+FP);
    recall=TP/(TP+FN);
    

    4、F 1指数
    F 1指数は、精度とリコール率(完全率)を両立させるため、P-Rマップのバランスポイントよりも一般的なメトリック値です.F 1 = 2 ∗ P ∗ R P + R = 2 ∗ T P m + T P − T N F1=\cfrac{2*P*R}{P+R}=\cfrac{2*TP}{m+TP-TN} F1=P+R2∗P∗R​=m+TP−TN2∗TP​
    function [F1]=calF1(TP,TN,predict)
    F1=(2*TP)/(length(predict)+TP-TN)
    

    5、ROC図を描き、AUCを計算する
    ROC曲線の理解と描画原理については前回pythonで書いた時にもう話しましたが、ここではあまり言いません.matlabの実現は、このブロガーが書いたものを直接見に行けばいいです.ここでもこのブロガーの説明に感謝します.しかし、このブロガーの書き方は(1,1)から減算された描画であるため、私たちは一般的に(0,0)からインクリメントされた図面を作成することができます.
    三、仮説検査
    いいえ、先生は先にしないと言いました.
    参考資料:
    1、モデル評価と選択2、matlabがROC曲線を描く3、スイカ本