How many files(0-15)

競馬の予想システムで一儲を企むおっさんのヨコシマな横顔

機械学習 其の002 ~NumPy、SciPy~

NumPyやSciPyってな~に?って方は、こちら。

NumPyは、プログラミング言語Pythonにおいて数値計算を効率的に行うための拡張モジュールである。効率的な数値計算を行うための型付きの多次元配列(例えばベクトルや行列などを表現できる)のサポートをPythonに加えるとともに、それらを操作するための大規模な高水準の数学関数ライブラリを提供する。

https://ja.wikipedia.org/wiki/NumPy

SciPy (サイパイ) は、プログラミング数学、科学、工学のための数値解析ソフトウェアである。無料かつオープンソースで、WindowsLinuxMac を含むオペレーティングシステムで動作する。

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については次回以降におあずけ。


実践 機械学習システム

実践 機械学習システム