【確認課題】Numpy#
必要モジュールのインポート#
この問題で使うモジュールをインポートします.
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
問1. ndarray
の生成#
以下の2つのndarray
を定義しなさい.
観測値
x
: 初項0
,末項5
,項数100
の等差数列ノイズ
noise
: 標準正規分布に従う100
個の乱数
x = #TODO
noise = #TODO
Cell In[2], line 1
x = #TODO
^
SyntaxError: invalid syntax
ここで,真の関数 \(y(x) = 3 - 5x + x^2\) を定義します.
def y(x):
"""真の関数"""
return 3 - 5 * x + x ** 2
問2. ndarray
の操作#
問1で生成した観測値 x
に対応する目標値 t
を定義しなさい.
目標値 \(t\) は, \(t = y(x) + \epsilon\) と表されます. ( \(y\): 真の関数, \(\epsilon\): ノイズ )
実際の観測値にはどうしてもノイズ(観測誤差)が発生してしまいます.今回は,それをnoise
で再現します.
問1で観測値を100個生成したので,それぞれに対応する目標値も100個作成する必要がありますが, for
文は絶対使ってはいけません.
t = #TODO
matplotlib で可視化すると以下のようなグラフになります. scatter → 散布図
plt.scatter(x, t)
問3. ndarray
の結合#
以下の3つのndarray
を垂直方向に結合した2次元配列を転置した行列 X
を定義しなさい.
x0: 長さが
x
と同じで要素が全て1のndarray
x1: 観測値
x
の各要素を1乗したndarray
x2: 観測値
x
の各要素を2乗したndarray
例: \(x = (1, 2, 3)\) のとき,
だから,
ちなみに,機械学習では X
のような行列を計画行列と呼びます.
X = #TODO
問4. 線形代数#
観測値 x, t
をもとに真の関数 y
を2次関数で回帰しなさい.
任意の2次関数は \(y(x) = w_0 + w_1 x + w_2 x^2\) と表すことができます.
なので,パラメータのベクトル \(\mathbf{w} = (w_0, w_1, w_2)\) を求めれば良いことになります.
これは以下の正規方程式から求めることができます.
\( \mathbf{w} = (X^T X)^{-1} X^T \mathbf{t} \)
この式の導出はdev_data勉強会で学びます.
行列の積が多い場合はnp.dot
を使わない方が簡潔に書けます.
w0, w1, w2 = #TODO
pred_y = w0 + w1 * x + w2 * x ** 2
結果#
先ほどのグラフに真の関数(緑)と回帰曲線(赤)を重ねると以下のようになります.
plt.scatter(x, t)
plt.plot(x, pred_y, linewidth=5, color="red", label="pred")
plt.plot(x, y(x), linewidth=5, color="green", label="true")
plt.legend()
今回使った手法は 真の関数 y
の定義を変更するとその他のコードを全く変更しなくても同様に回帰することができます.
例えば以下のように変更したらその関数を回帰します.
def y(x):
"""真の関数"""
return 5 * np.sin(np.pi * x / 5)
dev_data勉強会で詳しくやりますが,この回帰曲線の表現力は2次までです.
カーブが2つ以上の曲線を回帰したい場合は問3の計画行列の列数を x3, x4...
のように増やせば表現力が上がります.