LoginSignup
4
6

More than 5 years have passed since last update.

深い森(multi-Grained Cascade Forest)の苦手なデータを検証してみる。

Last updated at Posted at 2019-02-17

はじめに

背景

gcForest(multi-Grained Cascade Forest)の精度は画像認識や、感情分析、音楽分類、手の動きの分類などにおいて、一部の深層学習モデルとRandom Forestsの精度よりも高いことが知られている。

内容

本ページでは次のような決定木ベースの機械学習モデルを構築する。

  • Random Forests
  • gcForest

大規模なアンケートデータを想定し、Random Forestsの精度がgcForestの精度よりも高いことを示す。つまり、gcForestの苦手な部分を検証してみる。

学銃的な背景とインストール方法

前回の深い森(multi-Grained Cascade Forest)と浅い森(Random Forests)を動かして比較してみたを参照してください。

import numpy as np
import pandas as pd
import random
import uuid

from sklearn.datasets import make_classification
from sklearn.model_selection import StratifiedKFold, cross_validate
from sklearn.metrics import accuracy_score, cohen_kappa_score, balanced_accuracy_score, make_scorer, f1_score, recall_score

from sklearn.datasets import fetch_mldata
from sklearn.ensemble import ExtraTreesClassifier, RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score
from sklearn.model_selection import train_test_split

from deep_forest import MGCForest

実験

テスト用のデータ作成

パラメータの値

  • n_samples: サンプルの数
    • アンケート調査であれば回答者数に該当
  • n_features: 特徴量の数
    • 分類対象(クラス)を識別するために利用する特徴量の数
    • 例えば、アンケート調査であれば質問と回答のペア
  • n_informative:分類対象と関係のある特徴量の数
    • この数が多ければ多いほど予測が簡単になる
  • n_classes: 分類対象が何種類あるか
    • 2値分類問題にするならば 2 をセット
  • random_state: ランダムシードの設定
data = make_classification(n_samples=1000, #生成するサンプル数 
                           n_features=110,  
                           n_informative=100,
                           weights=[0.5,0.5],
                           n_classes=2,
                          random_state=43)
data_set = data[0] # 特徴量
target_set = data[1] # クラスラベル
#from sklearn.datasets import load_iris
#iris = load_iris()
#data_set = iris.data
#target_set =iris.target

gcforestの構築

mgc_forest = MGCForest(
    estimators_config={
        'mgs': [{
            'estimator_class': ExtraTreesClassifier,
            'estimator_params': {
                'n_estimators': 30,
                'min_samples_split': 21,
                'n_jobs': -1,
            }
        }, {
            'estimator_class': RandomForestClassifier,
            'estimator_params': {
                'n_estimators': 30,
                'min_samples_split': 21,
                'n_jobs': -1,
            }
        }],
        'cascade': [{
            'estimator_class': ExtraTreesClassifier,
            'estimator_params': {
                'n_estimators': 1000,
                'min_samples_split': 11,
                'max_features': 1,
                'n_jobs': -1,
            }
        }, {
            'estimator_class': ExtraTreesClassifier,
            'estimator_params': {
                'n_estimators': 1000,
                'min_samples_split': 11,
                'max_features': 'sqrt',
                'n_jobs': -1,
            }
        }, {
            'estimator_class': RandomForestClassifier,
            'estimator_params': {
                'n_estimators': 1000,
                'min_samples_split': 11,
                'max_features': 1,
                'n_jobs': -1,
            }
        }, {
            'estimator_class': RandomForestClassifier,
            'estimator_params': {
                'n_estimators': 1000,
                'min_samples_split': 11,
                'max_features': 'sqrt',
                'n_jobs': -1,
            }
        }]
    },
    stride_ratios=[1.0 / 4, 1.0 / 9, 1.0 / 16],
)
%%time
skf = StratifiedKFold(n_splits=5,
                      shuffle=True,
                      random_state=0)
r_data = {}
steps = 1
for train_index, test_index in skf.split(data_set, target_set):
    mgc_forest.fit(data_set[train_index,],target_set[train_index])
    target_pred = mgc_forest.predict(data_set[test_index,])
    r_data[steps] = {'test_accuracy': accuracy_score(target_set[test_index], target_pred),
            'test_kappa':  cohen_kappa_score(target_set[test_index], target_pred),
            'test_blanced_accuracy': balanced_accuracy_score(target_set[test_index], target_pred),
            'test_F1 score': f1_score(target_set[test_index], target_pred, average='weighted')
                     }
    steps +=1

