テクノロジー

【初心者向け】PythonでSVM(サポートベクトルマシン)を実装する方法

【初心者向け】PythonでSVM(サポートベクトルマシン)を実装する方法

機械学習による分類手法の1つに、SVM(サポートベクトルマシン)があります。SVMは、データの点の間に境界線を引くことで分類をおこなうアルゴリズムです。データの距離が最長になるように境界線を引くという仕組みになっています。とはいえ、これだけではちょっとピンとこないですよね。この後、もう少し詳しく説明をします。

そんなSVMは、実はPythonでも実装できます。Pythonは機械学習のプログラムを記述するための非常に一般的なプログラミング言語ですから、SVMをPythonで実装することができれば、さまざまな機械学習プログラムを併せて利用するうえでも便利です。SVMを実装するにあたって利用可能なライブラリは、さまざまに存在しますが、なかでもscikit-learnがおすすめ。ぜひ、この記事を読んでPythonでSVMを実装までできるようになりましょう。

そこで今回は、SVMの概要に加えて、PythonでSVMを書くために必要なライブラリや、実際にPythonでSVMを書く方法について説明します。

SVM(サポートベクトルマシン)とは

SVMのイメージ

SVM(サポートベクトルマシン)は、教師あり学習の1つで基本的にはクラス分類をおこなうためのアルゴリズムです。なお、SVMには回帰に応用する手法もありますが、ここでは分類に限って扱うことにします。

SVMでは、まずグラフ上にプロットされたラベル付きデータを参照し、境界線によってそのデータを分割します。境界線は、データ点との最短距離が最大となるように引きます。これは、偏りのない境界線を引くためだと言えば直感的に理解できるでしょう。

ちなみに3次元のデータであれば、境界は曲線ではなく面となります。4次元以上のデータであれば、境界はより大きな次元となります。この境界のことを、一般に「超平面」と呼びます。

※詳しくはこちらの記事でも図をつけて解説しています

2次元の説明変数の場合であっても、データSVMで引かれる境界線は、直線とは限りません。むしろ、ある程度複雑な曲線においてこそ、SVMの特徴が生かされているともいえます。SVMは、低次元の問題を高次元に変換することによって単純な境界によって分割することを可能にし、むしろ問題を簡単にするという性質を有しているからです。ここではその詳しいメカニズムに言及しませんが、それもおもしろいところの1つ。

またSVMのメリットは、ディープラーニングなどと違って、少ないレコード数でもそれなりの精度を発揮するところです。加えて、次元の呪いにも強く、多次元になっても精度を発揮できます。ですから、ディープラーニングの活躍が著しい画層認識のような分野でも、SVMが用いられる場面は残っています。

ここまで、SVMの概要について説明しました。SVMは非常にポピュラーなアルゴリズムでもちろん、PythonでもSVMを実装できます。次からは、いよいよSVMの実装に関して言及します。

PythonでSVMを書くために必要なライブラリ

ライブラリのイメージ

さて、PythonでSVMを書くためには、普通は何らかのライブラリを用いる必要がありますよね。SVMの本体は、scikit-learn(サイキットラーン)のものがよく用いられます。SVMを実装するだけであれば、これで十分なので、今回もscikit-learnだけを利用します。

他に、複雑な計算を含む高度な内容を記述するのであれば、数値計算を効率化するライブラリであるnumpyを入れるのも良いでしょう。numpyは、少ないコードによって複雑な数値計算を記述することを可能になるためです。

さらに、分類の様子をグラフ上で確認するのであれば、matplotlibを入れましょう。matplotlibは、グラフの描画をおこなうことができるライブラリですが、SVMは座標空間上でどのようにクラスが分かれているか確認することができるとわかりやすい部分もあるので、これを利用するケースも少なくありません。ただし、グラフを描画しなくてもSVMを利用するのには差し支えありません。あくまで、SVMの実装とは別にグラフによって分割の様子を確認したい場合などに使いましょう。

