Python の Scikit-Learn を使用して SVM とカーネル SVM を実装する

Python の Scikit-Learn を使用して SVM とカーネル SVM を実装する

概要

このガイドは、サポート ベクター マシン (SVM) に関する XNUMX つのガイドの最初の部分です。 このシリーズでは、偽造紙幣のユース ケースに取り組み、単純な SVM について学び、次に SVM ハイパーパラメーターについて学び、最後に、 カーネルトリック 他のタイプの SVM を調べます。

すべてのガイドを読みたい場合、または最も興味のあるガイドを確認したい場合は、各ガイドで取り上げるトピックの表を以下に示します。

1. Python の Scikit-Learn を使用した SVM およびカーネル SVM の実装

  • ユースケース: 紙幣を忘れる
  • SVMの背景
  • 単純な (線形) SVM モデル
    • データセットについて
    • データセットのインポート
    • データセットの探索
  • Scikit-Learn を使用した SVM の実装
    • トレーニング/テスト セットへのデータの分割
    • モデルのトレーニング
    • 予測する
    • モデルの評価
    • 結果の解釈

2. SVM ハイパーパラメータを理解する (近日公開!)

  • Cハイパーパラメータ
  • ガンマ ハイパーパラメータ

3. Python の Scikit-Learn を使用して他の SVM フレーバーを実装する (近日公開!)

  • SVM の一般的な考え方 (要約)
  • カーネル (トリック) SVM
  • Scikit-Learn を使用した非線形カーネル SVM の実装
  • ライブラリのインポート
    • データセットのインポート
    • データを特徴 (X) とターゲット (y) に分割する
    • トレーニング/テスト セットへのデータの分割
    • アルゴリズムのトレーニング
  • 多項式カーネル
    • 予測する
    • アルゴリズムの評価
  • ガウスカーネル
    • 予測と評価
  • シグモイドカーネル
    • 予測と評価
  • 非線形カーネル性能の比較

ユースケース: 偽造紙幣

紙幣を偽造する方法を見つける人もいます。 そのメモを見て正当性を確認する人がいれば、騙されにくいかもしれません。

しかし、各メモを見る人がいない場合はどうなりますか? 紙幣が偽造か本物かを自動的に判断する方法はありますか?

これらの質問に答える方法はたくさんあります。 XNUMX つの答えは、受け取った各紙幣の写真を撮り、その画像と偽造紙幣の画像を比較してから、本物か偽造かを分類することです。 メモの検証を待つのが面倒であったり重要であったりする場合は、その比較をすばやく行うことも興味深いでしょう。

画像が使用されているため、画像を圧縮したり、グレースケールに縮小したり、測定値を抽出または量子化したりすることができます。 このように、比較は各画像のピクセルではなく、画像の測定値間で行われます。

これまで、紙幣を処理して比較する方法を見つけてきましたが、本物か偽造かはどのように分類されるのでしょうか。 機械学習を使用してその分類を行うことができます。 と呼ばれる分類アルゴリズムがあります。 サポートベクターマシン、主にその省略形で知られています。 SVM.

SVMの背景

SVM は、1968 年に Vladmir Vapnik と Alexey Chervonenkis によって最初に導入されました。 当時、彼らのアルゴリズムは、XNUMX 本の直線だけで分離できるデータ、または分離されたデータの分類に限定されていました。 線形分離可能. その分離がどのように見えるかを見ることができます:

Python の Scikit-Learn PlatoBlockchain Data Intelligence を使用した SVM およびカーネル SVM の実装。垂直検索。あい。

上の画像では、中央に線があり、いくつかの点はその線の左側にあり、他の点はその線の右側にあります。 ポイントの両方のグループが完全に分離されていることに注意してください。ラインの間にポイントはなく、ラインに近いポイントさえありません。 似たような点とそれらを分ける線との間には余白があるようで、その余白と呼ばれる 分離マージン. 分離マージンの機能は、類似点とそれらを分割する線の間のスペースを大きくすることです。 SVM は、いくつかのポイントを使用してこれを行い、その垂直ベクトルを計算して、ラインのマージンの決定をサポートします。 それらは サポートベクター アルゴリズムの名前の一部です。 それらについては後で詳しく説明します。 そして、真ん中に見える直線は、 最大化します 線と点の間のスペース、または分離マージンを最大化します。 これらのメソッドは、 最適化理論.

