8.16 ランダム・フォレスト

oml.rfクラスは、分類のためのアンサンブル学習手法を提供するランダム・フォレスト(RF)モデルを作成します。

ランダム・フォレスト・アルゴリズムは、バギングと変数のランダム選択の概念を組み合せることにより、デシジョン・ツリーの一般的な問題であるオーバーフィットを回避しながら、分散が制御されたデシジョン・ツリーの集合を生成します。

oml.rfクラスの属性およびメソッドの詳細は、help(oml.rf)を呼び出すか、Oracle Machine Learning for Python APIリファレンスを参照してください。

ランダム・フォレスト・モデルの設定

次の表は、RFモデルの設定のリストです。

表8-14 ランダム・フォレスト・モデルの設定

設定名 設定値 説明
CLAS_COST_TABLE_NAME

table_name

モデルのスコアリングに使用するアルゴリズムのコスト・マトリックスを格納する表の名前。コスト・マトリックスは、分類ミスに関連するコストを指定します。

コスト・マトリックス表は、ユーザーが作成します。表の列の要件は次のとおりです。

  • 列名: ACTUAL_TARGET_VALUE

    データ型: 有効なターゲット・データ型

  • 列名: PREDICTED_TARGET_VALUE

    データ型: 有効なターゲット・データ型

  • 列名: COST

    データ型: NUMBER

CLAS_MAX_SUP_BINS

2 <= 数値 <= 254

各属性のビンの最大数を指定します。

デフォルト値は32です。

CLAS_WEIGHTS_BALANCED

ON

OFF

ターゲットの分布を平均化するモデルをアルゴリズムが作成する必要があるかどうかを示します。分布の平均化では、主要なクラスを重視する全体精度ではなく、平均精度(クラスごとの精度の平均)を向上できるため、この設定は稀なターゲットが存在する場合に最適です。デフォルト値はOFFです。

ODMS_RANDOM_SEED

負でない整数

均一な分布で乱数を生成するためにハッシュ関数で使用される乱数シードを制御します。デフォルト値は0です。

RFOR_MTRY

数値 >= 0

ノードでの分割を選択する際に考慮する列のランダムなサブセットのサイズ。各ノードで、プールのサイズは同じですが、特定の候補列が変更されます。デフォルトは、モデル・シグネチャの列の半分です。特殊な値である0は、候補プールにすべての列が含まれることを示します。

RFOR_NUM_TREES

1 <= 数値 <= 65535

フォレスト内のツリーの数

デフォルト値は20です。

RFOR_SAMPLING_RATIO

0 < 小数 <= 1

個々のツリーの作成で使用するためにランダムにサンプリングされるトレーニング・データの割合。デフォルトは、トレーニング・データ内の行数の半分です。

TREE_IMPURITY_METRIC

TREE_IMPURITY_ENTROPY

TREE_IMPURITY_GINI

デシジョン・ツリー・モデルのツリー不純メトリック。

ツリー・アルゴリズムでは、各ノードでのデータの分岐に最適なテスト質問が検索されます。最適な分岐および分岐値は、ノードのエンティティに対するターゲット値の同質性(純度)が最大限に高くなるものです。純度は、メトリックに従って測定します。デシジョン・ツリーでは、純度メトリックとしてジニ(TREE_IMPURITY_GINI)またはエントロピ(TREE_IMPURITY_ENTROPY)のいずれかを使用できます。デフォルトでは、アルゴリズムでTREE_IMPURITY_GINIが使用されます。

TREE_TERM_MAX_DEPTH

2 <= 数値 <= 100

分岐の条件: ツリーの最大深度(ルート・ノードとリーフ・ノードとの間(リーフ・ノードを含む)の最大ノード数)。

デフォルトは16です。

TREE_TERM_MINPCT_NODE

0 <= 数値 <= 10

トレーニング・データ内の行の割合として表現されたノード内のトレーニング行の最小数。

デフォルト値は0.05で、0.05%を示します。

TREE_TERM_MINPCT_SPLIT

0 < 数値 <= 20

トレーニング行の割合として表現された、ノードの分割を検討するために必要な行の最小数。

デフォルト値は0.1で、0.1%を示します。

TREE_TERM_MINREC_NODE

数値 >= 0

ノード内の行の最小数。

デフォルト値は10です。

