機械学習勉強ログ

機械学習に関連した勉強を記録していこうと思います。

線形代数の基本的な計算(3) ~回転行列~

前回は、拡大行列を掛けることで長方形を拡大させることを表現してみました。 今回は、拡大ではなく、座標の回転に挑戦してみたい思います。

回転行列の紹介

次の行列を掛けることで、2次元座標の回転を行うことができます。


R(\theta) =\begin{pmatrix}
cos(\theta) & -sin(\theta) \\\
sin(\theta) & cos(\theta)
\end{pmatrix}

試しに、

 
p_1=(1,1)^T 


\theta_1=\frac{\pi}{2}

でやってみましょう。

まずは、回転する角度に対応した 回転行列を求めます。


R(\theta_1)= \begin{pmatrix}
0 & -1 \\\
1 & 0
\end{pmatrix}

上のような感じで求まります。

これを、 座標のベクトルにかけると、


p_2=\begin{pmatrix}
0 & -1 \\\
1 & 0
\end{pmatrix} \cdot \begin{pmatrix}
1 \\\
1
\end{pmatrix} = \begin{pmatrix}
-1 \\\
1
\end{pmatrix} 

回転後の座標 p_2が求まります。

今回の回転操作も前回の拡大と同様の考え方で

回転後の座標 = 回転変換 * 回転前の座標

求めることができました。

イメージで確認すると、

こんな感じですね。

なぜ、回転行列で回転できるのか?(導出方法)

やっぱり、なぜあの式で回転できるか気になったので調べてみました。

以外に簡単だったので過程も書いておきます。

  • 回転前の座標を p1 , 回転後の座標を p2
  • p1の角度をφ, p2の角度をθとします。

そうすると、p2 (回転後) の座標は次の式で表せているはずです。

これを 加法定理 (確か高校の数Aで習ったが忘れていた)を使って式を変形します😎。

これをベクトル行列の表記に直すと、

あら不思議、回転変換の式が導けました!🙌

これをどう使う?

せっかく回転の式を覚えたので、次回は、回転の式を使って アナログ時計 を表現してみたいと思います。

やっぱり、学校の勉強みたいにひたすら覚えるだけなのはつまらないのでね。

今回は短いですが、ここまでにしようと思います。

線形代数の基本的な計算(2) ~内積、対角行列、拡大変換~

前回は、ベクトル、行列の基本的な計算方法について記載しましたが、

内積の計算方法さえわかれば、行列の基本的な計算ができることが分かりました。

今回は、前回保留にしていた 内積 の意味を見出していこうと思います。

内積を使ってベクトルの成分を取り出す

今回は、点

 p_1=(1, 2)^T

のベクトルを例にとって、

内積を使って何ができるか見ていきたいと思います。

f:id:fugafigs:20190330161436p:plain:w300

まず、点p1 を図示していくと、上記のような感じになります。

例1 : ベクトルからXとYのそれぞれの成分をスカラーとして取り出してみる。

X成分の場合

f:id:fugafigs:20190330145458p:plain:w300

これは、係数として

 a_x=(1, 0)

をかけてあげれば、Xの成分 + Yの成分*0 になるので、結果的にX成分が残る ことになります。

式として表現すると下記になります。

 p_x=a_x \cdot p_1=1

Y成分の場合

f:id:fugafigs:20190331002124p:plain:w300

これは、先ほどと逆で、Y成分側を1にしたベクトルをかけてあげれば、Y成分が残ることになります。

 a_y=(0, 1)

式として表現すると下記になります。

 p_y=a_y \cdot p_1=2

例2: 成分を整数倍する

f:id:fugafigs:20190330150455p:plain:w300

試しにX成分を2倍しました。これは、

 a_x=(2, 0)

整数倍したい成分のところに倍数を入れるだけです。簡単ですね。

式として表現すると下記になります。

 p_x=a_x \cdot p_1=2

例3: Xを3倍して、Yを2倍にする(そして、ベクトルで結果を返す)

f:id:fugafigs:20190330152737p:plain:w300

これは、例1例2の組み合わせで表現できます。

式として表現すると下記になります。


A=\begin{pmatrix}
3 & 0\\\
0 & 2
\end{pmatrix}

 p=A \cdot p_1=(3,4)^T