先ほど見た例では、個々のポイントが類似のポイントに近接しており、XNUMX つのグループが互いに離れているため、ポイントの両方のグループを簡単に分離できます。

しかし、XNUMX 本の直線を使用してデータを分離する方法がない場合はどうなるでしょうか。 場違いなポイントがある場合、またはカーブが必要な場合は?

この問題を解決するために、SVM はその後 1990 年代に改良され、外れ値などの中心傾向から離れた点を持つデータや、XNUMX 次元以上で線形に分離できないより複雑な問題も分類できるようになりました。 .

興味深いのは、SVM が広く採用されるようになったのはごく最近のことです。これは主に、90% 以上の正解または 精度、難しい問題の場合。

SVM は、学習とは何かの統計的説明に基づいているか、または 統計学習理論.

この記事では、サポート ベクター マシンのアルゴリズムとは何か、サポート ベクター マシンの背後にある簡単な理論、および Python の Scikit-Learn ライブラリでのそれらの実装について説明します。 次に、別の SVM の概念に進みます。 カーネル SVMまたは カーネルトリック、また Scikit-Learn の助けを借りて実装します。

単純な (線形) SVM モデル

データセットについて

導入部で示した例に従って、実際の紙幣と偽造紙幣の画像の測定値を持つデータセットを使用します。

XNUMX つのメモを見るとき、私たちの目は通常、それらを左から右にスキャンし、どこに類似点や相違点があるかを確認します。 緑の点の前にある黒の点、またはイラストの上にある光沢のあるマークを探します。 これは、ノートを見る順序があることを意味します。 緑と黒のドットがあることを知っていても、緑のドットが黒の前にある場合、または黒が緑の前にある場合は、音符を区別するのが難しくなります.

銀行券の画像に適用できる、今説明したものと同様の方法があります。 一般的に言えば、この方法は、画像のピクセルを信号に変換し、次に、画像を小さな波に変換することで、画像内で発生する各信号の順序を考慮します。 ウェーブレット. ウェーブレットを取得した後、ある信号が別の信号の前に発生する順序を知る方法があります。 時間、しかし正確にはどの信号かではありません。 それを知るには、画像の周波数を取得する必要があります。 それらは、各信号の分解を行うメソッドによって取得されます。 フーリエ法.

ウェーブレットによって時間次元が取得され、フーリエ法によって周波数次元が取得されると、時間と周波数の重ね合わせが行われ、両方が一致するタイミングが確認されます。 畳み込み 分析。 畳み込みは、ウェーブレットを画像の周波数と一致させる適合を取得し、どの周波数がより顕著であるかを見つけます。

ウェーブレットとその周波数を見つけて、両方をフィッティングするこの方法は、 ウェーブレット変換. ウェーブレット変換には係数があり、それらの係数を使用して、データセットにある測定値を取得しました。

データセットのインポート

このセクションで使用する銀行券データセットは、分類セクションで使用したものと同じです。 決定木チュートリアル.

注: データセットをダウンロードできます こちら.

データをパンダにインポートしましょう dataframe 構造を確認し、最初の XNUMX 行を head() 方法。

データは txt (テキスト) ファイル形式で、カンマで区切られ、ヘッダーなしです。 として読み取ることにより、テーブルとして再構築できます。 csv、を指定します separator コンマとして、列名を names 引数。

これら XNUMX つの手順を一度に実行してから、データの最初の XNUMX 行を見てみましょう。

import pandas as pd data_link = "https://archive.ics.uci.edu/ml/machine-learning-databases/00267/data_banknote_authentication.txt"
col_names = ["variance", "skewness", "curtosis", "entropy", "class"] bankdata = pd.read_csv(data_link, names=col_names, sep=",", header=None)
bankdata.head()

この結果:

	variance skewness curtosis entropy class
0 3.62160 8.6661 -2.8073 -0.44699 0
1 4.54590 8.1674 -2.4586 -1.46210 0
2 3.86600 -2.6383 1.9242 0.10645 0
3 3.45660 9.5228 -4.0112 -3.59440 0
4 0.32924 -4.4552 4.5718 -0.98880 0

注: データをローカルに保存して置き換えることもできます data_link for data_path、ローカル ファイルへのパスを渡します。

