Lesson 2 機械学習に欠かせない、NumPy入門と「多次元配列(ndarray)」:機械学習&ディープラーニング入門(データ構造編)
機械学習の現場で広く活用されているライブラリ「NumPy」の概要から、「多次元配列(ndarray)」データを作成する方法について説明する。また、類似のライブラリ「Pandas」についての概要も紹介する。
ご注意:本記事は、@IT/Deep Insider編集部(デジタルアドバンテージ社)が「deepinsider.jp」というサイトから、内容を改変することなく、そのまま「@IT」へと転載したものです。このため用字用語の統一ルールなどは@ITのそれとは一致しません。あらかじめご了承ください。
前回は、Python言語仕様のリスト型を用いて「多次元リスト」というデータ構造を作る方法について説明した。今回は、ライブラリ「NumPy」でデータ構造を作る方法について見ていこう。※脚注や図、コードリストの番号は前回からの続き番号としている。
本稿で示すサンプルコードの実行環境については、Lesson 1を一読してほしい。
Lesson 1でも示したように、本連載のすべてのサンプルコードは、下記のリンク先で実行もしくは参照できる。
AIプログラムにおけるデータの構造(基本編)
前回の説明までで、機械学習やディープラーニングを実施するのに必要なデータを、Python言語で記述できるようになったはずだ。「あとは多次元リストのデータを使って、ディープラーニングしていけばいいのね」と思うかもしれない。確かにそれも不可能ではないが、実際の現場では、素のPythonデータ構造である「リスト」をそのまま使うことはあまりない。というのも、Python標準の数値計算機能は非力で、リスト構造のデータをまとめて効率的に計算できないからだ。
そこで、機械学習・ディープラーニングといったAIプログラムのデータ処理では、より強力な、
- 数値計算ライブラリ「NumPy」(ナムパイ)
を用いることが一般的となっている。
数値計算ライブラリ「NumPy」の特長
NumPyの特長は、さまざまな算術・数学計算に対応しており、前回説明した多次元リスト形式のデータ構造をまとめて、しかも高速に計算できることである。要するに、数学に強いライブラリということだ。
ただし、「扱うデータ形式が変わる」という点に注意が必要だ。具体的には、Pythonの「多次元リスト」そのものではなく、
- NumPy独自のデータ型「多次元配列」(詳細後述)
という形式に変換したうえで、データを扱うことになる(※でも安心してほしい。変換作業は、変換していること自体に気が付かないほど簡単である)。
しかも、多次元配列のデータ構造は、多次元リストのデータ構造とまったく同じである。要は、数学計算機能を持たせるために、多次元リストと同形式のデータ構造を別に用意しているにすぎないのだ。Python言語のリストの知識があれば、それほど勉強しなくてもすぐに使いこなせるようになる、よくできたライブラリである。
実際にNumPyはとても有名で、よく使われており、データサイエンティストを中心にデータ分析業務に携わる人たちに愛されている。現在のPython人気の一部は、このNumPyの人気から来ている、と言っても過言ではないだろう。それほど使い勝手がよい。
さっそく、NumPyを使う方法を示し、サンプルコードを実行することでそのデータ構造を確かめてみよう。
【コラム】Pythonの基礎知識:パッケージ/モジュール/クラス/メソッド/関数など
Pythonでのライブラリ(library)のインストール方法、およびパッケージ(package)やモジュール(module)といったPython言語の基本仕様について知らない場合は、記事『機械学習&ディープラーニング入門(Python編): Lesson 2. モジュール』を一読することをお勧めする。本連載では、その記事と同等の知識があるものとして説明を進める。
その他、下記のプログラミング用語が、以下の本文中で使われているので、知らない場合は参考にしてみてほしい。
クラス(class)とは、オブジェクト(後述)を生成するための元となる遺伝子情報あるいは設計図のようなものである。
オブジェクト(object)については、前回の「【コラム】Pythonで数値を表現するための基礎知識」で紹介済みなので、説明は割愛する。
コンストラクター(constructor)とは、クラスからオブジェクトが生成されるタイミングで呼び出されるメソッド(後述)のことで、そのメソッド内では主にオブジェクトの初期化処理を実施する。
メソッド(method)とは、クラス内で定義された関数(後述)のことである。
関数(function)とは、入力として引数(ひきすう)を受け取り、内部で何らかの処理を実施し、最後に出力として戻り値(もどりち)を返すという特徴がある。
NumPyのインストール
ライブラリ「NumPy」は、PyPI(Python Package Index: Pythonの各種パッケージが登録されているサービス)から配布用プロジェクト(=PyPIにおけるパッケージ)をインストールする必要がある。ただし、前回から引き続き使用するPythonコードの実行環境「Google Colaboratory」(以下、Google Colab)には、NumPyが最初からインストール済みなので、今回も実質的にはインストールなしで利用できる。
ちなみに、通常のJupyter Notebookなど、NumPyが未インストールの環境であれば、コードセルに次のシェルコマンドを入力して明示的にnumpy配布用プロジェクトをインストールする必要があるので注意してほしい。
!pip install numpy
※先頭にある!は、コードセルからシェルコマンドを実行するための、Jupyter Notebook/Google Colab独自の特殊機能である。
numpyモジュールのインポート
それではNumPyを利用してみよう。まずはモジュールのインポートである。慣例では「np」という名前で、numpyモジュールをインポートする(リスト5-2)。
import numpy as np
NumPyのデータ型「多次元配列」オブジェクトの作成
Python言語の多次元リスト(Multi-dimensional list)に対応するNumPyのデータ型は、すでに紹介したが「多次元配列」(=N次元配列:N-dimensional array、略してndarray)である(=配列とリストは同じように多次元のデータ構造を表現できるオブジェクトで、要素の追加などで使い勝手が違う部分もあるものの、多次元リストと多次元配列の意味はほぼ同じだと捉えてよい)。ndarrayはコレクション機能を持つPythonクラスとして提供されており、NumPyのメイン機能である。
「ndarrayがどのようなクラスか」を知るために、公式のAPIリファレンス(numpy.ndarray)を見てみよう(図6-1)。
class numpy.ndarrayという記述から、numpy<モジュール階層>の配下にあるndarrayクラスであることや、そのコンストラクターがshape/dtype=float/buffer=None/offset=0/strides=None/order=Noneといった引数を持っていることが分かる(青色の枠)。
また、このクラスに対する説明として「多次元配列を表現するオブジェクト」と記載されている(緑色の枠)。
そして、「配列はarray、zeros、emptyを使って構築するのを推奨する」との注意書きがある(赤色の枠)。これに従って、ndarrayクラスのコンストラクターではなく、arrayから多次元の配列オブジェクトを作成してみよう*3。
*3 zerosやemptyは、arrayほど使われないので、説明を割愛する。
arrayの詳細を調べるために、図6-1にある[array]リンクをクリックして開いたのが、図6-2のページだ。
これについても、numpy.arrayという記述から、numpy<モジュール階層>の配下にarray()関数があることや、その引数としてobject/dtype=None/copy=True/order='K'/subok=False/ndmin=0が定義されていることが分かる(青色の枠)。
また、この関数に対する説明として「配列を作成する」と記載されている(緑色の枠)。この関数を呼び出すことで、ndarrayクラスをインスタンス化した多次元配列オブジェクトが作成できそうだ。
実際に下の方の[Returns](戻り値)欄を見てみると、ndarray型のオブジェクトを返す、と記載されている。
よって、array()関数を呼び出すコードを書くが、関数の引数について、今回は特に重要なobjectとdtypeについてのみ説明しておこう。
objectには、Pythonのリスト値や多次元リスト値を指定できる。多次元リスト値を代入済みの変数を指定してもよい。
dtypeは、NumPyが使えるデータ型を指定する。基本的には、前回の「【コラム】Pythonで数値を表現するための基礎知識」で説明したデータ型である数値型(intやfloat)に加え、正(True)か偽(False)かという値を扱うブール型(bool)が使える。例えば実数(厳密には浮動小数点数)を使うのなら、floatと指定する。なお、コンストラクターの構文で=floatとデフォルト引数(=指定しない場合に既定値として使われる値を持つ引数)が定義されているので、floatならば指定を省略可能だ。機械学習やディープラーニングを使う場面ではfloatを使うことが多いので省略するケースがほとんどだろう。
それでは、前回のリスト3と同じ3行2列の2次元配列を作ってみよう。
array2d = np.array([ [ 165.5, 58.4 ],
[ 177.2, 67.8 ],
[ 183.2, 83.7 ] ])
array2d # array([[165.5, 58.4],
# [177.2, 67.8],
# [183.2, 83.7]])
また、前回のリスト4で多次元リスト値を代入した変数list3dを指定して、次のように多次元配列を作成することも可能だ。
array3d = np.array(list3d)
array3d # array([[[165.5, 58.4],
# [177.2, 67.8],
# [183.2, 83.7]],
#
# [[155.5, 48.4],
# [167.2, 57.8],
# [173.2, 73.7]],
#
# [[145.5, 38.4],
# [157.2, 47.8],
# [163.2, 63.7]]])
要は、array()関数を使うと、多次元リスト値から、多次元配列オブジェクトへ変換できるというわけである。
「多次元配列」オブジェクトから多次元リスト値への変換
ちなみに逆に、NumPyの多次元配列オブジェクトから、Python標準の多次元リスト値に変換したいこともある。この場合は、ndarrayクラスのtolist()メソッドを使えばよい。引数はないので、リスト5-5のようにして呼び出せる。
tolist3d = array3d.tolist()
tolist3d # [[[165.5, 58.4], [177.2, 67.8], [183.2, 83.7]],
# [[155.5, 48.4], [167.2, 57.8], [173.2, 73.7]],
# [[145.5, 38.4], [157.2, 47.8], [163.2, 63.7]]]
「多次元配列」データを使った数学計算は次回
あとは、多次元配列データを使って好きな数学計算をしていけばよい。NumPyには、一通りの数学計算機能が関数として提供されている。次回、その関数について紹介し、実際にサンプルコードで計算する例を示す。
Copyright© Digital Advantage Corp. All Rights Reserved.