ベクトルの計算と関数の図示

20.4. ベクトルの計算と関数の図示

数学関数やデータをグラフに描く方法について、入門部分を紹介します。

ここで紹介するベクトルは、線形代数のベクトルとしても使えますが、このページでは一定の長さの実数の列としてのみ使います。

数学関数の図示 #

例として、ニューラルネットワークの訓練などでたまに登場するsoftplus関数を紹介します。 この関数は次の式で定義されます。

σ+(a)=log(1+ea) \sigma_+(a)=\log(1+e^a) この関数がどのような性質を持つかは、右図のグラフを見ると一目で分かることでしょう。

計算機がこのようなグラフを描く際には、 xx の範囲を決め、その範囲で xx の値をいくつかサンプルし (たとえば (0,1,2)(0, 1, 2) )、 対応する yy の値を計算し (同 (f(0),f(1),f(2))(f(0), f(1), f(2)) )、全体を滑らかにつなげるという手順を踏みます。

そこで x 座標の列をまとめて扱う方法、対応する y の列をまとめて計算する方法、最後にグラフを描く方法の順で紹介します。

ベクトルの作成と演算 #

Python の `numpy` というモジュールを使います。右のように import してください。これは `numpy` というモジュールをこれ以降 `np` という名前で使えるようにする指示です。
import numpy as np

長さが N で要素がすべて0のベクトルや1のベクトルは np.zeros(N), np.ones(N) という関数で作成します。

np.zeros(3)
array([0., 0., 0.])
np.ones(5)
array([1., 1., 1., 1., 1.])

`array` は、 正確には `numpy.ndarray` という型でベクトルを表します。 (今は割愛しますが、本来は、行列やテンソルも表します)

区間 [left, right] について、均等な幅で N個の点の列を作るには、 np.linspace(left, right, N) を使います。

np.linspace(21, 30, 10)
array([21., 22., 23., 24., 25., 26., 27., 28., 29., 30.])

演算 #

ベクトルに対して、主に2種類の演算を使います。

(1) 同じ長さのベクトル同士の四則演算は、各要素毎に行われます

和の例 (1,1,1)+(1,1,1)  ((1+1),(1+1),(1+1))  (2,2,2) \begin{aligned} & (1, 1, 1) + (1, 1, 1)\\ \to\;& ((1 + 1), (1 + 1), (1 + 1)) \\ \to\;& (2, 2, 2) \end{aligned}
np.ones(3) + np.ones(3)
array([2., 2., 2.])

積の例 (1,2,3)(1,2,3)((11),(22),(33))(1,4,9)\quad (1, 2, 3) * (1, 2, 3) \to ((1 \cdot 1), (2 \cdot 2), (3 \cdot 3)) \to (1, 4, 9)

np.linspace(1, 3, 3) * np.linspace(1, 3, 3)
array([1., 4., 9.])

(2) 数 (スカラー) とベクトルの四則演算は、ベクトルの各要素とスカラーの演算を行います。これは関数を作成するときに便利です。

np.ones(3) * 2
array([2., 2., 2.])
np.ones(3) * 2 + 10
array([12., 12., 12.])

関数 #

例として数学関数 f(x)=x2+1f(x) = x^2 + 1 x{1,2,3}x \in \{1,2,3\} の各点について、1度に計算してみましょう。

Python の関数 `f(x)` の定義や、使い方はスカラーの時と同じです。 20.2. 式と評価 参照
def f(x):
    return x ** 2 + 1
f(0)
1
x{1,2,3}x \in \{1,2,3\} の各点を表すベクトルを、`np.linspace(1,3,3)` で作成します。 これを x という定数で今後扱うことにします。
x = np.linspace(1,3,3)
x
array([1., 2., 3.])
この関数に、先ほどのベクトル x を渡し `f(x)` を計算すると、各点に対応する値の列を得ることができます。 この`f(x)` を y として、(x, y) のグラフを次に描いてみます。
f(x)
array([2., 5., 10.])

グラフを描く #

import matplotlib.pyplot as plt

上記のコードのようにPython の matplotlib.pyplot というモジュールを plt という名前で使います。正確に import してください。これが標準的な使い方になっているので、合わせましょう。

グラフの書き方は、plt.plot(x, y) で、引数の xy は同じ長さのベクトルを表す式を渡します。 早速描いてみましょう。

plt.plot(x, f(x))

