Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

updateMetrics

新しいデータにおけるインクリメンタル学習モデルのパフォーマンス メトリクスの更新

説明

ストリーミング データが与えられると、updateMetrics は、構成済みの線形回帰用インクリメンタル学習モデル (incrementalRegressionLinear オブジェクト) または線形バイナリ分類 (incrementalClassificationLinear オブジェクト) のパフォーマンスを測定します。updateMetrics はパフォーマンス メトリクスを出力モデルに格納します。

updateMetrics では柔軟なインクリメンタル学習が可能です。この関数を呼び出してデータの入力チャンクでモデルのパフォーマンス メトリクスを更新した後、モデルにデータを学習させる前に他のアクションを実行することができます。たとえば、データのチャンクでのパフォーマンスに基づいて、モデルに学習させる必要があるかどうかを決定できます。これに対して、代わりに updateMetricsAndFit を使用すると、その後、追加で、データが入ってきたときに 1 回の呼び出しでそのデータでモデルに学習させることができます。

指定したデータのバッチにおけるモデルのパフォーマンスを測定するには、代わりに loss を呼び出します。

Mdl = updateMetrics(Mdl,X,Y) は、インクリメンタル学習モデル Mdl を返します。これは、入力予測子と応答データ (それぞれ XY) のモデル パフォーマンスを含むように変更された入力インクリメンタル学習モデル Mdl です。

入力モデルが "ウォーム" (Mdl.IsWarmtrue) の場合、updateMetrics は以前に計算されたメトリクスを上書きし、Metrics プロパティに新しい値を保存します。それ以外の場合、updateMetrics は代わりに MetricsNaN 値を保存します。

入力モデルと出力モデルのデータ型は同じです。

Mdl = updateMetrics(Mdl,X,Y,Name,Value) は、1 つ以上の名前と値のペアの引数によって指定された追加オプションを使用します。たとえば、観測値の重みを指定したり、予測子データ行列の列が観測値に対応することを指定したりできます。

すべて折りたたむ

fitclinear を使用してバイナリ分類用の線形モデルに学習させ、それをインクリメンタル学習器に変換し、そのパフォーマンスをストリーミング データ チャンクまで追跡します。

データの読み込みと前処理

人の行動のデータ セットを読み込みます。データをランダムにシャッフルします。予測子データの観測値を列に配置します。

load humanactivity
rng(1); % For reproducibility
n = numel(actid);
idx = randsample(n,n);
X = feat(idx,:);
Y = actid(idx);

データ セットの詳細については、Description を表示してください。

応答は、5 つのクラスのいずれかになります。被験者が移動しているかどうか (actid > 2) を基準に、応答を二分します。

Y = Y > 2;

バイナリ分類用の線形モデルの学習

バイナリ分類用の線形モデルを、データの半分から取った無作為標本にあてはめます。

idxtt = randsample([true false],n,true);
TTMdl = fitclinear(X(idxtt,:),Y(idxtt))
TTMdl = 
  ClassificationLinear
      ResponseName: 'Y'
        ClassNames: [0 1]
    ScoreTransform: 'none'
              Beta: [60×1 double]
              Bias: -0.2998
            Lambda: 8.2967e-05
           Learner: 'svm'


  Properties, Methods

TTMdl は、バイナリ分類モデル用の従来式の学習済み線形モデルを表す ClassificationLinear モデル オブジェクトです。

学習済みモデルの変換

従来式の学習済み分類モデルを、インクリメンタル学習用のバイナリ分類線形モデルに変換します。

IncrementalMdl = incrementalLearner(TTMdl)
IncrementalMdl = 
  incrementalClassificationLinear

            IsWarm: 1
           Metrics: [1×2 table]
        ClassNames: [0 1]
    ScoreTransform: 'none'
              Beta: [60×1 double]
              Bias: -0.2998
           Learner: 'svm'


  Properties, Methods

IncrementalMdl.IsWarm
ans = logical
   1

インクリメンタル モデルがウォームです。そのため、updateMetrics は、与えられたデータでのモデルのパフォーマンス メトリクスを追跡できます。

パフォーマンス メトリクスの追跡とモデルのあてはめの個別の実行

updateMetrics を使用して、残りのデータでのモデル パフォーマンスを追跡します。50 個の観測値を一度に処理して、データ ストリームをシミュレートします。各反復で次を行います。

  1. updateMetrics を呼び出し、観測値の入力チャンクを所与として、モデルの分類誤差の累積とウィンドウを更新します。前のインクリメンタル モデルを上書きして、Metrics プロパティ内の損失を更新します。関数がモデルをデータ チャンクにあてはめないことに注意してください。チャンクはモデルに対して "新しい" データです。

  2. 分類誤差と最初の係数 β1 を保存します。