データセットには XNUMX つの列があることがわかります。 variance, skewness, curtosis, entropy, class. 3.62160 行の最初の 8.6661 列には、2.8073、XNUMX、-XNUMX、または 連続的な 値、および最後の class 列の最初の 0 行が XNUMX で埋められているか、 個別の の値です。

私たちの目的は銀行紙幣が本物かどうかを予測することなので、紙幣の XNUMX つの属性に基づいてそれを行うことができます。

  • variance ウェーブレット変換された画像の。 通常、分散は、データ ポイントがデータの平均値にどれだけ近いか、またはどれだけ離れているかを測定する連続値です。 ポイントがデータの平均値に近いほど、分布は正規分布に近くなります。これは、通常、その値がより適切に分布し、予測がやや容易であることを意味します。 現在のイメージ コンテキストでは、これはウェーブレット変換の結果として生じる係数の分散です。 分散が小さいほど、係数は実際の画像の変換に近くなります。

  • skewness ウェーブレット変換された画像の。 歪度は、分布の非対称性を示す連続値です。 平均の左側にさらに値がある場合、分布は次のようになります。 負に歪んだ、平均の右側にさらに値がある場合、分布は 正に歪んでいるであり、平均、最頻値、中央値が同じ場合、分布は 対称な. 分布がより対称的であるほど、正規分布に近くなり、その値もより適切に分布します。 現在のコンテキストでは、これはウェーブレット変換の結果として生じる係数の歪度です。 対称性が高いほど、係数が近くなりますvariance, skewness, curtosis, entropy実際の画像を翻訳します。

Python の Scikit-Learn PlatoBlockchain Data Intelligence を使用した SVM およびカーネル SVM の実装。垂直検索。あい。

  • curtosis ウェーブレット変換されたイメージの (または尖度)。 尖度は、歪度と同様に分布の形状を表す連続値です。 尖度係数 (k) に応じて、正規分布と比較した場合、分布は多かれ少なかれ平坦になるか、または端部または尾部に多かれ少なかれデータが含まれます。 分布がより広がり、より平坦な場合、それは呼ばれます 偏狭な; 広がりが少なく、中央に集中している場合、 メソクルティック; そして、分布がほぼ完全に中央に集中しているとき、それは呼び出されます レプトクルティック. これは分散と歪度の前のケースと同じケースで、分布がメソクルティックであるほど、係数は実際の画像の変換に近づきます。

Python の Scikit-Learn PlatoBlockchain Data Intelligence を使用した SVM およびカーネル SVM の実装。垂直検索。あい。

  • entropy 画像の。 エントロピーも連続値であり、通常はシステムのランダム性または無秩序を測定します。 画像のコンテキストでは、エントロピーは、ピクセルとその隣接ピクセルとの差を測定します。 このコンテキストでは、係数のエントロピーが大きいほど、画像を変換するときに損失が大きくなり、エントロピーが小さいほど、情報の損失が小さくなります。

Python の Scikit-Learn PlatoBlockchain Data Intelligence を使用した SVM およびカーネル SVM の実装。垂直検索。あい。

XNUMX 番目の変数は、 class この変数はおそらく 0 と 1 の値を持ち、紙幣が本物か偽造かを示します。

Pandas の XNUMX 列目にゼロと XNUMX が含まれているかどうかを確認できます。 unique() 方法:

bankdata['class'].unique()

上記のメソッドは以下を返します。

array([0, 1]) 

上記のメソッドは、0 と 1 の値を持つ配列を返します。 これは、クラス行に含まれる値は XNUMX と XNUMX だけであることを意味します。 として使用する準備ができています ターゲット 教師あり学習で。

  • class 画像の。 これは整数値で、画像が偽造されている場合は 0、画像が本物の場合は 1 です。

実画像と忘却画像の注釈を含む列があるため、これは、学習のタイプが 監督.

アドバイス: 銀行券の画像に対するウェーブレット変換の背後にある理由と SVM の使用について詳しく知るには、 著者の公開された論文をお読みください。

また、データの行数を shape プロパティ:

bankdata.shape

これは出力します:

(1372, 5)

上記の行は、変換された銀行券の画像が 1,372 行、5 列あることを意味します。 これが私たちが分析するデータです。

データセットをインポートし、いくつかのチェックを行いました。 これで、データを調査して理解を深めることができます。

