Main Content

loss

データのバッチでの単純ベイズ インクリメンタル学習分類モデルの損失

R2021a 以降

説明

loss は、構成されたインクリメンタル学習用の単純ベイズ分類モデル (incrementalClassificationNaiveBayes オブジェクト) の分類損失を返します。

データ ストリームでのモデルの性能を測定し、結果を出力モデルに保存するには、updateMetrics または updateMetricsAndFit を呼び出します。

L = loss(Mdl,X,Y) は、予測子データ X および対応する応答 Y のバッチを使用して、インクリメンタル学習用の単純ベイズ分類モデル Mdl の最小コスト分類損失を返します。

L = loss(Mdl,X,Y,Name,Value) は、1 つ以上の名前と値の引数によって指定された追加オプションを使用します。たとえば、分類損失関数を指定できます。

すべて折りたたむ

ストリーミング データでインクリメンタル モデルの性能を測定する方法は 3 通りあります。

  • 累積メトリクスで、インクリメンタル学習の開始以降の性能を測定します。

  • ウィンドウ メトリクスで、指定した観測値ウィンドウでの性能を測定します。指定したウィンドウをモデルが処理するたびにメトリクスが更新されます。

  • 関数 loss で、指定したデータのバッチについてのみ性能を測定します。

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

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

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

インクリメンタル学習用の単純ベイズ分類モデルを作成します。クラス名を指定し、メトリクス ウィンドウ サイズを観測値 1000 個に指定します。モデルを最初の 10 個の観測値に当てはめて loss 用に構成します。

Mdl = incrementalClassificationNaiveBayes('ClassNames',unique(Y),'MetricsWindowSize',1000);
initobs = 10;
Mdl = fit(Mdl,X(1:initobs,:),Y(1:initobs));
canComputeLoss = (size(Mdl.DistributionParameters,2) == Mdl.NumPredictors) + ...
    (size(Mdl.DistributionParameters,1) > 1) > 1
canComputeLoss = logical
   1

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

データ ストリームをシミュレートし、500 個の観測値の入力チャンクごとに次のアクションを実行します。

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

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

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

  4. すべてのパフォーマンス メトリクスを保存して、インクリメンタル学習中にそれらがどのように進化するかを確認します。

% Preallocation
numObsPerChunk = 500;
nchunk = floor((n - initobs)/numObsPerChunk);
mc = array2table(zeros(nchunk,3),'VariableNames',["Cumulative" "Window" "Chunk"]);

% Incremental learning
for j = 1:nchunk
    ibegin = min(n,numObsPerChunk*(j-1) + 1 + initobs);
    iend   = min(n,numObsPerChunk*j + initobs);
    idx = ibegin:iend;    
    Mdl = updateMetrics(Mdl,X(idx,:),Y(idx));
    mc{j,["Cumulative" "Window"]} = Mdl.Metrics{"MinimalCost",:};
    mc{j,"Chunk"} = loss(Mdl,X(idx,:),Y(idx));
    Mdl = fit(Mdl,X(idx,:),Y(idx));
end

Mdl は、ストリーム内のすべてのデータで学習させた incrementalClassificationNaiveBayes モデル オブジェクトになります。インクリメンタル学習中およびモデルがウォームアップされた後、updateMetrics は入力観測値でのモデルの性能をチェックし、関数 fit はモデルをそれらの観測値に当てはめます。loss はメトリクスのウォームアップ期間に依存しないため、すべてのチャンクについて最小コストを測定します。

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

figure
plot(mc.Variables)
xlim([0 nchunk])
ylim([0 0.1])
ylabel('Minimal Cost')
xline(Mdl.MetricsWarmupPeriod/numObsPerChunk + 1,'r-.')
legend(mc.Properties.VariableNames)
xlabel('Iteration')

Figure contains an axes object. The axes object with xlabel Iteration, ylabel Minimal Cost contains 4 objects of type line, constantline. These objects represent Cumulative, Window, Chunk.

黄色の線は、入力データの各チャンクの最小コストを表します。メトリクスのウォームアップ期間後、Mdl は累積およびウィンドウ メトリクスを追跡します。

インクリメンタル学習用の単純ベイズ分類モデルをストリーミング データに当てはめ、データの入力チャンクでマルチクラス クロス エントロピー損失を計算します。

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

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

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

