Python、機械学習

バイアスとバリアンスの違い、正則化の意味【機械学習, Python, スパースモデリング】

機械学習をやっていると、バイアスとバリアンスのバランスが重要だという話がよく出てきます。

バイアスとバリアンスとは何なのか?バランスをとるとはどういうことか?

そして、L1正則化、L2正則化とはどういう意味なのか?

それらについてまとめました。

ざっくりとしたイメージ

例えば、最小二乗法ですと、各データにおける実測値yと予測値yの差の二乗和(損失関数)が最小となるよう、モデルのパラメータを決めます。

よって、個々のデータにおいて、実測値yと予測値y はできるだけ乖離してほしくないです。

図で表すとこんな感じです。

バイアス、バリアンスの大小が変わると、こうなります。

バイアスが大きいと、どのデータ(i=1,2, …, n)を見ても、実測値yと予測値yが乖離していて、y-yが0から離れます。よって、損失関数は大きくなり、モデルの精度は悪化します。

バリアンスが大きいと、実測値yと予測値yの差がデータによってまちまちです。実測値yと予測値yの差が大きいものが足を引っ張り、損失関数が大きくなるため、モデルの精度は悪化します。

一般に、バイアスとバリアンスはトレードオフにあります。

以下、詳細を説明します。

機械学習において目指す方向性

学習データ(X, y)を用いて、Xからyを予測する機械学習のモデル f(X) を構築したとします。

機械学習モデルの精度の指標としてよく用いられるのが、平均2乗誤差(mean square error ; MSE)です。そして、テストデータに対するMSEが小さいほど、汎化性能が高い、よいモデルだと言えます。

テストデータに対する精度を上げることが、機械学習における「目指す方向性」です。

平均2乗誤差

まず2乗誤差とは、実測yと予測yの差を2乗したものです。

3つのテストデータ(X1、y1)(X2、y2)(X3、y3)があるとしたら、2乗誤差、平均2乗誤差は次のようになります。

それぞれの2乗誤差

(y1 – f(X1))2、(y2 – f(X2))2、(y3 – f(X3))2

平均2乗誤差

{ (y1 – f(X1))2 + (y2 – f(X2))2 + (y3 – f(X3))2 }/3

テストデータの平均2乗誤差は、

平均2乗誤差=バイアス2バリアンスノイズ

で表されます。

詳細はこちらです。

バイアス偏りと分散-Wikipedia

右辺の3つ目にある「ノイズ」は削減不能な誤差、という意味です。

したがって、モデルの精度を上げるためには、バイアスバリアンスをいかに小さくするかがポイントになります。

実際のモデル構築の流れ

実際のモデル構築の流れは、以下の通りです。

1)どのような「型」を使うか決めます。

線形回帰にするのか、サポートベクター回帰にするのか、ランダムフォレスト回帰にするのか、などです。

2)学習データを使って、型の「パラメータ」を決めます。

例えば、線形回帰なら傾きと切片がパラメータになります。サポートベクター回帰ならC、ε、γ がパラメータになります。型を決め、パラメータを決めたものが「モデル」です。

3)汎化性能を評価します。

構築したモデル f(X)でテストデータを予測し、テストデータに対する精度、つまり汎化性能を評価します。上で述べた平均2乗誤差(MSE)はその一例です。

バイアスとは

バイアスの定性的な意味は、「モデルの型が硬すぎるがゆえに生じる、実測値yへのアンフィット度」です。

例えば、複雑に分布したデータを線形モデルでフィッティングしようとすると、バイアスが大きくなります。例えるなら、パスタのような硬い線で、複雑に分布したデータに沿わせようとする行為です。どんなに頑張っても、限界があります。

モデルが硬すぎて、これ以上頑張ってもデータにフィットできない・・・、そのときのデータyと予測値f(x)の差がバイアスです。

もし、硬い線ではなくひものように柔らかい線なら、実際のデータが複雑に分布していてもうまく沿わせることができ、バイアスは小さくなります。

なお、モデルが硬いか柔らかいかは、どのようなモデルの型を選んでくるかで決まります。

また、モデルの硬い/柔らかいは、モデルの表現力が乏しい/豊かである、と言い換えることもできます。あるいは、データに対して鈍感/敏感、と言い換えることもできそうです。