TREE_TERM_MINREC_SPLIT

数値 > 1

分岐の条件: 値として表現される親ノードのレコードの最小数。レコード数がこの値よりも少ない場合、分岐は試行されません。

デフォルト値は20です。

例8-16 oml.rfクラスの使用方法

この例では、RFモデルを作成し、oml.rfクラスのメソッドの一部を使用します。

import oml
import pandas as pd
from sklearn import datasets

# Load the iris data set and create a pandas.DataFrame for it.
iris = datasets.load_iris()
x = pd.DataFrame(iris.data,
                 columns = ['Sepal_Length','Sepal_Width',
                            'Petal_Length','Petal_Width'])
y = pd.DataFrame(list(map(lambda x:
                           {0: 'setosa', 1: 'versicolor',
                            2:'virginica'}[x], iris.target)),
                 columns = ['Species'])

try:
    oml.drop('IRIS')
    oml.drop(table = 'RF_COST')
except:
    pass

# Create the IRIS database table and the proxy object for the table.
oml_iris = oml.create(pd.concat([x, y], axis=1), table = 'IRIS')

# Create training and test data.
dat = oml.sync(table = 'IRIS').split()
train_x = dat[0].drop('Species')
train_y = dat[0]['Species']
test_dat = dat[1]

# Create a cost matrix table in the database.
cost_matrix = [['setosa', 'setosa', 0], 
               ['setosa', 'virginica', 0.2], 
               ['setosa', 'versicolor', 0.8],
               ['virginica', 'virginica', 0],
               ['virginica', 'setosa', 0.5],
               ['virginica', 'versicolor', 0.5],
               ['versicolor', 'versicolor', 0],
               ['versicolor', 'setosa', 0.4], 
               ['versicolor', 'virginica', 0.6]]
cost_matrix = \
  oml.create(pd.DataFrame(cost_matrix, 
                          columns = ['ACTUAL_TARGET_VALUE', 
                                     'PREDICTED_TARGET_VALUE', 
                                     'COST']), 
             table = 'RF_COST')

# Create an RF model object.
rf_mod = oml.rf(tree_term_max_depth = '2')

# Fit the RF model according to the training data and parameter
# settings.
rf_mod = rf_mod.fit(train_x, train_y, cost_matrix = cost_matrix)

# Show details of the model.
rf_mod

# Use the model to make predictions on the test data.
rf_mod.predict(test_dat.drop('Species'), 
               supplemental_cols = test_dat[:, ['Sepal_Length',
                                                'Sepal_Width', 
                                                'Petal_Length', 
                                                'Species']])

# Return the prediction probability.
rf_mod.predict(test_dat.drop('Species'), 
               supplemental_cols = test_dat[:, ['Sepal_Length',
                                                'Sepal_Width', 
                                                'Species']], 
               proba = True)


# Return the top two most influencial attributes of the highest
# probability class.
rf_mod.predict_proba(test_dat.drop('Species'), 
               supplemental_cols = test_dat[:, ['Sepal_Length', 
                                                'Species']], 
               topN = 2).sort_values(by = ['Sepal_Length', 'Species'])

rf_mod.score(test_dat.drop('Species'), test_dat[:, ['Species']])

# Reset TREE_TERM_MAX_DEPTH and refit the model.
rf_mod.set_params(tree_term_max_depth = '3').fit(train_x, train_y, cost_matrix)

この例のリスト