実際にPythonでSVMを書いてみよう

SVMを書くイメージ

では、いよいよ実際にPythonでSVMを書いてみましょう。

ここでは、scikit-learn公式ドキュメントのコードを参照しながら、PythonにおけるSVMの書き方を見ていきます。

まず、学習部分のコードを書きましょう。次のコードをご覧ください。

from sklearn import svm
X = [[0, 0], [1, 1]] y = [0, 1] clf = svm.SVC()
clf.fit(X, y)

SVMの学習に最低限必要なコードがこれです。

Xが説明変数のデータです。説明変数は2次元で、レコード数は2。座標はそれぞれ(0,0),(1,1)です。

そして、yが目的変数のデータです。座標が(0,0)の1つめのレコードのラベルは0で、座標が(1,1)の2つめのレコードのラベルが1であることがわかりますよね。このデータのラベルは、2クラスの分類をおこなうということです。

次に、fit(X,y)と記述することによって学習を実行しました。いま、座標(0,0)と座標(1,1)の間のどこかに2つのクラスを分類する境界線が引かれたでしょう。

これで学習が終わったなら、次は推測のコードを書きましょう。推測のコードは次のように書きます。

clf.predict([[2., 2.]])

このコードを実行すると、次の結果が出力されるでしょう。

array([1])

このコードでは、座標(2,2)のデータのラベルを分類しています。そして、ラベル1に分類されたと出力されています。

なぜならば、座標(0,0)と(1,1)の間に境界線があり、座標(1,1)の側がラベル1なのですから、座標(2,2)のデータはもちろんラベル1に分類されます。そのため、この結果は当然ですよね。

もちろん、1レコードだけでなく多数のレコードを分類することもできます。その場合、clf.predict([[2,2],[3,3],[-1,-2])などと続けて書きます。

ここでは、たった2レコードのデータを使用したサンプルを示しました。もちろん、Xとyにより多次元で多レコードのデータを代入することで、複雑な分類も行うことができます。

また、別のSVMを行う場合は多くの場合、CSVファイルなどにデータを保持しておいて、それをロードしたものをXおよびyに代入するという方法を採用します。

PythonでSVMを使うと、こんなことができるようになる

発展のイメージ

SVMは、かつて郵便番号の手書き数字の画像認識に用いられました。画像認識は高度で、一般には深層学習が用いられる場合が多いですが、数字の画像認識であればSVMのような深層学習以前の手法で可能だったということです。

深層学習以前の手法で可能であれば、よりレコード数が少ないデータセットでも分類が実現できる可能性があります。深層学習は、複雑なモデルを成立させる性質上、非常に多くのデータを要求するからです。少ないデータで分類が実現できるということは、実用的には非常に重要なことです。

他に、迷惑メールの分類をおこなう商品にSVMが利用されている事例もあります。これはメールの中身の文字列に関する情報を説明変数として持っていると推測し、判断できます。

まとめ

さて今回は、SVMの概要と、PythonでSVMを記述する方法について説明しました。

SVMは、超平面という境界を探索するによってクラス分類を行う手法です。

PythonでSVMを実装できるライブラリとしてscikit-learnを挙げました。そして、scikit-learnを用いたサンプルコードを確認しました。学習用データとfit関数によってモデルを作成でき、PythonでSVMを実装することの簡単さを確認できたといえるでしょう。今回示したコードのデータの部分を変更するだけで、さまざまなSVMを作成できます。

PythonのSVMに関するインターネット上の情報は、SVMのメカニズムに関する数学的な難しさや、グラフの書き方のテクニックなど、少し細かいものもあります。ただ、そういった情報によって、SVMの利用に難解な印象が与えられている面もあるでしょう。今回示したコードのように、実装自体は非常に簡単です。

後はさまざまなデータを用いてSVMを作ってみる段階です。皆さんのデータでSVMがどのような結果を示すか、ぜひご自分の目で確かめましょう。

トップへ戻る
タイトルとURLをコピーしました