データセットの探索

クラスの列にはゼロと XNUMX しかないことがわかりましたが、それらがどのような割合であるか、つまり、XNUMX よりも XNUMX の方が多いか、XNUMX よりも XNUMX の方が多いか、またはゼロは XNUMX の数と同じです。 .

比率を知るために、データ内のゼロと XNUMX の値のそれぞれを数えることができます。 value_counts() 方法:

bankdata['class'].value_counts()

これは出力します:

0 762
1 610
Name: class, dtype: int64

上記の結果では、762 個のゼロと 610 個の 152、つまり 5500 よりも 610 個多いゼロがあることがわかります。 これは、実際の画像をもう少し偽造したことを意味します。たとえば、XNUMX 個のゼロと XNUMX 個の XNUMX のように、その差異が大きければ、結果に悪影響を与える可能性があります。 モデルでこれらの例を使用しようとすると、通常、例が多ければ多いほど、モデルが偽造紙幣か本物の紙幣かを判断する必要があることを意味します。実際の紙幣の例がほとんどない場合、モデルは偽造される傾向があります。それらを認識しようとすると間違っています。

さらに 152 の偽造紙幣があることは既にわかっていますが、モデルが学習するのに十分な例であると確信できますか? 学習に必要な例の数を知ることは、答えるのが非常に難しい質問ですが、代わりに、クラス間の違いがどの程度であるかをパーセンテージで理解しようとすることができます.

最初のステップは、パンダを使用することです value_counts() メソッドをもう一度使用しますが、引数を含めてパーセンテージを見てみましょう normalize=True:

bankdata['class'].value_counts(normalize=True)

  normalize=True 各クラスのデータのパーセンテージを計算します。 これまでのところ、偽造 (0) と実際のデータ (1) の割合は次のとおりです。

0 0.555394
1 0.444606
Name: class, dtype: float64

これは、データセットの約 (~) 56% が偽造され、44% が本物であることを意味します。 これにより、56%-44% の比率が得られます。これは、12% の差と同じです。 これは統計的にはわずかな差であると見なされます。これは 10% を少し上回っているため、データはバランスが取れていると見なされます。 56:44 の比率ではなく、80:20 または 70:30 の比率があった場合、データは不均衡であると見なされ、不均衡の処理を行う必要がありますが、幸いなことに、そうではありません。

以下を使用して、Pandas が埋め込まれたヒストグラムでクラスまたはターゲットの分布を調べることにより、この違いを視覚的に確認することもできます。

bankdata['class'].plot.hist();

これは、データフレーム構造を直接使用してヒストグラムをプロットし、 matplotlib 舞台裏にある図書館。

Python の Scikit-Learn PlatoBlockchain Data Intelligence を使用した SVM およびカーネル SVM の実装。垂直検索。あい。

ヒストグラムを見ると、ターゲット値が 0 または 1 のいずれかであり、データが均衡していることを確認できます。

これは予測しようとしていた列の分析でしたが、データの他の列の分析はどうでしょうか?

で統計測定値を見ることができます describe() データフレーム方式。 使用することもできます .T 転置の - 列と行を反転して、値を比較することをより直接的にします。

ベストプラクティス、業界で認められた標準、および含まれているチートシートを含む、Gitを学習するための実践的で実用的なガイドを確認してください。 グーグルGitコマンドを停止し、実際に 学ぶ それ!

bankdata.describe().T

この結果:

 count mean std min 25% 50% 75% max
variance 1372.0 0.433735 2.842763 -7.0421 -1.773000 0.49618 2.821475 6.8248
skewness 1372.0 1.922353 5.869047 -13.7731 -1.708200 2.31965 6.814625 12.9516
curtosis 1372.0 1.397627 4.310030 -5.2861 -1.574975 0.61663 3.179250 17.9274
entropy 1372.0 -1.191657 2.101013 -8.5482 -2.413450 -0.58665 0.394810 2.4495
class 1372.0 0.444606 0.497103 0.0000 0.000000 0.00000 1.000000 1.0000

歪度と尖度の列には、標準偏差値から離れた平均値があることに注意してください。これは、これらの値がデータの中心傾向から離れているか、変動性が大きいことを示しています。