Xの成分に3倍するベクトルYの成分を2倍するベクトル を行列にしてドット積をとると、

各成分に対する操作を合成できて、結果がそれぞれの要素となるベクトルになっています!

ちなみに、この結果をグラフでみると次のようになります。

f:id:fugafigs:20190330153444p:plain:w300

ちゃんと、座標が大きくなっていますね。 Aという行列を掛けるという操作が座標を拡大 に対応していることが分かりました。

ここで出てきた、Aのように行列の斜めの成分以外がゼロになっている行列を 対角行列 というそうです。

対角行列を使って、長方形を拡大する

先ほどは、点Pを拡大してみましたが、今度は点の集合体である長方形を拡大してみようと思います。

f:id:fugafigs:20190330155736p:plain:w300

試しに上図のような長方形を拡大しようと思います。長方形は、次のような4つの点のベクトルの集まりです。

 p_1=(1, 2)^T
 p_2=(0, 2)^T
 p_3=(0, 0)^T
 p_4=(1, 0)^T

これは、行列としても表現できます。


B=\begin{pmatrix}
1 & 0 & 0 & 1\\\
2 & 2 & 0 & 0
\end{pmatrix}

上のような感じ。(Bとしたのは、Boxを意図して)

先ほどの拡大行列を掛けると、拡大行列がそれぞれの点に対して分配されるので見事、長方形が拡大されます。

f:id:fugafigs:20190330155953p:plain:w300

グラフで見ると、下図のようになります。

f:id:fugafigs:20190331002651p:plain:w300

ちょっとだけ、これを抽象化すると

f:id:fugafigs:20190330160405p:plain:w400

点の集まりであるB1という長方形拡大行列であるAを掛けると、拡大後の長方形であるB2が得られるという感じになります。

これは、すごい。!

個別に式を作っていたら、このような簡潔な式にはならないと思いますが、これが 線形代数の表現力 の賜物なのかと思いました。😁

まとめ

  • まずは、内積が有効活用できる事が分かってよかったと思います。

  • ベクトルの内積とそれを発展させた行列のドット積を使う事で、座標の拡大という操作を行う 事ができました。

  • 座標の拡大は単一座標に対してだけでなく、複数の座標群に対してまとめて適用する 事もできました。

  • 抽象的な視点で見ると、ベクトルや行列を使うことで、複数の要素からなる数値の集合体に意味を与えて、まとめて操作することができることが分かった点も非常によかったと思います。

個人的な感想として線形代数を学んだ事で今まで数学に対して持っていた知識が手続き型プログラミングレベル ぐらいだったのが、構造化プログラミングレベル ぐらいにバージョンアップした感じがして嬉しいです。😄

次回は、今回の発展系として 回転行列 と、(可能であれば)ベクトルの次元を増やして 3次元の座標を扱ってみたい と思います。

線形代数の基本的な計算(1) ~ベクトルと行列の基本的な計算方法~

今回は、前回から1週間後の更新になりました。

最近は休日になるのが楽しみになっている状況です。

前回は、ベクトル・行列はプログラムにおける複合的なデータ構造(配列やハッシュ)と近しい という(個人的な理解)ところまで

話を進めてきました。今回は、それらの表現を使ってどんな操作ができるのか見ていきたいと思います。

工学基礎 はじめての線形代数学 (KS理工学専門書)

工学基礎 はじめての線形代数学 (KS理工学専門書)

ちなみに、僕はこの本を使って勉強していて、現状は5章まで解き進めた状態で、このブログを綴っています。

スカラー、ベクトル、行列の基本的な演算

まず、ベクトル行列の計算方法ですが、今読み進めていたところまでを振り返ると

最初は、まず次のことが理解できていれば問題ないと感じました。

  • (1)スカラーとベクトルの演算
  • (2)ベクトルとベクトルの演算
  • (3)ベクトルと行列の演算
  • (4)行列と行列の演算

いろいろな計算が出て来るのですが、

ベクトル行列の計算は、内積の計算を中心に計算方法が組み立てられている ように思えましたので、

その点を図解して説明していきたいと思います。

1. スカラー * ベクトル

f:id:fugafigs:20190330122246p:plain:w300

まず、スカラー * ベクトルですが、これは スカラーの値をベクトルの各要素に分配していく イメージです。これは簡単ですね!

