9.5.6 rqRowEval関数
rqRowEval関数は、EXP_NAMパラメータで指定されているスクリプト内のR関数を実行します。
               
INP_CURパラメータを使用して、データをR関数に渡します。PAR_CURパラメータを使用して、引数をR関数に渡すことができます。ROW_NUMパラメータは、R関数の各呼出しに渡す必要のある行数を指定します。最後のチャンクの行数は、指定した数より少なくなる可能性があります。
               
rqRowEval関数ではデータ・パラレル実行がサポートされており、1つ以上のRエンジンにより同じR関数(タスク)が個々の独立したデータ・チャンクで実行されます。Oracle Databaseは、データベース・サーバー・マシンで実行されるRエンジン(複数の場合もある)の管理および制御を処理し、自動的にデータをチャンク化して、パラレルで実行されるRエンジンに渡します。Oracle Databaseでは行のすべてのチャンクに対するR関数の実行完了が保証されており、完了しない場合はrqRowEval関数によってエラーが返されます。
               
R関数は、データベース内にSQL表として表示されるR data.frameオブジェクトを返します。OUT_QRYパラメータを使用して、返される値の形式を定義します。
               
構文
rqRowEval (
     INP_CUR     REF CURSOR     IN
     PAR_CUR     REF CURSOR     IN
     OUT_QRY     VARCHAR2       IN
     ROW_NUM     NUMBER         IN
     EXP_NAM     VARCHAR2       IN)パラメータ
表9-17 rqRowEval関数のパラメータ
| パラメータ | 説明 | 
|---|---|
| 
 | 
 | 
| 
 | R関数に渡す引数値を含むカーソル。 | 
| 
 | 次のうちの1つ。 
 | 
| 
 | R関数の各呼出しに含める行数。 | 
| 
 | OML4Rスクリプト・リポジトリ内のスクリプトの名前。 | 
戻り値
関数rqRowEvalは、OUT_QRYパラメータ値で指定されている構造を持つ表を返します。
                  
例
この例では、C50パッケージを使用して、C5.0デシジョン・ツリー・モデルを使用してチャーン・データをスコアリングします(つまり、解約傾向が高い顧客を予測します)。この例では、指定された状態からの顧客を並行してスコアリングします。この例では、関数ore.rowApplyを呼び出した場合と同じ結果になります。
                  
ヒント:
この例では、CHURN_TEST表とmyXLevelsデータストアを使用します。そのため、Rでは、この例を実行する前に、表を作成する関数、およびxlevelsオブジェクトを取得する関数を起動し、それをmyXLevelsデータストアに保存する必要があります。
                     
例9-24 rqRowEval関数の使用
この例では、ユーザー定義関数を作成し、その関数をOML4Rスクリプト・リポジトリに保存します。このユーザー定義関数は状態のC5.0モデルを作成し、そのモデルをデータストアに保存します。関数myC5.0FunctionForLevelsは、値TRUEを返します
                  
この例では、PL/SQLパッケージchurnPkgおよび関数churnGroupEvalを作成します。この例では、文字列myC5.0modelFLを含むデータストアの名前を取得するためのカーソルを宣言してから、これらのデータソースを削除するPL/SQLブロックを実行します。次に、churnGroupEval関数を呼び出すSELECT文を実行します。churnGroupEval関数はmyC5.0FunctionForLevels関数を呼び出してC5.0モデルを生成し、それをデータストアに保存します。
                  
この例では次に、myScoringFunction関数を作成してスクリプト・リポジトリに格納します。この関数は、状態のレベルでC5.0モデルをスコアリングし、結果をdata.frameで返します。
                  
最後に、rqRowEval関数を呼び出すSELECT文を実行します。rqRowEval関数への入力カーソルはPARALLELヒントを使用して、使用する並列度レベルを指定します。カーソルはデータソースとしてCHURN_TEST表を指定し、マサチューセッツの行のみが含まれるように行をフィルタ処理します。処理される行はすべて同じ予測モデルを使用します。
                  
パラメータ・カーソルはore.connect制御引数を指定して、データベース・サーバー上のOML4Rに接続し、myScoringFunction関数へのdatastorePrefix引数とxlevelsDatastore引数の値を指定します。
                  
