8章ではPythonの科学計算ライブラリの一つである『SciPy』およびSciPyの使用例として『行列計算・最適化計算』を紹介します。
SciPyは複雑な計算を簡単なコードで行える非常に便利なライブラリです。ぜひ最後までご覧ください!
本連載講座【Python ライブラリ編】では、データサイエンスに必要なPythonライブラリやその使い方を基礎から学ぶことができます。
NumPy・Pandas・Matplotlib・Scipy・Seabornについて、初学者の方にも分かりやすいよう丁寧に解説しています。
さらに、学習した内容を定着させられるように各章に演習問題を用意しています。
・Pythonでデータ分析ができるようになりたい
・Pythonの基礎事項は一通り学んだので、さらに深く学びたい
このように考えている方はTech Teacherが運営する【Python ライブラリ編】で、Pythonによるデータサイエンスの学習をすることをお勧めします!
なお、『Pythonについて全く知らない』・『Pythonの基礎事項がまだ分かっていない』という方は、まずコチラの【Python 基礎編】で基礎を一通り学習してからライブラリ編に取り掛かりましょう!
<ライブラリ編 目次>
<ライブラリの基礎>
1章:ライブラリとは
<NumPy>
2章:NumPyの概要と配列(ndarray)
3章:統計量や次元の取得/ソート
4章:配列のインデックス
5章:numpy.whereによる条件制御
6章:配列の結合/分割
7章:乱数
<SciPy>
8章:SciPyの概要と基本操作
<Pandas>
9章:SeriesとDataFrame/統計量の取得
10章:データの読み込み/書き込み
11章:データの取り出し/追加
12章:データのソート
13章:データの結合
14章:階層型インデックス
15章:groupbyによる集計
16章:マッピング処理
17章:欠損値の扱い
<Matplotlib>
18章:Matplotlibの概要
19章:pyplotインターフェース
20章:オブジェクト指向インターフェース
<Seaborn>
21章:Seabornの概要と基本操作
SciPyとは
『SciPy』はPythonの外部ライブラリの一つで、NumPyをベースにした科学技術計算ライブラリです。
・線形代数(scipy.linalg)
・方程式や最適化問題の計算(scipy.optimize)
・フーリエ変換(scipy.fft)
・積分計算(scipy.integrate)
などの複雑な計算を簡単なコードで実現できるため、データサイエンスの分野でもよく使用されています。
本記事では、SciPyの使用例として行列演算・最適化計算を紹介します。
SciPyのインポート
それでは早速、SciPyをインポートして使える状態にしていきましょう。
なお、SciPyはPythonの外部ライブラリのため、事前にインストールしておく必要があります。
ライブラリのインストール方法やインポート方法については以下の記事で詳しく解説していますので、ぜひ参照してください!
今回はSciPyのサブパッケージである『scipy.linalg』と『scipy.optimize』をインポートして使います。
まず初めに、以下のコードを実行してパッケージをインポートしておきましょう。
import numpy as np
from scipy import linalg
from scipy import optimize
SciPyによる行列演算
『scipy.linalg』パッケージを用いると、行列式・逆行列・ノルムの計算や固有値・固有ベクトルの計算などを非常に簡潔なコードで行うことができます。
では実行例とともに、使い方を見ていきましょう。
行列式
『linalg.det()』関数を用いると、引数で与えた行列(2次元配列)の行列式を計算することができます。
もちろん、引数として与える行列(2次元配列)はndarrayでも構いません。
x = np.array([[1,2], [3,4]])
print(x)
print()
#行列式
print(linalg.det(x))
[[1 2]
[3 4]]
-2.0
逆行列
『linalg.inv()』関数を用いると、引数で与えた行列の逆行列を計算することができます。
x = np.array([[1,2], [3,4]])
print(x)
print()
#逆行列
print(linalg.inv(x))
[[1 2]
[3 4]]
[[-2. 1. ]
[ 1.5 -0.5]]
行列のノルム
『linalg.norm()』関数を用いると、行列のノルムを計算することができます。
x = np.array([3,4])
#ノルム
print(linalg.norm(x))
5.0
固有値・固有ベクトル
『linalg.eig()』関数を用いると、行列の固有値と固有ベクトルを計算することができます。
eig()関数の戻り値は「(固有値のリスト, 固有ベクトルのリスト)」のようなタプルです。
そのため、『,(コンマ)』で区切った2つの変数に結果を代入することで固有値・固有ベクトルのリストをそれぞれ得ることができます。
x = np.array([[1,0,0], [0,2,1],[0,0,2]])
print(x)
print()
#固有値・固有ベクトル
eig_val, eig_vec = linalg.eig(x)
print(eig_val)
print(eig_vec)
[[1 0 0]
[0 2 1]
[0 0 2]]
[1.+0.j 2.+0.j 2.+0.j]
[[ 1.0000000e+00 0.0000000e+00 0.0000000e+00]
[ 0.0000000e+00 1.0000000e+00 -1.0000000e+00]
[ 0.0000000e+00 0.0000000e+00 4.4408921e-16]]
scipy.optimizeによる最適化計算
『scipy.optimize』パッケージを用いると、方程式を解いたり関数の最小値などを数値計算で簡単に求めることができます。
方程式を解く
SciPyで方程式を解くための関数は多数存在しますが、今回は『ニュートン法』と呼ばれる手法を用いて方程式を解く『optimize.newton()』関数を使います。
関数を定義し、第一引数に関数、第二引数に初期値を設定することで、初期値に近い解を求めることができます。
#根を求めたい関数の定義
def f(x):
return x**2 - 5*x + 6
print(optimize.newton(f, 1))
print(optimize.newton(f, 5))
2.0
3.0000000000000013
上の例では関数を$$ f(x) = x^2 – 5x + 6 $$と定義し、$$ f(x)=0 $$の解を求めています。
正しい解は$$x=2, x=3$$ですが、1に近い解として2が、5に近い解として3がそれぞれ得られているのが分かると思います。
なお、得られた解が真の値から少しだけずれているのは、数値計算の誤差の影響によるものです。
関数の最小値を求める
optimizeパッケージでは関数の最小値を求めるための関数が用意されています。
今回は例として関数の最小値を求める『optimize.minimize()』関数を使用します。
# 最小化する関数
def f(x):
return (x - 2) ** 2 + 3
# 最小化を実行(初期値0)
result = optimize.minimize(f, 0)
# 結果を表示
print("最小値を与えるxの値:", result.x)
print("最小値:", result.fun)
最小値の解: [1.99999999]
最小値: 3.0
『Tech Teacher』3つの魅力
魅力1. オーダーメイドのカリキュラム
『Tech Teacher』では、決められたカリキュラムがなくオーダーメイドでカリキュラムを組んでいます。「質問だけしたい」「相談相手が欲しい」等のご要望も実現できます。
魅力2. 担当教師によるマンツーマン指導
Tech Teacherでは、完全マンツーマン指導で目標達成までサポートします。
東京大学を始めとする難関大学の理系学生・院生・博士の教師がが1対1で、丁寧に指導しています。
そのため、理解できない箇所は何度も分かるまで説明を受けることができます。
魅力3. 3,960円/30分で必要な分だけ受講
Tech Teacherでは、授業を受けた分だけ後払いの「従量課金制」を採用しているので、必要な分だけ授業を受講することができます。また、初期費用は入会金22,000円のみです。一般的なプログラミングスクールとは異なり、多額な初期費用がかからないため、気軽に学習を始めることができます。
まとめ
・魅力1. 担当教師によるマンツーマン指導
・魅力2. オーダーメイドのカリキュラム
・魅力3. 3,960円/30分で必要な分だけ受講
質問のみのお問い合わせも受け付けております。
8章の練習問題
以下の練習問題を解いてみましょう。
練習問題
問1. 以下の行列matに対して、(1)~(3)を求めて出力してください。
mat = np.array([[1,0,0], [0,1,0], [0,0,1]])
(1) matの行列式
(2) matの逆行列
(3) matのノルム
問2. 以下の関数$$ f(x) = x^2 – 4x + 4 $$に関して、xについての方程式$$ f(x)=0 $$を解いてください。
解答
mat = np.array([[1,0,0], [0,1,0], [0,0,1]])
#(1)
print('(1):')
print(linalg.det(mat))
#(2)
print('\n(2):')
print(linalg.inv(mat))
#(3)
print('\n(3):')
print(linalg.norm(mat))
(1):
1.0
(2):
[[ 1. 0. -0.]
[ 0. 1. -0.]
[ 0. 0. 1.]]
(3):
1.7320508075688772
def f(x):
return x**2 - 4*x + 4
print(optimize.newton(f, 0))
1.9999999804639512
次のページへ