Pythonプログラミングにおいては,アルゴリズムを直接記述する方法も可能であるが,ライブラリと呼ばれる特定の機能をまとめた再利用可能なモジュール群が提供されている. これらを用いることにより,自分でアルゴリズム記述やそのデバッグをせずとも,プログラムを効率的に開発することができる. このなかでも,numpy, scipy, matplotlibといった外部ライブラリは,科学技術計算において幅広く用いられている. NumPyは高速な配列操作と線形代数,SciPyは信号処理などの計算機能,Matplotlib はグラフ作成やデータの可視化を簡単にする. Pythonのライブラリは組み合わせて使用され,データ処理,画像処理,可視化,制御,シミュレーション,機械学習など,工学の幅広い分野で活用されている.
参考:Pythonの基本については,情報処理実習1のPython入門を参照.
注:情報処理教室のPCでは,このページのサンプルプログラムをそのまま実行することができる.
一方,USBメモリにインストールした推奨開発環境(cprog20)には,Python本体やライブラリ類がインストールされていないため,大学の情報処理教室や生田仮想デスクトップPC上で実行する場合は問題ないが,自分のPC,Macなどで実行する場合は,Pythonおよびライブラリの適切なインストールが必要である.
具体的には,Python公式サイトからOSに適したPython本体をダウンロード・インストールし,さらにpipコマンドなどを用いて各種ライブラリを追加インストールする必要がある.
(ヒント:pip install numpy, pip install scipy, pip install matplotlib など)
以下に代表的なライブラリへのリンクを記すので,必要に応じてドキュメント,リファレンスマニュアル,検索を用いて,各自で調べて取り組んでみよう.
NumPyは数値計算の基盤となるライブラリで,多次元配列(ndarray)を中心として,多くの数学関数や線形代数,統計計算などを提供する. 配列の演算がC言語と同等の速度で最適化されており,Python標準のリストと比べて高速に計算できる. 科学計算や機械学習,データ解析において必須の基礎ライブラリである.
SciPyはNumPyをベースとした科学技術計算用ライブラリで,数値積分,微分方程式,信号処理,統計解析など,高度な数学処理を行うことができる. 各分野ごとにサブモジュールが分かれており,複雑な数値計算を簡潔なコードで記述できる. 研究・開発用途で利用される場面が多く,シミュレーションやデータ解析のツールとして利用されている.
MatplotlibはPythonでグラフや図を描画するための可視化ライブラリである. 折れ線グラフ,散布図,ヒストグラム,等値面図など多様な図を作成できる. 軸ラベルやタイトル,凡例,色・線のスタイルなど細かい設定が可能であり,再利用可能な形で保存しておくことができる. NumPyと組み合わせてデータを直接可視化できるため,データの分析結果や,シミュレーション・実験結果の表現に最適である. また,グラフの画面表示だけでなく,ファイルへの保存も簡単にでき,実験レポートや論文の図表作成まで幅広く利用されている.
Pythonでは,機械学習のための様々なフレームワークが提供されており,現状,機械学習開発の標準言語となっている. PyTorch と Tensorflow が2大勢力である.
Pythonには標準ライブラリと外部ライブラリが存在する.
標準ライブラリはPythonに最初から組み込まれており,追加インストール不要で利用できる.
たとえば,画面表示を行うprintや,文字列操作や日時計算に用いるdatetime,数学計算用のmathが該当する.
外部ライブラリは標準ではインストールされておらず,pipコマンドなどで追加インストールする必要がある.
標準ライブラリは基本的機能を補完するものであり,外部モジュールは特定分野の高度な処理を効率的に実現できる点で異なる.
ライブラリを利用するためには,ソースコードの先頭に以下のいずれかの宣言を記述する.
import numpy
import numpy as np
import文はモジュールを読み込むための構文である.
例えばimport mathとすると,math.sqrt()のようにモジュール名を接頭辞として関数を呼び出す必要がある.
一方,asを用いるとモジュールに別名を付けられる.
例えばimport numpy as npと書くと,numpy.array()ではなくnp.array()と短縮して利用できる.
asを使うことでコードの可読性や入力の手間を減らせる利点がある.
import numpy
numpy.array([1,2,3])
import numpy as np
np.array([1,2,3])
一次元配列 x,サイズ(=要素数) 100 として,このなかに 0 から 2π までの値を等間隔に生成し,この配列に対してy = sin(x) を計算して最初の5つの値を表示せよ.
NumPyの linspace で範囲を均等に分割した配列を作り,np.sin で要素ごとの正弦を計算する.
NumPyの関数は配列全体に一度に作用するため,for ループなどを記述する必要がない.
Pythonソースコード
import numpy as np
x = np.linspace(0, 2 * np.pi, 100) # x はnumpy配列,np.piは円周率
y = np.sin(x)
print('x=', x)
print('y=', y)
zに,余弦(cos) の値を格納して,同様に表示してみよう.xの最初の5要素は,x[:5] とかける.for文を使用しても良い.実行例 x= [0. 0.06346652 0.12693304 0.19039955 0.25386607] y= ... z= ...
比較のために,同様の計算処理を行うC言語ソースコードを以下に示す.
実行して,出力を比較してみよう.
C言語ソースコード
#include <stdio.h>
#include <math.h>
const double pi = 2.0*asin(1.0);
int main(void)
{
int i;
const int N=100;
double x[N]; // array
double y[N]; // array
// set x
for(i=0; i<N; i++) {
x[i] = 2.0*pi*i/(N-1);
}
// set y
for(i=0; i<N; i++) {
y[i] = sin(x[i]);
}
// show x on display
printf("x=");
for(i=0; i<N; i++) {
printf("%.10lf ", x[i]);
}
printf("\n");
// show y on display
printf("y=");
for(i=0; i<N; i++) {
printf("%.10lf ", y[i]);
}
printf("\n");
return 0;
}
NumPyでは,行列や多次元配列の定義も容易である.
以下の 2×2 行列 A, B を NumPy 配列として定義し,行列積 AB を求めてみよう.
C言語では,定数による配列の初期化を{}で表すが,Pythonでは[]を用いる.
A = [[2, 1], [-1, 3]]
B = [[0, 4], [5, -2]]
二次元配列を np.array で定義し,行列積は np.dot あるいは @ 演算子で求められる.
import numpy as np
A = np.array([[2, 1],
[-1, 3]])
B = np.array([[0, 4],
[5, -2]])
C = A @ B # 行列の積
print('A=\n', A, '\n')
print('B=\n', B, '\n')
print('C=\n', C, '\n')
行列とベクトルの積は,いろいろな分野で必須となる計算である.
この計算についても,forなどの繰り返し文を記述することなく計算することができる.
(内部的にはもちろん反復処理が行われている.多くのライブラリはC言語で書かれており,計算速度も最適化されている.)
import numpy as np
A = np.array([[4, 1],
[1, -2]])
v = np.array([2,-1])
print('A=\n', A, '\n')
print('v=\n', v, '\n')
w = A @ v # 行列とベクトルの積
print('w=\n', w, '\n')
逆行列は,NumPyのlinalg.inv() で容易に求めることができる.
import numpy as np
A = np.array([[4, 1],
[1, -2]])
v = np.array([2,-1])
print('A=\n', A, '\n')
print('v=\n', v, '\n')
w = A @ v # 行列 A とベクトル v の積
print('w=\n', w, '\n')
A_inv = np.linalg.inv(A) # A の逆行列
print('A_inv=\n', A_inv, '\n')
print('A*A_inv=\n', A@A_inv, '\n') # 行列 A と,その逆行列 A_inv との積
# Aの逆行列を使って w から v を計算
v_reconst = A_inv @ w
print('v_reconst=', v_reconst, '\n')
print('v (original)=', v, '\n')
Matplotlibは,折れ線グラフや散布図,等値面図などレポートや論文に必要な図表の作成を簡単に行うことができる.
ファイルの読み込みや,データ加工,表示されるグラフの種類や細かい体裁の設定,ファイル出力まで,すべてソースファイル内で制御することができるため,一度Pythonのソースコードを作成しておけば,次回以降は同様の品質のグラフを大量に生成することができる.
ここでは,x, y = sin(x) を折れ線グラフとして描画してみよう.横軸に「x」,縦軸に「sin(x)」,適切なタイトルもつけよう.
Matplotlibの基本描画は plt.plot である.
軸ラベルやタイトルは plt.xlabel などで設定できる.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
z = np.cos(x)
plt.plot(x, y)
plt.plot(x, z)
plt.xlabel('x')
plt.ylabel('sin(x), cos(x)')
plt.title('sinusoidal waves')
# グラフの保存
plt.savefig('waves.jpeg')
plt.show()
データ: x = [0,1,2,3,4], y = [1,2,2,3,4] を散布図として描画してみよう.
次に,(最小二乗法による)線形近似直線を求め,同じ図に重ねて描画してみよう.
まず,散布図を描画してみよう.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0, 1, 2, 3, 4])
y = np.array([1, 2, 2, 3, 4])
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Scatter plot')
plt.show()
次に,NumPyの polyfitで1次関数近似の係数を求める.
Pythonでは,戻り値が複数でもOK
import numpy as np
x = np.array([0, 1, 2, 3, 4])
y = np.array([1, 2, 2, 3, 4])
coeff = np.polyfit(x, y, 1) # 1次近似の係数を計算
print('coeff=', coeff) # 係数を表示
実行結果:
[0.7 1. ]
polyfit で求めた係数から,poly1d で関数化する.
最終的に,以下のように散布図と直線を同じグラフ上に描画する.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([0, 1, 2, 3, 4])
y = np.array([1, 2, 2, 3, 4])
plt.scatter(x, y) # 散布図を表示
coeff = np.polyfit(x, y, 1) # 1次近似の係数を計算
print('coeff=', coeff) # 係数を表示
linear = np.poly1d(coeff) # 係数から多項式の関数を生成
plt.plot(x, linear(x)) # 近似直線を追加
plt.xlabel('x')
plt.ylabel('y')
plt.title('Scatter plot and regression')
plt.show()
np.polyfit のリファレンスマニュアルを調べ,近似の次数を2次,3次に変更してみよう.Pythonソースファイルおよび必要に応じてグラフのファイルを提出せよ.
ある実験で,センサーから得られた以下のデータがあるとする.
data = [0.1, 0.5, 0.02, 0.3, 0.8, 0.05, 0.4, 0.9, 0.07, 0.2]
このリストを使って,次の値を計算して表示せよ.
自分でアルゴリズムを記述してもよいし,Pythonの公式ドキュメントから適切な関数を探して使用してもよい.
実行例: 合計: 3.34000000000 平均: 0.334 最小値: 0.02 最大値: 0.9 0.1 未満の値 (3 個): [0.02, 0.05, 0.07]
以下のような xy データがある.
x = [0, 1, 2, 3, 4, 5]
y = [1, 1.5, 1.8, 2.5, 2.2, 3.0]
このデータを使って,以下を行うプログラムを作成せよ.
必要な関数などは,matplotlibのWebサイトなどを用いて各自で調べてみよう.
例:matplotlib.pyplotのリファレンス
以下,結果の出力例である.プロットの形や色,線の種類などを自由に変えてもよい.