2. ベクトル * ベクトル (内積 )

f:id:fugafigs:20190330134959p:plain:w300

次に、こいつがかなり重要な概念な 内積 ですが、

計算自体は簡単で、ベクトルのそれぞれの要素を掛け算して、足したもの です。

それぞれの要素を足し合わせて、1つの要素にするので、内積の結果はベクトルではなく スカラー値 になります。

ちなみに、ベクトルの要素数(次元)があっていないと内積という演算そのものができない

仕様となっておりますw。ご注意ください!

内積は、ドット積とも言うそうです。

ベクトルの 内積という操作がどういう意味であるか については重要な概念なので、

次回1回かけて掘り下げていこうかと思います。

3. ベクトル * 行列

f:id:fugafigs:20190330134709p:plain:w300

次は、ベクトルと行列のドット積となります。

これは、上の図で見た通り、左側ベクトルを右側のそれぞれの縦ベクトルに分配して内積をとっていくイメージとなります。

内積の計算イメージをしっかり頭に入れておけば、そんなに難しくないはずです。

結果は、スカラー値が横に2つ並んだ結果になります。

4. 行列 * ベクトル

f:id:fugafigs:20190330135218p:plain:w300

次は、行列とベクトルのドット積ですが、先ほどと考え方はほとんど一緒です。

左側の横ベクトルから、右側の縦ベクトルに対して内積をとっていく イメージとなります。

結果は、要素数が2(つまり、2次元)のベクトルが1つとなりました。

5. 行列 * 行列

f:id:fugafigs:20190330125918p:plain:w300

これは、見ればわかる通り、3と4で出てきた演算の組み合わせですね。

4つのベクトルの内積を縦横に分配しているとみることもできます。

結果は、4x4の行列、(要素数が2のベクトルが2つ並んでいる)となります。

高校で習ったときは、やたら複雑な計算だと思っていましたが、

4つのベクトルが並んでいると見れれば、案外簡単だと思いました。(計算はそれなりにめんどくさいですが、)

まとめ

今回は、計算方法を図解して説明しました。

次回は、今回覚えた計算が実際に何の役に立つのかについて、見ていきたいと思います。

線形代数はじめました!

前回、今年は数学を勉強すると決めてから14日経過してしまいました。

案の定続かないと思いきや、はじめてみたら結構面白くて意外に続いています。

新しく購入した Surface Pro6 がかなり便利で、 One Note と組み合わせて使っていますが、これは素晴らしいですね。

線形代数の意義は何だろうか?

学生のころ、なぜ勉強が頭に入らなかったかを考えると、明確に理由があるんですよね。

たぶん、誰もが1度は自問自答したであろうことだと思いますが、

「これは、いったい何の役に立つんだ?」 と疑問を抱えたまま、目的なく勉強を続けようとしたからだと思います。

なので、まずはそのあたりから入ろうと思います。

個人的線形代数の存在意義とは(笑)

線形代数は何のためにいるのか?をまず個人的に考えました。

ググればいろいろ出てくるのですが、ブログは個人の考えをつづるメディアだと思うので、

思いっきりバイアスがかかった意見を綴っていきます。

一言でいえば、 「多次元の値を扱いやすくするための概念を作ったぜ!」

ということなんじゃないかと思います。

ベクトルと行列で多次元を表現する

僕はエンジニアなんで、プログラムで例えていきます。

(あくまで、僕は、数学もプログラムも道具としてみているので正しいかどうかは置いておきますw。)

そうすると、ベクトル行列ハッシュ配列に相当するものなのではないかと思います。

例えば、次のようなプログラムで

users = [
  { 
     'name' : 'bob',
     'age'    : 20,
     'gender' : 'male'
  },
  {
     'name' : 'alice',
     'age'    : 19,
     'gender' : 'female'
  }
]

def print_users(users):
    for user in users:
      print('name={}'.format(user['name']))
      print('age={}'.format(user['age']))
      print('name={}'.format(user['gender']))
  • もし、ハッシュや配列がなかったとしたら、どう ユーザー群 という概念を表現すればいいのでしょうか?
  • また、仮に users というハッシュと配列で表現されるデータ構造がなかったら、 print_users という操作をどう定義すればいいのでしょうか?