インクリメンタル学習用の単純ベイズ分類モデルを作成します。次のようにモデルを構成します。

  • クラス名を指定します。

  • メトリクスのウォームアップ期間を観測値 1000 個に指定。

  • メトリクス ウィンドウ サイズを観測値 2000 個に指定。

  • マルチクラス クロス エントロピー損失を追跡してモデルの性能を測定。新しい各観測値のマルチクラス クロス エントロピー損失を測定する無名関数を作成し、数値安定性を得るために許容誤差を含めます。名前 CrossEntropy とそれに対応する関数ハンドルを含む構造体配列を作成します。

  • モデルを最初の 10 個の観測値に当てはめて分類損失を計算。

tolerance = 1e-10;
crossentropy = @(z,zfit,w,cost)-log(max(zfit(z),tolerance));
ce = struct("CrossEntropy",crossentropy);

Mdl = incrementalClassificationNaiveBayes('ClassNames',unique(Y),'MetricsWarmupPeriod',1000, ...
    'MetricsWindowSize',2000,'Metrics',ce);
initobs = 10;
Mdl = fit(Mdl,X(1:initobs,:),Y(1:initobs));

Mdl はインクリメンタル学習用に構成された incrementalClassificationNaiveBayes モデル オブジェクトです。

インクリメンタル学習を実行します。各反復で次を行います。

  • 100 個の観測値のチャンクを処理して、データ ストリームをシミュレートします。

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

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

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

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

% Preallocation
numObsPerChunk = 100;
nchunk = floor((n - initobs)/numObsPerChunk);
tanloss = array2table(zeros(nchunk,3),'VariableNames',["Cumulative" "Window" "Chunk"]);

% Incremental fitting
for j = 1:nchunk
    ibegin = min(n,numObsPerChunk*(j-1) + 1 + initobs);
    iend   = min(n,numObsPerChunk*j + initobs);
    idx = ibegin:iend;    
    Mdl = updateMetrics(Mdl,X(idx,:),Y(idx));
    tanloss{j,1:2} = Mdl.Metrics{"CrossEntropy",:};
    tanloss{j,3} = loss(Mdl,X(idx,:),Y(idx),'LossFun',@(z,zfit,w,cost)mean(crossentropy(z,zfit,w,cost)));
    Mdl = fit(Mdl,X(idx,:),Y(idx));
end

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

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

figure
h = plot(tanloss.Variables);
xlim([0 nchunk])
ylabel('Cross Entropy')
xline(Mdl.MetricsWarmupPeriod/numObsPerChunk,'r-.')
xlabel('Iteration')
legend(h,tanloss.Properties.VariableNames)

Figure contains an axes object. The axes object with xlabel Iteration, ylabel Cross Entropy contains 4 objects of type line, constantline. These objects represent Cumulative, Window, Chunk.

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

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

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

  • updateMetrics は、ウィンドウ メトリクスを 2000 個の観測値 (20 回の反復) の処理後に計算。

  • Mdl がインクリメンタル学習の初めから観測値を予測するように構成されているため、loss はデータの入力チャンクごとにクロス エントロピーを計算可能。

入力引数

すべて折りたたむ

インクリメンタル学習用の単純ベイズ分類モデル。incrementalClassificationNaiveBayes モデル オブジェクトとして指定します。Mdl は、直接作成することも、サポートされている従来式の学習済み機械学習モデルを関数 incrementalLearner によって変換して作成することもできます。詳細については、対応するリファレンス ページを参照してください。

Mdl は、観測値のバッチでの損失を計算するように構成しなければなりません。

  • Mdl が従来式の学習済みモデルから変換される場合、いかなる修正も行うことなく損失を計算できます。

  • それ以外の場合、入力モデル Mdl を予測されるすべてのクラスが格納されたデータに当てはめる必要があります。つまり、Mdl.DistributionParameters は、列数が Mdl.NumPredictors で行数が 1 以上の cell 行列でなければなりません。各行は Mdl.ClassNames の各クラス名に対応します。

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

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

データ型: single | double

損失を計算するためのラベルのバッチ。categorical 配列、文字配列、string 配列、logical ベクトル、浮動小数点ベクトル、または文字ベクトルの cell 配列として指定します。

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

YMdl.ClassNames のメンバーではないラベルを含む場合、loss はエラーを生成します。YMdl.ClassNames のデータ型は同じでなければなりません。

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

名前と値の引数

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

R2021a より前では、名前と値をそれぞれコンマを使って区切り、Name を引用符で囲みます。