% Preallocation
idxil = ~idxtt;
nil = sum(idxil);
numObsPerChunk = 50;
nchunk = floor(nil/numObsPerChunk);
ce = array2table(zeros(nchunk,2),'VariableNames',["Cumulative" "Window"]);
beta1 = [IncrementalMdl.Beta(1); zeros(nchunk,1)];
Xil = X(idxil,:);
Yil = Y(idxil);

% Incremental fitting
for j = 1:nchunk
    ibegin = min(nil,numObsPerChunk*(j-1) + 1);
    iend   = min(nil,numObsPerChunk*j);
    idx = ibegin:iend;
    IncrementalMdl = updateMetrics(IncrementalMdl,Xil(idx,:),Yil(idx));
    ce{j,:} = IncrementalMdl.Metrics{"ClassificationError",:};
    beta1(j + 1) = IncrementalMdl.Beta(1);
end

IncrementalMdl は、モデル パフォーマンスをデータ ストリーム内の観測値まで追跡した incrementalClassificationLinear モデル オブジェクトです。

パフォーマンス メトリクスと推定された係数 β1 のトレース プロットをプロットします。

figure;
subplot(2,1,1)
h = plot(ce.Variables);
xlim([0 nchunk]);
ylabel('Classification Error')
legend(h,ce.Properties.VariableNames)
subplot(2,1,2)
plot(beta1)
ylabel('\beta_1')
xlim([0 nchunk]);
xlabel('Iteration')

累積の損失は安定していますが、ウィンドウの損失は不連続です。

updateMetrics がモデルをデータにあてはめないため、β1 は変更されません。

バイナリ分類用の既定のインクリメンタル線形 SVM モデルを作成します。観測推定期間を 5,000、ソルバーを SGD に指定します。

Mdl = incrementalClassificationLinear('EstimationPeriod',5000,'Solver','sgd')
Mdl = 
  incrementalClassificationLinear

            IsWarm: 0
           Metrics: [1×2 table]
        ClassNames: [1×0 double]
    ScoreTransform: 'none'
              Beta: [0×1 double]
              Bias: 0
           Learner: 'svm'


  Properties, Methods

isWarm = Mdl.IsWarm
isWarm = logical
   0

mwp = Mdl.MetricsWarmupPeriod
mwp = 1000
numObsBeforeMetrics = Mdl.MetricsWarmupPeriod + Mdl.EstimationPeriod
numObsBeforeMetrics = 6000

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

Mdl.IsWarm0 であるため、Mdl はウォームではありません。この特性は、fit を使用して 6000 の観測値でモデルに学習させるために、モデルを渡さなければならないことを意味します。この場合は、updateMetrics によってメトリクスの追跡が可能になる前にしなければなりません。

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

load humanactivity
n = numel(actid);
rng(1) % For reproducibility
idx = randsample(n,n);
X = feat(idx,:);
Y = actid(idx);

データ セットの詳細については、Description を表示してください。

応答は、5 つのクラスのいずれかになります。被験者が移動しているかどうか (actid > 2) を基準に、応答を二分します。

Y = Y > 2;

fit を使用してインクリメンタル モデルを学習データにあてはめます。50 個の観測値で構成されるチャンクを一度にあてはめ、データ ストリームをシミュレートします。各反復で次を行います。

  • 50 個の観測値を処理。

  • 前のインクリメンタル モデルを、入力観測値にあてはめた新しいモデルで上書き。

  • 観測値の学習回数 β1、および被験者が移動した (Y = true) かどうかの事前確率を保存して、インクリメンタル学習中の進化を監視。

% Preallocation
numObsPerChunk = 50;
nchunk = floor(n/numObsPerChunk);
ce = array2table(zeros(nchunk,2),'VariableNames',["Cumulative" "Window"]);
beta1 = zeros(nchunk,1);    

% Incremental fitting
for j = 1:nchunk
    ibegin = min(n,numObsPerChunk*(j-1) + 1);
    iend   = min(n,numObsPerChunk*j);
    idx = ibegin:iend;
    Mdl = updateMetrics(Mdl,X(idx,:),Y(idx));
    ce{j,:} = Mdl.Metrics{"ClassificationError",:};
    Mdl = fit(Mdl,X(idx,:),Y(idx));
    beta1(j) = Mdl.Beta(1);
end

IncrementalMdl は、ストリーム内のすべてのデータを適用させた incrementalClassificationLinear モデル オブジェクトです。

