Pythonライブラリ講座

【Python】SciPyとは?行列式や最適化を簡単に計算する方法

前のページ|次のページ

8章ではPythonの科学計算ライブラリの一つである『SciPy』およびSciPyの使用例として『行列計算・最適化計算』を紹介します。

SciPyは複雑な計算を簡単なコードで行える非常に便利なライブラリです。ぜひ最後までご覧ください!

本連載講座【Python ライブラリ編】では、データサイエンスに必要なPythonライブラリやその使い方を基礎から学ぶことができます。

NumPyPandasMatplotlibScipySeabornについて、初学者の方にも分かりやすいよう丁寧に解説しています。

さらに、学習した内容を定着させられるように各章演習問題を用意しています。

・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章:SeriesDataFrame/統計量の取得
10章:データの読み込み/書き込み
11章:データの取り出し/追加
12章:データのソート
13章:データの結合
14章:階層型インデックス
15章:groupbyによる集計
16章:マッピング処理
17章:欠損値の扱い

<Matplotlib>
18章:Matplotlibの概要
19章:pyplotインターフェース
20章:オブジェクト指向インターフェース

<Seaborn>
21章:Seabornの概要と基本操作

SciPyとは

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

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 $$を解いてください。

解答

問1(クリックして解答を表示)

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

問2(クリックして解答を表示)

def f(x):
    return x**2 - 4*x + 4

print(optimize.newton(f, 0))
1.9999999804639512

次のページへ

Pandasとは?SeriesやDataFrameを使いこなそう! 前のページ|次のページ 9章ではデータサイエンスにおいて必須ともいえるライブラリである『Pandas』の概要と『Series/D...