OUT_QRYパラメータのSELECT文は、出力形式を指定します。ROW_NUMパラメータでは、各パラレルRエンジンで一度に処理する行数として200を指定します。EXP_NAMEパラメータでは、呼び出すR関数としてスクリプト・リポジトリ内のmyScoringFunctionを指定します。
                  
BEGIN
  sys.rqScriptDrop('myC5.0FunctionForLevels');
  sys.rqScriptCreate('myC5.0FunctionForLevels',
    'function(dat, xlevelsDatastore, datastorePrefix) {
       library(C50)
       state <- dat[1,"state"]
       datastoreName <- paste(datastorePrefix, dat[1, "state"], sep = "_")
       dat$state <- NULL
       ore.load(name = xlevelsDatastore) # To get the xlevels object.
       for (j in names(xlevels))
         dat[[j]] <- factor(dat[[j]], levels = xlevels[[j]])
       c5mod <- C5.0(churn ~ ., data = dat, rules = TRUE)
       ore.save(c5mod, name = datastoreName)
       TRUE
      }');
END;
/
CREATE OR REPLACE PACKAGE churnPkg AS
  TYPE cur IS REF CURSOR RETURN CHURN_TEST%ROWTYPE;
END churnPkg;
/
CREATE OR REPLACE FUNCTION churnGroupEval(
  inp_cur churnPkg.cur,
  par_cur SYS_REFCURSOR, 
  out_qry VARCHAR2,
  grp_col VARCHAR2,
  exp_txt CLOB)
RETURN SYS.AnyDataSet
PIPELINED PARALLEL_ENABLE (PARTITION inp_cur BY HASH ("state"))
CLUSTER inp_cur BY ("state")
USING rqGroupEvalImpl;
/
DECLARE
 CURSOR c1
  IS
    SELECT dsname FROM RQUSER_DATASTORELIST WHERE dsname like 'myC5.0modelFL%';
BEGIN
  FOR dsname_st IN c1
  LOOP
    rqDropDataStore(dsname_st.dsname);
  END LOOP;
END;
SELECT *
  FROM table(churnGroupEval(
    cursor(SELECT * /*+ parallel(t,4) */ FROM CHURN_TEST t),
    cursor(SELECT 1 AS "ore.connect",
           'myXLevels' as "xlevelsDatastore",
           'myC5.0modelFL' AS "datastorePrefix" FROM dual),
    'XML', 'state', 'myC5.0FunctionForLevels'));
BEGIN
  sys.rqScriptDrop('myScoringFunction');
  sys.rqScriptCreate('myScoringFunction',
    'function(dat, xlevelsDatastore, datastorePrefix) {
       library(C50)
       state <- dat[1, "state"]
       datastoreName <- paste(datastorePrefix, state, sep = "_")
       dat$state <- NULL
       ore.load(name = xlevelsDatastore) # To get the xlevels object.
       for (j in names(xlevels))
         dat[[j]] <- factor(dat[[j]], levels = xlevels[[j]])
       ore.load(name = datastoreName)
       res <- data.frame(pred = predict(c5mod, dat, type = "class"),
                         actual= dat$churn,
                         state = state)
       res
     }');
END;
/
SELECT * FROM table(rqRowEval(
  cursor(select /*+ parallel(t, 4) */ *
         FROM CHURN_TEST t
         WHERE "state" = 'MA'),
  cursor(SELECT 1 as "ore.connect", 
         'myC5.0modelFL' as "datastorePrefix",
         'myXLevels' as "xlevelsDatastore"
         FROM dual),
  'SELECT ''aaa'' "pred",''aaa'' "actual" , ''aa'' "state" FROM dual',
   200, 'myScoringFunction'));
Oracle SQL Developerでの最後のSELECT文の結果は次のようになります。
                  
pred actual state ---- ------ ----- no no MA no no MA no no MA no no MA no no MA no no MA no no MA no yes MA yes yes MA yes yes MA no no MA no no MA no no MA no no MA no no MA no no MA yes yes MA no no MA no no MA no no MA no no MA no no MA no no MA no no MA no no MA no no MA no no MA no no MA no no MA no no MA no yes MA no no MA no no MA no no MA yes yes MA no no MA no no MA no no MA 38 rows selected