パラメーターがインクリメンタル学習中にどのように進化したかを確認するには、それらを別々のサブプロットにプロットします。

figure;
subplot(2,1,1)
plot(beta1)
ylabel('\beta_1')
xline(Mdl.EstimationPeriod/numObsPerChunk,'r-.');
xlabel('Iteration')
axis tight
subplot(2,1,2)
plot(ce.Variables);
ylabel('ClassificationError')
xline(Mdl.EstimationPeriod/numObsPerChunk,'r-.');
xline(numObsBeforeMetrics/numObsPerChunk,'g-.');
xlabel('Iteration')
xlim([0 nchunk]);
legend(ce.Properties.VariableNames)

mdlIsWarm = numObsBeforeMetrics/numObsPerChunk
mdlIsWarm = 120

プロットは、推定期間が経過するまでは、fit がモデルをデータにあてはめることも、パラメーターを更新しないことを示します。また、updateMetrics は、推定期間およびメトリクスのウォームアップ期間 (120 チャンク) が経過するまでは、分類誤差を追跡しません。

線形回帰モデルのパフォーマンスが低下した場合にのみ、そのモデルに対してインクリメンタル学習を行います。

2015 年のニューヨーク市住宅データ セットを読み込み、シャッフルします。このデータの詳細については、NYC Open Data を参照してください。

load NYCHousing2015

rng(1) % For reproducibility
n = size(NYCHousing2015,1);
shuffidx = randsample(n,n);
NYCHousing2015 = NYCHousing2015(shuffidx,:);

テーブルから応答変数 SALEPRICE を抽出します。数値安定性を得るために、SALEPRICE1e6 の尺度でスケールします。

Y = NYCHousing2015.SALEPRICE/1e6;
NYCHousing2015.SALEPRICE = [];

カテゴリカル予測子からダミー変数メトリクスを作成します。

catvars = ["BOROUGH" "BUILDINGCLASSCATEGORY" "NEIGHBORHOOD"];
dumvarstbl = varfun(@(x)dummyvar(categorical(x)),NYCHousing2015,...
    'InputVariables',catvars);
dumvarmat = table2array(dumvarstbl);
NYCHousing2015(:,catvars) = [];

テーブル内の他のすべての数値変数を売価の線形予測子として扱います。ダミー変数の行列を残りの予測子データに連結し、データを転置して計算を高速化します。

idxnum = varfun(@isnumeric,NYCHousing2015,'OutputFormat','uniform');
X = [dumvarmat NYCHousing2015{:,idxnum}]';

推定値またはメトリクスのウォーム アップ期間がなく、メトリクス ウィンドウ サイズが 1000 となるように、インクリメンタル学習用の線形回帰モデルを構成します。構成したモデルを最初の 100 個の観測値にあてはめて、観測値がデータの列に沿うように指定します。

Mdl = incrementalRegressionLinear('EstimationPeriod',0,'MetricsWarmupPeriod',0,...
    'MetricsWindowSize',1000);
numObsPerChunk = 100;
Mdl = fit(Mdl,X(:,1:numObsPerChunk),Y(1:numObsPerChunk),'ObservationsIn','columns');

MdlincrementalRegressionLinear モデル オブジェクトです。

条件付きのあてはめを行い、インクリメンタル学習を実行します。各反復でこの手順に従います。

  • 100 個の観測値のチャンクを一度に処理することで、データ ストリームをシミュレートします。

  • サイズが 200 の観測ウィンドウ内で、イプシロン不感応損失を計算することにより、モデル パフォーマンスを更新します。観測値がデータの列に沿うように指定します。

  • それまでの最小損失の倍を超える損失が発生した場合にのみ、モデルをデータ チャンクにあてはめます。観測値がデータの列に沿うように指定します。

  • パフォーマンスとあてはめを追跡するときは、前のインクリメンタル モデルを上書きします。

  • イプシロン不感応損失と β313 を保存して、損失と係数の進化を確認します。

  • fit がモデルに学習させるタイミングを追跡します。

% Preallocation
n = numel(Y) - numObsPerChunk;
nchunk = floor(n/numObsPerChunk);
beta313 = zeros(nchunk,1);
ei = array2table(nan(nchunk,2),'VariableNames',["Cumulative" "Window"]);
trained = false(nchunk,1);