>>> import oml
>>> import pandas as pd
>>> from sklearn import datasets
>>>
>>> # Load the iris data set and create a pandas.DataFrame for it.
... iris = datasets.load_iris()
>>> x = pd.DataFrame(iris.data, 
...                  columns = ['Sepal_Length','Sepal_Width',
...                             'Petal_Length','Petal_Width'])
>>> y = pd.DataFrame(list(map(lambda x: 
...                            {0: 'setosa', 1: 'versicolor', 
...                             2:'virginica'}[x], iris.target)), 
...                  columns = ['Species'])
>>>
>>> try:
...    oml.drop('IRIS')
...    oml.drop(table = 'RF_COST')
... except:
...    pass
>>>
>>> # Create the IRIS database table and the proxy object for the table.
... oml_iris = oml.create(pd.concat([x, y], axis=1), table = 'IRIS')
>>>
>>> # Create training and test data.
... dat = oml.sync(table = 'IRIS').split()
>>> train_x = dat[0].drop('Species')
>>> train_y = dat[0]['Species']
>>> test_dat = dat[1]
>>> 
>>> # Create a cost matrix table in the database.
... cost_matrix = [['setosa', 'setosa', 0], 
...                ['setosa', 'virginica', 0.2], 
...                ['setosa', 'versicolor', 0.8],
...                ['virginica', 'virginica', 0],
...                ['virginica', 'setosa', 0.5],
...                ['virginica', 'versicolor', 0.5],
...                ['versicolor', 'versicolor', 0],
...                ['versicolor', 'setosa', 0.4], 
...                ['versicolor', 'virginica', 0.6]]
>>> cost_matrix = \
...   oml.create(pd.DataFrame(cost_matrix, 
...                           columns = ['ACTUAL_TARGET_VALUE',
...                                      'PREDICTED_TARGET_VALUE', 
...                                      'COST']),
...              table = 'RF_COST')
>>>
>>> # Create an RF model object.
... rf_mod = oml.rf(tree_term_max_depth = '2')
>>>
>>> # Fit the RF model according to the training data and parameter
... # settings.
>>> rf_mod = rf_mod.fit(train_x, train_y, cost_matrix = cost_matrix)
>>>
>>> # Show details of the model.
... rf_mod

Algorithm Name: Random Forest

Mining Function: CLASSIFICATION

Target: Species

Settings: 
                    setting name            setting value
0                      ALGO_NAME       ALGO_RANDOM_FOREST
1           CLAS_COST_TABLE_NAME     "OML_USER"."RF_COST"
2              CLAS_MAX_SUP_BINS                       32
3          CLAS_WEIGHTS_BALANCED                      OFF
4                   ODMS_DETAILS              ODMS_ENABLE
5   ODMS_MISSING_VALUE_TREATMENT  ODMS_MISSING_VALUE_AUTO
6               ODMS_RANDOM_SEED                        0
7                  ODMS_SAMPLING    ODMS_SAMPLING_DISABLE
8                      PREP_AUTO                       ON
9                 RFOR_NUM_TREES                       20
10           RFOR_SAMPLING_RATIO                       .5
11          TREE_IMPURITY_METRIC       TREE_IMPURITY_GINI
12           TREE_TERM_MAX_DEPTH                        2
13         TREE_TERM_MINPCT_NODE                      .05
14        TREE_TERM_MINPCT_SPLIT                       .1
15         TREE_TERM_MINREC_NODE                       10
16        TREE_TERM_MINREC_SPLIT                       20

Computed Settings: 
  setting name setting value
0    RFOR_MTRY             2

Global Statistics: 
   attribute name  attribute value
0       AVG_DEPTH                2
1   AVG_NODECOUNT                3
2       MAX_DEPTH                2
3   MAX_NODECOUNT                2
4       MIN_DEPTH                2
5   MIN_NODECOUNT                2
6        NUM_ROWS              104

Attributes: 
Petal_Length
Petal_Width
Sepal_Length

Partition: NO

Importance: 

   ATTRIBUTE_NAME ATTRIBUTE_SUBNAME  ATTRIBUTE_IMPORTANCE
 0   Petal_Length              None              0.329971
 1    Petal_Width              None              0.296799
 2   Sepal_Length              None              0.037309
 3    Sepal_Width              None              0.000000

>>> # Use the model to make predictions on the test data.
... rf_mod.predict(test_dat.drop('Species'), 
...                supplemental_cols = test_dat[:, ['Sepal_Length', 
...                                                 'Sepal_Width', 
...                                                 'Petal_Length', 
...                                                 'Species']])
     Sepal_Length  Sepal_Width  Petal_Length     Species  PREDICTION
 0            4.9          3.0           1.4      setosa      setosa
 1            4.9          3.1           1.5      setosa      setosa
 2            4.8          3.4           1.6      setosa      setosa
 3            5.8          4.0           1.2      setosa      setosa
...           ...          ...           ...         ...         ...
42            6.7          3.3           5.7   virginica   virginica
43            6.7          3.0           5.2   virginica   virginica
44            6.5          3.0           5.2   virginica   virginica
45            5.9          3.0           5.1   virginica   virginica