いずれも、 難しい という結論になるのではないでしょうか?

たぶん、数学においてもスカラー変数だけでは、複雑な問題は解けないどころか、表現すらできません。

そのために、多次元の表現手段が必要となり、ベクトルや行列が生まれたのではないかと思います。

なので、プログラムでいえば、基本的なデータの表現の仕方やデータの操作を学ぶことと同じぐらいの大切さが線形代数にはあると思います。

ベクトルと行列を使って、ユーザー群を表現してみる

仮にベクトルを使って

  { 
     'name' : 'bob',
     'age'    : 20,
     'gender' : 'male'
  }

を表現するなら、


b=(bob, 20, male) ^T

たぶん、こんな感じですかね?

文字列は、数学では出てこないと思うので、あくまでイメージです。

ちなみに、ベクトルは下記のように縦で表記するのが一般的のようです。


b=\begin{pmatrix}
bob \\\
20 \\\
male
\end{pmatrix}

では、次にユーザー群を表してみたいと思います。

f:id:fugafigs:20190326001717p:plain:w500

こんな感じでしょうか?

ちなみに、行列はベクトルが並んだもので、

この場合が下方向に伸びていくと次元(要素)が増えて、右方向に伸びていくとベクトルの数が増える認識です。

綺麗に書くと、下のような感じになります。

{\
P=\begin{pmatrix}
bob & alice \\\
20 & 19 \\\
male & female 
\end{pmatrix}
}

まとめる

ベクトルは、複数の要素を持つ1つの概念を表す。

学生時代は、矢印と座標のイメージしかなかったですが、何を表してもいいようです。

例えば、グレースケールの10x10の画像は100次元のベクトルとして表現できます。

行列は、ベクトルが複数並んだものと思ってよさそう。

ちょうど、データベースの テーブルとレコードを考えるとわかりやすいと思います。

1レコードが、1つのベクトルに相当し、テーブル全体が行列のイメージだと思います。

先ほどの10x10のグレースケール画像が100個あったら、100x100の行列として表現できます。

次回のお題

ちょっとトンでもな感じで終わってしまいましたが、ベクトル・行列を使って、複数要素からなる値(多次元の数)を表現する手段を得ました。

次はこの表現手段を使って、どのような操作ができるのか!

また、独自の切り口で学んだ結果をアウトプットしていこうと思います。

更新は2週間後ぐらいを目指したいと思います。

線形代数を勉強しようと思う

なぜ勉強しようと思ったか?

機械学習を使った開発プロジェクトにJOINした。

なんとなくライブラリを使って機械学習っぽいことをやったり、データの分析(といえるレベルのものか?)などもしたりしてる。 しかし、この分野についてのバックグランドが全くないので、やれている感がない。 もうちょっとマシな感じになりたい!

困っていること

困っていることを列挙すると、次のような感じになる。

  • 数式が読めない。
  • 原理の理解があやふやなので、人にうまく説明できない。
  • 専門知識のある人との会話についていけない。説明してもらうコスト大。

たぶん、同じような境遇の人はいますよねw?

自分の略歴

  • 情報系の大学を中退 -> SIer -> Web 系(インターネット広告)のベンチャー企業
  • 大学時代、プログラミングは大好きでやってましたが、ほとんど単位を取ることなく、中退してしまいましたw。 線形代数微積確率統計 とかやっておけばと今更ながらに思いましたが、まさに後悔先に立たずです。
  • 直近はiOSのセキュリティ対策であるITP(Intelligent Tracking Prevention)に対応するための広告計測ツールの開発をやっていました。

今年の目標

はじめてのパターン認識

はじめてのパターン認識

目標に至るために攻略すべきテーマ

  • 線形代数
    • 基本的にベクトルや行列を使って数式が表されているので、これを理解できれば数式が頭に入ってくるのではないかと思っている。
  • 確率、統計
    • 古典統計
      • まずは、統計分析や検定手法などの機械学習ではなく、人間がデータをどう紐解いていくかについての手法を知る必要があると思っている。
    • ベイズ統計
      • 確率的なモデルで使われているのでベースであるベイズを知る必要があると思っている。

まぁ、そんな訳で続けられることを祈って、勉強記録を綴っていこうと思います。 月2回ぐらいの更新頻度で続けられるといいな。