% Incremental fitting
for j = 2:nchunk
    ibegin = min(n,numObsPerChunk*(j-1) + 1);
    iend   = min(n,numObsPerChunk*j);
    idx = ibegin:iend;
    Mdl = updateMetrics(Mdl,X(:,idx),Y(idx),'ObservationsIn','columns');
    ei{j,:} = Mdl.Metrics{"EpsilonInsensitiveLoss",:};
    minei = min(ei{:,2});
    pdiffloss = (ei{j,2} - minei)/minei*100;
    if pdiffloss > 100
        Mdl = fit(Mdl,X(:,idx),Y(idx),'ObservationsIn','columns');
        trained(j) = true;
    end    
    beta313(j) = Mdl.Beta(end);
end

Mdl は、ストリーム内のすべてのデータを適用させた incrementalRegressionLinear モデル オブジェクトです。

モデルのパフォーマンスと β313 が学習中にどのように進化したかを確認するには、それらを別々のサブプロットにプロットします。

subplot(2,1,1)
plot(beta313)
hold on
plot(find(trained),beta313(trained),'r.')
ylabel('\beta_{313}')
xline(Mdl.EstimationPeriod/numObsPerChunk,'r-.');
legend('\beta_{313}','Training occurs','Location','southeast')
hold off
subplot(2,1,2)
plot(ei.Variables)
ylabel('Epsilon Insensitive Loss')
xline(Mdl.EstimationPeriod/numObsPerChunk,'r-.');
xlabel('Iteration')
legend(ei.Properties.VariableNames)

β313 のトレース プロットは、損失がそれまでの最小損失の倍とならない定数値の期間を示します。

入力引数

すべて折りたたむ

パフォーマンスが測定されるインクリメンタル学習モデル。incrementalClassificationLinear または incrementalRegressionLinear モデル オブジェクトとして指定するか、直接作成するか、または関数 incrementalLearner を使用して、サポートされている従来式の学習済み機械学習モデルを変換して作成します。詳細については、学習問題に対応するリファレンス ページを参照してください。

Mdl.IsWarmfalse の場合、updateMetrics はモデルのパフォーマンスを追跡しません。updateMetrics がパフォーマンス メトリクスを追跡する前に、Mdl とデータを fit に渡して、MdlMdl.EstimationPeriod + Mdl.MetricsWarmupPeriod 観測値にあてはめなければなりません。詳細は、アルゴリズムを参照してください。

モデルのパフォーマンスを測定する予測子データのチャンク。n 個の観測値および Mdl.NumPredictors 予測子変数の浮動小数点行列として指定します。名前と値のペアの引数 'ObservationsIn' の値は、変数と観測値の方向を決定します。

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

メモ

  • Mdl.NumPredictors = 0 の場合、updateMetricsX から予測子の数を推測し、出力モデルの対応するプロパティを設定します。それ以外の場合、ストリーミング データ内の予測子変数の数が Mdl.NumPredictors から変化すると、updateMetrics がエラーを生成します。

  • updateMetrics は、浮動小数点の入力予測子データのみをサポートしています。入力モデル Mdl がカテゴリカル データにあてはめられた、変換された従来型の学習済みモデルを表す場合、dummyvar を使用して、各カテゴリカル変数をダミー変数で構成される数値行列に変換し、すべてのダミー変数行列とその他の数値予測子を連結します。詳細は、ダミー変数を参照してください。

データ型: single | double

モデルのパフォーマンスを測定するラベルのチャンク。分類問題では、categorical 配列、文字配列、string 配列、logical ベクトル、浮動小数点ベクトル、または文字ベクトルの cell 配列として指定します。回帰問題では、浮動小数点ベクトルとして指定します。

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

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

  • updateMetrics はバイナリ分類のみをサポートします。

  • 入力モデル MdlClassNames プロパティが空以外の場合は、次の条件が適用されます。

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

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

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

メモ

観測値 (予測子またはラベル) または重み Weight が少なくとも 1 つの欠損 (NaN) 値を含む場合、updateMetrics はその観測値を無視します。したがって、updateMetrics は n 個よりも少ない観測値を使用してモデル パフォーマンスを計算します。

名前と値のペアの引数

オプションの Name,Value 引数のコンマ区切りペアを指定します。Name は引数名で、Value は対応する値です。Name は引用符で囲まなければなりません。Name1,Value1,...,NameN,ValueN のように、複数の名前と値のペアの引数を、任意の順番で指定できます。

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

予測子データにおける観測値の次元。'ObservationsIn''columns' または 'rows' から構成されるコンマ区切りのペアとして指定します。

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

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

正規化方式を含む詳細については、観測値の重みを参照してください。

データ型: double | single

出力引数

すべて折りたたむ

更新されたインクリメンタル学習モデル。incrementalClassificationLinear または incrementalRegressionLinear の入力モデル Mdl と同じデータ型のインクリメンタル学習モデル オブジェクトとして返されます。

