機械学習 其の002 ~NumPy、SciPy~
NumPyやSciPyってな~に?って方は、こちら。
NumPyは、プログラミング言語Pythonにおいて数値計算を効率的に行うための拡張モジュールである。効率的な数値計算を行うための型付きの多次元配列(例えばベクトルや行列などを表現できる)のサポートをPythonに加えるとともに、それらを操作するための大規模な高水準の数学関数ライブラリを提供する。
https://ja.wikipedia.org/wiki/NumPy
SciPy (サイパイ) は、プログラミング数学、科学、工学のための数値解析ソフトウェアである。無料かつオープンソースで、Windows、Linux、Mac を含むオペレーティングシステムで動作する。
https://ja.wikipedia.org/wiki/SciPy
要するに、機械学習に必要な多次元配列の操作や数値解析のための諸々の機能を提供してくれる頼もしい味方というわけですね。
ある程度自由に使いこなせないと目的のものが作れないと思うので、改めて学習しなおしてみます。
まずはNumPy配列の使い方を学ぶために簡単なサンプルを作ってみました。
サンプルソースは以下のとおり。
# -*- coding: utf-8 -*- import numpy as np a = np.array([0, 1, 2, 3, 4, 5]) print "---------- array a ----------------" print a # 配列の内容 print a.size # 要素数 print a.ndim # 次元数を表示 print a.shape # 各次元の要素数を表示 b = a.reshape((3, 2)) # 2次元の行列に変換 print "---------- array b ----------------" print b # 配列の内容 print b.size # 要素数 print b.ndim # 次元数を表示 print b.shape # 各次元の要素数を表示 b[0][0] = 100 print "---------- array a' ----------------" print a # 配列の内容 print a.size # 要素数 print a.ndim # 次元数を表示 print a.shape # 各次元の要素数を表示 print "---------- array b' ----------------" print b # 配列の内容 print b.size # 要素数 print b.ndim # 次元数を表示 print b.shape # 各次元の要素数を表示
サンプルでは、配列aを定義し、aの内容、要素数、次元数、各次元の要素数を表示し、配列bとしてaの配列を3×2の2次元配列に変換し、同様に各種情報を表示させます。ここまでの実行結果は特に注意することもないのですが、ここで配列bの[0][0]要素に100を代入して配列a',b'として各種情報を表示しています。
配列の要素数や次元数、各次元の要素数については配列a',b'ともに最初に表示した配列a,bと一致していますが、配列の内容に関しては、b[0][0]に100を代入した場合でも配列aの最初の要素が100に書き換わっていることが確認できます。これはNumPyが無駄なデータのコピーを避けるためにこのようにしているそうで、注意が必要な個所です。
サンプルの実行結果は以下のとおり。
%run "C:/lab/python_learn/lesson1.py" ---------- array a ---------------- [0 1 2 3 4 5] 6 1 (6L,) ---------- array b ---------------- [[0 1] [2 3] [4 5]] 6 2 (3L, 2L) ---------- array a' ---------------- [100 1 2 3 4 5] 6 1 (6L,) ---------- array b' ---------------- [[100 1] [ 2 3] [ 4 5]] 6 2 (3L, 2L)
配列間の代入では、2つの配列の要素データがコピーされるわけではないため、本当にコピーが必要な場合は、以下のようにする必要があります。
b = a.reshape((3, 2)).copy() # 2次元の行列に変換し配列bへコピー
こうすることで、配列a'、b’の内容は以下のとおりとなります。
---------- array a' ---------------- [0 1 2 3 4 5] 6 1 (6L,) ---------- array b' ---------------- [[100 1] [ 2 3] [ 4 5]] 6 2 (3L, 2L)
またNumPyでは、配列の操作として次のようなことも可能です。
# NumPyの配列操作 print a + 50 # 各要素に50を加算 print a * 2 # 各要素を2倍 print a ** 2 # 各要素を二乗 # Pythonの配列操作 print [0, 1, 2, 3, 4, 5] + 50 # できない print [0, 1, 2, 3, 4, 5] * 2 # 配列のサイズを2倍にして元の要素を結合 print [0, 1, 2, 3, 4, 5] ** 2 # できない
処理結果は、次のとおり。
[50 51 52 53 54 55] [ 0 2 4 6 8 10] [ 0 1 4 9 16 25] --------------------------------------------------------------------------- TypeError Traceback (most recent call last) C:\lab\python_learn\lesson1.py in <module>() 37 print a ** 2 # 各要素を二乗 38 ---> 39 print [0, 1, 2, 3, 4, 5] + 50 [0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5] TypeError Traceback (most recent call last) C:\lab\python_learn\lesson1.py in <module>() 39 #print [0, 1, 2, 3, 4, 5] + 50 40 #print [0, 1, 2, 3, 4, 5] * 2 ---> 41 print [0, 1, 2, 3, 4, 5] ** 2 # できない TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
配列の各要素に対する操作として次のようなことも可能だ。
print a print a[np.array([0,1,2])] # 配列aの0,1,2番目の要素を表示 print a > 5 # 配列aの各要素が5より大きいかを評価して表示 print a[a>2] # 配列aの要素で2より大きい要素を表示 a[a>4] = 4 # 配列aの要素で4より大きい要素に4を代入 print a print a.clip(0,3) # 配列の各要素の下限を0、上限を3に設定
実行結果はこちら。
[0 1 2 3 4 5] [0 1 2] [False False False False False False] [3 4 5] [0 1 2 3 4 4] [0 1 2 3 3 3]
今回はこの辺で。SciPyについては次回以降におあずけ。
- 作者: Willi Richert,Luis Pedro Coelho,斎藤康毅
- 出版社/メーカー: オライリージャパン
- 発売日: 2014/10/25
- メディア: 大型本
- この商品を含むブログ (4件) を見る