機械学習 はじめよう

第11回 線形回帰を実装してみよう

この記事を読むのに必要な時間:およそ 3.5 分

推定した関数を図示する

こうしてwを求めることができましたが,数字だけ見てても,問題が解けた!!という実感は湧きませんよね。そこで,matplotlibで図を描いてみましょう。

そのためにまず(式1)または(式3)を使って,関数f(x)を用意する必要があります。

# (式 1) の場合
def f(w, x):
    return np.dot(w, phi(x))
# (式 3) の場合
def f(w, x):
    return w[0] + w[1] * x + w[2] * (x ** 2) + w[3] * (x ** 3)

どちらでもかまいませんが,⁠式1)に基づくコードは,phi(x)の定義を書き変えてもそのまま使えます。

関数を曲線として描くにはpyplot.plot関数を用います。点列を与えて曲線を描くのがmatplotlibの流儀です。

xlist = np.arange(0, 1, 0.01)
ylist = [f(w, x) for x in xlist]

plt.plot(xlist, ylist)

xlistは,グラフを描く範囲 [0, 1] を等間隔に刻んだ配列(ベクトル)です。

np.arange()の3つ目の引数0.01は刻み幅です。これを0.1などにするとカクカクしたグラフが描かれてしまいますので,曲線っぽく見えるくらいまで十分細かくしましょう。

ylistは,xlistのそれぞれの入力xに対応する関数の値f(x)のリストです。ここでもリスト内包が活躍していますね。

あとはデータ点の分布を描いて,曲線と見比べたいですよね。先ほど曲線を描くのに使ったplot()の第三引数に'o'を与えると,点の分布を描くことができます。

plt.plot(X, t, 'o')

最後にplt.show()を呼ぶと,描いたグラフが表示されます。

plt.show()

画像

様々な条件で試す

ここまでのコードをまとめましょう。

import numpy as np
import matplotlib.pyplot as plt

X = np.array([0.02, 0.12, 0.19, 0.27, 0.42, 0.51, 0.64, 0.84, 0.88, 0.99])
t = np.array([0.05, 0.87, 0.94, 0.92, 0.54, -0.11, -0.78, -0.79, -0.89, -0.04])

def phi(x):
    return [1, x, x**2, x**3]

PHI = np.array([phi(x) for x in X])
w = np.linalg.solve(np.dot(PHI.T, PHI), np.dot(PHI.T, t))

xlist = np.arange(0, 1, 0.01)
ylist = [np.dot(w, phi(x)) for x in xlist]

plt.plot(xlist, ylist)
plt.plot(X, t, 'o')
plt.show()

見通しの良い短いコードですから,いろいろ書き換えて楽しむことができます。

例えば,データを増やしたり減らしたりして,それに適した関数がきちんと得られるかを見てみる,というのが序の口でしょうが,もっと本質的な部分に触ってみたいという向きには,⁠基底関数の変更」「正則化の導入」あたりがおすすめです。

基底関数を変更する

上のコードではφ(x)の次数,つまり基底関数の個数はM=4でしたが,これを変えてみましょう。

例えばM=8にするには,phi(x)の返値を [1, x, x**2, x**3, x**4, x**5, x**6, x**7] にすればOKです。

あるいは,多項式以外の基底関数を試してみることもできます。例えばガウス基底は次の数式で表されます。

ここでは [0, 1] 区間をM等分する点を,sは正の定数をとります。sは0.1くらいから始めて,いろいろ変えてみるといいでしょう。

このように基底関数を取り替えても,phi(x)の定義を書き換えるだけでよいのが,線形回帰の良いところですね。

正則化項を入れる

「正則化」については連載の第9回をご覧ください。

実装に関係のある結果だけ説明すると,正則化を入れることでパラメータwを求める式が以下のように変わります。しかし,それ以外は今までの線形回帰そのままです。

Iは単位行列,λは正の定数です。これなら上のコードを一ケ所ちょこっと書き換えるだけで済みそうですよね。

λをいくつにするかが迷うところですが,0.01あたりから始めて,増やしたり減らしたりいろいろ試してみてください。ちなみに,基底関数を [1, x, ..., x**7] にしておくと,正則化の効果を実感しやすいですよ。

このように条件を少しずつ変えながら結果を確認しておくことで,線形回帰の「手触り」⁠つまり傾向や特性のようなものを感じることができるかもしれません。

そういった蓄積は,機械学習を実際に使いこなそうというときにきっと役にたちますから,是非いろいろ試してみてください。

次回は理論編。ベイズ線形回帰を紹介します。

著者プロフィール

中谷秀洋(なかたにしゅうよう)

サイボウズ・ラボ(株)にてWebアプリ連携や自然言語処理を中心に研究開発を行いながら,英単語タイピングゲーム iVocaをサービス提供している。

URLhttp://d.hatena.ne.jp/n_shuyo/
Twitterhttp://twitter.com/shuyo

コメント

  • とても分かりやすいです。

    約2か月前に初めて機械学習なる言葉をしりました。(今日は2012/01/11)
    現在ネットで勉強中です。
    中谷さんの説明はとってもわかりやすいです。
    実際に実装して確認すると、ますます分かった気になります。

    Commented : #1  加納 喜代継 (2012/01/11, 15:37)

コメントの記入