例: 'LossFun','classiferror','Weights',W は、誤分類誤差率を返すように指定し、観測値の重み W を指定します。

観測値を誤分類するコスト。次の表の値として指定します。ここで、c は Mdl.ClassNames 内のクラスの数です。指定された値は Mdl.Cost の値をオーバーライドします。

説明
c 行 c 列の数値行列

Cost(i,j) は、クラス Mdl.ClassNames(i) およびクラス Mdl.ClassNames(j) に対して、真のクラスが i の場合に観測値をクラス j に分類するコストです。つまり、行は真のクラスに、列は予測するクラスに対応します。たとえば、Cost = [0 2;1 0] は、Mdl.ClassNames(1) の誤分類に Mdl.ClassNames(2) の誤分類の 2 倍のペナルティを適用します。

構造体配列

次の 2 つのフィールドをもつ構造体配列です。

  • ClassNames には、Mdl.ClassNames と同じ値のクラス名が格納されます。

  • ClassificationCosts には、前述のコスト行列が格納されます。

例: Cost=struct('ClassNames',Mdl.ClassNames,'ClassificationCosts',[0 2; 1 0])

データ型: single | double | struct

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

次の表は、組み込みの損失関数名の一覧です。string ベクトルを使用して、複数指定できます。

名前説明
"binodeviance"二項分布からの逸脱度
"classiferror"誤分類誤差率
"exponential"指数
"hinge"ヒンジ
"logit"ロジスティック
"mincost"

最小予測誤分類コスト

"quadratic"2 次

詳細については、分類損失を参照してください。

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

lossval = lossfcn(C,S,W,Cost)

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

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

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

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

  • W は、観測値の重みの n 行 1 列の数値ベクトルです。

  • Cost は、誤分類コストの、K 行 K 列の数値行列です。

例: 'LossFun',"classiferror"

例: 'LossFun',@lossfcn

データ型: char | string | function_handle

事前クラス確率。この数値ベクトルの値を指定します。PriorMdl.ClassNames のクラス数と同じ長さであり、要素の順序は Mdl.ClassNames 内のクラスの順序に対応します。loss は結果の合計が 1 となるようにベクトルを正規化します。

指定された値は Mdl.Prior の値をオーバーライドします。

データ型: single | double

インクリメンタル学習関数が生の応答値を変換する方法を記述するスコア変換関数。文字ベクトル、string スカラー、または関数ハンドルとして指定します。指定された値は Mdl.ScoreTransform の値をオーバーライドします。

次の表は、スコア変換で使用可能な組み込み関数の一覧です。

説明
"doublelogit"1/(1 + e–2x)
"invlogit"log(x / (1 – x))
"ismax"最大のスコアをもつクラスのスコアを 1 に設定し、他のすべてのクラスのスコアを 0 に設定する
"logit"1/(1 + e–x)
"none" または "identity"x (変換なし)
"sign"x < 0 のとき –1
x = 0 のとき 0
x > 0 のとき 1
"symmetric"2x – 1
"symmetricismax"最大のスコアをもつクラスのスコアを 1 に設定し、他のすべてのクラスのスコアを –1 に設定する
"symmetriclogit"2/(1 + e–x) – 1

データ型: char | string

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

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

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

データ型: double | single

出力引数

すべて折りたたむ

分類損失。数値スカラーとして返されます。L はモデルの品質を示す尺度です。解釈は損失関数と加重スキームによって異なります。

詳細

すべて折りたたむ

分類損失

"分類損失" 関数は分類モデルの予測誤差を評価します。複数のモデルで同じタイプの損失を比較した場合、損失が低い方が予測モデルとして優れていることになります。