CPU times: user 13min 1s, sys: 27.4 s, total: 13min 28s
Wall time: 12min 37s
## Random forests の構築
model = RandomForestClassifier(random_state = 43,
                               n_jobs = -1,
                               n_estimators = 1000,
                               max_features = 'log2',
                               max_depth = None, 
                               oob_score=False)
%%time
skf = StratifiedKFold(n_splits=5,
                      shuffle=True,
                      random_state=0)
rf_data = {}
steps = 1
for train_index, test_index in skf.split(data_set, target_set):
    #print("分割されたデータセットの大きさ:{}".format(target_set[test_index].shape))
    #print("分割される以前のデータセットのどこを抽出したのか?:{}".format(test_index))
    #print("クラスラベル:{}".format(target_set[test_index]))
    #print("クラスラベルの種類別個数{}".format( np.unique(target_set[test_index],return_counts=True)))
    model.fit(data_set[train_index,],target_set[train_index])
    target_pred = model.predict(data_set[test_index,])
    rf_data[steps] = {'test_accuracy': accuracy_score(target_set[test_index], target_pred),
            'test_kappa':  cohen_kappa_score(target_set[test_index], target_pred),
            'test_blanced_accuracy': balanced_accuracy_score(target_set[test_index], target_pred),
            'test_F1 score': f1_score(target_set[test_index], target_pred, average='weighted')
                     }
    steps +=1


CPU times: user 17.2 s, sys: 1.64 s, total: 18.9 s
Wall time: 8.61 s

結果

gcforestの精度

r_data
{1: {'test_accuracy': 0.582089552238806,
  'test_kappa': 0.16357871792331324,
  'test_blanced_accuracy': 0.5817326732673267,
  'test_F1 score': 0.5799051338290626},
 2: {'test_accuracy': 0.6119402985074627,
  'test_kappa': 0.22363078142022386,
  'test_blanced_accuracy': 0.6117821782178218,
  'test_F1 score': 0.6115363902138791},
 3: {'test_accuracy': 0.675,
  'test_kappa': 0.35,
  'test_blanced_accuracy': 0.675,
  'test_F1 score': 0.6736210489317367},
 4: {'test_accuracy': 0.6030150753768844,
  'test_kappa': 0.20629070530620486,
  'test_blanced_accuracy': 0.6031818181818182,
  'test_F1 score': 0.6025936582952676},
 5: {'test_accuracy': 0.6080402010050251,
  'test_kappa': 0.21566447700859026,
  'test_blanced_accuracy': 0.6077777777777778,
  'test_F1 score': 0.6069481144323441}}

Random Forestsの精度

rf_data
{1: {'test_accuracy': 0.8507462686567164,
  'test_kappa': 0.7014851485148514,
  'test_blanced_accuracy': 0.8507425742574257,
  'test_F1 score': 0.8507462686567164},
 2: {'test_accuracy': 0.8159203980099502,
  'test_kappa': 0.6317405298341173,
  'test_blanced_accuracy': 0.8157920792079207,
  'test_F1 score': 0.8157835867115555},
 3: {'test_accuracy': 0.865,
  'test_kappa': 0.73,
  'test_blanced_accuracy': 0.865,
  'test_F1 score': 0.8647260702923422},
 4: {'test_accuracy': 0.8391959798994975,
  'test_kappa': 0.6783838383838383,
  'test_blanced_accuracy': 0.8391919191919192,
  'test_F1 score': 0.8391959798994975},
 5: {'test_accuracy': 0.8090452261306532,
  'test_kappa': 0.6181579478893153,
  'test_blanced_accuracy': 0.8091414141414142,
  'test_F1 score': 0.8089873493553846}}

まとめ

  • 小規模データセット(1000人, 110種類の質問)の精度
    • Random Forestsの精度がgcForestよりも優れていた。
  • 計算時間
    • gcforest: 12min 37s
    • Random Forests: 8.61 s

以上から、データに合わせて手法を選ぶべき、ということがわかる。

  • 想像
    • 訓練データへの精度は全て1.0であるため、データが少ないにも関わらず学習しすぎていることが、原因か?
4
6
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
6