また、各機能のヒストグラムを for ループ内にプロットすることで、各機能の分布を視覚的に確認することもできます。 分布を見るだけでなく、特徴ごとに各クラスのポイントがどのように分かれているかも見てみると面白いでしょう。 そのために、それらの間の特徴の組み合わせを作成する散布図をプロットし、そのクラスに関して各点に異なる色を割り当てることができます。

各特徴の分布から始めて、各データ列のヒストグラムをプロットします。 class カラム。 の class column は、bankdata 列配列内の位置によって考慮されません。 最後の列を除くすべての列が選択されます columns[:-1]:

import matplotlib.pyplot as plt for col in bankdata.columns[:-1]: plt.title(col) bankdata[col].plot.hist() plt.show();

上記のコードを実行すると、両方のことがわかります skewness および entropy データ分布は負に歪んでおり、 curtosis 正に歪んでいます。 すべての分布は対称的であり、 variance 正規分布に近い唯一の分布です。

XNUMX 番目の部分に進み、各変数の散布図をプロットします。 これを行うには、クラスを除くすべての列を選択することもできます。 columns[:-1]、シーボーンズを使用 scatterplot() XNUMX つの for ループは、各機能のペアリングのバリエーションを取得します。 また、最初の機能が XNUMX 番目の機能と等しいかどうかを if statement.

import seaborn as sns for feature_1 in bankdata.columns[:-1]: for feature_2 in bankdata.columns[:-1]: if feature_1 != feature_2: print(feature_1, feature_2) sns.scatterplot(x=feature_1, y=feature_2, data=bankdata, hue='class') plt.show();

すべてのグラフには、互いに明確に分離されていない実際のデータ ポイントと偽造されたデータ ポイントの両方があることに注意してください。これは、ある種のクラスの重ね合わせがあることを意味します。 SVM モデルは線を使用してクラスを分離するため、グラフ内のこれらのグループのいずれかを XNUMX 本の線だけで分離できますか? ありそうもない。 これは、ほとんどの実際のデータがどのように見えるかです。 分離に最も近いのは、 skewness および varianceまたは entropy および variance プロット。 これはおそらく variance より正規に近い分布形状を持つデータ。

しかし、これらすべてのグラフを順番に見るのは少し難しい場合があります。 Seaborn の pairplot().

前に実行した for ループは両方とも、次の行だけで置き換えることができます。

sns.pairplot(bankdata, hue='class');

ペアプロットを見ると、実際には、 curtosis および variance 機能の最も簡単な組み合わせになるため、さまざまなクラスを線で区切ることができます。 線形分離可能.

ほとんどのデータが線形に分離できない場合は、次元を減らすことでデータを前処理し、値を正規化して分布を正規に近づけることができます。

この場合、それ以上の前処理を行わずにデータをそのまま使用してみましょう。後で、XNUMX ステップ前に戻り、データの前処理を追加して結果を比較できます。

アドバイス: データを操作する場合、データをさらに収集するのではなく近似値を作成しているため、通常、データを変換するときに情報が失われます。 可能であれば、最初のデータをそのまま使用して、他の前処理手法を試す前のベースラインを提供します。 このパスをたどると、生データを使用した最初の結果を、データの前処理技術を使用した別の結果と比較できます。

注: 通常、統計学では、モデルを構築するときに、データの種類 (離散、連続、カテゴリ、数値)、その分布、およびモデルの仮定に応じた手順に従うのが一般的です。 コンピューター サイエンス (CS) にいる間は、試行錯誤と新しい反復のためのより多くのスペースがあります。 CS では、比較対象となるベースラインを用意するのが一般的です。 Scikit-learn には、 ダミー モデル (またはダミー推定器) の実装があり、コインを投げるよりも優れていないものもあり、ただ答えるだけです。 はい (または 1) 時間の 50%。 結果を比較する際に、実際のモデルのベースラインとしてダミー モデルを使用するのは興味深いことです。 実際のモデルの結果は、ランダムな推測よりも優れていると予想されます。そうでない場合、機械学習モデルを使用する必要はありません。

Scikit-Learn を使用した SVM の実装

SVM がどのように機能するかの理論に入る前に、データを使用して最初のベースライン モデルを構築し、Scikit-Learn の サポート ベクター分類器 or SVC とに提供されます。

