Optuna×XGBoostでred_wine_quality

# はじめに
XGBoostをクラス分けではなく回帰に使ってみる.(と言いつつも、結果は10クラス分類)
ということで、いろんな要素から赤ワインのQualityを当てるモデルを作る.
結論から言うと、あまり精度は出なかった.
# 実行環境とライブラリ
[前回の記事を参照](https://qiita.com/kuroneko-hornet/items/9e3e8ffba75c1dbf11c6)
# 実装
1.  適当なパラメータでやる(max_depth, learning_rate, round_num)
2.  1のパラメータをoptunaにかける
3.  パラメータを沢山にする

XGBoostにある２つの回帰アルゴリズム
* 線形回帰
* ロジスティック回帰
どっちも試した.
また,データ属性は全部使ってみる.
## 前処理
```python3:preprocess
def preprocess(df):
    df[target_column] = df[target_column] /10
    return df
```
ロジスティック回帰を用いるために,Quality[0,10]を[0,1]の少数として扱う.
最大値で割ろうかと思ったが,無限小数とかになった時に,精度が全く出なさそうなので10で割った.
元データがすでに全て数値なので、数値変換はしない.
全属性を使うのでdropもしない.

## XGBoostによる学習
```python3:train
def train(df,max_depth,learning_rate,num_round,how_objective):
    train_x = df.drop(target_column,axis=1)
    train_y = df[target_column]
    dtrain = xgb.DMatrix(train_x,label=train_y)
    param = { 'max_depth':max_depth,'learning_rate':learning_rate,'objective':how_objective,'silent':1}
    bst = xgb.train(param,dtrain,num_round)
    return bst
```
target_columnは目的変数

## optunaの目的関数の定義
```python3:objective
def objective(df, df_test, y, how_objective, trial):
    #目的関数
    max_depth = trial.suggest_int('max_depth',1,30)
    learning_rate = trial.suggest_uniform('learning_rate',0.0,1.0)
    round_num = trial.suggest_int('round_num',1,30)
    bst = train(df,max_depth,learning_rate,round_num,how_objective)
    answer = predict(bst,df_test).round().astype(int)
    score = accuracy_score(answer,y.astype(int))
    return 1.0 - score
```
max_depth, learning_rate, round_numについてチューニングを行う。

## main関数
```python3:main
def main():
    global target_column
    df_original = pd.read_csv("/Users/pc1013/Desktop/first/XGBoost_optuna/df/winequality-red.csv")
    df = preprocess(df_original)
    (df_train, df_test) = train_test_split(df, test_size = 0.1, random_state = 666)
    y = df_test[target_column]*10
    df_test = df_test.drop(target_column,axis=1)
    
    how_objective = 'reg:logistic' #or 'reg:linear'

    '''
    学習と結果出力
    必要があればoptunaの前処理とチューニング
    '''
```

# 実行結果
### パラメータを適当にやる
```py
#ハイパーパラメータ
    max_depth = 6
    learning_rate = 0.1
    round_num = 10
```
上から、linearとlogistic
<img width="486" alt="wine_quality_linear.png" src="https://qiita-image-store.s3.amazonaws.com/0/293940/68e724f0-72d9-36ea-ef1d-55e9a9b9e996.png">
<img width="480" alt="wine_quality_logistic.png" src="https://qiita-image-store.s3.amazonaws.com/0/293940/6e5686a5-ce90-c42f-0ecc-a697b957390c.png">

### ３つのパラメータを自動チューニング
上からlinearとlogistic

<img width="582" alt="wine_quality_1_linear.png" src="https://qiita-image-store.s3.amazonaws.com/0/293940/3a25462e-32ab-ae66-c76b-5dd5f907cfcf.png">
<img width="573" alt="wine_quality_1_log.png" src="https://qiita-image-store.s3.amazonaws.com/0/293940/5d5f5654-ac06-e29d-6a03-ace482447aaa.png">

**完璧なオーバーフィッティング**

### 沢山のパラメータを自動チューニング
上からlinearとlogistic

<img width="998" alt="wine_quality_2_linear.png" src="https://qiita-image-store.s3.amazonaws.com/0/293940/6d502d75-bdff-e10f-d542-18b30193e173.png">
<img width="991" alt="wine_quality_2_log.png" src="https://qiita-image-store.s3.amazonaws.com/0/293940/c4e3870f-355f-cdeb-e4a9-c1ad97b00c84.png">


# 改良
### データ前処理の変更
* 寄与率の低かった、citric acid, free sulfur dioxide, sulphatesをデータセットから削除する

### optunaの変更
* 試行回数(n_trial)を200回
パラメータの範囲を
* max_depth ≤ 30
* round_num ≤ 30
* learning_rate ≤ 1.0
* gamma ≤ 10.0
* min_childe_weigh ≤ 10.0
* alpha ≤ 10.0
とする

```py
def preprocess(df):
    df = df.drop(['citric acid','free sulfur dioxide','fixed acidity','alcohol'],axis=1)
    df[target_column] = df[target_column] /10
    return df
```
```py
#ハイパーパラメータの範囲(objective関数内)
    max_depth = trial.suggest_int('max_depth',1,25)
    learning_rate = trial.suggest_uniform('learning_rate',0.0,1.0)
    round_num = trial.suggest_int('round_num',1,30)
    gamma = trial.suggest_uniform('gamma',0.0,10.0)
    colsample_bytree = trial.suggest_uniform('colsample_bytree',0.0,1.0)
    min_childe_weigh = trial.suggest_uniform('min_childe_weigh',0.0,10.0)
    alpha = trial.suggest_uniform('alpha',0.0,10.0)
```

# 実行結果 #2
上からlinearとlogistic
<img width="983" alt="wine_quality_imprline.png" src="https://qiita-image-store.s3.amazonaws.com/0/293940/37d92e33-4de5-3f97-17f4-bd19355c8791.png">
<img width="991" alt="wine_quality_2_log.png" src="https://qiita-image-store.s3.amazonaws.com/0/293940/7ad67173-8b5e-c60e-71b2-a05557ea3ecd.png">

  
過学習がマシになった...?　(なってない)
# まとめ
精度が出ない。
自動化と言っても、過学習を防ぐために、ハイパーパラメータの範囲の調整が必要だった。