Main Content

loss

インクリメンタル ドリフト認識学習器の回帰誤差または分類誤差

R2022b 以降

    説明

    Err = loss(Mdl,X,Y) は、X の予測子と Y の真の観測値を使用して学習させたモデル Mdl の回帰誤差または分類誤差を返します。

    Err は n 行 1 列のベクトルで、n は観測値の数です。

    Err = loss(Mdl,X,Y,Name=Value) では、1 つ以上の名前と値の引数を使用して追加オプションを指定します。たとえば、予測子データの次元や計算する損失関数を指定できます。

    すべて折りたたむ

    人の行動のデータセットを読み込みます。データをランダムにシャッフルします。

    load humanactivity;
    n = numel(actid);
    rng(123) % For reproducibility
    idx = randsample(n,n);

    データ セットの詳細については、コマンド ラインで Description を入力してください。

    予測子変数と応答変数を定義します。

    X = feat(idx,:);
    Y = actid(idx);

    応答は、次の 5 つのクラスのいずれかになります。座る、立つ、歩く、走る、または踊る。

    被験者が移動しているかどうか (actid > 2) を基準に、応答を二分します。

    Y = Y > 2;

    データセットの後半部分のラベルを反転してドリフトをシミュレートします。

    Y(floor(numel(Y)/2):end,:) = ~Y(floor(numel(Y)/2):end,:);

    分類用の既定のインクリメンタル ドリフト認識モデルを次のように開始します。

    1. バイナリ分類用の既定のインクリメンタル線形 SVM モデルを作成します。

    2. インクリメンタル線形 SVM モデルをベース学習器として使用して、既定のインクリメンタル ドリフト認識モデルを開始します。

    BaseLearner = incrementalClassificationLinear();
    idaMdl = incrementalDriftAwareLearner(BaseLearner);

    idaMdlincrementalDriftAwareLearner モデルです。そのプロパティはすべて読み取り専用です。

    データ ストリームの作成用に各チャンクの変数の数を事前に割り当てて、分類誤差を格納するための変数も割り当てます。

    numObsPerChunk = 50;
    nchunk = floor(n/numObsPerChunk);
    ce = array2table(zeros(nchunk,3),VariableNames=["Cumulative" "Window" "Loss"]);
    PoL = zeros(nchunk,numObsPerChunk); % To store per observation loss values
    driftTimes = [];

    それぞれ 50 個の観測値の入力チャンクを使用して、データ ストリームをシミュレートします。各反復で次を行います。

    1. updateMetrics を呼び出して、累積性能および観測値ウィンドウ内での性能を測定します。前のインクリメンタル モデルを新しいモデルで上書きして、パフォーマンス メトリクスを追跡します。

    2. fit を呼び出して、モデルを入力チャンクに当てはめます。前のインクリメンタル モデルを、入力観測値に当てはめた新しいモデルで上書きします。

    3. perObservationLoss を呼び出して、データの入力チャンクに含まれる各観測値の分類誤差を計算します。

    4. loss を呼び出して、入力チャンクでのモデルの性能を測定します。

    5. すべてのパフォーマンス メトリクスを ce に保存して、インクリメンタル学習中にそれらがどのように進化するかを確認します。idaMdlMetrics プロパティに累積とウィンドウの分類誤差が格納され、各反復で更新されます。各チャンクの損失値を ce の 3 列目に格納します。

    for j = 1:nchunk
    
     ibegin = min(n,numObsPerChunk*(j-1)+1);
     iend   = min(n,numObsPerChunk*j);
     idx = ibegin:iend;   
    
     idaMdl = updateMetrics(idaMdl,X(idx,:),Y(idx));
     idaMdl = fit(idaMdl,X(idx,:),Y(idx));
    
     PoL(j,:) = perObservationLoss(idaMdl,X(idx,:),Y(idx));
     ce{j,["Cumulative" "Window"]} = idaMdl.Metrics{"ClassificationError",:};
     ce{j,"Loss"} = loss(idaMdl,X(idx,:),Y(idx));
     if idaMdl.DriftDetected
        driftTimes(end+1) = j; 
     end
    end

    関数 updateMetrics は、入力観測値を処理しながらモデルの性能を評価します。指定したメトリクスについて、関数で処理された観測値の累積の測定値と指定したウィンドウにおける測定値が Metrics モデル プロパティに書き込まれます。関数 fit は、データの入力バッチに基づいてベース学習器を更新してドリフトを監視することでモデルを当てはめます。

    累積とウィンドウごとの分類誤差をプロットします。ウォームアップ期間と学習期間、およびドリフトが発生した時点をマークします。

    h = plot(ce.Variables);
    xlim([0 nchunk])
    ylim([0 0.07])
    ylabel("Classification Error")
    xlabel("Iteration")
    
    xline(idaMdl.MetricsWarmupPeriod/numObsPerChunk,"g-.","Warmup Period",LineWidth= 1.5)
    xline(idaMdl.TrainingPeriod/numObsPerChunk,"b-.","Training Period",LabelVerticalAlignment="middle",LineWidth= 1.5)
    %xline(floor(numel(Y)/2)/numObsPerChunk,"m--","Drift",LabelVerticalAlignment="middle",LineWidth= 1.5)
    
    xline(driftTimes,"m--","Drift",LabelVerticalAlignment="middle",LineWidth=1.5)
    legend(h,ce.Properties.VariableNames)
    legend(h,Location="best")

    Figure contains an axes object. The axes object with xlabel Iteration, ylabel Classification Error contains 6 objects of type line, constantline. These objects represent Cumulative, Window, Loss.

    黄色の線は、入力データの各チャンクの分類誤差を表します。loss はメトリクスのウォームアップ期間に依存しないため、すべての反復について分類誤差を測定します。メトリクスのウォームアップ期間後、idaMdl は累積およびウィンドウ メトリクスを追跡します。

    観測値ごとの損失をプロットします。

    figure()
    plot(PoL,'b.');

    Figure contains an axes object. The axes object contains 50 objects of type line. One or more of the lines displays its values using only markers

    perObservationLoss で、データの入力チャンクに含まれる各観測値の分類誤差が計算されます。

    補助関数の HelperRegrGeneratorHelperConceptDriftGenerator をそれぞれ使用して、ランダムな概念データと概念ドリフト発生器を作成します。

    concept1 = HelperRegrGenerator(NumFeatures=100,NonZeroFeatures=[1,20,40,50,55], ...
            FeatureCoefficients=[4,5,10,-2,-6],NoiseStd=1.1);
    concept2 = HelperRegrGenerator(NumFeatures=100,NonZeroFeatures=[1,20,40,50,55], ...
            FeatureCoefficients=[4,7,10,-1,-5],NoiseStd=1.1);
    driftGenerator = HelperConceptDriftGenerator(concept1,concept2,15000,1250);

    HelperRegrGenerator は、関数の呼び出しで指定された回帰用の特徴量と特徴量係数を使用してストリーミング データを生成します。この関数は、各ステップで正規分布から予測子を抽出します。その後、特徴量係数と予測子の値を使用して、平均がゼロで指定のノイズ標準偏差をもつ正規分布からランダム ノイズを追加することで応答を計算します。

    HelperConceptDriftGenerator は、概念ドリフトを確立します。このオブジェクトでは、シグモイド関数 1./(1+exp(-4*(numobservations-position)./width)) を使用して、データ生成時に 1 つ目のストリームが選択される確率を判定します [3]。この例では、位置の引数が 15000 で、幅の引数が 1250 です。観測値の数が位置の値から幅の半分を引いた値を超えると、データ生成時に 1 つ目のストリームから抽出される確率が低下します。このシグモイド関数により、一方のストリームからもう一方への滑らかな遷移が実現します。幅の値が大きいほど、両方のストリームがほぼ等しい確率で選択される遷移期間が大きいことを示します。

    回帰用のインクリメンタル ドリフト認識モデルを次のように構成します。

    1. 回帰用のインクリメンタル線形モデルを作成します。平均絶対偏差 (MAD) を追跡して、モデルの性能を測定します。新しい各観測値の絶対誤差を測定する無名関数を作成します。名前 MeanAbsoluteError とそれに対応する関数を含む構造体配列を作成します。メトリクスのウォームアップ期間を観測値 1000 個に指定します。メトリクス ウィンドウ サイズを観測値 500 個に指定します。

    2. 連続データ用のインクリメンタルな概念ドリフト検出器を開始します。移動平均による Hoeffding 境界のドリフト検出法 (HDDMA) を使用します。

    3. インクリメンタル線形モデルと概念ドリフト検出器を使用して、インクリメンタル ドリフト認識モデルをインスタンス化します。学習期間を 1000 個の観測値として指定します。

    maefcn = @(z,zfit,w)(abs(z - zfit)); % Mean absolute deviation function
    maemetric = struct(MeanAbsoluteError=maefcn);
    
    baseMdl = incrementalRegressionLinear(MetricsWarmupPeriod=1000,MetricsWindowSize=400,Metrics=maemetric,EstimationPeriod=0);
    dd = incrementalConceptDriftDetector("hddma",Alternative="greater",InputType="continuous");
    idaMdl = incrementalDriftAwareLearner(baseMdl,DriftDetector=dd,TrainingPeriod=2000);

    20 個の観測値を含む初期標本を生成し、その初期標本に当てはめて応答を予測するようにモデルを構成します。

    initobs = 20;
    rng(1234); % For reproducibility
    [driftGenerator,X,Y] = hgenerate(driftGenerator,initobs); 
    idaMdl = fit(idaMdl,X,Y);

    データ ストリームの作成用に各チャンクの変数の数と反復回数を事前に割り当てて、分類誤差、ドリフト ステータス、およびドリフト時間を格納するための変数も割り当てます。

    numObsPerChunk = 50;
    numIterations = 500;
    
    mae = array2table(zeros(numIterations,3),VariableNames=["Cumulative" "Window" "Chunk"]);
    PoL = zeros(numIterations,numObsPerChunk); % Per observation loss values
    
    driftTimes = [];
    dstatus = zeros(numIterations,1);
    statusname = strings(numIterations,1);

    それぞれ 50 個の観測値の入力チャンクを使用してデータ ストリームをシミュレートし、インクリメンタル ドリフト認識学習を実行します。各反復で次を行います。

    1. 予測子データとラベルをシミュレートし、補助関数 hgenerate を使用してドリフト発生器を更新します。

    2. updateMetrics を呼び出して、データの入力チャンクの累積メトリクスとウィンドウ メトリクスを計算します。前のインクリメンタル モデルを、前のメトリクスを上書きするように当てはめた新しいモデルで上書きします。

    3. loss を呼び出して、データの入力チャンクの MAD を計算します。累積メトリクスおよびウィンドウ メトリクスでは、カスタム損失が各観測値の損失を返す必要がありますが、loss ではチャンク全体での損失が必要です。絶対偏差の平均を計算します。

    4. perObservationLoss を呼び出して、観測値ごとの回帰誤差を計算します。

    5. fit を呼び出して、データの入力チャンクにインクリメンタル モデルを当てはめます。

    6. 累積、ウィンドウ、およびチャンクのメトリクスと観測値ごとの損失を保存して、インクリメンタル学習中にそれらがどのように進化するかを確認します。

    for j = 1:numIterations
      
      % Generate data
        [driftGenerator,X,Y] = hgenerate(driftGenerator,numObsPerChunk); 
    
      % Perform incremental fitting and store performance metrics  
        idaMdl = updateMetrics(idaMdl,X,Y);
        PoL(j,:) = perObservationLoss(idaMdl,X,Y,'LossFun',@(x,y,w)(maefcn(x,y)));
        mae{j,1:2} = idaMdl.Metrics{"MeanAbsoluteError",:};
        mae{j,3} = loss(idaMdl,X,Y,LossFun=@(x,y,w)mean(maefcn(x,y,w)));
        idaMdl = fit(idaMdl,X,Y);
    
        statusname(j) = string(idaMdl.DriftStatus);
        if idaMdl.DriftDetected
           driftTimes(end+1) = j; 
           dstatus(j) = 2;
        elseif idaMdl.WarningDetected
           dstatus(j) = 1;
        else 
           dstatus(j) = 0;
        end   
    
    end

    idaMdl は、ストリーム内のすべてのデータで学習させた incrementalDriftAwareLearner モデル オブジェクトです。インクリメンタル学習中およびモデルがウォームになった後、updateMetrics は入力観測値でのモデルの性能をチェックし、関数 fit はモデルをその観測値に当てはめます。

    ドリフト ステータスをプロットします。

    gscatter(1:numIterations,dstatus,statusname,'gmr','*',4,'on',"Iteration","Drift Status")
    xlim([0 numIterations])

    Figure contains an axes object. The axes object with xlabel Iteration, ylabel Drift Status contains 3 objects of type line. One or more of the lines displays its values using only markers These objects represent Stable, Warning, Drift.

    パフォーマンス メトリクスをプロットして、インクリメンタル学習中にそれらがどのように進化したかを確認します。

    figure
    h = plot(mae.Variables);
    xlim([0 numIterations])
    ylim([0 4])
    ylabel("Mean Absolute Deviation")
    xlabel("Iteration")
    
    xline(idaMdl.MetricsWarmupPeriod/numObsPerChunk,"g-.","Warmup Period",LineWidth= 1.5)
    xline(idaMdl.TrainingPeriod/numObsPerChunk,"b-.","Training Period",LabelVerticalAlignment="middle",LineWidth= 1.5)
    xline(driftTimes,"m--","Drift",LabelVerticalAlignment="middle",LineWidth=1.5)
    legend(h,mae.Properties.VariableNames)

    Figure contains an axes object. The axes object with xlabel Iteration, ylabel Mean Absolute Deviation contains 6 objects of type line, constantline. These objects represent Cumulative, Window, Chunk.

    プロットは次のことを示しています。

    • updateMetrics は、パフォーマンス メトリクスをメトリクスのウォームアップ期間後にのみ計算。

    • updateMetrics は、累積メトリクスを各反復中に計算。

    • updateMetrics は、ウィンドウ メトリクスを 400 個の観測値の処理後に計算

    • idaMdl が観測値の予測のためにインクリメンタル学習の初めから構成されたため、loss はデータの入力チャンクごとに MAD を計算可能。

    観測値ごとの損失をプロットします。

    figure()
    plot(PoL,'b.');

    Figure contains an axes object. The axes object contains 50 objects of type line. One or more of the lines displays its values using only markers

    perObservationLoss で、メトリクスのウォームアップ期間後にデータの入力チャンクに含まれる各観測値の分類誤差が計算されます。

    入力引数

    すべて折りたたむ

    ストリーミング データに当てはめるインクリメンタル ドリフト認識学習モデル。incrementalDriftAwareLearner モデル オブジェクトとして指定します。Mdl は関数 incrementalDriftAwareLearner を使用して作成できます。詳細については、オブジェクトのリファレンス ページを参照してください。

    損失を計算するための予測子データのバッチ。n 個の観測値および Mdl.BaseLearner.NumPredictors 個の予測子変数の浮動小数点行列として指定します。

    Mdl.BaseLearner が名前と値の引数 ObservationsIn を受け入れる場合、ObservationsIn の値で変数と観測値の方向が決まります。ObservationsIn の既定値は "rows" であり、予測子データの観測値が X の行に沿うことを示しています。

    観測値の応答 (またはラベル) Y の長さと X の観測値の数は同じでなければなりません。Y(j)X 内の観測値 j (行または列) の応答 (またはラベル) です。

    メモ

    loss は、浮動小数点の入力予測子データのみをサポートしています。入力データに categorical データが含まれている場合は、エンコード バージョンの categorical データを準備する必要があります。dummyvar を使用して、各カテゴリカル変数をダミー変数で構成される数値行列に変換します。その後、すべてのダミー変数行列とその他の数値予測子を連結します。詳細については、ダミー変数を参照してください。

    データ型: single | double

    損失を計算するための応答またはラベルのチャンク。次のいずれかとして指定します。

    • 回帰モデルの場合、n 要素の浮動小数点ベクトル。ここで、n は X の行数です。

    • 分類モデルの場合、categorical 配列、文字配列、string 配列、logical ベクトル、または文字ベクトルの cell 配列。Y が文字配列の場合、各行に 1 つのクラス ラベルを含めなければなりません。それ以外の場合、n 要素のベクトルでなければなりません。

    Y の長さと X の観測値の数は同じでなければなりません。Y(j)X 内の観測値 j (行または列) の応答 (またはラベル) です。

    分類問題では次のようになります。

    • YMdl.BaseLearner.ClassNames のメンバーではないラベルを含む場合、loss はエラーを生成します。

    • YMdl.BaseLearner.ClassNames のデータ型は同じでなければなりません。

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

    名前と値の引数

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

    例: ObservationsIn="columns",Weights=W は、予測子行列の列が観測値に対応すること、および適用する観測値の重みがベクトル W に格納されていることを指定します。

    損失関数。組み込みの損失関数名または関数ハンドルとして指定します。

    次の表は、組み込みの損失関数名の一覧です。

    • 回帰モデル:

      名前説明
      "mse"平均二乗誤差
      "epsiloninsensitive"イプシロン不感応誤差

      回帰モデルの既定値は "mse" です。

    • 分類モデル:

      名前説明
      "binodeviance"二項分布からの逸脱度
      "classiferror"誤分類誤差率
      "exponential"指数
      "hinge"ヒンジ
      "logit"ロジスティック
      "quadratic"2 次
      "mincost"最小予測誤分類コスト (incrementalClassificationNaiveBayes のみ)

      既定値は、incrementalClassificationNaiveBayes モデル オブジェクトの場合は "mincost"、その他の分類オブジェクトの場合は "classiferror" です。

      メモ

      incrementalClassificationECOC には "classiferror" のみを指定できます。

    カスタム損失関数を指定するには、関数ハンドル表記を使用します。関数は次のいずれかの形式でなければなりません。

    • 回帰モデル:

      lossval = lossfcn(Y,YFit,W)

      • 出力引数 lossval は浮動小数点スカラーです。

      • 関数名 (lossfcn) を指定します。

      • Y は、観測応答の長さ n の数値ベクトルです。

      • YFit は、対応する予測応答の長さ n の数値ベクトルです。

      • W は、観測値の重みの長さ n の数値ベクトルです。

    • 分類モデル:

      lossval = lossfcn(C,S,W)

      • 出力引数 lossval は n 行 1 列の浮動小数点ベクトルです。n は X 内の観測値の個数です。lossval(j) の値は観測値 j の分類損失です。

      • 関数名 (lossfcn) を指定します。

      • C は n 行 K 列の logical 行列であり、対応する観測値が属するクラスを各行が示します。K は異なるクラスの個数 (numel(Mdl.BaseLearner.ClassNames)) で、列の順序は Mdl.BaseLearner.ClassNames プロパティのクラスの順序に対応します。C を作成するには、指定されたデータの各観測値について観測値 p がクラス q に属する場合に C(p,q) = 1 を設定します。行 p の他の要素を 0 に設定します。

      • S は、予測分類スコアの n 行 K 列の数値行列です。Spredict の出力 Score に似ています。ここで、行はデータの観測値に対応し、列の順序は Mdl.BaseLearner.ClassNames プロパティのクラスの順序に対応しています。S(p,q) は、クラス q に分類されている観測値 p の分類スコアです。

      • W は、観測値の重みの長さ n の数値ベクトルです。

    例: LossFun="logit"

    例: LossFun=@lossfcn

    データ型: char | string | function_handle

    予測子データにおける観測値の次元。"columns" または "rows" として指定します。

    loss は、Mdl.BaseLearner が名前と値の引数 ObservationsIn をサポートする場合にのみ ObservationsIn をサポートします。

    例: ObservationsIn="columns"

    データ型: char | string

    観測値の重みのチャンク。正の値の浮動小数点ベクトルとして指定します。loss は、Weights 内の対応する値を使用して X 内の観測値に重みを付けます。Weights のサイズは X 内の観測値の数 n と同じでなければなりません。

    既定では Weightsones(n,1) です。

    例: Weights=w

    データ型: double | single

    参照

    [1] Barros, Roberto S.M. , et al. "RDDM: Reactive drift detection method." Expert Systems with Applications. vol. 90, Dec. 2017, pp. 344-55. https://doi.org/10.1016/j.eswa.2017.08.023.

    [2] Bifet, Albert, et al. "New Ensemble Methods for Evolving Data Streams." Proceedings of the 15th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining. ACM Press, 2009, p. 139. https://doi.org/10.1145/1557019.1557041.

    [3] Gama, João, et al. "Learning with drift detection". Advances in Artificial Intelligence – SBIA 2004, edited by Ana L. C. Bazzan and Sofiane Labidi, vol. 3171, Springer Berlin Heidelberg, 2004, pp. 286–95. https://doi.org/10.1007/978-3-540-28645-5_29.

    バージョン履歴

    R2022b で導入