モデルはウェーブレット係数を受け取り、クラスに基づいて分類しようとします。 このプロセスの最初のステップは、係数または 機能を使用 クラスからまたは ターゲット. そのステップの後、XNUMX 番目のステップは、データをモデルの学習に使用されるセットにさらに分割することです。 列車セット モデルの評価に使用される別のもの テストセット.

注: テストと評価の命名法は、データをトレーニング セット、評価セット、テスト セットに分割することもできるため、少し混乱する可能性があります。 このように、XNUMX つのセットを使用する代わりに、中間セットを使用して、モデルのパフォーマンスが向上しているかどうかを確認します。 これは、モデルがトレーニング セットでトレーニングされ、評価セットで強化され、テスト セットで最終的なメトリックが取得されることを意味します。

評価はその中間セットであると言う人もいれば、テスト セットが中間セットであり、評価セットが最終セットであると言う人もいます。 これは、モデルが同じ例をまったく見ていないことを保証しようとする別の方法です。 データ漏洩 発生しておらず、最後に設定されたメトリックの改善によるモデルの一般化があることを示しています。 そのアプローチに従いたい場合は、これで説明されているように、データをさらに分割することができます Scikit-Learn の train_test_split() – トレーニング、テスト、および検証セット ガイド。

トレーニング/テスト セットへのデータの分割

前回のセッションでは、データを理解し、調査しました。 これで、データを XNUMX つの配列に分割できます。XNUMX つは XNUMX つの機能用で、もう XNUMX つは XNUMX 番目の機能、つまりターゲット機能用です。 ウェーブレット係数に応じてクラスを予測したいので、 y になります class 列と私たちの X なります variance, skewness, curtosis, entropy 列。

ターゲットと機能を分離するために、 class 列から y、後でデータフレームからドロップして、残りの列を属性にします X   .drop() 方法:

y = bankdata['class']
X = bankdata.drop('class', axis=1) 

データを属性とラベルに分割したら、さらにトレーニング セットとテスト セットに分割できます。 これは手動で行うこともできますが、 model_selection Scikit-Learn のライブラリには、 train_test_split() データをトレーニングセットとテストセットにランダムに分割できる方法。

それを使用するには、ライブラリをインポートして、 train_test_split() メソッド、渡す X および y データを定義し、 test_size 引数として渡します。 この場合、次のように定義します。 0.20– これは、データの 20% がテストに使用され、残りの 80% がトレーニングに使用されることを意味します。

このメソッドは、定義したパーセンテージに関してランダムにサンプルを取得しますが、サンプリングによって関係が完全に混乱しないように、Xy ペアを尊重します。

サンプリング プロセスは本質的にランダムであるため、メソッドを実行すると常に異なる結果が得られます。 同じ結果または再現可能な結果を​​得るために、SEED という定数を値 42 で定義できます。

これを行うには、次のスクリプトを実行できます。

from sklearn.model_selection import train_test_split SEED = 42 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = SEED)

ていることに注意してください train_test_split() メソッドはすでに X_train, X_test, y_train, y_test この順番で設定します。 の最初の (0) 要素を取得することで、トレーニングとテスト用に分離されたサンプルの数を出力できます。 shape プロパティが返すタプル:

xtrain_samples = X_train.shape[0]
xtest_samples = X_test.shape[0] print(f'There are {xtrain_samples} samples for training and {xtest_samples} samples for testing.')

これは、トレーニング用に 1097 個のサンプル、テスト用に 275 個のサンプルがあることを示しています。

モデルのトレーニング

データをトレーニング セットとテスト セットに分割しました。 次に、トレーニング データで SVM モデルを作成してトレーニングします。 そのために、Scikit-Learn の svm と一緒にライブラリ サポート ベクター分類器 クラス、または SVC とに提供されます。

クラスをインポートした後、そのインスタンスを作成できます。単純な SVM モデルを作成しているため、データを線形に分割しようとしているため、データを分割する線を引くことができます。これは、 一次関数 – 定義することにより kernel='linear' 分類子の引数として:

from sklearn.svm import SVC
svc = SVC(kernel='linear')

このようにして、分類子はデータを分離する線形関数を見つけようとします。 モデルを作成したら、それをトレーニングしましょう、または フィット それは、列車データを使用して、 fit() メソッドと与える X_train 機能と y_train 引数としてのターゲット。

モデルをトレーニングするために、次のコードを実行できます。

