機械学習実践チュートリアル(11):サポートベクターマシンSVM

SVMとは何ですか?

VM の正式な英語名は Support Vector Machines で、私たちはこれをサポート ベクター マシンと呼びます。サポート ベクター マシンは、分類に使用するアルゴリズムです。短編小説の形で SVM の旅を始めましょう。

昔のバレンタインデー、恋人を助けに行った英雄だったが、空の悪魔が主人公を相手にゲームをした。

悪魔はテーブルの上に 2 色のボールを定期的に置いているようで、「棒を使ってそれらを分離しますか? 要件: さらにボールを置いた後もそれを適用するようにしてください。」 そこで、主人公はボールをこのように置きました。よくやった
ここに画像の説明を挿入します
?
ここに画像の説明を挿入します
それから悪魔はさらに多くのボールをテーブルの上に置きましたが、1 つのボールが間違った側にあるように見えました。明らかに、主人公はスティックを調整する必要があります。
ここに画像の説明を挿入します
SVM は、スティックの両側にできるだけ多くのスペースができるように、スティックを最適な位置に配置しようとします。このギャップがボールからスティックまでの距離です。
ここに画像の説明を挿入します
さて、たとえデビルズがより多くのボールを置いたとしても、スティックは依然として良い境界線です。
ここに画像の説明を挿入します
さて、主人公は 2 種類のボールを分けるのに役立つ棒を持っていません。どうすればよいでしょうか? もちろん、他の格闘技映画と同様に、主人公がテーブルを叩き、ボールが空中に飛びます。そして、主人公の軽さを頼りに、主人公は一枚の紙を掴み、二種類のボールの間に差し込みました。
ここに画像の説明を挿入します
さて、空中の悪魔の視点からこれらのボールを見ると、これらのボールは曲線で区切られているように見えます。
ここに画像の説明を挿入します
その後、退屈な大人たちはこれらのボールをデータと呼び、スティック分類器、最適化と呼ばれる最大のギャップを見つけるトリック、カーネリングと呼ばれるテーブルを叩く、そして超平面と呼ばれる紙切れと呼びました。

概要を説明すると、次のようになります。

分類問題であり、データが線形分離可能な場合、つまり 2 種類のボールをスティックで分離できる場合、ボールとスティックの間の距離が最大になる位置にスティックを配置するだけで済みます。この最大間隔を見つけるプロセスは、最適化と呼ばれます。しかし、現実は非常に残酷な場合が多く、一般にデータは線形分離不可能、つまり 2 種類のボールを適切に分類できる棒は存在しません。このとき、私たちはヒーローのようにボールを拾い、棒の代わりに紙を使ってボールを分類する必要があります。データを飛ばすために必要なのはカーネル関数 (カーネル)であり、ボールを切るために使用される紙は超平面です。

数学的モデリング

サポート ベクター マシン (SVM) は教師あり学習に基づくデータの一般化線形分類の一種であり、その決定境界は学習サンプルを解く最大マージン超平面です。SVM はカーネル関数を通じて非線形分類を実行でき、一般的なカーネル学習方法の 1 つです。

サポート ベクター マシン (サポート ベクター マシン) は、サンプルをセグメント化するための超平面を見つけます。セグメント化の原理は、間隔を最大化し、最終的に凸二次計画問題に変換して解決することです。線形分離可能性と線形不可能性の両方を解決でき、分類問題と回帰問題の両方を解決できます。

間隔を最大化する