バリアンスとは

バリアンスの定性的な意味は、「モデルの型が柔らかすぎるがゆえに生じる、モデルのぶれやすさ」です。

機械学習とは、手持ちのデータから、他のデータにも当てはまる共通の法則を導き出すプロセスです。共通の法則というのがモデルです。

もし、学習に使えるデータが1000個あるとします。

このうち、No.1~100のデータを使ってモデルを組もうが、No.901~1000を使ってモデルを組もうが、はたまたNo.1~1000の全データを使ってモデルを組もうが、導き出される法則は一つであってほしいわけです。

ただし、推定の誤差などもあり、同じ型を使ってモデル構築しようとしても、学習に使うデータが変わるとモデルは多少バラついてしまいます。

単回帰モデルなら、傾きがこれ、切片がこれ、と一つに決まってほしいのですが、学習データにより、傾きが〇〇、切片が△△の直線になる場合もありますし、傾きが□□、切片が××の直線になる場合もあります。

学習に使うデータにより回帰の線が多少ぶれるのは仕方がないにしても、我々はテストデータを一意に予測したいわけで、予測のよりどころとなる法則(モデル)はできるだけぶれてほしくありません。

モデルの型が柔らかすぎると、学習に使うデータに従順に沿ってしまうばかりに不自然に細かくぐねぐねした線になってしまいます。

そして、学習に使うデータが変われば線の形状も大きく変わります。要は、柔らかいモデルの型は無駄に学習データにフィットするため、学習データが変わるたびにモデルの姿は大きくぶれる、つまりバリアンスが大きくなるわけです。

一方、線形回帰のような硬いモデルの型だと、学習データが変わっても線の傾きなどはあまり変わりません。モデルが硬いので、学習データに対して無駄にフィットすることができないからです。

過学習(オーバーフィッティング)

学習モデルに無駄にフィットしたグネグネ回帰曲線、つまりバリアンスの大きいモデルはテストデータにフィットしません。これを過学習といいます。

世の物理法則を見ても、グネグネした複雑な方程式というのは少なく、比較的シンプルなモデルのものが多いです。このことからも、不自然にグネグネしたモデルは汎用性のある法則になり得ないことがイメージできるかと思います。

バイアスとバリアンスはトレードオフ

線形回帰のような硬い「型」は、データにきれいにフィットさせることはできないけれど、モデルはわりと一意に決まりやすいです。

つまり、硬い、表現力が乏しい、鈍感なモデルはバイアスは大きく、バリアンスは小さいと言えます。

一方、非線形モデルのような柔らかい「型」は、データにきれいにフィットさせることはできるけれど、モデルが一意に決まりにくいです。

つまり、柔らかい、表現力が豊かな、敏感なモデルはバイアスは小さく、バリアンスは大きいと言えます。

一般にバイアスとバリアンスはトレードオフの関係にあり、どちらかを小さくすると、もう片方は大きくなる関係にあります。

バイアスは学習不足、バリアンスは過学習を表す指標ですので、トレードオフになることは理解できるかと思います。

バイアスとバリアンスの和が最小となる、ほどほどに学習させたモデルを探ることが重要だということです。

学習不足を抑える方法

バイアスが大きい状態、つまり学習不足な状態を解消するには、柔らかいモデルを使ってみることです。線形回帰ではなく非線形なモデルを使ってみる、などです。

過学習を抑える方法

バリアンスが大きい状態、つまり過学習な状態を解消するには、硬いモデルを使ってみることです。非線形なモデルではなく、線形なモデルを使ってみる、などです。

また、以下で説明するように、モデルに使用する説明変数を減らすことでモデルを硬くする方法も有効です。

線形重回帰モデルを例に

次のようなモデル式を例に詳しく見ていきます。

y=ax1+bx2+cx3+ … 

x1、x2、x3、… : 説明変数

a、b、c、… : 各説明変数の係数(おもみ)

モデル自体はシンプルな線形重回帰ですが、説明変数の数が多くなるとモデルの柔らかさが上がります。

例えば、x1、x2、y の3軸からなる空間があるとして、もし説明変数がx1の1つだけだと、直線は常にx1とy の2軸で貼られた面の上にしか存在できません。したがって、面内に存在しないデータプロットに線を沿わせることができません。

