プライマリ・コンテンツに移動
Oracle® R Enterpriseユーザーズ・ガイド
リリース1.5.1
E88296-01
目次へ移動
目次
索引へ移動
索引

前
次

6.2.6 ore.rowApply関数の使用方法

ore.rowApply関数は、入力データとしてore.frameを指定してRスクリプトを起動します。ore.rowApply関数は、ore.frameを最初の引数としてユーザー定義の入力関数に渡します。ore.rowApply関数に対するrows引数には、ユーザー定義のR関数の呼出しごとに渡す行の数を指定します。最後のチャンクまたは行は、指定した数より少なくなる可能性があります。ore.rowApply関数は、1つ以上のRエンジンが同じR関数(タスク)をデータの別のパーティションで実行するデータ・パラレル実行を使用できます。

ore.rowApply関数の構文は次のとおりです。

ore.rowApply(X, FUN, ..., FUN.VALUE = NULL, FUN.NAME = NULL, rows = 1, FUN.OWNER = NULL,
             parallel = getOption("ore.parallel", NULL))

ore.rowApply関数は、ore.listオブジェクトまたはore.frameオブジェクトを返します。

関連項目:

例6-15では、事前にCRANからダウンロードしてあるe1071パッケージを使用します。また、この例では、例6-12で作成したNaive Bayesモデルであるnbmodオブジェクトも使用します。

例6-15では、次の処理を行います。

  • パッケージe1071をロードします。

  • irisデータセットをIRIS一時表およびore.frameオブジェクトとしてデータベースにプッシュします。

  • IRISIRIS_PREDとしてコピーし、予測を含めるためにPRED列をIRIS_PREDに追加します。

  • ore.rowApply関数を呼び出し、IRIS ore.frameをユーザー定義R関数のデータソースおよびユーザー定義R関数自体として渡します。

  • ユーザー定義の関数は、次のことを実行します。

    • パッケージe1071を、データベース内で稼働するRエンジンまたはエンジンで使用できるようにロードします。

    • ore.frameはファクタを定義しますが、ユーザー定義の関数にロードされたときにファクタが文字列ベクターとして表示されるため、Species列をファクタに変換します。

    • predictメソッドを起動し、データセットに追加された列に予測が含まれているresオブジェクトを返します。

  • この例では、モデルをクライアントのRセッションにプルします。

  • IRIS_PREDを引数FUN.VALUEとして渡しますが、この引数にore.rowApply関数が返すオブジェクトの構造を指定します。

  • ユーザー定義関数の呼出しごとに渡す行の数を指定します。

  • resのクラスを表示し、table関数を呼び出してSpecies列およびresオブジェクトのPRED列を表示します。

例6-15 ore.rowApply関数の使用方法

library(e1071)
IRIS <- ore.push(iris)
IRIS_PRED <- IRIS
IRIS_PRED$PRED <- "A"
res <- ore.rowApply(
  IRIS,
  function(dat, nbmod) {
    library(e1071)
    dat$Species <- as.factor(dat$Species)
    dat$PRED <- predict(nbmod, newdata = dat)
    dat
  },
  nbmod = ore.pull(nbmod),
  FUN.VALUE = IRIS_PRED,
  rows = 10)
class(res)
table(res$Species, res$PRED)
例6-15のリスト
R> library(e1071)
R> IRIS <- ore.push(iris)      
R> IRIS_PRED <- IRIS
R> IRIS_PRED$PRED <- "A"
R> res <- ore.rowApply(
+   IRIS ,
+   function(dat, nbmod) {
+     library(e1071)
+     dat$Species <- as.factor(dat$Species)
+     dat$PRED <- predict(nbmod, newdata = dat)
+     dat
+   },
+   nbmod = ore.pull(nbmod),
+   FUN.VALUE = IRIS_PRED,
+   rows = 10)
R> class(res)
[1] "ore.frame"
attr(,"package")
[1] "OREbase"
R> table(res$Species, res$PRED)
            
             setosa versicolor virginica
  setosa         50          0         0
  versicolor      0         47         3
  virginica       0          3        47

例6-16では、例6-13と同様にC50パッケージを使用し、C5.0モデルを使用してチャーン・データをスコアリングします(つまり、解約傾向が高い顧客を予測します)。ただし、例6-16では、列によってデータをパーティショニングするのではなく、多数の行によってデータをパーティショニングします。この例では、指定された状態からの顧客を並行してスコアリングします。データストアを使用し、関数をOracle R EnterpriseのRスクリプト・リポジトリに保存することにより、これらの関数をOracle R Enterprise SQL API関数で使用できるようにします。

