読者です 読者をやめる 読者になる 読者になる

Sideswipe

情報工学、計算論的神経科学など、真面目なこと書くブログ。お仕事の話は Twitter: @kazoo04 にお願いします。

オンライン線形分類器とSCW

はじめに

こんにちは。Machine Learning Advent Calendar 2012 、 12/20 を担当させていただく @kazoo04 です。
普段は(株)ウサギィでエンジニアをやっています。

今日の話

今日は Exact Soft Confidence-Weight Learning (Wang et al, ICML2012) (以下SCW)のご紹介を致します。
SCWは線形オンライン形分類器のひとつで、

  • 学習が高速
  • オンライン学習
  • ノイズに強い
  • 精度が良い

という素晴らしいアルゴリズムです。 SCWはCWを改良したアルゴリズムですが、本記事ではPerceptronから始まり、PA、CWなどを経てSCWに至るまでの過程とSCWのアルゴリズムについてまとめたいと思います。

数式の表記

すみません、はてなブログを始めたばかりで、ベクトルを太字の立体にする方法がイマイチわかりませんでした。すこし表記が揺れているところがありますがご了承いただければと思います。

線形分類器

線形分類器は、  x \in \mathbb{R}^m から出力  y={-1, +1}を推定する関数  f(\mathbf{x}; \mathbf{w}) を学習するというものです。また、各訓練事例が1つ与えられるたびにパラメータを更新する方法をオンライン学習と呼びます。

Perceptron

もっとも単純なオンライン線形分類器としては、 Rosenblatt の Perceptron が挙げられます。訓練事例 (\mathbf{x}, y) が与えられた時、現在の分類器で正しく分類できるかどうかを調べ、間違っている場合は  \mathbf{w}_{i+1} = \mathbf{w}_i + y\mathbf{x} に従って更新します。単純ではありますが、線形分離可能な問題であれば有限回の更新ですべての訓練事例を正しく分類できることが保証されており(Perceptronの収束定理)、またそうでない場合でもまあまあな結果が得られます(問題にもよるが)。

Passive Aggressive

CrammerのPAは、Gmailの優先トレイにも使われているアルゴリズムです。
PAでも、訓練事例が正しく分類できたら重みは変更しません(Passive)。うまく動いてるものには手を触れないという方針なのです。
逆に、正しく分類ができなかったら、その訓練事例が正しく分類できる最小限だけ分離面を動かします(Aggressive)。
下の図を見てください。左の例では、提示されたデータが正しく分類できているので、分離面は動かしません(なにもしません)。
右の例では、提示されたデータがうまく分類できなかったので、分類ができる最小限だけ分離面を動かしています(わかりやすさのため、最小限よりはちょっと多めに動かしていますが)。

f:id:kazoo04:20121219213823p:plain

ただ、この方法はアグレッシブすぎて、ノイズがあったときに分離面が振り回されてしまうというデメリットがあります。
そこで、 PA-I, PA-IIでは誤識別をある程度許容することでノイズに対してロバスト性を確保しています。

Confidence-Weighted Algorithm *1

CWは、今までの線形分類器とは異なる考え方を導入し、収束を早めると同時に精度も高くしたという夢の様なアルゴリズムです。
機械学習に食わせる訓練事例は、ふつう各特徴の頻度に大きなばらつきがあります。また、低頻度の特徴が大きな影響を持っていることも多々あります。
先に挙げた手法では、各訓練事例の出現頻度は考慮されていないため、高頻度の特徴は比較的信頼できる一方で、低頻度の特徴は重みがあまり更新されていないので、あまり信頼できないと言えます。

そこで、CWでは「過去にどれくらい現れたか」を考慮した上で学習を行います。
CWでは、重みベクトル  wガウス分布 N(\mu, \Sigma) を導入し、平均と共分散を同時に更新していきます。
 \mu は、その時点で一番もっともらしい重みベクトルで、  \Sigma はその重みにどれくらい自信があるのかを表す共分散行列になります。
分散の大きいパラメータは、まだあまり自信がないので、思い切って大きめに更新します。逆に分散が小さいパラメータはある程度正確に学習できていると考え、小さめに更新します。

例として、既存のアルゴリズムで、文を肯定か否定かに分類する場合の更新を考えてみましょう(参考: Confidence Weighted Linear Classificationを読んだ - 射撃しつつ前転)。 "I liked this author." という肯定的な文があったとして、この事例の分類に失敗した場合(つまり否定的な文だと分類された場合)は、 I, liked, this, author それぞれについて重みが加算されます。 また、 "I liked this author, but found the book is dull." という否定的な文の分類に失敗した場合は、 I, liked, this, author, but, found, the, book, is, dull それぞれについて重みが減算されます。このとき、それぞれの重みは同じだけ加減算されます。
たくさん出現する単語であれば、少しくらいノイズがあっても頑健なパラメータ推定が可能であると考えられます。たとえば、否定的な文に liked という単語が入っていても、肯定的な文により多くの liked という単語が入っていれば、うまく学習できます。

