人工知能について学ぶ中で機械学習の話は必ず出てきます。
機械学習には様々な手法がありますが、最初の方に出会う手法としてSVM(サポートベクタマシン)があります。
そこでこの記事では
「SVMって何か知りたい」
「でも入門書レベルで分からないけど、大丈夫かな」
こういった疑問や不安がある方向けにSVMについて解説していきます。
この記事を書いているボクは大学の研究室で人工知能を専攻おり、ディープラーニングや機械学習を勉強してます。
10冊以上の機械学習入門書を読み、その中でも分かりやすい内容をピックアップしながら解説していきます。
簡単に説明しますが、内容はかなりガッツリなので、SVMについて入門書で見たけど難しすぎて挫折したという方はぜひ参考にしてみてください。
※なお、この記事では実際のコードは記載してません。
プログラムする時に必要な考え方を詳しく解説している内容になっています
もくじ
SVMとは一体なにか?内容をカンタンにまとめました
この部分だけ見ればSVM(サポートベクタマシン)がどんなことをする子なのか全体像がつかめると思います。
SVMの全体像を理解するために大事なことは次の2つです。
- 一言で言えば分類する基準(直線)決め
- 一番のポイントは「マージンの最大化」
SVMが最も得意とするのは「分類問題」です。
ここからは分類問題とは何かも含めてSVMがカンタンに解説していきます。
一言で言えば分類する基準(直線)決め
ボクらが人工知能を作る時、最初にやりたいことは「分類問題」です。
「分類問題」ってなに?
一言で言えば仕分けです。
例えば「りんご?みかん?」「人?車?」「有害?無害?」など、なにか特徴を見た時にどのグループになるかを判定する作業です。
この時、仕分けるグループのことを「クラス」と言ったりします。
SVMはこういった分類をする基準を決める時に活躍します。
人間であれば「こんな特徴があるものは〇〇だよ」と教えられますが、コンピュータは人間の言葉が分からないため、基本的には数字で特徴を教えます。
特徴を数字で表したものを「特徴量」といったりします。
たとばりんごかレモンかを分類したい時「酸っぱいか甘いか」「赤色か黄色か」を判断する特徴とすると考えるとこんなグラフが描けそうです。
このように特徴量をグラフにしたものを「特徴空間」といいます。
酸っぱいくて黄色ならレモン、甘くて赤色ならリンゴとなりそうです。
実際の特徴量をこのグラフに入れるとこんなグラフになったとします。
この時、分類する境界線はどうやって引けるでしょうか?
候補の直線としてこの3つが考えられたとします。
識別境界より右側にあればりんご、左側にあればレモンです。
この境界線のことを「識別境界(超平面)」と言ったりします。
①~③どれも100%仕分けできていますが、ここに新しいデータを追加した時にしっかり仕分けできる線はどれかを考えるのがSVMでやることです。
この青いデータに対して③の識別境界では正確に仕分けできてません。
そうすると①か②になりそうですが、こんなデータが入ってきたらどうでしょうか。
この場合なら①はちゃんと分類できてなさそうです。
すると②か③になることが分かります。
このように「新たに入ったデータにもより正確に分類できる(汎化性能が高い)直線」これを決める手法がSVMになります。
一番のポイントはマージンの最大化
より識別能力が高い識別境界を決める手法であるSVM(サポートベクタマシン)はこのような手順で直線を決めていきます。
step
1代表的なサンプル(サポートベクタ)を選ぶ
step
2サポートベクタ間の距離(マージン)が最大となる境界線を選ぶ
ステップ①代表的なサンプル(サポートベクタ)を選ぶ
汎化性能が高い直線を決めるためにサポートベクタを選びます。
サポートベクタってなに?
特徴を表す代表的なサンプルです。決め方はいろいろありますが、SVMでは識別境界から最も近い点とすることがあります。
②の直線でお話をすると、サポートベクタはこのようになります。
ステップ②サポートベクタと直線の距離(マージン)が最大となる境界線を選ぶ
先ほど決めたサポートベクタと識別境界との距離が最大となる点を探します。
この時、サポートベクタと識別境界との距離を「マージン」と言ったりします。
それぞれのサポートベクタからの距離が最も遠くにある直線こそ、ちょうど中間地点になるため、汎化性能が高い直線を引くことができます。
【文系でもOK】数式まで理解するSVM入門書の入門書
便利なフレームワークで実装だけなら簡単ですが、中身の原理を知る必要がある場面が出てくると思います。
しかし
「数式とか出てきたら自信ないんだけど...」
「文系の自分でも大丈夫かなぁ」
「入門書読んでも挫折したんだよなぁ...」
と感じる方もいると思います。
多くの入門書では数式は知っているものとして進むものが多いですが、この記事では数式そのものへの解説も丁寧に行っていきます。
できるだけ文系の方にも分かるように頑張って書いていきますので、ガッツリ理解してみたい方はぜひ参考にしてみてください。
SVM(サポートベクタマシン)はこの3つのステップで構成されています。
step
1前提条件の確認
step
2サポートベクタを選ぶ
step
3マージンの最大化
Step1.前提条件と必要な知識の確認
「できるだけ汎化性能が高い識別境界を決める」
これがSVMのミッションでした。
そのためにはサポートベクタ間の距離が最大となる直線を決めていきます。
その際に必要になる前提知識は以下の3つです。
- 「+」なら直線より上側、「ー」なら直線より下側にある
- 符号化関数\(\mbox{sgn()}\)
- 重みとバイアス
マメ知識
直線式の表し方について覚えておくと便利な豆知識です!
直線式は\(y=\alpha x+\beta\)で表されること多いです。
一方で、この分野では\(ax+by+c=0\)という形で表現すると便利ですので、ここからはこの形で表していきます。
理由は後ほど分かってくるのでお楽しみに♪
【必要な前提知識①】「+」なら直線より上側、「ー」なら下側にある
「直線式に数値を代入して、「+」なら直線より上側、「ー」なら直線より下側にある」
これを理解すると直線式で分類を行うとはどういうことなのかがハッキリ見えてきます
ここからはこの理由について詳しく解説していきます。
先ほど紹介した式\(ax+by+c\)が\(a=1,b=1,c=-10\)という条件だった時を考えます。
すると\(x+y-10\)となります。
さあ、この式に4パターンの数値が代入されました。
A:\((x,y)=(2.5,2.5)\)
B:\((x,y)=(5.0,5.0)\)
C:\((x,y)=(7.5,7.5)\)
D:\((x,y)=(0,0)\)
グラフにその値を入れていくとこのようになります。
実はこれがクラスの仕分けをする超重要な考え方です。
これだけではまだ分からないという方のために、次は点A,B,C,Dの値を直線の式(\(ax+by+c\))に代入してみます。
直線の式(\(ax+by+c\))に点A,B,C,Dの値をそれぞれ代入してみると
A:\((x,y)=(2.5,2.5)\)→\(2.5+2.5-10=-5\)
B:\((x,y)=(5.0,5.0)\)→\(5.0+5.0-10=0\)
C:\((x,y)=(7.5,7.5)\)→\(7.5+7.5-10=+5\)
D:\((x,y)=(0,0)\)→\(0+0-10=-10\)
この結果を見ると
点AとDはマイナスの値になり、グラフ上では直線より下側
点Cはプラスの値になり、グラフ上では直線よりも上側
点Bは0の値になり、グラフ上では直線上
になっていることが分かります。
つまり直線式に何か値を代入して、
プラスの値が出れば直線より上側、
マイナスの値が出れば直線式より下側
になるので、2つのクラスに仕分けできることが分かりますね。
マメ知識
【出てきた値は直線からの距離を表している】
高校数学では「点と直線の距離」でこんな公式として出てきます。
$$d=\frac{|ax+by+c|}{\sqrt{a^{2}+b^{2}}}$$「+」or「-」で直線の上か下かが分かり、
中身の値(絶対値)で点から直線までの距離が分かってしまうんです。
頭が既にパンクしそうな方は「こんな式があるんだ。へ~...」くらいの理解でOKです。
【必要な前提知識②】符号化関数\(\mbox{sgn()}\)
先ほどは直線の性質を解説しましたが、ここから一気に工知能の世界に近づけていきます。
仕分け問題を人工知能で実装する時には関数にある値を入れた時に「+」になるのか、「-」になるのかで識別できます。
そこでSVMでは
「直線式に数値を代入して、「+」なら直線より上側、「ー」なら直線より下側にある」
この直線式の性質を使うことにしました。
この性質を数式で表すとこうなります。
$$\mbox{sgn(ax+by+c)}$$
ポイント
\(\mbox{sgn(ax+by+c)}\)の意味
式\(ax+by+c\)の値が0以上の時に+1、0より小さい時に-1を出す
という意味になります。
この意味を数式で表すとこうなります。
\[
\begin{equation*}
\begin{cases}
+1 (ax+by+c \geq 0)\\
-1 (ax+by+c < 0)
\end{cases}
\end{equation*}
\]
-1か+1の符号だけ判定していることから\(\mbox{sgn()}\)は「符号化関数」と呼ばれています。
【必要な前提知識③】重みとバイアス
人工知能の世界では
特徴量(データの値)である\(x,y\)の係数\(a,b\)は「重み」、切片の\(c\)は「バイアス」といいます。
これは人工知能分野でよく出てくるニューラルネットワークの世界でも出てきます。
(ピンと来ない方は軽く流してもらってOKです)
この考え方を例題に反映させると直線式は\(w_1x_1+w_2x_2+b\)と表せます。
(よく分からない方は焦ると思いますが、\(a=w_1,b=w_2,x=x_1,y=x_2,c=b\)に置き換えただけです)
最初の例題ではデータ数が\(x,y\)の2つでしたが、人工知能分野ではデータ数が10や100に増えていくため、\(x_1,x_2\)といったように添え字を付けて表した方が便利です。
つまり「SVMで直線を決める」とは直線式の係数(重み)である\(x_1,x_2\)と切片(バイアス)\(b\)を決めていくことがミッションになります。
Step2.サポートベクタを選ぶ
基本的ななSVM(サポートベクタマシン)でのサポートベクタの選び方はこうでした。
「識別境界から最も距離が近いデータをサポートベクタとする」
メモ
サポートベクタの選び方は色々ある
今回はハードマージンSVMという手法の選び方を紹介しています。
他にもソフトマージンSVMといった方法もあり、実際はハードマージンSVMを使用する機会はあまりないかもしれません。
しかし、今回はSVMの手法を理解することをメインとしているため、最も分かりやすい手法を紹介しています。
なお、識別境界から最も距離が近いデータを選ぶため、グラフ(特徴空間)にあるすべてのデータでこの計算を行います。
$$d=\frac{|w_1x_1+w_2x_2+b|}{\sqrt{w_1^{2}+w_2^{2}}}$$
先ほども紹介した、「点と直線の距離」を求める公式です。
すべてのデータ点で距離計算を行って、最小値の特徴点をサポートベクタとして選びます。
Step3.マージンの最大化
先ほど選んだサポートベクタから直線までの距離が最大になるように重み\(x_1,x_2,b\)を決めていきます。
3つの値を調整するため、答えを1つに確定させることはできません。
計算にうまく制約条件を加えたりとできるだけ計算量を少なくするような工夫をしたうえで、計算していきます。
とはいえ人の手で計算することは難しいので、実際はコンピュータに任せます。
この計算を効率よく行うだけでも研究はされていますし、フレームワークも用意されているので、プログラムで実装する時はそちらを使います。
プログラムで実装は超カンタン
実際にプログラムする時はこのプロセスを実装する必要はありません。
今回はプログラム実装の説明を省いていますが、最近では便利なフレームワークを使って、数行のプログラムでSVMを実装することができます。
しかし、中身の原理も知っておくとうまくいかなかった時の原因も見つけやすくなります。
(お仕事で使う場合は説明責任もあるので、必須と言ってもいいかもしれませんね)
このブログで紹介した考え方を頭に置いて、入門書を読むと言ってることが分かると思いますので、挫折した経験がある方はぜひもう一度読んでみてください!