例6-16ではまず、C50パッケージおよびデータセットをロードします。この例では、名前にmyC5.0modelFLが含まれるデータストアが存在する場合、そのデータストアを削除します。ore.dropを呼び出してCHURN_TEST表(存在する場合)を削除した後、ore.createを呼び出してchurnTestデータセットからCHURN_TEST表を作成します。

次に、ファクタ列ごとにレベルのlistを返すore.getLevelsを呼び出します。この呼出しでは、最初の列(state)のレベルは必要ないため最初の列は除外されます。最初にレベルを取得しておくと、モデル構築中に、一部のレベルに対して値を持たない行があっても、すべての使用可能なレベルを確実に取得できます。ore.deleteの呼出しによって、指定された名前のデータストアが存在しないことが確認され、ore.saveの呼出しによって、xlevelsオブジェクトがmyXLevelsという名前のデータストアに保存されます。

例6-16では、C5.0モデルを生成するユーザー定義関数myC5.0FunctionForLevelsを作成します。この関数は、例6-13のようにas.factor関数をユーザー定義関数として使用してレベルを計算するのではなく、関数ore.getXlevelsにより返されたレベルのリストを使用します。レベルを使用して、列タイプを文字ベクターからファクタに変換します。関数myC5.0FunctionForLevelsは、値TRUEを返します。この例では、この関数をOracle R EnterpriseのRスクリプト・リポジトリに保存します。

次に、指定された文字列を含む名前のデータストアのリストを取得し、これらのデータストアが存在していれば削除します。

その後、ore.groupApplyを呼び出し、それによってCHURN_TESTデータの各状態に対して関数myC5.0FunctionForLevelsが呼び出されます。myC5.0FunctionForLevelsの呼出しのたびに、ore.groupApplyは、xlevelsオブジェクトを含むデータストアと、myC5.0FunctionForLevelsにより生成されたデータストアのネーミングに使用する接頭辞を渡します。また、ore.connect制御引数を渡して埋込みR関数でデータベースに接続することにより、データストアに格納されているオブジェクトを使用できるようにします。ore.groupApplyの呼出しにより、myC5.0FunctionForLevelsのすべての呼出しの結果を含むリストが返されます。

この例では、結果をローカルなRセッションにプルし、データソース内の各状態に対してmyC5.0FunctionForLevelsTRUEを返したことを確認します。

例6-16では次に、別のユーザー定義関数myScoringFunctionを作成し、Oracle R EnterpriseのRスクリプト・リポジトリに格納します。この関数は、状態のレベルでC5.0モデルをスコアリングし、結果をdata.frameで返します。

次に、関数ore.rowApplyを呼び出します。マサチューセッツ州のデータのみを使用するように入力データをフィルタ処理します。呼び出す関数としてmyScoringFunctionを指定し、xlevelsオブジェクトを含むデータストアの名前と、状態に対するC5.0モデルを含むデータストアをロードする際に使用する接頭辞をそのユーザー定義関数に渡します。ore.rowApplyの呼出しにより、各パラレルRエンジンでデータセット200行に対してmyScoringFunctionを呼び出すことを指定します。ore.rowApplymyScoringFunctionのすべての呼出しの結果を含むore.frameを返すように、FUN.VALUE引数を使用します。変数scoresは、ore.rowApply呼出しの結果を取得します。

例6-16では最後に、scoresオブジェクトを出力した後、表関数を使用してスコアリング用の混同マトリクスを表示します。

関連項目:

例6-16ore.rowApply関数と同じ結果を生成するrqRowEval関数の呼出しは、例A-8を参照してください。

例6-16 データストアおよびスクリプトを指定したore.rowApply関数の使用方法

library(C50)
data(churn)

ore.drop("CHURN_TEST"
ore.create(churnTest, "CHURN_TEST")

xlevels <- ore.getXlevels(~ ., CHURN_TEST[,-1])
ore.delete("myXLevels")
ore.save(xlevels, name = "myXLevels")

ore.scriptDrop("myC5.0FunctionForLevels")
ore.scriptCreate("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)
    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
  })

ds.v <- ore.datastore(pattern= "myC5.0modelFL")$datastore.name
for (ds in ds.v) ore.delete(name = ds)