トレーニング サンプルが線形分離可能な場合はハード マージン最大化 (ハード マージン SVM) を使用し、ほぼ線形分離可能な場合はソフトウェア最大化 (ソフト マージン SVM) を使用します。カーネル関数とソフト マージンの最大化は、トレーニング サンプルが線形分離できない場合に使用されます。
ここに画像の説明を挿入します
実際の問題では、決定境界が一意ではない状況がよくありますが、これは不適切な問題です。トレーニング サンプル セット
D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( xm , ym ) } , yi ∈ { − 1 , 1 } D = \{(x_{1}) の場合, y_{1}), (x_{2}, y_{2}), \dots , (x_{m}, y_{m})\}, y_{i} \in \{-1, 1\}D={( x1y1( ×2y2( ×メートルyメートル)} y私は{ 1 1 }分類アルゴリズムの基本的な考え方は、トレーニング セットに基づいてサンプル空間内で分割超平面を見つけることですが、トレーニング サンプルを分離できる分割超平面は多数存在する可能性があります。見つけるには?
ここに画像の説明を挿入します
svm によって検出される直線は、モデルの汎化能力を確保するために、決定境界から最も近い赤い点と青い点からできるだけ遠くにあることが望まれます。SVM は、2 つのカテゴリの最も近いサンプルから最も遠い最適な決定境界を見つけようとします。図内の 3 つの点は、決定境界から同じ距離にあります。これら 3 つの点はサポート ベクターと呼ばれます。判定境界に平行な2直線間の距離がマージンであり、SVMではマージンを最大化するため、この問題を最適化問題に変換します。

最適化問題

分類区間の式

Svm はマージンを最大化します (マージン = 2d)。これは d を最大化することに対応します。つまり、点から直線までの距離が最大になります。解析幾何学で 2 次元空間内の点(x, y) (x,y)を思い出してください。( x ,y )を直線A x + B y + C = 0 Ax+By+C=0×+によって_+C=0の距離の公式: ∣ A x + B y + C ∣ A 2 + B 2 \frac{\mid Ax+By+C \mid} {\sqrt{A^2+B^2}}2 +B2 A x + B y + C
これを n 次元θ T ⋅ xb = 0 \theta^T \cdot x_{b}=0に拡張します。Tバツb=0
其中 θ \theta θ には切片と係数xb x_bバツbちょうどxx年に定数 1 の行をxサンプルに追加します。これは前の線形回帰と同じです。

切片を取るとw T x + b = 0 w^Tx + b = 0wT ×+b=その中のw
は、サンプル内の各データに重みを割り当てることです。これらは、直線の方程式を表現する 2 つの異なる方法です。次に、新しい点から線までの距離方程式を取得できます:
∣ w T x + b ∣ ∥ w ∥ \frac{\mid w^Tx + b \mid}{\Parallel w \Parallel}_wT x+b,その中∥ w ∥ = w 1 2 + w 2 2 + ⋯ + wn 2 \Parallel w \Parallel = \sqrt {w_{1}^2 + w_{2}^2 + \dots + w_{n}^2 }w∥=w12+w22++wn2

制限

目的関数の数学的形式を取得することに成功したようです。ただし、w の最大値を見つけるには。私たちは次のような問題に直面しなければなりません。

  1. 超平面がサンプル点を正しく分類しているかどうかをどのように判断すればよいでしょうか?
  2. 距離 d の最大値が必要であることはわかっています。まずサポート ベクトル上の点を見つける必要があります。多数の点の中からサポート ベクトル上の点を選択するにはどうすればよいでしょうか?
    上記で直面する必要がある問題は制約条件です。これは、最適化する変数 d の値の範囲が制限され、制約されていることを意味します。実際、最適化問題において常に制約が最も厄介なものでした。
    しかし、これらの制約が存在することがわかったので、それらを説明するには数学的言語を使用する必要があります。ここに図の説明を挿入してください。ただし、SVM アルゴリズムはいくつかの巧妙なトリックを使用して、これらの制約を不等式に統合します。

この 2 次元平面上には 2 種類の点があり、それぞれにマークを付けます。

赤い点は 1 としてマークされ、これを陽性サンプルとして人為的に指定し、
青い五芒星は -1 としてマークされ、これを人為的に陰性サンプルとして指定します。
カテゴリ ラベル yi を各サンプル ポイント xi に追加します。
ここに画像の説明を挿入します

スキル
中央の直線は決定境界ですw T x + b = 0 w^Tx+b=0wT ×+b=0であり、上と下の直線は距離が d より大きくなければならないことを意味するため、
{ w T x ( i ) + b ∥ w ∥ ≥ d ∀ y ( i ) = 1 w T x ( i ) + b ∥ w ∥ ≤ − d ∀ y ( i ) = − 1 \begin {cases} \frac{w^Tx^{(i)} + b} {\Parallel w \Parallel} \geq d \qquad \forall y^{ (i)} = 1 \\ \frac{w^Tx^{(i)} + b}{\Parallel w \Parallel} \leq -d \qquad \forall y^{(i)} = -1 \\ \end {件}{ _wT ×( i ) +bd∀y _()=1_wT ×( i ) +bd∀y _()= 1
このとき、2種類のサンプルがそれぞれ1と-1であるとする。次に、上記の式の左辺と右辺を同時に d で割って、
{ w T x ( i ) + b ∥ w ∥ d ≥ 1 ∀ y ( i ) = 1 w T x ( i ) + b を取得します。 ∥ w ∥ d ≤ − 1 ∀ y ( i ) = − 1 \begin {cases} \frac{w^Tx^{(i)} + b} {\Parallel w \Parallel d} \geq 1 \qquad \forall y^{(i )} = 1 \\ \frac{w^Tx^{(i)} + b}{\平行 w \平行 d} \leq -1 \qquad \forall y^{(i)} = -1 \\ \ 終了 {件}{ w dwT ×( i ) +b1∀y _()=1w dwT ×( i ) +b1∀y _()= 1

ここで、 |w| と d は両方ともスカラーです (制限値の計算には影響しません) このとき、分母は削除され、 {
w T x ( i ) + b ≥ 1 ∀ y ( i ) = 1 w T x ( i ) + b ≤ − 1 ∀ y ( i ) = − 1 \begin {cases} {w^Tx^{(i)} + b} \geq 1 \qquad \forall y^{(i)} = 1 \\ {w^ Tx^{(i)} + b} \leq -1 \qquad \forall y^{(i)} = -1 \\ \end {ケース}{ wT ×()+b1∀y _()=1wT ×()+b1∀y _()= 1
この時点で 2 つの方程式が得られますが、ちょっとしたトリックを使用して 2 つの方程式を 1 つにマージします。
yi ( w T x ( i ) + b ) ≥ 1 \boxed {y_{i} (w^Tx^{(i)} + b) \geq 1}y私は( wT ×()+b )1

目的関数の最大化

ここで私たちの考えをまとめると、目的関数が得られます:
max ∣ w T x + b ∣ ∥ w ∥ max \frac{\mid w^Tx +b \mid}{\Parallel w \Parallel}×_wT x+b
私たちの最適化目標は、d を最大化することです。d の最大化問題を解くためにサポート ベクター上のサンプル ポイントを使用することはすでに述べました。では、サポート ベクター上のサンプル ポイントの特徴は何でしょうか?
∣ w T x + b ∣ = 1 |w^Tx+b|=1wT ×+b =1したがって、
これはmax 1 ∥ w ∥ max \frac{1}{\Parallel w \Parallel} を×_1つまり、min ∥ w ∥ min\Parallel w \Parallelを最小化します。w∥しかし、
多くの場合、導出の便宜上、min 1 2 ∥ w ∥ 2 \boxed{min\frac{1}{2} \Parallel w \Parallel^2}21w2
ただし、これは制約付きの最適化問題であり、s . t . yi ( w T x ( i ) + b ) ≥ 1 , i = 1 , 2 , … , m st \quad y_{i} (w ^Tx^{(i)} + b) \geq 1, \quad i=1,2,\dots,ms y私は( wT ×()+b )1 =1 2 ここで、m
はサンプル ポイントの総数であり、略語 st は「Subject to」を意味し、「特定の条件に従う」ことを意味します。上の式は、不等式制約の下での典型的な 2 次関数の最適化問題を記述しており、サポート ベクター マシンの基本的な数学モデルでもあります。
制約のある最適化問題を解くには、ラグランジュ乗数法を使用して双対問題を取得する必要があります。次に問題の関数:
L ( w , b , α ) = 1 2 ∥ w ∥ 2 + ∑ i = 1 m α i ( 1 − yi ( w T xi + b ) ) \boxed{L(w, b, \ alpha) = \frac{1}{2} \Parallel w \Parallel^2 + \sum_{i=1}^m \alpha_{i} (1-y_{i}(w^Tx_{i}+b) )}L ( w ,b _=21w2+i = 1メートルある私は( 1y私は( wT ×私は+b ))

ここで、α i \alpha_iある私はそれはラグランジュ乗数です。これはハード マージン SVM です。

ソフトマージンとSVM正則化

実際の適用中に青い点が赤い点の近くに現れる場合、つまり 2 つのカテゴリは比較的近いが、青い点との全体的な違いが明らかな場合、それは特別な点または間違った特異点と見なすことができます。は誤解を招き、最終的なハード マージン分類境界が直線 1 になります。現時点では、モデルの汎化能力には疑問があります。通常、非常に特殊な青い点は、直線 2 のように無視して、ほとんどのデータが直線から最も遠ざかるようにする必要がありますが、おそらくこれが最良の分類境界であり、一般化能力が高いことを意味します。これは、モデルの精度が高すぎる場合、モデルの過剰適合につながる可能性があることを間接的に説明することもできます。

ここに画像の説明を挿入します
より一般的な例としては、青い点が赤い点に混合されると、データ セットが線形分離不可能になります。2 つのカテゴリを分離できる直線はありません。この場合、ハード マージンもはや汎化能力が強いかどうかの問題ではなく、両者を分ける直線はないということです。
ここに画像の説明を挿入します
したがって、上記の 2 つの状況をどの角度から始めるにしても、svm モデルに部分的なフォールト トレランスを与えることを検討する必要があります。これはソフトマージン SVM につながります。
min 1 2 ∥ w ∥ 2 , s . t . yi ( w T x ( i ) + b ) ≥ 1 − ξ i , ξ i > 0 , i = 1 , 2 , … , m min\frac{1}{ 2} \Parallel w \Parallel^2, \quad st \quad y_{i} (w^Tx^{(i)} + b) \geq 1 - \zeta_{i}, \\ \quad \zeta_{i } >0、\quad i=1,2,\dots,m21w2s y私は( wT ×()+b )1g私はg私は>0 =1 2 Hard Margin SVM と比較してm は
条件を緩和することに相当し、グラフから直感的に理解すると上記の直線を点線に緩和することに相当します。さらに、より重要な点はξ i \zeta_{i}g私は固定値ではなく、各サンプルxi x_iに対応します。バツ私はξ i \zeta_{i}を持っていますg私はただし、このξ i \zeta_{i}については、g私は一定の制限も必要ですが、この条件が無期限に緩和されるわけではありません。つまり、このフォールト トレランス スペースは大きすぎてはいけないため、制限する必要があります。
ここに画像の説明を挿入します
L1 通常
min ( 1 2 ∥ w ∥ 2 + C ∑ i = 1 m ζ i ) 、 s . t . yi ( w T x ( i ) + b ) ≥ 1 − ζ i 、 ζ i ≥ 0 、 i = 1 , 2 , … , m \boxed { min(\frac{1}{2} \Parallel w \Parallel^2 +C \sum_{i=1}^m \zeta_{i}), \quad st \quad y_ {i} (w^Tx^{(i)} + b) \geq 1 - \zeta_{i}, \\ \qquad \qquad \qquad \qquad \zeta_{i} \geq 0, \quad i=1 ,2,\ドット,m }21w2+ Ci = 1メートルg私はs y私は( wT ×()+b )1g私はg私は0 =1 2 メートル
フォールトトレランスと目的関数を重み付けるために新しいハイパーパラメータ C を導入しました。実際、これは、モデルが極端な方向に発展するのを防ぐために、それに L1 正規項を追加したという事実としても理解できます。極端なデータセットや未知のデータに敏感であり、データの一般化能力が優れています。このいわゆる L1 正規は、絶対値を持たないという点で以前の L1 正規とは異なります。これは、単にξ i ≥ 0 \zeta_{i} \geq 0 を制限しているためです。g私は0なので、絶対値を加算しないのが妥当です。C が大きいほどハード マージン SVM に近づき、C が小さいほどフォールト トレランスの余地が大きいことを意味します。svm の正則化と線形回帰の正則化の違いは、C の位置が異なることです。具体的な理由をより深く理解した後、更新します。
次に、次のように L1 規則性があり、それに対応して L2 規則性があります。
min ( 1 2 ∥ w ∥ 2 + C ∑ i = 1 m ζ i 2 ) 、 s . t . yi ( w T x ( i ) + b ) ≥ 1 − ξ i 、 ξ i > 0 、 i = 1 、 2 , … , m \boxed { min(\frac{1}{2} \Parallel w \Parallel^2 +C \sum_{i=1}^m \zeta_{i}^2), \quad st \quad y_{i} (w^Tx^{(i)} + b) \geq 1 - \zeta_{i}, \\ \qquad \qquad \qquad \qquad \zeta_{i} >0, \quad i=1 ,2,\ドット,m }21w2+ Ci = 1メートルg2s y私は( wT ×()+b )1g私はg私は>0 =1 2 メートル

Sklearnのsvm

実際にSVMを使用する場合は、どちらも距離が関係するため、KNNと同様にデータを標準化する必要があります。なぜなら、データのスケールが違いすぎる場合、たとえば下図の横軸が0~1、縦軸が0~10000の場合です。したがって、まず標準化が必要です。

最初のステップは、単純な二値分類データ セットを準備することです。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
"""
load_iris是一个经典的机器学习数据集,它包含了150个样本
这个数据集中的四个特征分别是花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)和花瓣宽度(petal width),
它们都是以厘米(cm)为单位测量的。目标变量是鸢尾花的种类,
有三种不同的种类:Setosa、Versicolour和Virginica。
它们的中文名分别是山鸢尾、杂色鸢尾和维吉尼亚鸢尾。
"""
iris = datasets.load_iris()

x = iris.data
y = iris.target
# 只做一个简单的二分类,获取分类是山鸢尾、杂色鸢尾的数据,同时取2维的特征就行了
x = x[y<2, :2]
y = y[y<2]
#分别绘制出分类是0和1的点,不同的scatter颜色不一样
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

ここに画像の説明を挿入します
svm を実装するには、まず比較的大きな C を使用します。


# 标准化数据
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
#数据归一化
standardscaler = StandardScaler()
standardscaler.fit(x)
x_standard = standardscaler.transform(x)
svc = LinearSVC(C=1e9)
svc.fit(x_standard, y)

def plot_decision_boundary(model, axis):
    x0, x1 = np.meshgrid(np.linspace(axis[0], axis[1], int((axis[1] - axis[0])*100)).reshape(1, -1),
                         np.linspace(axis[2], axis[3], int((axis[3] - axis[2])*100)).reshape(1, -1),)
    x_new = np.c_[x0.ravel(), x1.ravel()]
    y_predict = model.predict(x_new)
    zz = y_predict.reshape(x0.shape)

    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])

    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
    w = model.coef_[0]
    b = model.intercept_[0]
    # w0*x0 + w1*x1 + b = 0
    # x1 = -w0/w1 * x0 - b/w1
    plot_x = np.linspace(axis[0], axis[1], 200)
    up_y = -w[0]/w[1] * plot_x - b/w[1] + 1/w[1]
    down_y = -w[0]/w[1] * plot_x - b/w[1] - 1/w[1]
    
    up_index = (up_y >= axis[2]) & (up_y <= axis[3])
    down_index = (down_y >= axis[2]) & (down_y <= axis[3])
    
    plt.plot(plot_x[up_index], up_y[up_index], color='black')
    plt.plot(plot_x[down_index], down_y[down_index], color='black')
plot_decision_boundary(svc, axis=[-3, 3, -3, 3])
plt.scatter(x_standard[y==0, 0], x_standard[y==0, 1], color='red')
plt.scatter(x_standard[y==1, 0], x_standard[y==1, 1], color='blue')
plt.show()

ここに画像の説明を挿入します
より小さい C を使用し、C のさまざまな値の効果を比較します。

svc2 = LinearSVC(C=0.01)
svc2.fit(x_standard, y)

plot_decision_boundary(svc2, axis=[-3, 3, -3, 3])
plt.scatter(x_standard[y==0, 0], x_standard[y==0, 1], color='red')
plt.scatter(x_standard[y==1, 0], x_standard[y==1, 1], color='blue')
plt.show()

ここに画像の説明を挿入します
2 つの写真を比較すると、C が小さい場合、赤い点が誤って青に分割されていることがわかり、C が小さいほど誤差の余地が大きいことがわかります。

SVM での多項式機能の使用

これまで話してきたのは線形 svm です。svm では非線形問題も解決できます。線形回帰から非線形回帰の考え方と類推して、多項式特徴が最初に使用されます。

まずデータセットを生成します。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets

x, y = datasets.make_moons()
x.shape
# (100, 2)
y.shape
# (100,)
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

ここに画像の説明を挿入します
次に、データにランダム ノイズを追加します。

x, y = datasets.make_moons(noise=0.15, random_state=666)
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

ここに画像の説明を挿入します
多項式、正規化、線形 SVM を使用する

from sklearn.preprocessing import PolynomialFeatures, StandardScaler
from sklearn.svm import LinearSVC
from sklearn.pipeline import Pipeline

def PolynomiaSVC(degree, C=1.0):
    return Pipeline([
        ('poly', PolynomialFeatures(degree=degree)),
        ('std_scale', StandardScaler()),
        ('linear_svc', LinearSVC(C=C))
    ])

poly_svc = PolynomiaSVC(degree=3)
poly_svc.fit(x, y)

def plot_decision_boundary(model, axis):
    x0, x1 = np.meshgrid(np.linspace(axis[0], axis[1], int((axis[1] - axis[0])*100)).reshape(1, -1),
                         np.linspace(axis[2], axis[3], int((axis[3] - axis[2])*100)).reshape(1, -1),)
    x_new = np.c_[x0.ravel(), x1.ravel()]
    y_predict = model.predict(x_new)
    zz = y_predict.reshape(x0.shape)

    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])

    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

plot_decision_boundary(poly_svc, axis=[-1.5, 2.5, -1.0, 1.5])
plt.scatter(x1[y1==0, 0], x1[y1==0, 1])
plt.scatter(x1[y1==1, 0], x1[y1==1, 1])
plt.show()

ここに画像の説明を挿入します
この方法を使用して多項式特徴を追加し、それらを線形 SVC に入力することに加えて、同様の機能を実現する別の方法もあります。


from sklearn.svm import SVC

# 这种方法训练的过程并不完全是先将数据进行标准化,再使用linearSVC这么一个过程
# SVC中默认的C=0
def PolynomiaKernelSVC(degree, C=1.0):
    return Pipeline([
        ('std_scale', StandardScaler()),
        ('kernel_svc', SVC(kernel='poly', degree=degree, C=C))
    ])

poly_kernel_svc = PolynomiaKernelSVC(degree=3)
poly_kernel_svc.fit(x1, y1)
# Pipeline(memory=None,
#     steps=[('std_scale', StandardScaler(copy=True, with_mean=True, with_std=True)),
#  ('kernel_svc', SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
#   decision_function_shape='ovr', degree=3, gamma='auto_deprecated',
#   kernel='poly', max_iter=-1, probability=False, random_state=None,
#   shrinking=True, tol=0.001, verbose=False))])

plot_decision_boundary(poly_kernel_svc, axis=[-1.5, 2.5, -1.0, 1.5])
plt.scatter(x1[y1==0, 0], x1[y1==0, 1])
plt.scatter(x1[y1==1, 0], x1[y1==1, 1])
plt.show()

ここに画像の説明を挿入します
このメソッドは svm のカーネル関数です。次に、カーネル機能について詳しく説明する。

カーネル関数とは

実際のタスクでは、元のサンプル空間に 2 つのカテゴリを正しく分割できる超平面が存在しない場合があります。このような問題に対しては、サンプルを元の空間から高次元の特徴空間にマッピングして、サンプルがこの空間に収まるようにすることができます。特徴空間内部的に線形分離可能。したがって、カーネル関数の役割は、本来線形分離不可能なデータを線形分離可能にすることです。以下は、多項式カーネル マッピングを使用する手順です。
ここに画像の説明を挿入します
以下の関数に変換するとデータは線形分離可能になります。
ここに画像の説明を挿入します
一般的に使用されるカーネル関数:
1. 線形カーネル: k (xi, xj) = xi T xj + ck(x_{i}, x_{j}) = x_{i}^T x_{j} + ck ( x私はバツj)=バツTバツj+c
2. 多項式カーネル:k (xi, xj) = (xi T xj + c) dk(x_{i}, x_{j}) = (x_{i}^T x_{j} + c)^dk ( x私はバツj)=( ×Tバツj+c )d、 d=1 の場合、線形カーネルに縮退します。
3. ガウス カーネル RBF:k ( xi , xj ) = exp ( − ∥ xi − xj ∥ 2 2 σ 2 ) , σ > 0 k(x_{i}, x_{j}) = exp(-\frac{\平行 x_{i} - x_{j} \平行 ^2}{2\sigma ^2})、\sigma >0k ( x私はバツj)=e x p ( 2P _2×私は×j2p>0はガウス カーネルの帯域幅 RBF カーネルです: 放射基底関数カーネル
4. ラプラシアン カーネル:k ( xi , xj ) = exp ( − ∥ xi − xj ∥ σ ) , σ > 0 k(x_{i}, x_ { j}) = exp(-\frac{\Parallel x_{i} - x_{j} \Parallel}{\sigma}), \sigma > 0k ( x私はバツj)=e x p ( p×私は×j) p>0
5、シグモイド核:k ( xi , xj ) = Tanh ( β xi T xj + θ ) k(x_{i}, x_{j}) = Tanh(\beta x_{i}^T x_{j} + \θ)k ( x私はバツj)=( β x _ _Tバツj+

ガウスカーネル関数

ガウス カーネル関数は、一般的に使用されるカーネル関数であり、通常はサポート ベクター マシン (SVM) などの機械学習アルゴリズムで使用されます。元の空間から高次元の空間にデータをマッピングできるため、本来分離できなかったサンプルを新しい空間で分離できます。

平たく言えば、ガウス カーネル関数は 2 つのサンプル間の類似性を計算できる「類似性測定」のようなものです。ガウス カーネル関数を使用する場合、最初に中心点を選択し、次に各サンプル点と中心点の間の距離を計算し、その距離を類似性の尺度として使用します。この距離は通常、ガウス分布関数によって重み付けされます。これがガウス カーネル関数の名前の由来です。
より具体的には、ガウス カーネル関数は 2 つのサンプル点xi x_iを変換できます。バツ私はそしてxj x_jバツj高次元空間にマッピングし、新しい空間で内積を計算し、次の式を取得します。
K ( xi , xj ) = exp ⁡ ( − γ ∣ ∣ xi − xj ∣ ∣ 2 ) K(x_i, x_j) = \exp(-\ガンマ ||x_i - x_j||^2)K ( ×私はバツj)=exp ( γ ∣∣ x私はバツj2 )

その中で、γ \ガンマγ はガウス分布の幅を制御するパラメータです。∣ ∣ xi − xj ∣ ∣ 2 ||x_i - x_j||^2∣∣ ×私はバツj2はサンプル点xi x_iバツ私はそしてxj x_jバツj間のユークリッド距離の二乗 γ \ガンマのときγの値が大きい場合、ガウス分布のピーク値は狭くなり、類似性測定では 2 つのサンプル点間の距離により注意が払われますγの値が小さい場合、ガウス分布のピーク値は広くなり、2 つのサンプル点間の全体的な類似性に焦点を当てた類似性測定がより滑らかになります。

全体として、ガウス カーネル関数は、特に非線形分類問題に関しては、多くの機械学習アルゴリズムで使用できる、非常に柔軟で強力な類似性尺度です。

ここに画像の説明を挿入します
ここに画像の説明を挿入します
次に、ガウス カーネル関数マッピングを通じてマッピング プロセス全体をより直感的に理解できます。

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-4, 5, 1)
# array([-4, -3, -2, -1,  0,  1,  2,  3,  4])
y = np.array((x >= -2) & (x <= 2), dtype='int')
# array([0, 0, 1, 1, 1, 1, 1, 0, 0])
plt.scatter(x[y==0], [0] * len(x[y==0]))
plt.scatter(x[y==1], [0] * len(x[y==1]))
plt.show()

ここに画像の説明を挿入します
ガウスカーネル以降

def gaussian(x, l):
    gamma = 1.0
    return np.exp(-gamma *(x-l)**2)

l1, l2 = -1, 1

x_new = np.empty((len(x), 2))
for i,data in enumerate(x):
    x_new[i, 0] = gaussian(data, l1)
    x_new[i, 1] = gaussian(data, l2)

plt.scatter(x_new[y==0, 0], x_new[y==0, 1])
plt.scatter(x_new[y==1, 0], x_new[y==1, 1])
plt.show()

ここに画像の説明を挿入します
実際、実ガウス カーネル関数を実現するプロセスは固定されていませんγ \gammaγですが、各データ点ではγ \gammaγ、半径 gamma = 1.0 を決定すると、
ここに画像の説明を挿入します
次のようになります:g ( x ) = 1 σ 2 π e − 1 2 ( x − µ σ ) g(x)= \frac{1}{\sigma \sqrt{2 \円周率 } } e^{-\frac{1}{2}(\frac{x - \mu}{\sigma})}g ( x )=p午後2時 1e21(px m)
ここで、μ \muμ は関数​​ σ \sigmaσ はグラフ全体の近さの度合いを決定します、σ \sigmaσが小さいほど画像が高くなり、画像が相対的に集中していることを示します。反対のσ \sigmaσが大きいほど、グラフはより分散します。
K ( xi , xj ) = e − γ ∥ xi − xj ∥ 2 K(x_{i},x_{j}) = e^{-\gamma \Parallel x_{i} - x_{j} \Parallel ^2 }K ( ×私はバツj)=eγ x私は×j2
γ \ガンマγが大きいほど、ガウス分布は広くなります。

γ \ガンマγ が小さいほど、ガウス分布は狭くなります。

次に、sklearn でカプセル化されたガウス カーネル関数を使用します。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets

x, y = datasets.make_moons(noise=0.15, random_state=666)

from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline

def RBFKernelSVC(gamma=1.0):
    return Pipeline([
        ('std_scale', StandardScaler()),
        ('svc', SVC(kernel='rbf', gamma=gamma))
    ])

svc = RBFKernelSVC(gamma=1.0)
svc.fit(x, y)

def plot_decision_boundary(model, axis):
    x0, x1 = np.meshgrid(np.linspace(axis[0], axis[1], int((axis[1] - axis[0])*100)).reshape(1, -1),
                         np.linspace(axis[2], axis[3], int((axis[3] - axis[2])*100)).reshape(1, -1),)
    x_new = np.c_[x0.ravel(), x1.ravel()]
    y_predict = model.predict(x_new)
    zz = y_predict.reshape(x0.shape)

    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])

    plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)

plot_decision_boundary(svc, axis=[-1.5, 2.5, -1.0, 1.5])
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

ここに画像の説明を挿入します

svc_gamma100 = RBFKernelSVC(gamma=100)
svc_gamma100.fit(x, y)

plot_decision_boundary(svc_gamma100, axis=[-1.5, 2.5, -1.0, 1.5])
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

ここに画像の説明を挿入します

svc_gamma10 = RBFKernelSVC(gamma=10)
svc_gamma10.fit(x, y)

plot_decision_boundary(svc_gamma10, axis=[-1.5, 2.5, -1.0, 1.5])
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

ここに画像の説明を挿入します

svc_gamma01 = RBFKernelSVC(gamma=0.1)
svc_gamma01.fit(x, y)

plot_decision_boundary(svc_gamma01, axis=[-1.5, 2.5, -1.0, 1.5])
plt.scatter(x[y==0, 0], x[y==0, 1])
plt.scatter(x[y==1, 0], x[y==1, 1])
plt.show()

ここに画像の説明を挿入します
ガンマはモデルの複雑さを調整することに相当し、ガンマが小さいほどモデルの複雑さは低くなり、ガンマが大きいほどモデルの複雑さは高くなります。したがって、ハイパーパラメータ ガンマを調整して、過学習と過小学習のバランスを取る必要があります。

この記事のテキストと例の出典:

  1. https://cuijiahua.com/blog/2017/11/ml_8_svm_1.html
  2. https://zhuanlan.zhihu.com/p/79679104

おすすめ

転載: blog.csdn.net/liaomin416100569/article/details/130483107