モデルがウォームでない場合、updateMetrics はパフォーマンス メトリクスを計算しません。その結果、MdlMetrics プロパティは、NaN 値で構成された状態を完全に維持します。それ以外の場合、updateMetrics は、新しいデータ XY における累積およびウィンドウのパフォーマンス メトリクスを計算します。また、入力モデル Mdl における Mdl.Metrics の他のすべてのプロパティの対応する要素を上書きし、Mdl に引き継ぎます。詳細は、アルゴリズムを参照してください。

分類問題の場合、入力モデル MdlClassNames プロパティが空の配列であれば、updateMetrics は出力モデル MdlClassNames プロパティを unique(Y) に設定します。

ヒント

  • 従来式の学習とは異なり、インクリメンタル学習用の個別の検定 (ホールドアウト) セットが存在しない場合もあります。そのため、データの各入力チャンクを検定セットとして扱うには、インクリメンタル モデルと各入力チャンクを、fit を使用して同じデータでモデルに学習させる前に updateMetrics に渡します。

アルゴリズム

すべて折りたたむ

パフォーマンス メトリクス

  • updateMetrics は、インクリメンタル モデルが "ウォーム" (IsWarm プロパティが true) のときに、Mdl.Metrics のテーブルの行ラベルによって指定され、新しいデータから得られるモデルのパフォーマンス メトリクスのみを追跡します。インクリメンタル モデルは、fit がインクリメンタル モデルを Mdl.MetricsWarmupPeriod の観測値 ("メトリクスのウォームアップ期間") にあてはめた後、ウォームになります。

    Mdl.EstimationPeriod > 0 の場合、関数はモデルをデータにあてはめる前にハイパーパラメーターを推定します。そのため、関数は、モデルがメトリクスのウォームアップ期間を開始する前に EstimationPeriod の観測値を追加で処理しなければなりません。

  • インクリメンタル モデルの Metrics プロパティは、各パフォーマンス メトリクスの 2 つの形式を table の変数 (列) Cumulative および Window として格納し、個々のメトリクスが行に沿うようにします。インクリメンタル モデルがウォームになると、updateMetrics は次の頻度でメトリクスを更新します。

    • Cumulative — 関数は、モデルの性能追跡の開始以降の累積メトリクスを計算します。関数は、関数が呼び出されるたびにメトリクスを更新し、提供されたデータ セット全体に基づいて計算を行います。

    • Window — 関数は、名前と値のペアの引数 Mdl.MetricsWindowSize によって決定されたウィンドウ内のすべての観測値に基づいてメトリクスを計算します。Mdl.MetricsWindowSize によってソフトウェアが Window メトリクスを更新する頻度も決まります。たとえば、Mdl.MetricsWindowSize が 20 の場合、関数は提供されたデータの最後の 20 個の観測値に基づいてメトリクスを計算します (X((end - 20 + 1):end,:) および Y((end - 20 + 1):end))。

      ウィンドウ内のパフォーマンス メトリクスを追跡するインクリメンタル関数は、次のプロセスを使用します。

      1. 指定された各メトリクスについて、長さ Mdl.MetricsWindowSize のバッファーおよび観測値の重みのバッファーを保存します。

      2. 入力観測値のバッチに基づくモデル性能をメトリクス バッファーの要素に入力し、対応する観測値の重みを重みバッファーに格納します。

      3. バッファーがいっぱいになると、Mdl.Metrics.Window をメトリクス ウィンドウの性能の加重平均で上書きします。関数が観測値のバッチを処理するときにバッファーがあふれる場合、最新の入力観測値 Mdl.MetricsWindowSize がバッファーに入り、最も古い観測値がバッファーから削除されます。たとえば、Mdl.MetricsWindowSize が 20 で、メトリクス バッファーには前に処理されたバッチからの 10 個の値が存在し、15 個の値が入力されるとします。長さ 20 のウィンドウを構成するため、関数は 15 個の入力観測値からの測定値と前のバッチからの最新の 5 個の測定値を使用します。

観測値の重み

分類問題では、クラスの事前確率分布が既知 (Mdl.PriorNaN 値で構成されない) の場合、updateMetrics は、観測値の重みを正規化して、それぞれのクラスの事前クラス確率の合計になるようにします。このアクションは、観測値の重みが既定でそれぞれのクラスの事前確率であることを前提としています。

回帰問題の場合、またはクラスの事前確率分布が未知である場合、ソフトウェアは、updateMetrics が呼び出されるたびに、指定された観測値の重みを正規化して、合計が 1 になるようにします。

R2020b で導入