>>> # Return the prediction probability.
... rf_mod.predict(test_dat.drop('Species'), 
...                supplemental_cols = test_dat[:, ['Sepal_Length', 
...                                                 'Sepal_Width', 
...                                                 'Species']], 
...                proba = True)
     Sepal_Length  Sepal_Width     Species  PREDICTION  PROBABILITY
 0            4.9          3.0      setosa      setosa     0.989130
 1            4.9          3.1      setosa      setosa     0.989130
 2            4.8          3.4      setosa      setosa     0.989130
 3            5.8          4.0      setosa      setosa     0.950000
...           ...          ...         ...         ...          ...
42            6.7          3.3   virginica   virginica     0.501016
43            6.7          3.0   virginica   virginica     0.501016
44            6.5          3.0   virginica   virginica     0.501016
45            5.9          3.0   virginica   virginica     0.501016

>>> # Return the top two most influencial attributes of the highest
... # probability class.
>>> rf_mod.predict_proba(test_dat.drop('Species'), 
...               supplemental_cols = test_dat[:, ['Sepal_Length', 
...                                                'Species']], 
...               topN = 2).sort_values(by = ['Sepal_Length', 'Species'])
     Sepal_Length     Species       TOP_1  TOP_1_VAL       TOP_2  TOP_2_VAL
 0            4.4      setosa      setosa   0.989130  versicolor   0.010870
 1            4.4      setosa      setosa   0.989130  versicolor   0.010870
 2            4.5      setosa      setosa   0.989130  versicolor   0.010870
 3            4.8      setosa      setosa   0.989130  versicolor   0.010870
...           ...         ...         ...        ...         ...        ...
42            6.7   virginica   virginica   0.501016  versicolor   0.498984
43            6.9  versicolor   virginica   0.501016  versicolor   0.498984
44            6.9   virginica   virginica   0.501016  versicolor   0.498984
45            7.0  versicolor   virginica   0.501016  versicolor   0.498984

>>> rf_mod.score(test_dat.drop('Species'), test_dat[:, ['Species']])
0.76087
 
>>> # Reset TREE_TERM_MAX_DEPTH and refit the model.
... rf_mod.set_params(tree_term_max_depth = '3').fit(train_x, train_y, cost_matrix)

Algorithm Name: Random Forest

Mining Function: CLASSIFICATION

Target: Species
Settings: 
                    setting name            setting value
0                      ALGO_NAME       ALGO_RANDOM_FOREST
1           CLAS_COST_TABLE_NAME     "OML_USER"."RF_COST"
2              CLAS_MAX_SUP_BINS                       32
3          CLAS_WEIGHTS_BALANCED                      OFF
4                   ODMS_DETAILS              ODMS_ENABLE
5   ODMS_MISSING_VALUE_TREATMENT  ODMS_MISSING_VALUE_AUTO
6               ODMS_RANDOM_SEED                        0
7                  ODMS_SAMPLING    ODMS_SAMPLING_DISABLE
8                      PREP_AUTO                       ON
9                 RFOR_NUM_TREES                       20
10           RFOR_SAMPLING_RATIO                       .5
11          TREE_IMPURITY_METRIC       TREE_IMPURITY_GINI
12           TREE_TERM_MAX_DEPTH                        3
13         TREE_TERM_MINPCT_NODE                      .05
14        TREE_TERM_MINPCT_SPLIT                       .1
15         TREE_TERM_MINREC_NODE                       10
16        TREE_TERM_MINREC_SPLIT                       20

Computed Settings: 
  setting name setting value
0    RFOR_MTRY             2

Global Statistics: 
   attribute name  attribute value
0       AVG_DEPTH                3
1   AVG_NODECOUNT                5
2       MAX_DEPTH                3
3   MAX_NODECOUNT                6
4       MIN_DEPTH                3
5   MIN_NODECOUNT                4
6        NUM_ROWS              104

Attributes: 
Petal_Length
Petal_Width
Sepal_Length

Partition: NO

Importance: 

  ATTRIBUTE_NAME ATTRIBUTE_SUBNAME  ATTRIBUTE_IMPORTANCE
0   Petal_Length              None              0.501022
1    Petal_Width              None              0.568170
2   Sepal_Length              None              0.091617
3    Sepal_Width              None              0.000000