一方、説明変数がx1、x2 の2つだと直線は面内に縛られず、x1、x2、y からなる3次元空間のどこにでも存在できるようになります。よって、よりたくさんのデータプロットに沿えるようになります。

スパースモデリング(説明変数を少なくする)

説明変数が少なめのモデルを作ることをスパースモデリングと言います。

スパースとは、本質的な少数の変数に絞り込んだ状態のことを言います。最も汎化性能が高くなるように、モデルに使用する説明変数を絞り込みます。

スパースモデリングによりモデルをシンプルにできれば、汎化性能が上がるのみならずモデルの説明がし易くなるメリットもあります。したがって、考察が進んだり他者の理解が得られやすくなります。

また、説明変数が多すぎると「次元の呪い」と呼ばれる不都合が起こります。「次元の呪い」の影響をなくす意味でも、スパース化は重要です。

次元の呪いとは?説明変数が多すぎると、汎化性能が悪くなる。説明変数は多ければ多いほどよいわけではありません。 説明変数が多すぎると、テストデータに対する予測精度が悪くなる(汎化性能が悪くなる)...

後ほど述べるLasso(ラッソ)回帰は、スパースモデリングの方法の一つです。

ペナルティ項の追加(おもみを小さくする)

説明変数を減らすアプローチではなく、係数(おもみ)を意図的に小さく抑えることでモデルを硬くするアプローチもあります。

おもみを小さくするとモデルが硬くなることはなかなかイメージしにくいのですが・・・、おもみは感度のようなもので、おもみが大きいほど敏感な、表現力の高い、柔らかいモデルになります。

そこで、おもみが大きくなりすぎない仕掛けを入れよう、というのが正則化です。具体的には、各説明変数のおもみが大きくなると値が増える「ペナルティ項」なるものを損失関数に入れて、「ペナルティ項」があまり大きくならないように制御します。

ペナルティ項にはノルムが使われます。ノルムにはいくつか種類があります。

L1ノルムは、各重みの絶対値を足したものです。マンハッタン距離ともいいます。

L2ノルムは、各重みの絶対値を2乗したものを足し合わせ、最後に2乗根したもの(ルート√したもの)です。ユーグリッド距離ともいいます。

一般化して書くと、「各重みの絶対値をn乗したものを足し合わせ、最後にn乗根したもの」がLnノルムです。

ペナルティ項にL1ノルムを使ったものをLasso(ラッソ)回帰、L2ノルムを使ったものをRidge(リッジ)回帰といいます。

両者とも、各変数の重みを小さくする方向にもっていき、バリアンスを小さくする手法です。

詳細は省きますが、L1ノルムはおもみがゼロになりやすい手法であり、説明変数の種類を減らす方向にもっていってくれます。先ほどのスパースモデリングの一つです。

L2ノルムは各説明変数のおもみを全体的に小さく抑えてくれます。

なお、LassoとRidgeの間をとる、Elastic Netとよばれるものもあります。

集団学習(アンサンブル学習)を使う

ランダムフォレストに代表されるようなアンサンブル学習を使うと、バリアンスを下げて過学習を抑えることができます。

アンサンブル学習では、例えば学習データ全体から一部をサンプリングして、モデルを作って予測値を求めます。これを繰り返してたくさんの予測値を出します。最後に、それぞれの予測値の平均を出して、最終的な予測値とします。

この方法だと、柔らかいモデルの型を使ってもバリアンスが大きくなりません。1つ1つのモデルは学習データによってぶれますが、最終的な予測値は、各モデルの結果を均(なら)したものが出てくるため、学習データによるぶれはあまり出てこない、というからくりです。

よって、柔らかいモデルのアンサンブル学習とすることで、バイアスとバリアンスの両方を低く抑えて汎化性能を高めたモデルができます。Kaggleでよく使われている勾配ブースティング木(XGBoost, LightGBM, CatBoost)もこの一種です。

最後に・・・受験生的な覚え方を

バイアスとバリアンス、両者とも名前が似ている上に意味合いがイメージしにくいです。

・モデルが硬すぎると増えるのがバイアス

・モデルが柔らかすぎて増えるのがバリアンス

ととりあえず覚えましょう。