連載
» 2020年11月19日 05時00分 公開

AI・機械学習の数学入門:[AI・機械学習の数学]行列の基本と、回帰/ニューラルネットワークでの表現

多くの変数や係数をひとまとめにして取り扱うために、機械学習では行列がよく利用される。前回のベクトルを踏まえて、今回は行列の基本的な計算方法を確認する。さらに、回帰式やニューラルネットワークを行列でどう表現するかを見ていく。

[羽山博,著]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「AI・機械学習の数学入門」のインデックス

連載目次

 前回のベクトルを踏まえて、今回は行列を取り扱います。

 ベクトルとは、簡単にいうと、複数の数値や式を一列に並べてひとまとめにしたものでした。

 一方、今回取り扱う行列は、複数の数値や式を縦横に並べてひとまとめにしたものです。複数のベクトルをひとまとめにしたものと考えてもいいでしょう。……などという能書きよりは、具体例で見ていった方が分かりやすいので、簡単な例で見ていくことにしましょう。本稿では、行列の基本的な計算方法を確認した後、回帰式やニューラルネットワークをどう表現するかを見ていきます。

目標【その1】: 行列とは

 行列とは、複数の数値や式を行方向と列方向に並べたものです。例えば、以下のようなものが行列です。

 この行列の行数は2、列数は3です。つまり、1行目が[1,2,3]、2行目が[4,5,6]です。なお、全体を囲むかっこは以下のように丸かっこを使う場合もあります。が、この連載では角かっこを使うことにします。

 ベクトルの場合と同様に、個々の数値や式を「成分」と呼びます。しかし、重要なのは、それぞれの成分を個別に扱うことよりも、これらの成分を持つ行列を1つの文字で扱えるということです。以下のように書けば、6つの値Aというたったの1文字で扱えます。

 行列を文字で表すときには、ABなどの大文字を使うのが一般的です(太字の大文字で表すこともあります)。なお、行と列の数が等しい行列のことを「正方行列」と呼びます。

解説【その1】: 行列とは

 2009年に改訂された学習指導要領(施行は2012年以降)により、数学Cが他の科目に統合された関係で、行列は高校数学ではほぼ扱われなくなりました。そのため、行列にあまりなじみのない人も多いかもしれません。しかし、機械学習で使う行列は単に行や列の成分を四則演算で計算する程度なので、ベクトルの知識があれば簡単に理解できます。

 目標のところに記した例を使って、行と列を図で確認しておきましょう。

行列の「行」 図1 行列の「行」

行列の「列」 図2 行列の「列」

 このように多くの成分から成り立つ行列を1つの文字で表せば、複雑な式や多くの計算が簡単に表せる、というのが行列の便利なところです。それについては計算の方法を見ればより実感が湧くことと思います。が、計算の方法は後述することとして、行列の成分を文字と添字で表す方法を確認しておきましょう。行列がmn列である場合は、以下のように表すことができます。

 つまり、図3に示すように、行位置(行番号)と列位置(列番号)を添字として右下に小さく書いて表す、ということですね。なお、上のように成分を並べると煩雑なので、A=(aij),1≤ i ≤ m,1≤ j ≤ n と書いたり、さらにA=(aij)と簡略化して書いたりすることもあります。

行列の成分の表し方 図3 行列の成分の表し方

 ただし、mnが2桁になると、例えばa123のようになり両者の値が区別できないので、行番号と列番号の間にカンマを入れることもあります。例えば、123列のつもりでa123と書くと、123列と解釈されてしまうかもしれないので、a1,23と書くわけです。

*1

*1 プログラミング言語では、配列などのインデックスは0から始まるのが一般的です。例えば、Pythonで利用できるNumPyというライブラリの配列を使って行列を表す場合、mn列の行列はa[0,0]からa[m-1,n-1]までとなります。例えば33列であれば、行列の添字は「13」になりますが、プログラミング言語では「02」になるということです。


 では、配列に慣れるために簡単な練習問題をやっておきましょう。

練習問題

 以下の配列について、問いに答えてください。解答はオレンジ色の部分をクリックまたはタップすれば表示されます。

(1)この行列の3行2列目における成分の値は 0.1 である
(2)この行列の成分をaijと表したとき、i=1,j=3のときのaijの値は 0.8 である
(3)この行列の右下の成分(=0.3)はa33  と表せる
(4)この行列の2行目だけを取りだし、ベクトルとして表すと[  0.1 , 0.2 , 0.5  ]となる

目標【その2】: 行列の和と定数倍

 行列の和は、成分ごとの和になります。従って、同じサイズの行列でないと和が求められません。差は和と同じ考え方です。つまり、成分ごとの差になります。行列を一般的に表す方法には慣れたでしょうから、文字と添字を使って表しておきます。

のとき、

 行列の定数倍は、各成分を定数倍したものです。定数をλ(「ラムダ」と読みます)、配列Aを上に記したものとすると、以下のようになります。

 なお、λの筆順は漢字の「入」と同じ(左払いを先に書く)書き方が一般的です。

解説【その2】: 行列の和と定数倍

 行列の和と定数倍の計算方法は簡単ですね。何度も繰り返しますが、個々の成分計算を手計算でできることが大事なのではなく、多数の成分からなる行列の和がA+B、定数倍がλAのように極めて簡単に表せるということが行列の便利なところです。

 とはいえ、どういう仕組みで計算が行われるかを理解しておくことは重要なので、穴埋めをしながら、目標に記した計算方法を具体例で確認しておきましょう。解答はオレンジ色の部分をクリックまたはタップすると表示されます。[ア]〜[キ]などの部分には数値が入ります。