svc.fit(X_train, y_train)

ちょうどそのように、モデルは訓練されています。 ここまでで、データを理解し、分割し、単純な SVM モデルを作成し、そのモデルをトレーニング データに適合させました。

次のステップは、適合がデータをどの程度うまく説明できたかを理解することです。 言い換えれば、線形 SVM が適切な選択であったかどうかを答えることです。

予測する

モデルがデータを説明できたかどうかを答える方法は、何らかの分類を計算して調べることです メトリクス.

学習が教師ありであることを考慮すると、予測を行うことができます X_test それらの予測結果を比較します。 y_pred – 実際の y_testまたは グラウンドトゥルース.

一部のデータを予測するために、モデルの predict() 方法を採用することができます。 このメソッドは、テスト機能を受け取ります。 X_test、引数として、それぞれの 0 または 1 の予測を返します X_testの行。

を予測してから X_test 結果は y_pred 変数。 したがって、単純な線形 SVM モデルで予測された各クラスは、現在 y_pred 変数に保存します.

これは予測コードです:

y_pred = svc.predict(X_test)

予測ができたので、実際の結果と比較できます。

モデルの評価

予測を実際の結果と比較する方法はいくつかあり、それらは分類のさまざまな側面を測定します。 最もよく使用される分類指標は次のとおりです。

  1. 混乱マトリックス: どれだけのサンプル数が正解または不正解だったかを知る必要がある場合 各クラス. 正しく、正しく予測された値が呼び出されます 真陽性、陽性として予測されたが陽性ではなかったものは呼び出されます 偽陽性. の同じ命名法 真のネガティブ および 偽陰性 負の値に使用されます。

  2. 精度: 分類器によってどの正しい予測値が正しいと見なされたかを理解することが目的の場合。 精度は、これらの真の陽性値を、陽性と予測されたサンプルで割ります。

$$
精度 = frac{text{真陽性}}{text{真陽性} + text{偽陽性}}
$$

  1. リコール: 通常、分類器によって識別された真陽性の数を理解するために、精度とともに計算されます。 再現率は、真の陽性を、陽性と予測されるはずだったもので割ることによって計算されます。

$$
リコール = frac{text{真陽性}}{text{真陽性} + text{偽陰性}}
$$

  1. F1スコア: バランスの取れたまたは 調和平均 精度と再現率。 最小値は 0 で、最大値は 1 です。 f1-score が 1 の場合、すべてのクラスが正しく予測されたことを意味します。これは、実際のデータで取得するのが非常に難しいスコアです (例外はほとんど常に存在します)。

$$
text{f1-score} = 2* frac{text{precision} * text{recall}}{text{precision} + text{recall}}
$$

混同行列、適合率、再現率、および F1 スコアの尺度については既に説明しました。 それらを計算するには、Scikit-Learn の metrics 図書館。 このライブラリには、 classification_report および confusion_matrix メソッドの場合、分類レポート メソッドは適合率、再現率、および f1 スコアを返します。 両方 classification_report および confusion_matrix これらすべての重要なメトリックの値を見つけるために簡単に使用できます。

メトリクスを計算するために、メソッドをインポートして呼び出し、予測された分類を引数として渡します。 y_test、および分類ラベル、または y_true.

混同行列をよりよく視覚化するために、Seaborn でプロットできます。 heatmap 量の注釈とともに、分類レポートの場合は、その結果を印刷するのが最善です。そのため、結果は書式設定されます。 これは次のコードです。

from sklearn.metrics import classification_report, confusion_matrix cm = confusion_matrix(y_test,y_pred)
sns.heatmap(cm, annot=True, fmt='d').set_title('Confusion matrix of linear SVM') print(classification_report(y_test,y_pred))

これは以下を表示します:

 precision recall f1-score support 0 0.99 0.99 0.99 148 1 0.98 0.98 0.98 127 accuracy 0.99 275 macro avg 0.99 0.99 0.99 275
weighted avg 0.99 0.99 0.99 275

Python の Scikit-Learn PlatoBlockchain Data Intelligence を使用した SVM およびカーネル SVM の実装。垂直検索。あい。