以下のシナリオを考えます。

  • L は加重平均分類損失です。

  • n は標本サイズです。

  • バイナリ分類は以下です。

    • yj は観測されたクラス ラベルです。陰性クラスを示す -1 または陽性クラスを示す 1 (あるいは、ClassNames プロパティの最初のクラスを示す -1 または 2 番目のクラスを示す 1) を使用して符号化されます。

    • f(Xj) は予測子データ X の観測値 (行) j に対する陽性クラスの分類スコアです。

    • mj = yjf(Xj) は、yj に対応するクラスに観測値 j を分類する分類スコアです。正の値の mj は正しい分類を示しており、平均損失に対する寄与は大きくありません。負の値の mj は正しくない分類を示しており、平均損失に大きく寄与します。

  • マルチクラス分類 (つまり、K ≥ 3) をサポートするアルゴリズムの場合、次のようになります。

    • yj* は、K - 1 個の 0 と、観測された真のクラス yj に対応する位置の 1 から構成されるベクトルです。たとえば、2 番目の観測値の真のクラスが 3 番目のクラスであり K = 4 の場合、y2* = [0 0 1 0]′ になります。クラスの順序は入力モデルの ClassNames プロパティ内の順序に対応します。

    • f(Xj) は予測子データ X の観測値 j に対するクラス スコアのベクトルで、長さは K です。スコアの順序は入力モデルの ClassNames プロパティ内のクラスの順序に対応します。

    • mj = yj*′f(Xj).したがって mj は、観測された真のクラスについてモデルが予測するスカラー分類スコアです。

  • 観測値 j の重みは wj です。観測値の重みは、その合計が Prior プロパティに格納された対応するクラスの事前確率になるように正規化されます。そのため、次のようになります。

    j=1nwj=1.

この状況では、名前と値の引数 LossFun を使用して指定できる、サポートされる損失関数は次の表のようになります。

損失関数LossFun の値
二項分布からの逸脱度"binodeviance"L=j=1nwjlog{1+exp[2mj]}.
観測誤分類コスト"classifcost"

L=j=1nwjcyjy^j,

ここで、y^j はスコアが最大のクラスに対応するクラス ラベル、cyjy^j は真のクラスが yj である場合に観測値をクラス y^j に分類するユーザー指定のコストです。

10 進数の誤分類率"classiferror"

L=j=1nwjI{y^jyj},

ここで、I{·} はインジケーター関数です。

クロスエントロピー損失"crossentropy"

"crossentropy" はニューラル ネットワーク モデルのみに適しています。

加重クロスエントロピー損失は次となります。

L=j=1nw˜jlog(mj)Kn,

ここで重み w˜j は、合計が 1 ではなく n になるように正規化されます。

指数損失"exponential"L=j=1nwjexp(mj).
ヒンジ損失"hinge"L=j=1nwjmax{0,1mj}.
ロジット損失"logit"L=j=1nwjlog(1+exp(mj)).
最小予測誤分類コスト"mincost"

"mincost" は、分類スコアが事後確率の場合にのみ適しています。

重み付きの最小予測分類コストは、次の手順を観測値 j = 1、...、n について使用することにより計算されます。

  1. 観測値 Xj をクラス k に分類する予測誤分類コストを推定します。

    γjk=(f(Xj)C)k.

    f(Xj) は観測値 Xj のクラス事後確率の列ベクトルです。C はモデルの Cost プロパティに格納されるコスト行列です。

  2. 最小予測誤分類コストに対応するクラス ラベルを観測値 j について予測します。

    y^j=argmink=1,...,Kγjk.

  3. C を使用して、予測を行うために必要なコスト (cj) を求めます。

最小予測誤分類コスト損失の加重平均は次となります。

L=j=1nwjcj.

二次損失"quadratic"L=j=1nwj(1mj)2.

既定のコスト行列 (正しい分類の場合の要素値は 0、誤った分類の場合の要素値は 1) を使用する場合、"classifcost""classiferror"、および "mincost" の損失の値は同じです。既定以外のコスト行列をもつモデルでは、ほとんどの場合は "classifcost" の損失と "mincost" の損失が等価になります。これらの損失が異なる値になる可能性があるのは、最大の事後確率をもつクラスへの予測と最小の予測コストをもつクラスへの予測が異なる場合です。"mincost" は分類スコアが事後確率の場合にしか適さないことに注意してください。

次の図では、1 つの観測値のスコア m に対する損失関数 ("classifcost""crossentropy"、および "mincost" を除く) を比較しています。いくつかの関数は、点 (0,1) を通過するように正規化されています。

Comparison of classification losses for different loss functions

アルゴリズム

すべて折りたたむ

観測値の重み

それぞれの条件付き予測子分布について、loss は加重平均と標準偏差を計算します。

事前クラス確率分布が既知の場合 (つまり、事前分布が経験的分布でない場合)、loss は、観測値の重みを正規化して、それぞれのクラスの事前クラス確率の合計になるようにします。このアクションは、既定の観測値の重みがそれぞれの事前クラス確率であることを前提としています。

クラスの事前確率分布が経験的分布の場合、ソフトウェアは、loss が呼び出されるたびに、指定された観測値の重みを正規化して、合計が 1 になるようにします。

バージョン履歴

R2021a で導入