この方法だと、よく出現する単語については正確なパラメータの推定が可能になると考えられますが、めったに出現したい単語(dullなど)はうまくパラメータを推定できない(推定出来るだけの事例がない)ので、思い切って大きく重みを更新します。

既存のアルゴリズムでは、重みはたとえば 0.8→0.6 に更新する、といった単純な加減算からなりますが(図の上側)、CWの場合は  \mu を0.8→ 0.6 にすると共に、  \Sigma は少し減らす(すこし自信がでてきた)ようにします(図の下側)。

f:id:kazoo04:20121220140516p:plain

このように、低頻度の特徴を活用することで、収束が非常に早くなったのがCWの大きなメリットです。通常のオンライン学習では全学習データを何度か学習させますが、CWは最初に1回でほぼ収束する(それ以上学習させても精度に大きな違いがない)ことがわかります。

具体的にはPassive Aggressiveの場合と似ていて、

  • 現在の訓練例を正しく分類できる
  • 今までの分布になるべく近くする

の2つを満たす分布  (\mu, \Sigma) を探すことになります。

 {{\rm arg~min}\limits}_{\mathbf{\mu}, \Sigma} D_{KL} (\rm N(\mathbf{\mu}, \Sigma) || \rm N(\mathbf{\mu}, \Sigma))  s.t. Pr_{\mathbf{w} \sim \rm N(\mathbf{\mu}, \Sigma)} [y \mathbf{w}_i^T \mathbf{x} \ge 0] \ge \eta

この最適化問題は嬉しいことに閉じた解を持っており、簡単に計算できます。すばらしいですね!

Adaptive Regularization of Weight Vectors (AROW) *2

ところが、CWには弱点があり、訓練事例にノイズがあると急激に性能が劣化します。Passive Aggressiveと同様、与えられた訓練事例を確実に分類できるように更新してしまうためです。 Crammer によって考案されたAROWは、次の3つの条件を同時に考慮して最適化します。

  1. 各特徴の分散は少しずつ小さくしていく(自信を上げる)
  2. 現在の訓練例を正しく分類する(PA, CW と同じ)
  3. 今までの分布に近い

 {{\rm arg~min}\limits}_{\mathbf{\mu}, \Sigma} D_{KL} (\rm N(\mathbf{\mu}, \Sigma) || \rm N(\mathbf{\mu}, \Sigma))  + \lambda_1 L(\mathbf{x}, y, \mu) + \lambda_2 L(\mathbf{x}^T \Sigma \mathbf{x})

 \lambda_1は条件1,  \lambda_2は条件2をどれくらい重視するかのパラメータです。「そのパラメータの設定が大変なんでしょう?」と思うかもしれませんが、これは結構適当でも大丈夫で、問題によって調整する必要はありません(たとえば0.1とか)。

ごちゃごちゃと書きましたが、実装は難しくありません。論文中の擬似コードはこんな感じです。

f:id:kazoo04:20121220000918p:plain

昔書いたD言語のコードだとこんなかんじです。

    int Update(feature[] fv, int label) 
      in
      {
        assert(label == -1 || label == +1);
        assert(fv != null);
      }
      out (result)
      {
        assert(result == 0 || result == 1);
      }
      body
      {
        double m = GetMargin(fv);

        if(m * label >= 1) return 0;

        double confidence = GetConfidence(fv);
        double beta = 1.0 / (confidence + hyperparameter);
        double alpha = (1.0 - label * m) * beta;

        //Update mean(μ)
        //平均の更新
        foreach (v; fv) {
          mean[v.index] += alpha * cov[v.index] * label * v.weight;
        }

        //Update covariance(∑)
        //分散の更新
        foreach (v; fv) {
          cov[v.index] = 1.0
            / ((1.0 / cov[v.index]) + v.weight * v.weight / hyperparameter);
        }

        //損失の計算 (Squared Hinge-loss)
        int loss = m * label < 0 ? 1 : 0;

        return loss;
      }

Exact Soft Confidence-Weight Learning (SCW) *3

さて、ようやく本題のSCWです。
SCWも、CWの「ノイズに弱い」という部分を改良したアルゴリズムであるという点では、AROW(やその他のアルゴリズム― NHERDやNAROWなど)と同じですが、ソフトマージンSVMのように、マージン最適化も行うという点で画期的です。また、マージンを考慮するためAROWなどのアルゴリズムよりさらに高速に収束するという特徴もあります。