分類レポートでは、精度が 0.99、再現率が 0.99、偽造紙幣またはクラス 1 の f0.99 スコアが 0 であることがわかっています。これらの測定値は、サポート コラムに示されているように 148 のサンプルを使用して取得されました。 一方、クラス 1、つまりリアル ノートの場合、結果は 0.98 単位低く、精度は 0.98、再現率は 1 で、f127 スコアは同じでした。 今回は、これらの結果を得るために XNUMX の画像測定が使用されました。

混同行列を見ると、148 個のクラス 0 サンプルから、146 個が正しく分類され、2 個の偽陽性があったのに対し、127 個のクラス 1 サンプルでは、​​2 個の偽陰性と 125 個の真陽性があったことがわかります。

分類レポートと混同行列を読むことができますが、それらは何を意味するのでしょうか?

結果の解釈

その意味を理解するために、すべての指標を組み合わせて見てみましょう。

クラス 1 のほとんどすべてのサンプルが正しく分類されましたが、実際の銀行券を識別する際にモデルに 2 つの誤りがありました。 これは、0.98 または 98% のリコールと同じです。 クラス 0 についても同様のことが言えます。誤って分類されたのは 2 つのサンプルだけで、148 は真の陰性であり、合計 99% の精度です。

これらの結果に加えて、他のすべての結果は 0.99 をマークしており、これはほぼ 1 であり、非常に高い指標です。 ほとんどの場合、実際のデータでこのような高いメトリックが発生する場合、これはモデルがデータに過度に調整されていることを示している可能性があります。 過剰適合.

オーバーフィットがある場合、モデルは既知のデータを予測するときにうまく機能する可能性がありますが、現実のシナリオで重要な新しいデータに一般化する機能が失われます。

オーバーフィットが発生しているかどうかを確認するための簡単なテストも、トレーニング データを使用して行います。 モデルがトレーニング データをある程度記憶している場合、メトリックは 1 または 100% に非常に近くなります。 学習データはテスト データよりも大きいことに注意してください。このため、オーバーフィットがない限り、サンプル数が多いほど、間違いを犯す可能性が高くなります。

トレーニングデータで予測するには、テストデータに対して行ったことを繰り返すことができますが、今度は X_train:

y_pred_train = svc.predict(X_train) cm_train = confusion_matrix(y_train,y_pred_train)
sns.heatmap(cm_train, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with train data') print(classification_report(y_train,y_pred_train))

これは出力します:

 precision recall f1-score support 0 0.99 0.99 0.99 614 1 0.98 0.99 0.99 483 accuracy 0.99 1097 macro avg 0.99 0.99 0.99 1097
weighted avg 0.99 0.99 0.99 1097

Python の Scikit-Learn PlatoBlockchain Data Intelligence を使用した SVM およびカーネル SVM の実装。垂直検索。あい。

99 倍のデータがあるときにトレーニング メトリクスが 4% になると、オーバーフィットがあるように見えることは簡単にわかります。 このシナリオで何ができるでしょうか?

オーバーフィットを元に戻すには、トレーニングの観測を追加し、次のようなデータセットのさまざまな部分でトレーニングする方法を使用します。 相互検証、また、トレーニングの前に、モデルを作成するときに既に存在するデフォルトのパラメーターを変更するか、または ハイパーパラメータ. ほとんどの場合、Scikit-learn はいくつかのパラメーターをデフォルトとして設定します。これは、ドキュメントを読むための時間があまりない場合に、黙って発生する可能性があります。

このガイドの XNUMX 番目の部分を確認できます (近日公開!) を参照して、クロス検証を実装し、ハイパーパラメーターの調整を実行する方法を確認してください。

まとめ

この記事では、単純な線形カーネル SVM について学習しました。 SVM アルゴリズムの背後にある直感を得て、実際のデータセットを使用し、データを調査し、Python の Scikit-Learn ライブラリを使用して実装することで、このデータを SVM と共に使用する方法を確認しました。

練習を続けるために、次のような場所で利用可能な他の実世界のデータセットを試すことができます Kaggle, UCI, BigQuery の一般公開データセット、大学、および政府の Web サイト。

また、SVM モデルの背後にある実際の数学を調べることもお勧めします。 SVM アルゴリズムを使用するために必ずしも必要というわけではありませんが、アルゴリズムが決定境界を見つけている間、舞台裏で実際に何が起こっているかを知ることは非常に便利です。

タイムスタンプ:

より多くの スタックアバス