res <- ore.groupApply(CHURN_TEST, 
          INDEX=CHURN_TEST$state,
          FUN.NAME = "myC5.0FunctionForLevels",
          xlevelsDatastore = "myXLevels",
          datastorePrefix = "myC5.0modelFL",
          ore.connect = TRUE)
res <- ore.pull(res)
all(as.logical(res) == TRUE)

ore.scriptDrop("myScoringFunction")
ore.scriptCreate("myScoringFunction",
                  function(dat, xlevelsDatastore, datastorePrefix) {
                     library(C50)
                     state <- dat[1,"state"]
                     datastoreName <- paste(datastorePrefix,state,sep="_")
                     dat$state <- NULL
                     ore.load(name = xlevelsDatastore)
                     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
                  }
                )

scores <- ore.rowApply(
  CHURN_TEST[CHURN_TEST$state == "MA",],
  FUN.NAME = "myScoringFunction",
  xlevelsDatastore = "myXLevels", 
  datastorePrefix = "myC5.0modelFL",
  ore.connect = TRUE, parallel = TRUE,
  FUN.VALUE = data.frame(pred = character(0), 
                         actual = character(0), 
                         state = character(0)),
  rows=200)
scores
table(scores$actual, scores$pred)
例6-16のリスト
R> library(C50)
R> data(churn)
R>
R> ore.drop("CHURN_TEST"
R> ore.create(churnTest, "CHURN_TEST")
R>
R> xlevels <- ore.getXlevels(~ ., CHURN_TEST[,-1])
R> ore.delete("myXLevels")
[1] "myXLevels
R> ore.save(xlevels, name = "myXLevels")
R>
R> ore.scriptDrop("myC5.0FunctionForLevels")
R> ore.scriptCreate("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)
+      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
+    })
R>
R> ds.v <- ore.datastore(pattern="myC5.0modelFL")$datastore.name
R> for (ds in ds.v) ore.delete(name=ds)
R>
R> res <- ore.groupApply(CHURN_TEST, 
+                       INDEX=CHURN_TEST$state,
+                       FUN.NAME="myC5.0FunctionForLevels",
+                       xlevelsDatastore = "myXLevels",
+                       datastorePrefix = "myC5.0modelFL",
+                       ore.connect = TRUE)
R> res <- ore.pull(res)
R> all(as.logical(res) == TRUE)
[1] TRUE
R>
R> ore.scriptDrop("myScoringFunction")
R> ore.scriptCreate("myScoringFunction",
+                    function(dat, xlevelsDatastore, datastorePrefix) {
+                      library(C50)
+                      state <- dat[1,"state"]
+                      datastoreName <- paste(datastorePrefix,state,sep="_")
+                      dat$state <- NULL
+                      ore.load(name = xlevelsDatastore)
+                      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
+                  }
+ )
R>
R> scores <- ore.rowApply(
+     CHURN_TEST[CHURN_TEST$state =="MA",],
+     FUN.NAME = "myScoringFunction",
+     xlevelsDatastore = "myXLevels",
+     datastorePrefix = "myC5.0modelFL",
+     ore.connect = TRUE, parallel = TRUE,
+     FUN.VALUE = data.frame(pred=character(0),
+                            actual=character(0),
+                            state=character(0)),
+     rows=200
R>
R> scores
   pred actual state
1    no     no    MA
2    no     no    MA
3    no     no    MA
4    no     no    MA
5    no     no    MA
6    no    yes    MA
7   yes    yes    MA
8   yes    yes    MA
9    no     no    MA
10   no     no    MA
11   no     no    MA
12   no     no    MA
13   no     no    MA
14   no     no    MA
15  yes    yes    MA
16   no     no    MA
17   no     no    MA
18   no     no    MA
19   no     no    MA
20   no     no    MA
21   no     no    MA
22   no     no    MA
23   no     no    MA
24   no     no    MA
25   no     no    MA
26   no     no    MA
27   no     no    MA
28   no     no    MA
29   no    yes    MA
30   no     no    MA
31   no     no    MA
32   no     no    MA
33  yes    yes    MA
34   no     no    MA
35   no     no    MA
36   no     no    MA
37   no     no    MA
38   no     no    MA
Warning message:
ORE object has no unique key - using random order
R> table(scores$actual, scores$pred)
 
      no yes
  no  32   0
  yes  2   4