SCWの考え方は、ある程度(  1 - \eta )の誤分類を許容して、パラメータの急激な変化を防ぐことです。
何度か述べているように、訓練事例に現れた頻度によって、自信のあるパラメータとそうでないパラメータが存在します。そこで、現在の識別超平面から信頼度による重み付けマージンを計算して、それを損失関数  l に組み込みます( \phi はちょっとわかりにくいのですが、 ガウス分布の累積密度関数の逆関数を、さらに  \eta で評価したものです)。

 l(\rm N(\mu_t, \Sigma_t);(\mathbf{x}_t, y_t)) = {\rm max} (0, \phi \sqrt{\mathbf{x}_t^T \Sigma x_t} - y_t(\mu_t \cdot \mathbf{x})_t)

そして、次の2つの条件を同時に考慮して最適化します。

  1. ガウス分布間の重み付けマージンを最適化する
  2. 今までの分布に近い

 {{\rm arg~min}\limits}_{\mathbf{\mu}, \Sigma} D_{KL} (\rm N(\mathbf{\mu}, \Sigma) || \rm N(\mathbf{\mu}, \Sigma))  +C (l(N(\mu_t, \Sigma_t);(x_t, y_t)))

Cは、どれくらい条件1を考慮するかというパラメータです。上に挙げたのは SCW-I というバージョンで、

 {{\rm arg~min}\limits}_{\mathbf{\mu}, \Sigma} D_{KL} (\rm N(\mathbf{\mu}, \Sigma) || \rm N(\mathbf{\mu}, \Sigma))  +C (l(N(\mu_t, \Sigma_t);(x_t, y_t))^2)

というものもあり、こちらは SCW-II と著者は呼んでいます。まあ実験結果を見る限り、そこまで大きな差はないのでSCW-Iでいいんじゃないかな?と思います。
論文から擬似コードを抜粋するとこんな感じで、非常に簡単です。AROWやCWとあまり変わりません。

f:id:kazoo04:20121219215301p:plain

パラメータが2つ出てきてしまいましたが、 AROWと同じく、  \eta C もかなり適当でいいです。

まとめ

オンライン線形分類器は、高速に処理ができる上に、追加学習や実装も容易です。一時はCWの登場で大幅な精度向上を達成しましたが、ノイズに弱いという点を克服するためにAROWやSCWなどのアルゴリズムが考案されました。

Algorithm Large Margin Confidence Non-Separable Adaptive Margin
PA
CW
AROW
SCW

特にSCWはノイズに対してロバストなことはもちろん、信頼度による重み付けマージンを導入し、ソフトマージンの最適化をしている点や、損失上限の証明がなされているなどのメリットがあります。
元の論文の実験でもSCWは他の手法より優れた成績を残しており、非常に実用的なものになっています。

実装上の注意点ついては、CW, AROW, SCWともに、共分散行列をまともに扱うとメモリを食いますし実装も面倒なので、対角項だけ計算すればOKです(非対角項は0にする)。こうしても精度はほとんどかわりません。

論文を見てわかるとおり、AROWやSCWにいたってはSVMよりよい成績を叩きだしており、線形識別器が欲しいのであればSCWを使えばいいんじゃないかなとおもいます。

NHERDもたまに見ますが、AROWと比べるとAROWのほうがいいことが多いです。それにSCWのほうが基本的に精度が良いので、迷ったらとりあえずSCWを使えばいいんじゃないかなとおもいます。

SCWについては、kisaさんの記事が非常に参考になるので、ご興味がありましたらぜひこちらもご覧ください。

それでは。

追記

その後 SCW と AROW を使う機会(画像の分類)があり、実践してみたので所感を。

  • SCW-II はぜんぜんダメ SCW-I を使おう
  • SCW はパラメータが2個あるので調整が面倒
  • AROW はパラメータが1個しかないので楽(気持ちAROWのほうがパラメータに敏感でないのでそれもまた使いやすい)
  • パラメータを調整した AROW とパラメータを調整した SCW-I はほぼ同じ性能(まあ平均すると SCW−I のほうがすこし良いが)

というわけでデータセットにもよりますが個人的には AROW のほうがいいなあという感じです。

  • すこしでも精度を上げたくて、そのために良いパラメータの探索を行うのが苦でないのなら SCW
  • そうでないなら AROW

が良いと思います。

*1:Dredze, Mark, Crammer, Koby, and Pereira, Fernando. Confidence-weighted linear classification. In ICML, pp. 264–271, 2008.

*2:Crammer, Koby, Kulesza, Alex, and Dredze, Mark. Adaptive regularization of weight vectors. In NIPS, pp. 345–352, 2009b.

*3:Peilin Zhao, Jialei Wang, Steven C.H. Hoi. Exact Soft Confidence-Weighted Learning. ICML 2012.