LoginSignup
4
2

More than 5 years have passed since last update.

optuna×svmでwine_quality

Last updated at Posted at 2019-02-26

はじめに

xgboostの性能評価のため、
前回の実験との比較実験として、アルゴリズムをSVMに切り替えてやってみた.
結果、制度は出なかった.
XGBoostよりやや精度が低いが、大差ない.

実行環境

  • python 3.6.5
  • XGBoost 0.81
  • optuna 0.7.0

実装

方針

  1. SVMだけ
  2. optuna使う

ライブラリ

import matplotlib.pyplot as plt
import pandas as pd
import optuna
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC

方針1(SVMのみ)

前処置

データは1599個あるので、そのうちの1割をランダムにテストデータとして使う.
また、説明変数は正規化する(X_~_std)

def preprocess(df):
    X = df.drop(target_column,axis=1)
    y = df[target_column]
    X_train, X_test, y_train, y_test = train_test_split(X, y,test_size = 0.1, random_state = 666)
    sc = StandardScaler()
    sc.fit(X_train)
    X_train_std = sc.transform(X_train)
    X_test_std = sc.transform(X_test)
    return X_train_std, X_test_std, y_train, y_test

main関数

main.py
def main():
    global target_column
    df = pd.read_csv("winequality-red.csv")
    X_train_std, X_test_std, y_train, y_test = preprocess(df)

    params = {
        'kernel': 'rbf',
        'C': 5,
        'gamma': 0.1,
    }

    mdl = SVC(**params)
    mdl.fit(X_train_std, y_train)

    pred_train = mdl.predict(X_train_std)
    accuracy_train = accuracy_score(y_train, pred_train)
    pred_test = mdl.predict(X_test_std)
    accuracy_test = accuracy_score(y_test, pred_test)
    print('train score :',accuracy_train)
    print('test score :',accuracy_test)

target_columnはqualityです.
ハイパーパラメータは

  • kernel = rbf
  • C = 5
  • gamma = 0.1

それ以下のコードは学習データ、テストデータに対して評価しているだけ.

方針2(+optuna)

optunaで自動チューニングする時に必要なのが、

  • 目的関数を最適化するobjective()関数
  • objecitveの準備と実行(main関数内)

    objective()

    def objective(X_train_std, X_test_std, y_train, y_test, trial):
    #目的関数
    params = {
        'kernel': trial.suggest_categorical('kernel', ['linear','rbf','sigmoid']),
        'C': trial.suggest_loguniform('C', 1e+0, 1e+2/2),
        'gamma': trial.suggest_loguniform('gamma', 1e-3, 3.0),
    }
    mdl = SVC(**params)
    mdl.fit(X_train_std, y_train)
    pred_test = mdl.predict(X_test_std)
    accuracy_test = accuracy_score(y_test, pred_test)
    return 1.0 - accuracy_test
    

    objevtiveの目的変数(ハイパーパラメータ)の範囲は

  • kernel = linear, rbf, sigmoid

  • C = 1 ~ 50

  • gamma = 0.001 ~ 3.0

main()(追加分)

main.py
    #objective()に与える変数
    obj_f = partial(objective, X_train_std, X_test_std, y_train, y_test)
    #セッション作成
    study = optuna.create_study()
    #回数
    study.optimize(obj_f, n_trials=100)

これをmdl = SVC()の前に入れると、自動チューニングができる.
SVC()の引数はpramsからstudy.best_params(チューニングしたパラメータの値)に変更すること.

実行結果

結果1(SVMのみ)

kernel C gamma
rbf 5 0.1
train score test score
0.6692147324530924 0.61875

結果2(+optuna)

kernel C gamma
rbf 24.258778854648092 0.777764797855619
train score test score
0.9986101459346769 0.65

まとめ

綺麗に過学習した.
optuna使うとちょっと精度上がる.

結論 : 前処理が大事

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2