【初心者】コピペでできるサポートベクタマシン分類

スポンサーリンク
Python




非エンジニアサラリーマンがお届けする、コピペでできる機械学習シリーズのサポートベクタマシン編です。サポートベクタマシンは分類問題と回帰問題をどちらにも対応でき、機械学習のなかで広く使われているモデルです。線形・非線形の分類・回帰など対応できますが、今回は分類問題をみていきましょう。

問題解決にコードは最低限でいいと考えています。コードはコピーして、データ収集や結果の解釈に力を注いで下さい。だれでも、すぐに実践できるようにscikit-learnのデータセットを使います。

また、自身のデータでもすぐにコピペできるように、scikit-learnのデータセットを一旦データフレームにしてから機械学習を実施していきます。

環境構築は、【2020年最新】Anacondaのインストール方法

それでは、やっていきましょう!

必要なライブラリ―をインポート

import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
import warnings
warnings.filterwarnings('ignore')

今回のデータセットはscikit-learnのデータセットにあるcancerを使用します。

データセットを整える

【超重要】はじめてのデータ収集方法

目的変数:ガンが良性(benign:1)悪性(malignant:0)
説明変数:さまざまな検査結果(ここでは詳細は言及しません、ゴメンナサイ)

cancer = load_breast_cancer()       # データセットを "cancer" に格納する

# データセットをデータフレームの形に変換する
df = pd.DataFrame(data=cancer.data, columns=cancer.feature_names)
series1 = pd.Series(data=[cancer.target_names[i] for i in cancer.target], name="cancer")
df = pd.concat([df,series1], axis=1)

mapping = {'malignant': 1, 'benign': 0}      # "malignant" を1に、"benign" を0に変換する
df['cancer'] = df['cancer'].map(mapping)     # その変換をデータフレームに適応させる
df

上のコードはデータフレームにするためのコードです。
cancerのデータセットで実践する場合は上のコードを実行して下さい。
自身のデータを使用する場合は、以下のコードから実行して下さい。

出力:

出力の左下に「569 rows × 31 columns」とあります。

これは、569行と31列の数値があることを意味します。そして、31列目(上の表の右端の列)は「cancer」となっています。これが今回の目的変数(ターゲット)になるガンの有無のデータです。

機械学習がしやすいデータの形に整える

X = df.iloc[:,0:30]  # 1~30列を目的変数として「X」に入れる
y = df.iloc[:,-1]    # 最後の列(31列目)を目的変数として「y」に入れる

つぎに、データを訓練用とテスト用に分割します

# データを訓練用とテスト用に分割する
from sklearn.model_selection import train_test_split, GridSearchCV
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size = 0.25,
    random_state = 1,
    stratify = y)

さらに、説明変数を標準化しておきます。標準化とは、すべての説明変数の数値を平均が0、標準偏差が1にする処理のことです。標準化しておいたほうが、予測精度が高くなりやすいです。

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler().fit(X_train)  # 標準化は訓練データで行う、テストデータは使わない
X_train = scaler.transform(X_train)

標準化するためには、平均値と標準偏差を計算して、データに適合させる。そのため、標準化からが機械学習の開始になるので、必ず訓練データのみで行います。決して、テストデータを使用してはいけません。テストデータは機械学習後のモデルの評価のみにしか使用できません。テストデータを使うと、過剰適合してしまい、新しいデータへの汎用性は下がってしまいます。

サポートベクタマシン分類

from sklearn.svm import SVC

svm = SVC(random_state=1)

param_grid={
    'C':[0.001, 0.01, 0.1, 1, 10, 100],
    'gamma':[0.001, 0.01, 0.1, 1, 10, 100]}

grid_svm=GridSearchCV(svm,
                     param_grid=param_grid,
                     cv=10,
                     n_jobs=-1
                     )


grid_svm.fit(X_train,y_train)

X_test = scaler.transform(X_test)
y_pred = grid_svm.predict(X_test)

出力:
Train accuracy_random_forest: 0.976
{‘C’: 10, ‘gamma’: 0.01}

基本的には、grdi_svm.fitX_train, y_yrain) の一行のみが機械学習の実行です。
最後の行では、モデル(grid_svm)を使って、説明変数のテストデータ(X_test)で、目的変数の予測値を計算(predict)して、y_pred に入れています。

モデル作成に使用した訓練データでは正解率が97.6%です。

【基礎】分類モデルの評価方法

以前行った別の学習モデルと比較してみましょう。

ロジスティック回帰の正解率:97.7%

決定木の正解率:93.7%

ランダムフォレストの正解率:96.0%

XGBoostの正解率:98.6%

悪くはない程度ですね。

(過去の記事を参照してみてください)

【初心者】コピペでできるロジスティック回帰

【初心者】コピペでできる決定木とランダムフォレスト

【初心者】コピペでできるXGBoost

モデルの評価(サポートベクタマシン分類)

from sklearn.metrics import precision_score, recall_score, f1_score, roc_auc_score
print('Test accuracy: %.3f' % grid_svm.best_estimator_.score(X_test, y_test))
print('Precision: %.3f' % precision_score(y_test, y_pred))
print('Recall: %.3f' % recall_score(y_test, y_pred))
print('F1: %.3f' % f1_score(y_test, y_pred))
print('roc_auc: %.3f' % roc_auc_score(y_test, y_pred))

出力:
Test accuracy: 0.972
Precision: 0.967
Recall: 0.989
F1: 0.978
roc_auc: 0.966

結果の見方は、こちらをご覧下さい。

ここでは、一番分かりやす正解率のみをみていきます。テストデータ正解率は97.2%です。テスト用の結果も比較してみましょう。

ロジスティック回帰の正解率:94.4%

決定木の正解率:90.0%

ランダムフォレストの正解率:94.4%

XGBoostの正解率:97.2%

でしたので、テスト用の結果ではXGBoostと並んで、一番正解率が高くなりました。訓練データの正解率は97.6%なので、正解率が大きく変化していません。これは、過学習しておらずモデルが安定しているといえるでしょう。学習不足ともいえますが。

(過去記事)

【初心者】コピペでできるロジスティック回帰

【初心者】コピペでできる決定木とランダムフォレスト

【初心者】コピペでできるXGBoost

もう少し分かりやすく、混同行列をみてみましょう

import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
# テストと予測のデータから混合行列を生成
confmat = confusion_matrix(y_true=y_test, y_pred=y_pred)

fig, ax = plt.subplots(figsize=(3, 3),dpi=200)
# matshow関数で行列からヒートマップを描画
ax.matshow(confmat, cmap=plt.cm.Blues, alpha=0.3)
for i in range(confmat.shape[0]):       # クラス0の繰り返し処理
    for j in range(confmat.shape[1]):   # クラス1の繰り返し処理
        ax.text(x=j, y=i, s=confmat[i, j], va='center', ha='center')  # 件数を表示

plt.xlabel('Predicted label')
plt.ylabel('True label')
plt.tight_layout()
plt.show()

出力:

左上と、右下の塗りつぶしている箇所が、予測が正しかったということなので、そこの数値が大きいほうが良いでと判断できます。

サポートベクタマシン分類のコードは以上です。
Xサポートベクタマシンは、精度の高いモデルです。このコードのコピペである程度の精度がでると思います。









コメント

タイトルとURLをコピーしました