Help us understand the problem. What is going on with this article?

【機械学習】LPノルムってなんだっけ?

More than 3 years have passed since last update.

機械学習の勉強をしているとL1正則化とかL2正則化という用語が出てくると思います。1

L1正則化の場合のペナルティ項:L1ノルムはこんな感じ、

lp1.png

L2正則化の場合のペナルティ項:L2ノルムはこんな感じ、
lp2.png

という説明を見ますが、なぜL1ノルムとL2ノルムこんな形で表されているのか、をもうちょっとだけ掘り下げてみます。

Lpノルムの定義

ベクトル${\bf x}$をn次元、

$$
{\bf x} = (x_1, \cdots, x_n)
$$

としたとき、その時$L^p$ノルムは次のように定義されます。

\| {\bf x} \|_p = (\ |x_1|^p + |x_2|^p + \cdots + |x_n|^p )^{1/p}

L1ノルム

ここで、グラフに書けるように${\bf x}$を2次元としたときの$L^1$ノルムは

\| {\bf x} \|_1 = |x_1| + |x_2|

のように$x_1$と$x_2$のただの絶対値の足し算になります。それを等高線で表したものが
lp1.png
だったのです。これはマンハッタン距離とも呼ばれ、碁盤の目のように縦横垂直な道路しかないので、縦or横移動のみ可、斜めに移動できない、という世界の距離をあらわしているものと同じになります。
L1_manhattan.png
つまり、こんな感じで水色、赤、緑の線は全て長さ10なので、同じ距離のところを線で結ぶとこのように直線になります。なので先ほどのグラフの等高線がひし形になっているのですね。

L2ノルム

同じく2次元ベクトルの$L^2$ノルムは

\| {\bf x} \|_2 = \sqrt{|x_1|^2 + |x_2|^2}

です。これはおなじみのユークリッド距離です。円周上の点の原点との距離は常に一定なので、下記のような綺麗な円を描く等高線となります。
lp2.png

様々なpでのノルム

機械学習でよく使うのはL1ノルムとL2ノルムですが、理解のために様々なpの値でどのような等高線が描かれるのかを試してみました。

$p=0.1,\ p=0.5〜7.5$まで$0.5$ずつ、と、$p=1000$の図を描いてみました。
(本来Lpノルムの$p$は $p\ge1$の実数ですが、あえて0.1と0.5を描いてみました。)

pが0に近づくと"+"のような形に、1のときひし形(正方形を45度回転したもの)、2のとき円、∞に近づくと"□"のような形になることがわかります。

(Lpノルムの定義外ではありますがp=0.1の世界があったら、斜めに進むのがものすごく大変な世界です :sweat_smile:

lps.png

このようなL1ノルム、L2ノルムが応用されて、Lasso回帰、Ridge回帰、ElasticNetなどで使われているのですね :kissing_closed_eyes:

Pythonコード @GitHub

本記事のメイン部分のコードは下記になります。

def LP(x, y, lp=1):
    x = np.abs(x) 
    y = np.abs(y)
    return (x**lp + y**lp)**(1./lp)

def draw_lp_contour(lp=1, xlim=(0, 1), ylim=(0, 1)):
    n = 201
    X, Y = np.meshgrid(np.linspace(xlim[0], xlim[1], n), np.linspace(ylim[0], ylim[1], n))
    Z = LP(X, Y, lp) 
    cm = generate_cmap(['salmon', 'salmon', 'salmon', 'salmon', 'blue'])
    interval = [i/10. -1 for i in range(20)]

    plt.contour(X, Y, Z, interval, alpha=0.5, cmap=cm)
    plt.title("Contour of LP{}".format(lp))
    plt.xlim(xlim[0], xlim[1])
    plt.ylim(ylim[0], ylim[1])

# 16種のpの値のグラフを描画
fig =plt.figure(figsize=(14,14))
size = 4
for i, lp in enumerate(np.r_[[0.1], np.linspace(0.5, 7, 14), [1000]]):
    plt.subplot(size, size, i+1)
    draw_lp_contour(lp, (-1, 1),(-1, 1))

このグラフを描いたPythonコードの全文はGitHubに置いてあります。
https://github.com/matsuken92/Qiita_Contents/blob/master/General/LP-Norm.ipynb

参考

Wikipedia Lp空間
 https://ja.wikipedia.org/wiki/Lp空間

オンライン機械学習 (機械学習プロフェッショナルシリーズ) [海野、岡野原、得居、徳永著]
 http://www.kspub.co.jp/book/detail/1529038.html

RでL1 / L2正則化を実践する
 http://tjo.hatenablog.com/entry/2015/03/03/190000

回帰モデルにおけるL1正則化とL2正則化の効果
 http://breakbee.hatenablog.jp/entry/2015/03/08/041411

注釈


  1. TJOさんの「銀座で働くデータサイエンティストのブログ」記事 RでL1 / L2正則化を実践する でも取り上げられています。 

kenmatsu4
Kaggle Master (https://www.kaggle.com/kenmatsu4) データ解析的なことや、統計学的なこと、機械学習などについて書いています。 【今まで書いた記事一覧】http://qiita.com/kenmatsu4/items/623514c61166e34283bb 【English Blog】 http://kenmatsu4.tumblr.com
https://www.kaggle.com/kenmatsu4
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away