Handsonマシン学習Chatper 5-SVM


5. 1. リニアSVM分類

  • SVMの基本的な考え方は,直線状の決定境界を用いてデータを分類することである.
  • SVM分類器は、クラス間で最も広い道路(最高利益)を探す方向で分類する.従って,道路外部により多くの訓練サンプルを追加することは決定境界に影響を及ぼさず,かえって道路境界に位置するサンプルによって完全に決定される.
  • SVMは特性尺度に敏感であり、Scalerを用いて尺度を調整すると良い結果が得られる.
  • 5. 1. 1.ソフト利益分類


  • ハード利益区分
    すべてのサンプルが道路の外部に分類されたときに発生します.データが線形に区分されなければならない条件は必須であり、異常値に敏感な特徴は、利益率の誤りが発生し、普及しにくいことである.


  • ソフト境界分類:道路幅をできるだけ広く保つとともに、境界誤差を適切に調整しなければならない.◇SVMモデルを作成する際には、複数のスーパーパラメータを使用して調整できます.
  • iris = datasets.load_iris()
    X = iris['data'][:,(2,3)]
    y = (iris['target'] == 2).astype(np.float64)
    
    svm_clf = Pipeline([('scaler', StandardScaler()), ('linear_svc', LinearSVC(C=1, loss='hinge'))])
    svm_clf.fit(X, y)
    
    svm_clf.predict([[5.5, 1.7]])
  • HyperパラメータC:数字が高いほど利益が小さくなり、逆にモデルの誇張に伴って利益誤りが増加し、利益誤りが多くなってもCを減らしてモデルを制限する.
  • X, y = make_classification(n_samples=200, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2,random_state=42)
    
    clf_1 = SVC(C=0.1, kernel='linear').fit(X, y)
    clf100 = SVC(C=100, kernel='linear').fit(X, y)
    
    fig, axes = plt.subplots(2, 1, figsize=(10, 15))
    
    axes[0].set_title("Linear kernel with C=0.1", fontsize=18)
    axes[0].scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='cool')
    plot_svc_decision_function(clf_1,ax=axes[0])
    
    axes[1].set_title("Linear kernel with C=100", fontsize=18)
    axes[1].scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='cool')
    plot_svc_decision_function(clf100,ax=axes[1])
  • ソフト利益区分例の使用
    1. LinearSVC(C=1 ,loss="hinge")2.SVC(kernel="linear", C=1):SVCモードではビッグデータの速度が遅く、推奨されません.
    3.SGDClassifier(loss="hinge", alpha=1/(m*c)):リニアSVM分類器を訓練するため、従来の確率傾斜降下法を採用する.LinarSVCほど高速ではありませんが、データ量が多く、特性が多く、メモリにマウントできない場合は空きです.
    参考hinge損失関数?
    仮想マシンの損失関数を使用して、利益の最大から離れたエラー・インスタンスを重み付けした損失
  • 5. 2. 非線形SVM分類

  • 線形に分類できないデータセットに対しては、線形SVM」を使用して複数の特性を追加するなどの特性を線形に区分することはできません.
  • PolynomialFeatures変換器、標準カレンダー、LinearSVC接続パイプライン、非線形データを線形分類器に分類する.
  • X, y = datasets.make_moons(n_samples=100, noise=0.15)
    polynomial_svm_clf = Pipeline([('poly_features', PolynomialFeatures(degree=3)), ('scaler', StandardScaler()), ('svm_clf', LinearSVC(C=10, loss='hinge'))])
    polynomial_svm_clf.fit(X, y)

    5. 2. 1多項式カーネル

  • 多項式特性を追加すると、低次多項式では複雑なデータセットをうまく表現できず、高次多項式の特性が多くなり、モデルが遅くなる.
  • kernel='poly':SVMに対応可能なカーネルは、実際には特性を追加しないが、多数の多項式特性が追加されているのと同じ結果となり、実際には特性が追加されないため、多くの特性の組み合わせが発生しない.
  • coef0:多項式カーネルの定数項r.多項式カーネルの次元数が高いほど、1未満の値と1以上の値の差が大きくなるため、coef 0を適切な値として指定すると、高次項の影響を低減できます.
  • X, y = datasets.make_moons(n_samples=100, noise=0.15)
    
    poly_kernel_svm_clf = Pipeline([
        ('scaler', StandardScaler()), 
        ('svm_clf', SVC(C=5, kernel='poly', degree=3, coef0=1))
    ])
    poly_kernel_svm_clf.fit(X, y)
    
    poly100_kernel_svm_clf = Pipeline([
        ('scaler', StandardScaler()), 
        ('svm_clf', SVC(C=5, kernel='poly', degree=10, coef0=100))
    ])
    poly100_kernel_svm_clf.fit(X, y)
    
    plt.figure(figsize=(11,4))
    
    plt.subplot(121)
    plot_predictions(poly_kernel_svm_clf, [-1.5, 2.5, -1, 1.5])
    plot_dataset(X, y, [-1.5, 2.5, -1, 1.5])
    plt.title(r'd = 3, r = 1, C = 5',fontsize=18)
    
    plt.subplot(122)
    plot_predictions(poly100_kernel_svm_clf, [-1.5, 2.5, -1, 1.5])
    plot_dataset(X, y, [-1.5, 2.5, -1, 1.5])
    plt.title(r'd = 10, r = 100, C = 5',fontsize=18)

    5. 2. 2.類似度特性

  • 非線形特性を扱うために、各サンプルが特定のランドマークとどれだけ類似しているかを測定する類似度関数で計算した特性を追加する.
    Example
    1 Dデータセットに2つのランドマークがあります𝑥₁=-2わあ𝑥₁=1を追加した後𝛾 = 0.3のGauss放射基底関数(Radical Basis Function,RBF)も定義されている場合、Gauss RBF関数は以下のように定義される.

    この関数の値は0から1に変化し、時計形をします.
    𝑥8321=-1の場合、この例は1番目のランドマークからわずか1、2番目のランドマークからわずか2です.したがって、新しく作成されたプロパティ𝑥₂ = exp(-0.3 × 1²) ≒0.74 W𝑥₃ = exp(-0.3 × 2²) ≈0.30.高西安RBFの類似度特性を用いて以下のように図表化した.

  • 5. 2. 3.高西安RBFコア

  • kernel='rbf':SVMに適したカーネルであり、類似度特性が多数追加された類似の結果が得られる
  • gamma:gammaが増加した場合、上記高西安RBFの類似度特性を用いた時計パターンが狭くなり、各サンプルの影響範囲が減少し、Cと同様に制限作用を果たし、モデルが大きすぎると減少し、逆に増加すべきである.
  • gamma_lst = [0.1, 0.1, 5, 5]
    C_lst = [0.001, 1000, 0.001, 1000]
    
    for g, c in zip(gamma_lst, C_lst):
        rbf_kernel_svm_clf = Pipeline([
            ("scaler", StandardScaler()),
            ("svm_clf", SVC(kernel="rbf", gamma=g, C=c))
        ])
    
        rbf_kernel_svm_clf.fit(X, y)
        mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
        mglearn.plots.plot_2d_separator(rbf_kernel_svm_clf, X)
        plt.title('gamma : {}, C : {}'.format(g, c))
        plt.show()

    5. 2. 4.計算の複雑さ


    LinearSVC Pythonクラスはカーネルをサポートしていないが,訓練サンプルと特性数ではほぼ線形成長を示す線形SVMに対する最適化アルゴリズムを実現した.このとき,このアルゴリズムの訓練時間の複雑さはO(m,n)であり,他の類似アルゴリズムの特徴と比較すると以下のようになる.

    5. 3. VM回帰

  • SVMアルゴリズムはマルチターゲットで使用可能であり、線形・非線形分類のみならず線形・非線形回帰にも使用可能・SVMを回帰ではなく分類に適用するためには、目標を逆方向に設定する必要がある.
  • 既存のSVM分類:一定の利潤率が間違っている場合、両クラス間の道路幅を最大にする.
  • SVM回帰:限られた利益誤差内でできるだけ多くのサンプルを学習して道路に入る
  • epsilon:境界幅のパラメータを調整し、境界内にトレーニングサンプルを追加してもモデルの予測に影響はなく、このときモデルをepsilonに敏感ではないと表現する.
  • np.random.seed(42)
    m = 100
    X = 2 * np.random.rand(m, 1) - 1
    y = (0.2 + 0.1 * X + 0.5 * X**2 + np.random.randn(m, 1)/10).ravel()
    
    svm_poly_reg1 = SVR(kernel="poly", degree=2, C=100, epsilon=0.1)
    svm_poly_reg1.fit(X, y)
    
    svm_poly_reg2 = SVR(kernel="poly", degree=2, C=0.01, epsilon=0.1)
    svm_poly_reg2.fit(X, y)
    
    plt.figure(figsize=(12,4))
    
    plt.subplot(121)
    plot_svm_regression(svm_poly_reg1, X, y, [-1, 1, 0, 1])
    plt.title(r"$degree={}, C={}, \epsilon = {}$".format(svm_poly_reg1.degree, svm_poly_reg1.C, svm_poly_reg1.epsilon), fontsize=18)
    plt.ylabel(r"$y$", fontsize=18, rotation=0)
    
    plt.subplot(122)
    plot_svm_regression(svm_poly_reg2, X, y, [-1, 1, 0, 1])
    plt.title(r"$degree={}, C={}, \epsilon = {}$".format(svm_poly_reg2.degree, svm_poly_reg2.C, svm_poly_reg2.epsilon), fontsize=18)
    
    plt.show()

    制限が多ければ多いほど、利益が高くなります.