サポートベクトルマシン(カーネル法)
ディープラーニングが登場する少し前には、カーネル法を用いたサポートベクトルマシンは大変人気がありました。
サポートベクトルマシンにカーネル法というテクニックを導入することで、複雑なデータに対して人手で特徴量を作らなくとも扱えるようになったためです。もちろん、今もさまざまな分類・回帰の問題に使われるアルゴリズムです。
概要
本節ではサポートベクトルマシンにカーネル法を導入することで、複雑な決定境界を学習できることを説明します。ここでは分類を例にとって説明していますが、回帰にも同様にカーネル法を利用できます。
線形サポートベクトルマシンではマージン最大化により、データからなるべく離れた「良い」決定境界を得ることができます。しかし、決定境界が必ず直線になるため、ラベルごとの境界が曲線になっている図1のようなデータを分類することは苦手です。
図1のようなデータを分離するためには、曲線の線形な決定境界を学習する必要があります。サポートベクトルマシンではカーネル法と呼ばれる手法を用いて、複雑な決定境界を学習できます。例えば、今回のデータに対してカーネル法を用いると、図2のように円形の決定境界を学習できます。
カーネル法については次の「アルゴリズム」で詳しく説明していきます。
アルゴリズム
カーネル法では「データを別の特徴空間に移してから線形回帰を行う」という説明がよくされています。これについてもう少し詳細に触れてみましょう。
まず線形分離可能でないデータを線形分離可能にすることを考えます。これを考えるために、学習データよりも高次元な空間があって、学習データのそれぞれの点はその高次元空間の点に対応していると考えます。高次元空間の中では、学習データに対応する点は線形分離可能であり、実際の学習データはその高次元空間からの射影だと考えます。このような空間が手に入れば、高次元な空間でサポートベクトルマシンを用いて決定境界を学習できるでしょう。最後に、高次元な決定境界を元の特徴量のなすベクトル空間に射影して決定境界を得ます。
もともと線形分離でないデータを高次元空間に移して線形分離している様子をイメージにしたのが次の図3です。
線形分離になる高次元な空間を具体的に構成することは困難ですが、カーネル法ではカーネル関数と呼ばれる関数を利用することで、線形分離になる高次元な空間を具体的に構築することなく、高次元空間で学習した決定境界を利用できます。 カーネル関数については、代表的なものを次の「詳細」で説明します。
サンプルコード
サンプルコードで、カーネル法を用いたサポートベクトルマシンが円形に分布するデータについて、決定境界を学習できることを確かめてみましょう。円形に分布するデータを生成して学習データと検証データに分割し、学習データを用いてモデルを学習させ、検証データで正解率を評価します。コード中で明示的に利用するカーネルを指定していないのは、デフォルトでRBF(Radial Basis Function、放射基底関数)カーネルを利用するためです。
from sklearn.svm import SVC from sklearn.datasets import make_gaussian_quantiles from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # データ生成 X, y = make_gaussian_quantiles(n_features=2, n_classes=2, n_samples=300) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3) model = SVC() model.fit(X_train, y_train) y_pred = model.predict(X_test) accuracy_score(y_pred, y_test)
0.97777777777777775
詳細
カーネル関数による学習結果の違い
カーネル法で利用できるカーネル関数にはさまざまなものが知られています。また、利用するカーネル関数によって得られる決定境界の様子が変わります。ここではサポートベクトルマシンに代表的なカーネル関数である、線形カーネル(a)、シグモイドカーネル(b)、多項カーネル(c)、RBFカーネル(d)を用いて、同じデータに対して学習させた時の様子を示します(図4)。
図4(a)の線形カーネルは線形サポートベクトルマシンと等価です。(b)ではカーネル関数としてシグモイドカーネルを用いています。カーネル関数を変更したことで、曲がった決定境界を学習したことがわかります。また、(c)の多項カーネル(二次)では円形の決定境界を学習しています。(d)のRBFカーネルではより複雑な決定境界を学習している様子がわかります。
注意点
カーネル法を利用すると、サポートベクトルマシンで利用している特徴量が何であるかを明示的に知ることはできなくなります。図5はカーネル関数としてRBFカーネルを利用し、RBFカーネルのハイパーパラメータであるcを3.0としたときのものです。この値は大きくすることで、データからより複雑な決定境界を学習する傾向があります。
図5では複雑な決定境界を学習していますが、特徴量として何を見ているのかはわからなくなっています。カーネル法は図1のように、データが何らかの点を中心に分布している場合に利用すると良いでしょう。また。サンプルコードで学習したようなわかりやすい決定境界が得られるとは限らない点には注意が必要です。
これらの特徴から、サポートベクトルマシンを利用する場合、いきなり非線形なカーネル関数を利用するのではなく、その前に線形カーネルを利用した分析などを行い、データの様子を掴んでからカーネル関数を利用した学習を行うべきでしょう。
k-means法
似たもの同士のデータをクラスタとしてまとめる手法をクラスタリングといいます。
k-means法はクラスタリングの一種であり、その手法の簡潔さからデータ分析において広く利用されています。
概要
k-means法は、代表的なクラスタリングの1つです。手法の理解がしやすく、また比較的大きなデータへも適用が可能なことから、マーケットの分析やコンピュータビジョンなど幅広い分野で利用されています。
k-means法によって、どのようにクラスタリングが行われるのかを見てみましょう。図6は人工のデータセットに対して、k-means法を適用し、各データ点を3つのクラスタに分類したものです。図6(b)においてxで示された点は、各クラスタの重心といい、k-means法によって作成されたクラスタの代表点となっています。
データ点の所属するクラスタは、各クラスタの重心への距離を計算し、最も近いクラスタの重心を求めることで決まります。このクラスタの重心を求めることが、k-means法では重要な計算となっています。
アルゴリズム
k-means法の代表的なアルゴリズムは以下のような手順になっています。
- データ点の中から、適当な点をクラスタ数だけ選び、それらを重心とする
- データ点と各重心の距離を計算し、最も近い重心をそのデータ点の所属するクラスタとする
- クラスタごとにデータ点の平均値を計算し、それを新しい重心とする
- 2と3を繰り返し実行し、すべてデータ点が所属するクラスタが変化しなくなるか、計算ステップ数の上限に達するまで計算を続ける
1.のクラスタ数はハイパーパラメータなので、学習の際に設定する必要があります。データセットによっては、設定するクラスタ数を明確に決めることが難しい場合があるのですが、「詳細」で説明するElbow法などの手法を使うことで、クラスタ数の見当をつけることができます。
また、2、3では、重心の選び方によって、学習がうまく進まない場合があります。これは初期14値として選択した重心同士が近すぎるときなどに発生します。k-means++という手法を利用すると、なるべく離れた重心を初期値として選ばれるため、この問題に対応することができます。
サンプルコード
アヤメデータを利用したk-means法のコードです。クラスタ数は3に設定してあります。
from sklearn.cluster import KMeans from sklearn.datasets import load_iris data = load_iris() n_clusters = 3 # クラスタ数を3に設定 model = KMeans(n_clusters=n_clusters) model.fit(data.data) print(model.labels_) # 各データ点が所属するクラスタ print(model.cluster_centers_) # fit()によって計算された重心
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 2 2 2 2 0 2 2 2 2 2 2 0 0 2 2 2 2 0 2 0 2 0 2 2 0 0 2 2 2 2 2 0 2 2 2 2 0 2 2 2 0 2 2 2 0 2 2 0]
[[5.9016129 2.7483871 4.39354839 1.43387097] [5.006 3.418 1.464 0.244 ] [6.85 3.07368421 5.74210526 2.07105263]]
詳細
クラスタリング結果の評価方法について
前述の「アルゴリズム」でどのように重心を更新していくのかがわかりました。
では、k-means法の評価方法、つまりクラスタリング結果の良し悪しをどのように決めるかを説明していきます。図8では、同一のデータセットに対してk-means法を実行しました。
図8(a)の方がクラスタごとの領域がはっきり分かれているので、うまく分割ができているような印象を受けます。ですが、グラフの印象から分析結果の良し悪しを決めるというのは、定性的な判断になってしまいます。また、高次元空間のデータでは、そもそも可視化自体が難しい場合もあります。クラスタリングの良さに関する何らかの定量的な基準が必要です。
クラスタリング結果の良し悪しは、クラスタ内平方和(Within-Cluster Sum of Squares:WCSS)を計算することで、定量的に評価することができます(このWCSSはクラスタ数を増やすほど、小さくなるので、同じクラスタ数での比較の場合に利用できます)。
WCSSは、すべてのクラスタについて、所属するデータ点とクラスタ重心の距離の平方和を計算し、それらについて和をとったもので、この値が小さいほど、良いクラスタリングということがいえます。
クラスタ重心と所属するデータ点との距離が小さいほど、つまり、データ点がクラスタ重心近くに凝集しているクラスタリングほど、WCSSは小さくなります。
図8(a)のWCSSは、50.1、図8(b)のWCSSは、124.5となっているため、左図の方がうまくクラスタリングができていると判断することができます。
Elbow法を用いたクラスタ数の決定方法について
k-means法ではクラスタ数をハイパーパラメータとして最初に与えますが、クラスタ数をいくつにするべきかが明らかではないことがあります。妥当なクラスタ数を決定するための手法の1つがElbow法です。クラスタ数を増やしていくとWCSSが減少していくことは先ほど説明しましたが、このWCSSの減少が、あるクラスタ数からゆるやかになっていくことがあります。
図9では、クラスタ数が3のときまでWCSSが大きく減少していきますが、クラスタ数が4,5,...と増えていくにつれ、WCSSの減少がゆるやかになっているのがわかります。Elbow法では、グラフ内で腕を曲げた肘のように見える点を目安にクラスタ数を決めます。この場合はクラスタ数を3と定めるのが良いようです。
Elbow法は、クラスタ数を決める強い理由がないときや、データに対する知見が少ないときに役に立ちます。一方で、実際の分析では図のような"肘"が明確に現れないこともよくあることですので、あくまで"目安として利用する"くらいに考えておくとよいでしょう。