3点を線でつないだグラフが表示されました。 2次関数を把握できるように、点の数や区間を調整してみましょう。x を、たとえば区間 [0,5] で等間隔の 50点の列に変更して再度描画すると、見慣れた曲線になります。

x = np.linspace(0, 5, 50)
plt.plot(x, f(x))

なお、数が50の時は省略できます。つまり、np.linspace(0, 5, 50)np.linspace(0, 5) は同じです。

最後に、このページ冒頭の softplus 関数の定義の例を示します。

def softplus(x):
    return np.log(1 + np.exp(x))

数学関数は math のものの代わりに np のものを使います。つまり、 math.log の代わりに np.log を、math.exp の代わりに np.exp を使ってください。np.sin なども同様です。 この置き替えで、x がベクトルの時に、まとめて計算することができます。

複数の関数の描画 #

複数の関数を1枚のグラフに描画することもできます。

例として次の問題を考えてみましょう
d=0,1,2,d = 0, 1, 2, \cdots に対して、以下の関数を定義する: fd(x)=(1)d2πcos((2d+1)x)2d+1. f_d(x) = (-1)^d \cdot \frac{2}{\pi} \cdot \frac{\cos((2d+1)x)}{2d+1}. この関数を組み合わせた FN(x)=f0(x)+f1(x)+f2(x)++fN(x)F_N(x) = f_0(x)+f_1(x)+f_2(x)+\cdot +f_N(x) を考えると、大きなNに対して、 FN(x)F_N(x) の概形はどのような形か?

Python で、小さな d についてのグラフを描いて予想してみましょう。

[π,π][-\pi, \pi] と x の区間を決めておきます。
x = np.linspace(-math.pi, 
                math.pi)

d=0d=0 をまず描いてみます。
def f0(x):
  return 2/math.pi*np.cos(x)
plt.plot(x, f0(x))
d=1d=1 も同様に描けます。
def f1(x):
  return -2/math.pi*np.cos(3*x)/3
plt.plot(x, f1(x))
F1(x)=f0(x)+f1(x)F_1(x) = f_0(x) + f_1(x) も、 次のように簡潔に書くことができます。 f0(x)+f1(x) がPythonの式であることと対応しています。
plt.plot(x, f0(x)+f1(x))
同様に `f_2(x)` を作成後に、3つの関数を描いてみます。`plt.plot` を続けて描くと、複数の関数を1枚のグラフに描くことができます。形が見えてきました。
plt.plot(x, f1(x))
plt.plot(x, f1(x)+f2(x))
plt.plot(x, f1(x)+f2(x)+f3(x))

少し応用的な文法になりますが、グラフに凡例を付与することもできます。

plt.plot(x, f1(x), 
         label='1')
plt.plot(x, f1(x)+f2(x), 
         label='1+2')
plt.plot(x, f1(x)+f2(x)+f3(x),
         label='1+2+3')
plt.legend()
変更部分は、label=文字列の式 という引数を plt.plot 関数に加えたことと、最後に plt.legend() という行の追加です。前者の文法は、キーワード引数と言い実用的にはよく使われます。HWBでの説明は後に回します。

授業などで、新しい関数を目にしたら、まずは概形を描いてみましょう。 実測データのときでも、グラフの書き方は基本は同じなので、データの読み込み方を習得すれば図示できます。

グラフのファイルへの保存 #

グラフを pdf で保存するには、描画直後 (同じセルの中) に以下の文を加えます。

# 実際のグラフを描くコード (省略)
plt.savefig('filename.pdf')
filename の部分を適宜変更してください。また拡張子を、.svg.png に変更することで、それぞれの形式の画像を得ることもできます。 作成したファイルを Colabからダウンロードするには、Colab 画面左上のフォルダアイコンをで、ファイル一覧を表示します。

ファイルを見つけたら、右クリックからダウンロードします。

ファイルの保存直後は、ファイル一覧に現れないかもしれません。その場合は、上部のリロードボタン (回転する矢印) を押すと一覧が更新されます。
保存されたファイルが真っ白 --- `plt.savefig('filename.pdf')` を別のセルで動かすと、描画内容が消去されてしまっているかもしれません。少し複雑になりますが、`plt.figure()` を利用して今描画中の図を変数で参照できるようにすると、別のセルから保存することもできます。
fig = plt.figure()
# 実際のグラフを描くコード (省略)
fig.savefig('filename.pdf')
文字列と式 ベクトルの計算と関数の図示 真偽値と比較・論理演算
このサイトは開発版の はいぱーワークブック です.