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
オブジェクトを返します。
関連項目:
関数ore.rowApply
の引数の詳細は、「スクリプトを実行する関数の引数」を参照してください。
例6-15では、事前にCRANからダウンロードしてあるe1071
パッケージを使用します。また、この例では、例6-12で作成したNaive Bayesモデルであるnbmod
オブジェクトも使用します。
例6-15では、次の処理を行います。
パッケージe1071
をロードします。
iris
データセットをIRIS
一時表およびore.frame
オブジェクトとしてデータベースにプッシュします。
IRIS
をIRIS_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.0FunctionForLevels
がTRUE
を返したことを確認します。
例6-16では次に、別のユーザー定義関数myScoringFunction
を作成し、Oracle R EnterpriseのRスクリプト・リポジトリに格納します。この関数は、状態のレベルでC5.0モデルをスコアリングし、結果をdata.frame
で返します。
次に、関数ore.rowApply
を呼び出します。マサチューセッツ州のデータのみを使用するように入力データをフィルタ処理します。呼び出す関数としてmyScoringFunction
を指定し、xlevels
オブジェクトを含むデータストアの名前と、状態に対するC5.0モデルを含むデータストアをロードする際に使用する接頭辞をそのユーザー定義関数に渡します。ore.rowApply
の呼出しにより、各パラレルRエンジンでデータセット200行に対してmyScoringFunction
を呼び出すことを指定します。ore.rowApply
がmyScoringFunction
のすべての呼出しの結果を含むore.frame
を返すように、FUN.VALUE
引数を使用します。変数scores
は、ore.rowApply
呼出しの結果を取得します。
例6-16では最後に、scores
オブジェクトを出力した後、表関数を使用してスコアリング用の混同マトリクスを表示します。
例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