のとき、ABの和は以下のようになります。

(答え: [ア]= -4 、[イ]= 10 、[ウ]= -7 、[エ]= -2 、[オ]= 4 、[カ]= 12 、[キ]= -9 

 また、A3を掛けると以下のようになります。

(答え: [ア]= 3 、[イ]= 3 、[ウ]= 3 、[エ]= 3 、[オ]= 3 、[カ]= 3 、[キ]= 24 、[ク]= 15 、[ケ]= 30 、[コ]= 12 、[サ]= -21 、[シ]= 6 

目標【その3】: 行列とベクトルの積

 行列とベクトルの積は、以下のように計算されます。一般的な表し方にすると、少し難しく感じられますが、後の解説で具体例を見れば簡単なルールだということが分かります。抵抗を感じた方は先に具体例を見てから、以下の一般的な表し方に戻ってくるといいでしょう。行列をA、ベクトルをxで表すことにします。Amn列で、xは長さnとします。

のとき、

 注意すべき点は2つあります。一つは行列の列数nとベクトルの長さnが等しい場合のみ積が求められるということ、もう一つは結果が長さmのベクトルになるということです。なお、A ⋅ xの各行は行列Aの各行とベクトルxの内積になっているということも分かります。各行は対応する成分の積の総和なので、A ⋅ xi行目は以下のように表せます。

 なお、値や式を横方向に並べたベクトルを行ベクトルと呼び、縦方向に並べたベクトルを列ベクトルと呼びます。その方向を変えることを「転置」と呼び、ベクトルxを転置したベクトルはtxxTなどと書かれます。また、行列についても、Aの行と列を入れ替えることを「転置」と呼び、同様に、tAATと表します。ベクトルについては行ベクトルであるか列ベクトルであるかはさほど気にする必要はありませんが、行列の場合は行や列がどのような値の並びであるかを明確にしておくことは重要です。例えば、データの並びが数式で想定している方向と異なる場合には、転置を行って正しく計算できるようにする必要があります。

解説【その3】: 行列とベクトルの積

 では、行列とベクトルの積の計算方法を具体例で見てみましょう。以下の計算方法については、動画も用意してあるので、1歩ずつステップを踏んで計算方法を確認したい人はぜひ視聴してください。

動画1 行列とベクトルの積


のとき、 A ⋅ xを求めてみましょう。Aの列数「3」とxの長さ「3」は等しいので、積が求められることが分かります。結果はAの行数「2」と同じ長さのベクトルになるはずです。手順は以下の通りです。

行列の1行目をベクトルとみなし、内積を求める

行列とベクトルの積(ステップ1) 図4-1 行列とベクトルの積(ステップ1)

 行列Aの1行目とベクトルxの内積は1×2+3×4+4×(−3)=2です。これを結果の1行目に書きました。次は、2行目の計算です。

行列の2行目をベクトルとみなし、内積を求める

行列とベクトルの積(ステップ2) 図4-2 行列とベクトルの積(ステップ2)

 行列Aの2行目とベクトルxの内積は−2×2+6×4+5×(−3)=5です。これを結果の2行目に書きました。はい、これで計算は終わりです。配列やベクトルのサイズがいくつでも、この手順と同じ要領で計算すれば、簡単に答えが求められます(ただし、配列の列数とベクトルの長さが等しい場合だけです)。といっても、いちいち手計算を行うのは面倒なので、方法が確認できれば、実際の計算はパソコンにまかせてしまってもいいですね*2


*2

*2 この例の計算をPythonで書いてみました。Pythonのプログラミングについては、こちらの連載『Python入門』を参照していただくこととして、配列やベクトルを表すことができれば、計算そのものはパソコンにまかせてしまえることが分かりますね。

import numpy as np             # numpyパッケージをインポート
A=np.array([[1,3,4],[-2,6,5]]) # 行列(配列)「A」をNumPy配列として定義
x=np.array([2,4,-3])           # ベクトル「x」をNumPy配列として定義
np.dot(A,x)                    # 行列とベクトルの積(ドット:dot)

リスト1 行列とベクトルの積を計算するPythonコード例

 NumPyのarrayクラスのオブジェクトが行列やベクトルを表しており、dot()が行列とベクトル、あるいは行列同士の積を求めるメソッド(命令)です。実行結果は以下の通りです。ちゃんと(2,5) というベクトルになっています。

array([2, 5])

リスト2 上記のPythonコードの実行結果


練習問題

 では、練習問題をやっておきましょう。

(1)以下のような配列Xとベクトルa、ベクトルbがあるとき、X⋅ abを求めてみてください(文字式の部分はもちろん文字のままで構いません)。

(2)図5のようなニューラルネットワークの隠れ層をベクトルyとしたとき、yに入力される値は、

となります。このとき、yを、重みの配列W、入力層の値を表すベクトルx、バイアスのベクトルbで表してみましょう。

ニューラルネットワークの例 図5 ニューラルネットワークの例

 (1)(2)とも、解答は穴埋め方式にしておきます。問題を考えながらオレンジ色の部分をクリックまたはタップして、答えを確認してみてください。[ア]〜[オ]などの部分には数値や記号が入ります。解答は動画でも解説しています。

動画2 「行列とベクトルの積」の練習問題


練習問題の解答

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。