6 Oracle Machine Learning for Rの埋込みRの実行の使用

OML4Rの埋込みRの実行では、Oracle Databaseサーバーで稼働するRセッションでRスクリプトを起動できます。

次の各トピックでは、埋込みRの実行について説明します。

6.1 Oracle Machine Learning for Rの埋込みRの実行について

OML4Rでは、埋込みRの実行により、データベースによって動的に起動されて管理されるRエンジンでRスクリプトを実行できます。

RスクリプトをOML4Rスクリプト・リポジトリに格納し、埋込みRの関数を使用してこれらのスクリプトを起動できます。スクリプトを起動すると、そのスクリプトは、データベース・サーバーで稼働する1つ以上のRエンジンで実行されます。OML4Rでは、埋込みRの実行用にRインタフェースとSQLインタフェースの両方が提供されています。同じRスクリプトから、構造化データ、RオブジェクトおよびイメージのXML表現、さらにはデータベース表のBLOB列を介してPNGイメージを取得できます。

次の各トピックでは、埋込みRの実行について説明します。

6.1.1 埋込みRの実行の利点

埋込みRの実行には次の利点があります。

  • Oracle DatabaseサーバーからローカルのRセッションへデータを移動する必要がありません。

    セキュリティを向上するでなく、Oracle Databaseと内部Rエンジン間のデータベース・データの転送は、別個のクライアントRエンジンよりはるかに高速です。

  • データベース・サーバーを使用して、サーバーで稼働するRエンジンでRスクリプトの実行を開始、管理および制御します。

  • Rエンジンの実行に、データベース・サーバー・マシンのメモリーおよび処理能力を活用することで、より優れたスケーラビリティおよびパフォーマンスを提供します。

  • Hadoopのマップ/リデュース・ジョブの特殊なケースに対応したユーザー定義のR関数をデータ・パラレルおよびタスク・パラレルに実行できます。

  • パラレル・シミュレーション機能が装備されています。

  • データベース・サーバーで稼働するRスクリプトで、オープン・ソースのCRANパッケージを使用できます。

  • R環境を終了することなく、分析アプリケーション用の包括的なスクリプトを1つのステップで開発および操作できるようにする機能が装備されています。

    探索的分析で使用されるRスクリプトをアプリケーション・タスクに直接統合できます。また、移植を排除し、アプリケーション・コードに対する変更の即時更新を可能にすることによって、本番でRスクリプトをすばやく起動して、開発期間を大幅に減少できます。

  • SQLからRスクリプトを実行することで、Rスクリプトの結果をOracle Business Intelligence Enterprise Edition (OBIEE)、Oracle BI Publisherおよび構造化データ、Rオブジェクトおよびイメージ用のその他のSQL対応のツールと統合できます。

6.1.2 埋込みRの実行用のAPI

Oracle Machine Learning for Rには、埋込みRの実行用のRおよびSQLのアプリケーション・プログラミング・インタフェースがあります。

次の表は、埋込みRの実行およびOML4Rスクリプト・リポジトリの管理用のR関数とそれに対応するSQL関数およびプロシージャのリストです。関数fは、OML4Rスクリプト・リポジトリ内のスクリプトで定義されている名前付きR関数またはR関数を表します。

表6-1 埋込みRの実行用のRおよびSQLのAPI

RのAPI SQLのAPI 説明

ore.doEval

rqEval

データを自動転送せずにfを実行します。

ore.tableApply

rqTableEval

fの最初の引数として指定された入力ore.frameのすべての行を渡すことでfを実行します。fの最初の引数をdata.frameとして指定します。

ore.groupApply

rqGroupEval

この関数は、ユーザーが明示的に定義する必要があります。

グループ化列の値に応じてデータをパーティショニングすることでfを実行します。各データ・パーティションをfの最初の引数にdata.frameとして指定します。データベースのサーバー側Rエンジンで各f呼出しのパラレル実行をサポートします。

ore.rowApply

rqRowEval

指定された入力ore.frameの指定された行数(チャンク)を渡すことでfを実行します。各チャンクをfの最初の引数にdata.frameとして指定します。データベースのサーバー側Rエンジンで各f呼出しのパラレル実行をサポートします。

ore.indexApply

該当するものはありません。

データの自動転送なしでfを実行しますが、1からnまで(nは関数を呼び出す回数)の呼出しの索引を提供します。データベース・サーバーで稼働するRエンジンのプールでの各f呼出しのパラレル実行をサポートします。

ore.grant rqGrant データストアまたはスクリプトへの読取りアクセス権を付与します。
ore.revoke rqRevoke データストアまたはスクリプトへの読取りアクセス権を取り消します。

ore.scriptCreate

sys.rqScriptCreate

指定されたR関数を、指定された名前でOML4Rスクリプト・リポジトリに追加します。

ore.scriptDrop

sys.rqScriptDrop

指定されたR関数をOML4Rスクリプト・リポジトリから削除します。

ore.scriptList ALL_RQ_SCRIPTS

USER_RQ_SCRIPTS

スクリプトに関する情報をリストします。
ore.scriptLoad 該当するものはありません。 スクリプトのR関数をR環境にロードします。

6.1.3 スクリプトのセキュリティ

Rスクリプトではデータベース・サーバーへのアクセスが許可されるため、スクリプトの作成を制御する必要があります。

RQADMINロールは、ユーザーがスクリプトを作成してOracle Machine Learning for Rのスクリプト・リポジトリに格納したり、スクリプトをリポジトリから削除するために必要なOracle Database権限の集合です。

OML4Rをデータベース・サーバーにインストールすると、RQADMINロールが作成されます。このロールは、明示的にユーザーに付与する必要があります。RQADMINをユーザーに付与するには、SQL*Plusをsysdbaで起動し、次のようなGRANT文(ロールをユーザーOML_USERに付与します)を入力します。

GRANT RQADMIN to OML_USER

ノート:

RQADMINは、必要とするユーザーにのみ付与してください。

スクリプトを作成するとき、所有者は、global引数を使用して、スクリプトがパブリックであるか、プライベートであるかを指定できます。global = TRUEの場合、すべてのユーザーにスクリプトへの読取りアクセス権があります。global = FALSEの場合(デフォルト)、所有者は、他のユーザーにアクセス権を付与することにより、スクリプトを共有できます。所有者は、アクセス権をいつでも取り消すことができます。

6.1.4 パラレル実行のサポート

Oracle Machine Learning for Rの埋込みRの実行関数の一部では、データベースでのパラレル実行の使用がサポートされています。

関数ore.groupApplyore.rowApplyrq.groupEvalおよびrq.rowEvalはデータ・パラレル実行をサポートし、ore.indexApplyはタスク・パラレル実行をサポートします。このパラレル実行機能によって、Oracle Exadataデータベース・マシンなどの高パフォーマンスのコンピューティング・ハードウェアをスクリプトで利用できます。

関数ore.groupApplyore.rowApplyおよびore.indexApplyparallel引数には、埋込みRの実行で使用する並列度を指定します。引数の値には、次のいずれかを指定できます。

  • 特定の並列度では、2以上の正の整数

  • パラレル化しない場合は、FALSEまたは1

  • data引数のデフォルトのパラレル化の場合はTRUE

  • 操作に対するデータベースのデフォルトはNULL

この引数のデフォルト値は、グローバル・オプションore.parallelの値、またはore.parallelが設定されていない場合はFALSEです。

ore.doEvalまたはore.tableApplyを使用して呼び出したユーザー定義のR関数は、並行して実行されません。このような関数は1つのRエンジンで実行されます。

rq.groupEval関数およびrq.rowEval関数の場合、並列度は入力カーソル引数のPARALLELヒントによって指定します。

ore.groupApply関数およびrq.groupEval関数のデータ・パラレル実行では、1つ以上のRエンジンが同じR関数(タスク)を別のデータ・パーティションで実行します。この機能によって、たとえば何万または何十万もの予測モデルを顧客に1モデルずつ構築するなどの、多数のモデルの構築が可能です。

ore.rowApply関数およびrq.rowEval関数のデータ・パラレル実行では、1つ以上のRエンジンが同じR関数をデータの非結合チャンクで実行します。この機能によって、大規模なデータセットでのスケーラブルなモデルのスコアリングおよび予測が可能です。

ore.indexApply関数のタスク・パラレル実行では、1つ以上のRエンジンが同じまたは異なる計算(タスク)を実行します。実行の索引に関連付けられている数字が、関数に提供されます。この機能は、シミュレーションの実行などの各種の操作で重要です。

Oracle Databaseは、複合的である可能性のあるRエンジンの管理および制御をデータベース・サーバーで処理し、自動的にパーティショニングしてデータをRエンジンに渡して並行して実行します。すべてのパーティションですべてのR関数の実行が完了することが保証されますが、そうでない場合はOML4Rの関数はエラーを返します。各ユーザー定義の埋込みR関数の実行結果は、ore.listに収集されます。このリストは、ユーザーが結果を要求するまでデータベースに保持されます。

埋込みRの実行では、Comprehensive R Archive Network (CRAN)のオープン・ソースのRパッケージまたは他のサード・パーティのRパッケージの関数を使用する可能性のあるユーザー定義のR関数のデータ・パラレル実行も可能です。ただし、サード・パーティのパッケージは、インデータベース並列性を活用しないため、Rの並列性制約の対象となります。サード・パーティのパッケージは、埋込みRの実行でサポートされているデータ・パラレル実行およびタスク・パラレル実行を利用できます。

6.1.5 埋込みRの実行で使用するためのサード・パーティのパッケージのインストール

埋込みRの実行では、Oracle Databaseサーバーで実行されるユーザー定義のR関数で、CRANまたは他のサード・パーティのパッケージを使用できます。

埋込みRの実行でサード・パーティのパッケージを使用するには、そのパッケージをデータベース・サーバーにインストールする必要があります。埋込みRの実行用のRインタフェースでこのパッケージを使用する場合は、パッケージをクライアントにもインストールする必要があります。非互換性を回避するために、クライアント・マシンとサーバー・マシンの両方に同じバージョンのパッケージをインストールする必要があります。

Oracle Database管理者(DBA)は、埋込みR関数またはすべてのRユーザーが使用できるようにパッケージをデータベース・サーバーにインストールできます。DBAは、パッケージを1つまたは複数のデータベース・サーバーにインストールできます。

通常、DBAは次の手順を実行します。

  1. CRANからパッケージをダウンロードしてインストールします。CRANからパッケージをダウンロードするには、インターネット接続が必要です。
  2. サーバーで稼働するOracle Machine Learning for Rセッションで、パッケージをロードします。パッケージ内の関数を使用して、パッケージが正しくインストールされていることを確認します。

1つのデータベース・サーバーにパッケージをインストールするには、次のいずれかを実行します。

  • サーバーで稼働するOML4Rセッションで、例6-1に示すようにinstall.packages関数を呼び出します。この関数によって自動的にパッケージがダウンロードされ、依存性がインストールされます。

  • wgetを使用してCRANからパッケージ・ソースをダウンロードします。このパッケージが、使用されているR Distribution内にないパッケージのいずれかに依存している場合は、それらのパッケージもダウンロードします。

    オペレーティング・システムのコマンドラインからORE CMD INSTALLコマンドを使用して、このパッケージをOML4Rパッケージと同じ場所($ORACLE_HOME/R/library)にインストールします。例6-2を参照してください。

パッケージおよび依存パッケージをOracle Real Application Clusters (Oracle RAC)や複数ノードのOracle Exadataデータベース・マシン環境などの複数のデータベース・サーバーにインストールする場合は、例6-3に示すように、Exadata Distributed Command Line Interface (DCLI)ユーティリティを使用します。

パッケージが正しくインストールされたことを確認するには、例6-4に示すように、パッケージをロードしてパッケージ内の関数を使用します。

例6-1 OML4Rセッションでの単一データベースへのパッケージのインストール

この例では、install.packages関数を呼び出して、CRANからC50パッケージをダウンロードし、インストールします。C50パッケージには、C5.0デシジョン・ツリーおよびパターン認識用のルールベース・モデルを作成するための関数が含まれています。

この例の出力は示されていませんが、例6-2ORE CMD INSTALLコマンドの出力とほとんど同じです。

install.packages("c50")

例6-2 コマンドラインからの単一データベースへのパッケージのインストール

この例では、LinuxコマンドラインからORE CMD INSTALLを使用して、CRANからC50パッケージをダウンロードし、インストールする方法を示します。

wget http://cran.r-project.org/src/contrib/C50_0.1.0-19.tar.gz
ORE CMD INSTALL C50_0.1.0-19.tar.gz

この例のリスト

$ wget http://cran.r-project.org/src/contrib/C50_0.1.0-19.tar.gz
# The output of wget is not shown.
$ ORE CMD INSTALL C50_0.1.0-19.tar.gz
* installing to library '/example/dbhome_1/R/library'
* installing *source* package 'C50' ...
** package 'C50' successfully unpacked and MD5 sums checked
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
configure: creating ./config.status
config.status: creating src/Makevars
** libs
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c attwinnow.c -o attwinnow.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c classify.c -o classify.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c confmat.c -o confmat.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c construct.c -o construct.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c contin.c -o contin.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c discr.c -o discr.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c formrules.c -o formrules.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c formtree.c -o formtree.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c getdata.c -o getdata.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c getnames.c -o getnames.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c global.c -o global.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c hash.c -o hash.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c hooks.c -o hooks.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c implicitatt.c -o implicitatt.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c info.c -o info.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c mcost.c -o mcost.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c modelfiles.c -o modelfiles.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c p-thresh.c -o p-thresh.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c prune.c -o prune.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c rc50.c -o rc50.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c redefine.c -o redefine.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c rsample.c -o rsample.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c rulebasedmodels.c -o rulebasedmodels.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c rules.c -o rules.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c ruletree.c -o ruletree.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c siftrules.c -o siftrules.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c sort.c -o sort.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c strbuf.c -o strbuf.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c subset.c -o subset.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c top.c -o top.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c trees.c -o trees.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c 
update.c -o update.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c utility.c -o utility.o
gcc -m64 -std=gnu99 -I/usr/include/R -DNDEBUG -DNDEBUG -I/usr/local/include   -ffloat-store -g -fpic  -g -O2  -c xval.c -o xval.o
gcc -m64 -std=gnu99 -shared -L/usr/local/lib64 -o C50.so attwinnow.o classify.o confmat.o construct.o contin.o discr.o formrules.o formtree.o getdata.o getnames.o global.o hash.o hooks.o implicitatt.o info.o mcost.o modelfiles.o p-thresh.o prune.o rc50.o redefine.o rsample.o rulebasedmodels.o rules.o ruletree.o siftrules.o sort.o strbuf.o subset.o top.o trees.o update.o utility.o xval.o -L/usr/lib64/R/lib -lR
installing to /example/dbhome_1/R/library/C50/libs
** R
** data
** preparing package for lazy loading
** help
*** installing help indices
  converting help for package 'C50'
    finding HTML links ... done
    C5.0                                    html  
    C5.0Control                             html  
    churn                                   html  
    predict.C5.0                            html  
    summary.C5.0                            html  
    varImp.C5.0                             html  
** building package indices
** testing if installed package can be loaded
* DONE (C50)

例6-3 DCLIを使用したパッケージのインストール

この例では、C50パッケージをインストールするためのDLCIコマンドを示します。dcli -gフラグはインストール先のノードのリストを含むファイルを指定し、-lフラグはコマンドの実行時に使用するユーザーIDを指定します。

dcli -g nodes -l oracle R CMD INSTALL C50_0.1.0-19.tar.gz

例6-4 C50パッケージ関数の使用方法

この例では、Rを起動し、サーバー上のOML4Rに接続して、C50パッケージをロードし、パッケージ内の関数を使用する方法を示します。この例では、LinuxコマンドラインからOREコマンドを実行してRを起動します。また、OML4Rに接続して、C50パッケージをロードします。demo関数を呼び出して、パッケージ内のサンプル・プログラムを検索します。このパッケージにはサンプルが含まれていないため、この例ではC5.0関数のヘルプを取得します。このヘルプからサンプル・コードを呼び出します。

ORE

library(ORE)
ore.connect(user = "OML_USER", sid = "orcl", host = "myhost", 
            password = "oml_userStrongPassword", port = 1521, all=TRUE)

library(C50)
demo(package = "C50")
?C5.0
data(churn)
treeModel <- C5.0(x = churnTrain[, -20], y = churnTrain$churn)
treeModel

この例のリスト

$ ORE

R> library(ORE)
Loading required package: OREbase
 
Attaching package: 'OREbase'
 
The following objects are masked from 'package:base':
 
    cbind, data.frame, eval, interaction, order, paste, pmax, pmin,
    rbind, table
 
Loading required package: OREembed
Loading required package: OREstats
Loading required package: MASS
Loading required package: OREgraphics
Loading required package: OREeda
Loading required package: OREmodels
Loading required package: OREdm
Loading required package: lattice
Loading required package: OREpredict
Loading required package: ORExml
 
> ore.connect(user = "OML_USER", sid = "orcl", host = "myhost", 
+             password = "oml_userStrongPassword", port = 1521, all=TRUE)
Loading required package: ROracle
Loading required package: DBI
 
R> library(C50)
R> demo(package = "C50")
no demos found
R> ?C5.0     # Output not shown.
R> data(churn)
R> treeModel <- C5.0(x = churnTrain[, -20], y = churnTrain$churn)
R> treeModel
Call:
C5.0.default(x = churnTrain[, -20], y = churnTrain$churn)
 
Classification Tree
Number of samples: 3333 
Number of predictors: 19 
 
Tree size: 27 
 
Non-standard options: attempt to group attributes

6.2 埋込みRの実行用のRインタフェース

Oracle Machine Learning for Rには、Oracle Databaseに埋め込まれている1つ以上のRエンジンで実行するRスクリプトを起動する関数があります。

他には、R関数の作成およびスクリプトとしてのOML4Rスクリプト・リポジトリへの格納、スクリプトへの読取りアクセス権の付与または取消し、使用可能なスクリプトのリスト、R環境へのスクリプト関数のロード、またはリポジトリからのスクリプトの削除を行う関数があります。この項では、次の各トピックでこれらの関数について説明します。

6.2.1 スクリプトを実行する関数の引数

Oracle Machine Learning for Rの埋込みRの実行関数のore.doEvalore.tableApplyore.groupApplyore.rowApplyおよびore.indexApplyには、これらの関数の一部またはすべてに共通の引数があります。

一部の関数には、その関数に固有の引数もあります。次の各トピックでは、これらの引数について説明します。

関連項目:

  • 関数シグネチャおよび関数の引数の詳細は、help(ore.doEval)を呼び出すことで表示されるオンライン・ヘルプを参照してください。

  • 引数の使用例は、「ore.doEval関数の使用方法」および埋込みRの実行関数の使用方法に関するその他のトピックを参照してください

6.2.1.1 実行するための入力関数

すべての埋込みRの実行関数には、スクリプトの実行時に適用するR関数が必要です。

次の相互に排他的な引数のどちらかを使用して入力関数を指定します。

  • FUN

  • FUN.NAME (およびオプションのFUN.OWNER)

FUN引数は、関数オブジェクトを直接指定された関数としてまたはR変数に割り当てられた関数として使用します。RQADMINロールを持つユーザーのみが、埋込みR関数の呼出し時にFUN引数を使用できます。

FUN.NAME引数は、OML4RのRスクリプト・リポジトリに格納されているスクリプトを指定します。格納されたスクリプトには、スクリプトの実行時に適用する関数が含まれます。すべてのOML4Rユーザーが、埋込みR関数の呼出し時にFUN.NAME引数を使用できます。

オプションの引数FUN.OWNERには、Rスクリプト・リポジトリ内のスクリプトの所有者を指定します。所有者は、スクリプトを作成したユーザーです。この引数は、FUN.NAME引数とともにのみ使用します。FUN.NAMEが、読取りアクセス権を付与されているプライベート・スクリプトである場合は、FUN.OWNNERを使用して、プライベート・スクリプトの所有者を指定してください。

RQSYSスキーマは、パブリック・スクリプトおよび事前定義済のOML4Rスクリプトの所有者です。事前定義済スクリプトのリストは、help("ore.doEval")を呼び出し、FUN.NAME引数の説明を参照してください。FUN.OWNNERが指定されていないか、NULLである場合、OML4Rによって、現行のセッションのユーザー、RQSYSの順に所有者が検索されます。スクリプトの所有者が現行のユーザーまたはRQSYSでない場合は、エラーが発生します。

ノート:

OREmodelsパッケージのOML4R関数であるore.glmore.lmore.neuralおよびore.randomForestは、埋込みRの実行フレームワークを内部で使用し、埋込みRの実行関数では使用できません。

6.2.1.2 オプションの制御引数

すべての埋込みRの実行関数は、指定が可能または不可能なオプションの引数を取ります。

Oracle Machine Learning for Rは、ユーザー定義のオプションの引数を入力関数に渡します。モデルなどの複合Rオブジェクトを含む入力関数に、任意の数のオプションの引数を渡すことができます。

ore.で始まる引数は、特殊な制御引数です。OML4Rはそれらを入力関数に渡しませんが、かわりに、それらを使用して入力関数の実行前または後に発生することを制御します。次の制御引数がサポートされます。

  • ore.connectは、埋込みRの実行関数内でOML4Rに自動的に接続するかどうかを制御します。これは、クライアント・セッションと同じ資格証明を指定してore.connectをコールすることと同等です。デフォルト値はFALSEです。

    自動接続を有効にすると、次の機能を実現できます。

    • 埋込みRスクリプトがデータベースに接続されます。

    • 接続は、埋込みR SQL関数を呼び出すセッションと同じ資格証明を持ちます。

    • このスクリプトは自律型トランザクション内で実行されます。

    • ROracle問合せは自動接続と連携できます。

    • OML4Rの透過層の機能が埋込みスクリプトで使用可能になります。

  • ore.dropは入力データを制御します。オプション値がTRUEの場合、1列のdata.framevectorに変換されます。デフォルト値はTRUEです。

  • ore.envAsEmptyenvは、シリアライズ中にオブジェクト内の参照される環境を空の環境で置き換えるかどうかを制御します。一部のタイプの入力パラメータおよび戻りオブジェクト(listformulaなど)は、データベースに保存される前にシリアライズされます。制御引数の値がTRUEの場合、オブジェクト内の参照される環境は親が.GlobalEnvである空の環境で置き換えられ、参照される元の環境内のオブジェクトはシリアライズされません。これにより、シリアライズされるオブジェクトのサイズを大幅に削減できる場合があります。制御引数の値がFALSEの場合、参照される環境内のすべてのオブジェクトがシリアライズされますが、後からシリアライズ解除してリカバリすることができます。デフォルト値は、グローバル・オプションore.envAsEmptyenvによって決定されます。

  • ore.na.omit入力データの欠損値の処理を制御します。ore.na.omit = TRUEを指定した場合、欠損値を含む行またはベクター要素(ore.drop設定に応じて)が入力データから削除されます。チャンクのすべての行に欠損値がある場合、そのチャンクの入力データは空のdata.frameまたはvectorになります。デフォルト値はFALSEです。

  • ore.graphicsは、グラフィカル・ドライバを起動して画像を検索するかどうかを制御します。デフォルト値はTRUEです。

  • ore.png.*には、ore.graphicsTRUEの場合に、pngグラフィック・ドライバの追加引数を指定します。これらの引数のネーミング規則では、png関数の引数にore.png.接頭辞を追加します。たとえば、ore.png.heightを指定すると、引数heightpng関数に渡されます。設定しない場合は、png関数に標準のデフォルト値が使用されます。

関連項目:

制御引数の詳細は、help(ore.doEval)を呼び出すことで表示されるオンライン・ヘルプを参照してください。

6.2.1.3 戻り値の構造

すべての埋込みRの実行関数に適用されるもう1つの引数にFUN.VALUEがあります。

FUN.VALUE引数がNULLの場合、ore.doEval関数およびore.tableApply関数はore.objectクラス・オブジェクトとしてシリアライズRオブジェクトを返し、ore.groupApplyore.indexApplyおよびore.rowApplyの各関数はore.listオブジェクトを返します。ただし、data.frameまたはore.frameFUN.VALUE引数を指定した場合、この関数は、指定したdata.frameオブジェクトまたはore.frameオブジェクトの構造を持つore.frameを返します。

ore.frameの対応する出力列がCLOBまたはBLOBデータベース・データ型を持つように指定するには、FUN.VALUE data.frameの列に属性ora.typeを適用できます。ora.typeの使用例は、例6-11を参照してください。

6.2.1.4 入力データ

ore.doEval関数およびore.indexApply関数は、データベースから自動的にデータを受け取りません。

FUN引数またはFUN.NAME引数で指定された関数を単純に実行します。入力関数で必要なすべてのデータは、その関数内で生成されるか、Oracle Database、その他のデータベースまたはフラット・ファイルなどのデータ・ソースから明示的に取得するかのいずれかです。入力関数は、ore.pull関数またはその他の透過層関数を使用して、ファイルまたは表からデータをロードできます。

ore.tableApplyore.groupApplyおよびore.rowApplyの各関数には、入力データとしてデータベース表が必要です。この表はore.frameで表されます。このデータに、X引数(埋込みRの実行関数の最初の引数)で指定するore.frameを指定します。埋込みRの実行関数は、ore.frameオブジェクトを最初の引数としてユーザー定義の入力関数に渡します。

ノート:

ユーザー定義のR関数に渡されたore.frameオブジェクトによって表されるデータは、Oracle Databaseからデータベース・サーバーのRエンジンにコピーされます。Rメモリーの制限が適用されます。データベース・サーバー・マシンに32GBのRAMがあり、データ表が64GBの場合、Oracle R EnterpriseはデータをRエンジンのメモリーにロードできません。

6.2.1.5 パラレル実行

parallel引数は、入力関数の埋込みRの実行で使用する並列度を指定します。

ore.groupApplyore.indexApplyおよびore.rowApplyの各関数は、parallel引数を取ります。

「パラレル実行のサポート」を参照してください。

6.2.1.6 固有の引数

関数ore.groupApplyore.indexApplyおよびore.rowApplyは、それぞれの関数に固有の引数を取ります。

ore.groupApply関数はINDEX引数を取り、これには、入力データの行が入力関数での処理のためにパーティショニングされる列の名前を指定します。

ore.indexApply関数はtimes引数を取り、これには、入力関数を実行する回数を指定します。

ore.rowApply関数はrows引数を取り、これには、入力関数の各呼出しに渡す行の数を指定します。

6.2.2 Rでのスクリプトの管理

埋込みRの実行関数で、OML4Rスクリプト・リポジトリにスクリプトとして格納されているR関数を呼び出すことができます。このトピックで説明するR関数を使用すると、スクリプトを作成および管理できます。

埋込みRの実行関数はFUN.NAME引数を取ることができます。その引数は、OML4Rスクリプト・リポジトリ内のスクリプトの名前を指定します。Rスクリプト・リポジトリ内のスクリプトは、埋込みRの実行用のSQL APIインタフェースで使用することもできます。

スクリプトを管理するためのR関数は次のとおりです。

  • ore.grant

  • ore.revoke

  • ore.scriptCreate

  • ore.scriptList

  • ore.scriptLoad

  • ore.scriptDrop

これらの関数については、次の各項で説明します。

これらの関数の使用例は、例6-5を参照してください。

スクリプトの追加

OML4Rスクリプト・リポジトリにスクリプトとしてR関数を追加するには、ore.createScript関数を使用します。この関数を呼び出すには、RQADMINロールを持っている必要があります。ore.createScript関数の構文は次のとおりです。

ore.scriptCreate(name, FUN, global, overwrite)

引数について、次に説明します。

引数 説明
name OML4Rスクリプト・リポジトリ内のスクリプトの名前。
fun R関数。
global スクリプトがパブリック(グローバル)であるか、プライベートであるかを示す論理値。FALSE (デフォルト)は、スクリプトがパブリックではなく、所有者または所有者が読取りアクセス権を付与したユーザーにのみ表示されることを示します。TRUEは、スクリプトがパブリックであるため、すべてのユーザーに表示されることを示します。
overwrite スクリプトのR関数を、fun引数で指定した関数に置き換えるかどうかを示す論理値。TRUEは、関数を置き換えることを示します(存在する場合)。FALSE (デフォルト)は、既存の内容を置き換えることができないことを示します。

overwrite = FALSEであるときに、同じ名前のスクリプトがOML4Rスクリプト・リポジトリにすでに存在する場合、エラー条件が発生します。それ以外の場合、ore.scriptCreateNULLを返します。

スクリプトへの読取りアクセス権の付与または取消し

スクリプトの作成者は、ore.grant関数を使用してスクリプトへの読取りアクセス権を付与したり、ore.revoke関数を使用してそのアクセス権を取り消すことができます。これらの関数の構文は次のとおりです。

ore.grant(name, type = "rqscript", user)
ore.revoke(name, type = "rqscript", user)

引数について、次に説明します。

引数 説明
name OML4Rスクリプト・リポジトリ内のスクリプトの名前。
type スクリプトの場合、タイプはrqscriptです。
user 読取りアクセス権を付与する、または取り消すユーザー。

nameおよびtype引数は必須です。引数userを指定しなかった場合、読取りアクセス権がすべてのユーザーに付与されるか、すべてのユーザーから取り消されます。

次のいずれかに該当する場合、エラーが発生します。

  • 指定したスクリプトがOML4Rスクリプト・リポジトリ内にありません。

  • type引数が指定されていません。

  • ユーザーが見つかりません。

  • 読取り権限がすでにユーザーに付与されているか、ユーザーから取り消されています。

  • 指定したスクリプトがパブリックです。

使用可能なスクリプトのリスト

自分が使用できるスクリプトをリストするには、ore.scriptListを使用します。名前、パターンまたはタイプに基づいてスクリプトをリストできます。RQADMINロールを持っている場合は、システム・スクリプトもリストできます。関数の構文は次のとおりです。

ore.scriptList(name, pattern, type)

引数について、次に説明します。

引数 説明
name OML4Rスクリプト・リポジトリ内のスクリプトの名前。引数patternを指定する場合は使用できません。
pattern 正規表現パターン。パターンと一致するスクリプトがリストされます。引数nameを指定する場合は使用できません。
type スクリプトのタイプとして、次のいずれかを指定できます。
  • user: 現行のユーザーが所有しているスクリプトがリストされます。

  • global: すべてのユーザーに表示されるパブリック・スクリプトがリストされます。

  • grant: 現行のユーザーが他のユーザーに読取りアクセス権を付与したスクリプトがリストされます。

  • granted: 現行のユーザーが別のユーザーによって読取りアクセス権を付与されたスクリプトがリストされます。

  • all: ユーザーのスクリプト、パブリック・スクリプトおよびアクセス権を付与されたスクリプトがすべてリストされます。

ore.scriptList関数は、OML4Rスクリプト・リポジトリ内のスクリプトおよびスクリプト内の関数の名前を含むdata.frameを返します。

R環境へのスクリプトのロード

R環境にスクリプトのR関数をロードするには、ore.scriptLoadを使用し、その構文は次のとおりです。

ore.scriptLoad(name, owner, newname, envir)

引数について、次に説明します。

引数 説明
name OML4Rスクリプト・リポジトリ内のスクリプトの名前。
owner スクリプトの所有者。
newname スクリプトをロードする新しい関数名。
envir スクリプトをロードするR環境。

ore.scriptLoadを呼び出すユーザーにスクリプトへのアクセス権が付与されている場合、スクリプトの所有者を指定すると便利です。

OML4Rスクリプト・リポジトリ内のスクリプトの名前が有効なR関数名でない場合、新しい関数名を指定すると便利です。

次のいずれかに該当する場合、エラーが発生します。

  • スクリプトがOML4Rスクリプト・リポジトリ内にありません。

  • 現行のユーザーにスクリプトへの読取りアクセス権がありません。

  • name引数で指定した関数が有効なR関数名ではありません。

  • newname引数が有効なR関数名ではありません。

スクリプトの削除

OML4Rスクリプト・リポジトリからスクリプトを削除するには、ore.scriptDrop関数を使用します。この関数を呼び出すには、RQADMINロールを持っている必要があります。ore.scriptDrop関数の構文は次のとおりです。

ore.scriptDrop(name, global, silent)

引数について、次に説明します。

引数 説明
name OML4Rスクリプト・リポジトリ内のスクリプトの名前。
global スクリプトがグローバル(パブリック)であるか、プライベートであるかを示す論理値。TRUEは、グローバル・スクリプトを削除することを示します。FALSE (デフォルト)は、現行のユーザーが所有しているスクリプトを削除することを示します。
silent ore.scriptDropでエラー条件が検出された場合にエラー・メッセージを表示するかどうかを示す論理値。TRUEは、エラー・メッセージを表示することを示します。FALSE (デフォルト)は、表示しないことを示します。

次のいずれかに該当する場合、エラー条件が発生します。

  • スクリプトがOML4Rスクリプト・リポジトリ内にありません。

  • global = TRUEの場合に、スクリプトがプライベート・スクリプトです。

  • global = FALSEの場合に、スクリプトがパブリック・スクリプトです。

成功すると、ore.scriptDropNULLを返します。

例6-5 Rスクリプト管理関数の使用方法

# Create an ore.frame object from the data.frame for the iris data set.
IRIS <- ore.push(iris)

# Create a private R script for the current user.
ore.scriptCreate("myRandomRedDots", function(divisor = 100){
                 id <- 1:10
                 plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 2 )
                 data.frame(id = id, val = id / divisor)
                 })

# Create another private R script.
ore.scriptCreate("MYLM",
                 function(data, formula, ...) lm(formula, data, ...))

# Create a public script, available to any user.
ore.scriptCreate("GLBGLM",
                 function(data, formula, ...) 
                 glm(formula = formula, data = data, ...),
                 global = TRUE)

# List only my private scripts.
ore.scriptList()                

# List my private scripts and the public scripts. 
ore.scriptList(type = "all")    

# List my private scripts that have the specified pattern.
ore.scriptList(pattern = "MY")  

# Grant read access to a private script to all users.
ore.grant("MYLM", type = "rqscript")

# Grant read access to a private script to a specific user.
ore.grant("myRandomRedDots", user = "SCOTT",  type = "rqscript")

# List the granted scripts.
ore.scriptList(type = "grant")

# Use the MYLM script in an embedded R execution function.
ore.tableApply(IRIS[1:4], FUN.NAME = "MYLM",
               formula = Sepal.Length ~ .)
# Use the GLBGLM script in an embedded R execution function.
ore.tableApply(IRIS[1:4], FUN.NAME = "GLBGLM",
               formula = Sepal.Length ~ .)

# Load an R script to an R function object
ore.scriptLoad(name = "MYLM")

# Invoke the function.
MYLM(iris, formula = Sepal.Length ~ .)

# Load another R script to an R function object
ore.scriptLoad(name = "GLBGLM", newname = "MYGLM")

# Invoke the function.
MYGLM(iris, formula = Sepal.Length ~ .)

# Drop some scripts.
ore.scriptDrop("MYLM")
ore.scriptDrop("GLBGLM", global = TRUE)

# List all scripts.
ore.scriptList(type = "all")

この例のリスト

R> # Create an ore.frame object from the data.frame for the iris data set.
R> IRIS <- ore.push(iris)
R> 
R> # Create a private R script for the current user.
R> ore.scriptCreate("myRandomRedDots", function(divisor = 100){
+                   id <- 1:10
+                   plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 2 )
+                   data.frame(id = id, val = id / divisor)
+                   })
R> 
R> # Create another private R script.
R> ore.scriptCreate("MYLM",
+                   function(data, formula, ...) lm(formula, data, ...))
R> 
R> # Create a public script, available to any user.
R> ore.scriptCreate("GLBGLM",
+                   function(data, formula, ...) 
+                   glm(formula = formula, data = data, ...),
+                   global = TRUE)
R> 
R> # List only my private scripts.
R> ore.scriptList()
             NAME      SCRIPT
1            MYLM      function (data, formula, ...) \nlm(formula, data, ...)
2 myRandomRedDots      function (divisor = 100) \n{\n    id & lt\n    -1:10\n
                       plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 2)\n
                       data.frame(id = id, val = id/divisor)\n}
R> 
R> # List my private scripts and the public scripts. 
R> ore.scriptList(type = "all")    
   OWNER              NAME    SCRIPT
1  RQSYS            GLBGLM    function (data, formula, ...) \nglm(formula = formula, data = data, ...)
2 OML_USER            MYLM    function (data, formula, ...) \nlm(formula, data, ...)
3 OML_USER myRandomRedDots    function (divisor = 100) \n{\n    id & lt\n    -1:10\n
                              plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 2)\n
                              data.frame(id = id, val = id/divisor)\n}
R> 
R> # List my private scripts that have the specified pattern.
R> ore.scriptList(pattern = "MY")
  NAME  SCRIPT
1 MYLM  function (data, formula, ...) \nlm(formula, data, ...)
R> 
R> # Grant read access to a private script to all users.
R> ore.grant("MYLM", type = "rqscript")
R> 
R> # Grant read access to a private script to a specific user.
R> ore.grant("myRandomRedDots", user = "SCOTT",  type = "rqscript")
R> 
R> # List the granted scripts.
R> ore.scriptList(type = "grant")
             NAME GRANTEE
1            MYLM  PUBLIC
2 myRandomRedDots   SCOTT
R> 
R> # Use the MYLM script in an embedded R execution function.
R> ore.tableApply(IRIS[1:4], FUN.NAME = "MYLM",
+                 formula = Sepal.Length ~ .)

Call:
lm(formula = formula, data = data)

Coefficients:
 (Intercept)   Sepal.Width  Petal.Length   Petal.Width  
      1.8560        0.6508        0.7091       -0.5565 
R> 
R> # Use the GLBGLM script in an embedded R execution function.
R> ore.tableApply(IRIS[1:4], FUN.NAME = "GLBGLM",
+                formula = Sepal.Length ~ .) 

Call:  glm(formula = formula, data = data)

Coefficients:
 (Intercept)   Sepal.Width  Petal.Length   Petal.Width  
      1.8560        0.6508        0.7091       -0.5565  

Degrees of Freedom: 149 Total (i.e. Null);  146 Residual
Null Deviance:      102.2 
Residual Deviance: 14.45        AIC: 84.64
R> 
R> # Load an R script to an R function object
R> ore.scriptLoad(name="MYLM")
R> 
R> # Invoke the function.
R> MYLM(iris, formula = Sepal.Length ~ .)
R> 
R> # Load another R script to an R function object
R> ore.scriptLoad(name = "GLBGLM", newname = "MYGLM")
R> 
R> # Invoke the function.
R> MYGLM(iris, formula = Sepal.Length ~ .)
R> 
R> # Drop some scripts.
R> ore.scriptDrop("MYLM")
R> ore.scriptDrop("GLBGLM", global = TRUE)
R> 
R> # List all scripts.
R> ore.scriptList(type = "all")
   OWNER               NAME    SCRIPT
  OML_USER  myRandomRedDots    function (divisor = 100) \n{\n    id & lt\n    -1:10\n
                               plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 
                               2)\n data.frame(id = id, val = id/divisor)\n}

関連項目:

6.2.3 ore.doEval関数の使用

ore.doEval関数は、入力関数によって生成されたデータを使用して指定された入力関数を実行します。

ore.frameオブジェクトまたはシリアライズRオブジェクトをore.objectオブジェクトとして返します。

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

ore.doEval(FUN, ..., FUN.VALUE = NULL, FUN.NAME = NULL, FUN.OWNER = NULL)

関連項目:

関数ore.doEvalの引数の詳細は、「スクリプトを実行する関数の引数」を参照してください

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

この例では、RandomRedDotsによって、1つの引数を取り、2つの列を持つdata.frameオブジェクトを返し、100個のランダム標準値を表示する関数を取得します。次に、ore.doEval関数を呼び出して、RandomRedDots functionオブジェクトを渡します。イメージがクライアントに表示されますが、これはRandomRedDots関数を実行したデータベース・サーバーのRエンジンによって生成されます。

RandomRedDots <- function(divisor = 100){
  id<- 1:10
  plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 2 )
  data.frame(id=id, val=id / divisor)
}
ore.doEval(RandomRedDots)

この例のリスト

R> RandomRedDots <- function(divisor = 100){
+   id<- 1:10
+   plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 2 )
+   data.frame(id=id, val=id / divisor)
+ }
R> ore.doEval(RandomRedDots)
   id  val
1   1 0.01
2   2 0.02
3   3 0.03
4   4 0.04
5   5 0.05
6   6 0.06
7   7 0.07
8   8 0.08
9   9 0.09
10 10 0.10

図6-1 ランダムの赤い点の表示

図6-1の説明が続きます
「図6-1 ランダムの赤い点の表示」の説明

例6-7 オプションの引数を指定したore.doEval関数の使用方法

doEval関数のオプションの引数として入力関数に引数を指定できます。この例では、RandomRedDots関数のdivisor引数をオーバーライドするオプションの引数を指定してdoEval関数を呼び出します。

ore.doEval(RandomRedDots, divisor = 50)

この例のリスト

R> ore.doEval(RandomRedDots, divisor = 50)
   id  val
1   1 0.02
2   2 0.04
3   3 0.06
4   4 0.08
5   5 0.10
6   6 0.12
7   7 0.14
8   8 0.16
9   9 0.18
10 10 0.20
# The graph displayed by the plot function is not shown.

例6-8 FUN.NAME引数を指定したore.doEval関数の使用方法

入力関数がOML4Rスクリプト・リポジトリに格納されている場合は、ore.doEval関数をFUN.NAME引数を指定して呼び出すことができます。この例ではまず、myRandomRedDotsという名前のスクリプトがスクリプト・リポジトリに含まれないようにするために、ore.scriptDropを呼び出します。この例では、例6-6RandomRedDots関数をmyRandomRedDotsという名前でリポジトリに追加します。この例では、ore.doEval関数を呼び出し、myRandomRedDotsを指定します。結果は変数resに割り当てられます。

RandomRedDots関数の戻り値はdata.frameですが、この例では、ore.doEval関数はore.objectオブジェクトを返します。data.frameオブジェクトを取得するために、ore.pullを呼び出して結果をクライアントのRセッションにプルします。

ore.scriptDrop("myRandomRedDots")
ore.scriptCreate("myRandomRedDots", RandomRedDots)
res <- ore.doEval(FUN.NAME = "myRandomRedDots", divisor = 50)
class(res)
res.local <- ore.pull(res)
class(res.local)

この例のリスト

R> ore.scriptDrop("myRandomRedDots")
R> ore.scriptCreate("myRandomRedDots", RandomRedDots)
R> res <- ore.doEval(FUN.NAME = "myRandomRedDots", divisor = 50)
R> class(res)
[1] "ore.object"
attr(,"package")
[1] "OREembed"
R> res.local <- ore.pull(res)
R> class(res.local)
[1] "data.frame"

例6-9 FUN.VALUE引数を指定したore.doEval関数の使用方法

doEval関数でore.objectではなくore.frameオブジェクトが返されるようにするには、この例に示すように、引数FUN.VALUEを使用して結果の構造を指定します。

res.of <- ore.doEval(FUN.NAME="myRandomRedDots", divisor = 50,
                     FUN.VALUE= data.frame(id = 1, val = 1))
class(res.of)
例6-9のリスト
R> res.of <- ore.doEval(FUN.NAME="myRandomRedDots", divisor = 50,
+                        FUN.VALUE= data.frame(id = 1, val = 1))
R> class(res.of)
[1] "ore.frame"
attr(,"package")
[1] "OREbase"

例6-10 ore.connect引数を指定したdoEval関数の使用方法

この例では、特殊なオプションの引数ore.connectを使用して埋込みR関数でデータベースに接続することにより、データストアに格納されているオブジェクトを使用できるようにする方法を示します。この例では、RandomRedDots2関数オブジェクト(例6-6RandomRedDots関数と似ているが、RandomRedDots2関数はデータストア名を指定する引数を取る)を作成します。この例では、myVar変数を作成して、datastore_1という名前のデータストアに保存します。次に、doEval関数を呼び出してデータストア名を渡し、TRUEに設定したore.connect制御引数を渡します。

RandomRedDots2 <- function(divisor = 100, datastore.name = "myDatastore"){
  id <- 1:10
  plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 2 )
  ore.load(datastore.name) # Contains the numeric variable myVar.
  data.frame(id = id, val = id / divisor, num = myVar)
}
myVar <- 5
ore.save(myVar, name = "datastore_1")
ore.doEval(RandomRedDots2, datastore.name = "datastore_1", ore.connect = TRUE)

この例のリスト

R> RandomRedDots2 <- function(divisor = 100, datastore.name = "myDatastore"){
+   id <- 1:10
+   plot(1:100, rnorm(100), pch = 21, bg = "red", cex = 2 )
+   ore.load(datastore.name) # Contains the numeric variable myVar.
+   data.frame(id = id, val = id / divisor, num = myVar)
+ }
R> ore.doEval(RandomRedDots2, datastore.name = "datastore_1", ore.connect = TRUE)
   id  val num
1   1 0.01   5
2   2 0.02   5
3   3 0.03   5
4   4 0.04   5
5   5 0.05   5
6   6 0.06   5
7   7 0.07   5
8   8 0.08   5
9   9 0.09   5
10 10 0.10   5
# The graph displayed by the plot function is not shown.

例6-11 ora.type属性の使用方法

この例では、ora.type属性を使用して、FUN.VALUE引数で指定されたdata.frameオブジェクト内の列にデータベース・データ型のCLOBおよびBLOBを指定する方法を示します。

eval1 <- ore.doEval(function() "Hello, world")
eval2 <-
  ore.doEval(function()
	           data.frame(x = "Hello, world", stringsAsFactors = FALSE))
eval3 <-
  ore.doEval(function()
	           data.frame(x = "Hello, world", stringsAsFactors = FALSE),
	           FUN.VALUE =
	           data.frame(x = character(), stringsAsFactors = FALSE))
out.df <- data.frame(x = character(), y = raw(), stringsAsFactors = FALSE)
attr(out.df$x, "ora.type") <- "clob"
attr(out.df$y, "ora.type") <- "blob"
eval4 <- 
  ore.doEval(function() {
	           res <- data.frame(x = "Hello, world",stringsAsFactors = FALSE)
	           res$y[[1L]] <- charToRaw("Hello, world")
	           res},
	           FUN.VALUE = out.df)
eval1
class(eval1)  # ore.object
eval2
class(eval2)  # ore.object
eval3
class(eval3)  # ore.frame
eval4$x
rawToChar(ore.pull(eval4$y))

この例のリスト

R> eval1 <- ore.doEval(function() "Hello, world")
R> eval2 <- 
+    ore.doEval(function()
+               data.frame(x = "Hello, world", stringsAsFactors = FALSE))
R> eval3 <-
+    ore.doEval(function()
+               data.frame(x = "Hello, world", stringsAsFactors = FALSE),
+               FUN.VALUE =
+               data.frame(x = character(), stringsAsFactors = FALSE))
R> out.df <- data.frame(x = character(), y = raw(), stringsAsFactors = FALSE)
R> attr(out.df$x, "ora.type") <- "clob"
R> attr(out.df$y, "ora.type") <- "blob"
R> eval4 <- 
+    ore.doEval(function() {
+               res <- data.frame(x = "Hello, world",stringsAsFactors = FALSE)
+               res$y[[1L]] <- charToRaw("Hello, world")
+               res},
+               FUN.VALUE = out.df)
R> eval1
[1] "Hello, world"
R> class(eval1)
[1] "ore.object"
attr(,"package")
[1] "OREembed"
R> eval2
             x
1 Hello, world
R> class(eval2)
[1] "ore.object"
attr(,"package")
[1] "OREembed"
R> eval3
             x
1 Hello, world
Warning message:
ORE object has no unique key - using random order 
R> class(eval3)
[1] "ore.frame"
attr(,"package")
[1] "OREbase"
R> eval4$x                              
[1] "Hello, world"
Warning message:
ORE object has no unique key - using random order 
R> rawToChar(ore.pull(eval4$y))
[1] "Hello, world"
Warning message:
ORE object has no unique key - using random order 

6.2.4 ore.tableApply関数の使用

ore.tableApply関数は、入力データとしてore.frameを指定してRスクリプトを起動します。

ore.tableApply関数は、ore.frameを最初の引数としてユーザー定義の入力関数に渡します。ore.tableApply関数は、ore.frameオブジェクトまたはシリアライズRオブジェクトをore.objectオブジェクトとして返します。

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

ore.tableApply(X, FUN, ..., FUN.VALUE = NULL, FUN.NAME = NULL, FUN.OWNER = NULL)

関連項目:

関数ore.tableApplyの引数の詳細は、「スクリプトを実行する関数の引数」を参照してください

例6-12 ore.tableApply関数の使用方法

この例では、ore.tableApply関数を使用して、irisデータセットに基づいてNaive Bayesモデルを構築します。naiveBayes関数はe1071パッケージにあり、クライアントとデータベース・サーバー・マシンの両方のRエンジンにインストールする必要があります。ore.tableApply関数の最初の引数として、ore.push(iris)の呼出しでは一時データベース表およびその表のプロキシであるore.frameが作成されます。2番目の引数は入力関数で、これには引数datがあります。ore.tableApply関数は、ore.frame表プロキシをdat引数として入力関数に渡します。この入力関数は、ore.tableApply関数がore.objectオブジェクトとして返すモデルを作成します。

library(e1071)
nbmod <- ore.tableApply(
  ore.push(iris),
  function(dat) {
    library(e1071)
    dat$Species <- as.factor(dat$Species)
    naiveBayes(Species ~ ., dat)
})
class(nbmod)
nbmod

この例のリスト

R> nbmod <- ore.tableApply(
+   ore.push(iris),
+   function(dat) {
+     library(e1071)
+     dat$Species <- as.factor(dat$Species)
+     naiveBayes(Species ~ ., dat)
+ })
R> class(nbmod)
[1] "ore.object"
attr(,"package")
[1] "OREembed"
R> nbmod
 
Naive Bayes Classifier for Discrete Predictors
 
Call:
naiveBayes.default(x = X, y = Y, laplace = laplace)
 
A-priori probabilities:
Y
    setosa versicolor  virginica 
 0.3333333  0.3333333  0.3333333 
 
Conditional probabilities:
            Sepal.Length
Y             [,1]      [,2]
  setosa     5.006 0.3524897
  versicolor 5.936 0.5161711
  virginica  6.588 0.6358796
 
            Sepal.Width
Y             [,1]      [,2]
  setosa     3.428 0.3790644
  versicolor 2.770 0.3137983
  virginica  2.974 0.3224966
 
            Petal.Length
Y             [,1]      [,2]
  setosa     1.462 0.1736640
  versicolor 4.260 0.4699110
  virginica  5.552 0.5518947
 
            Petal.Width
Y             [,1]      [,2]
  setosa     0.246 0.1053856
  versicolor 1.326 0.1977527
  virginica  2.026 0.2746501

6.2.5 ore.groupApply関数の使用

ore.groupApply関数は、入力データとしてore.frameを指定してRスクリプトを起動します。

ore.groupApply関数は、ore.frameを最初の引数としてユーザー定義の入力関数に渡します。ore.groupApply関数のINDEX引数は、ore.frameの列の名前を指定しますが、これによってOracle Databaseはユーザー定義のR関数による処理のために行をパーティショニングします。ore.groupApply関数は、1つ以上のRエンジンが同じR関数(タスク)をデータの別のパーティションで実行するデータ・パラレル実行を使用できます。

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

ore.groupApply(X, INDEX, FUN, ..., FUN.VALUE = NULL, FUN.NAME = NULL, FUN.OWNER = NULL,
               parallel = getOption("ore.parallel", NULL))

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

ore.groupApply関数の使用例は、次の各項で説明します。

6.2.5.1 単一列へのパーティション化

この例では、ore.groupApply関数を使用して、データを単一列にパーティション化します。

この例では、デシジョン・ツリーおよびルールベース・モデルを構築する関数が含まれるC50パッケージを使用します。このパッケージには、トレーニング・データとテスト・データのセットも含まれています。この例では、状態ごとのデータに基づいて1つのチャーン・モデルを作成することを目的に、C50パッケージのchurnデータセットからのchurnTrainトレーニング・データセットに基づいてC5.0モデルを構築します。この例では、次の操作を実行しています。

  • C50パッケージをロードした後に、churnデータセットをロードします。

  • ore.create関数を使用して、churnTrain (data.frameオブジェクト)からCHURN_TRAINデータベース表およびそのプロキシore.frameオブジェクトを作成します。

  • CHURN_TRAIN (プロキシore.frameオブジェクト)をore.groupApply関数の最初の引数として指定し、state列をINDEX引数として指定します。ore.groupApply関数は、state列のデータをパーティショニングし、ユーザー定義の関数を各パーティションで呼び出します。

  • ore.groupApply関数によって返されるore.listオブジェクトを取得するための変数modListを作成します。ore.listオブジェクトには、データの各パーティションでユーザー定義の関数を実行した結果が含まれています。この場合は、状態ごとに1つのC5.0モデルで、各モデルはore.objectオブジェクトとして格納されています。

  • ユーザー定義の関数を指定します。ユーザー定義の関数の最初の引数は、データ(1つの状態に関連付けられたすべてのデータ)の1つのパーティションを受け取ります。

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

    • データベースのRエンジンで起動したときに関数で使用できるように、C50パッケージをロードします。

    • state列がモデルに含まれないように、data.frameからこの列を削除します。

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

    • 状態のモデルを構築し、それを返します。

  • ore.pull関数を使用してデータベースからmod.MA変数としてモデルを取得し、そこでsummary関数を呼び出します。mod.MAのクラスはC5.0です。

例6-13 ore.groupApply関数の使用方法

library(C50)
data("churn")
 
ore.create(churnTrain, "CHURN_TRAIN")

modList <- ore.groupApply(
  CHURN_TRAIN,
  INDEX=CHURN_TRAIN$state,
    function(dat) {
      library(C50)
      dat$state <- NULL
      dat$churn <- as.factor(dat$churn)
      dat$area_code <- as.factor(dat$area_code)
      dat$international_plan <- as.factor(dat$international_plan)
      dat$voice_mail_plan <- as.factor(dat$voice_mail_plan)
      C5.0(churn ~ ., data = dat, rules = TRUE)
    });
mod.MA <- ore.pull(modList$MA)
summary(mod.MA)

この例のリスト

R> library(C50)
R> data(churn)
R> 
R> ore.create(churnTrain, "CHURN_TRAIN")
R>
R> modList <- ore.groupApply(
+   CHURN_TRAIN,
+   INDEX=CHURN_TRAIN$state,
+     function(dat) {
+       library(C50)
+       dat$state <- NULL
+       dat$churn <- as.factor(dat$churn)
+       dat$area_code <- as.factor(dat$area_code)
+       dat$international_plan <- as.factor(dat$international_plan)
+       dat$voice_mail_plan <- as.factor(dat$voice_mail_plan)
+       C5.0(churn ~ ., data = dat, rules = TRUE)
+     });
R> mod.MA <- ore.pull(modList$MA)
R> summary(mod.MA)
 
Call:
C5.0.formula(formula = churn ~ ., data = dat, rules = TRUE)
 
 
C5.0 [Release 2.07 GPL Edition]         Thu Feb 13 15:09:10 2014
-------------------------------
 
Class specified by attribute `outcome'
 
Read 65 cases (19 attributes) from undefined.data
 
Rules:
 
Rule 1: (52/1, lift 1.2)
        international_plan = no
        total_day_charge <= 43.04
        ->  class no  [0.963]
 
Rule 2: (5, lift 5.1)
        total_day_charge > 43.04
        ->  class yes  [0.857]
 
Rule 3: (6/1, lift 4.4)
        area_code in {area_code_408, area_code_415}
        international_plan = yes
        ->  class yes  [0.750]
 
Default class: no
 
 
Evaluation on training data (65 cases):
 
                Rules     
          ----------------
            No      Errors
 
             3    2( 3.1%)   <<
 
 
           (a)   (b)    <-classified as
          ----  ----
            53     1    (a): class no
             1    10    (b): class yes
 
 
        Attribute usage:
 
         89.23% international_plan
         87.69% total_day_charge
          9.23% area_code
 
 
Time: 0.0 secs
6.2.5.2 複数列へのパーティション化

この例では、ore.groupApply関数を使用して、データを複数列にパーティション化します。

ore.groupApply関数は、INDEX引数として1つの列または複数の列を取ります。次の例は、CHURN_TRAINデータセットのデータを使用して、指定したデータのパーティション(voice_mail_plan列およびinternational_plan列)に対するルールを作成するrpartモデルを構築します。この例では、Rのtable関数を使用して各パーティションで予測される行の数を示します。

この例では、指定された名前のスクリプトがOML4Rスクリプト・リポジトリに存在しないようにするために、ore.scriptDrop関数を呼び出します。その後、ore.scriptCreate関数を使用してmy_rpartFunctionという名前のスクリプトを定義し、それをリポジトリに格納します。格納されたスクリプトでは、OML4Rのデータストア・オブジェクトの命名に使用されるデータ・ソースおよび接頭辞を使用する関数を定義します。関数my_rpartFunctionの各呼出しは、voice_mail_planおよびinternational_plan列の値によって特定されたパーティションのいずれかからデータを受け取ります。ソース・パーティションの列は定数のため、この関数はそれらをNULLに設定します。文字列ベクターをファクタに変換し、流動を予測するためのモデルを構築し、そこに適切に命名されたデータストアを保存します。この関数は、特定のパーティション列値、流動値の分布およびモデル自身を返すためのリストを作成します。

次にrpartライブラリをロードし、データストアの接頭辞を設定し、INDEX引数としてvoice_mail_plan列およびinternational_plan列の値を、スクリプト・リポジトリに格納されているユーザー定義関数を呼び出すためのFUN.NAME引数の値としてmy_rpartFunctionを使用して、ore.groupApplyを呼び出します。ore.groupApply関数は、オプションの引数を使用してdatastorePrefix変数をユーザー定義の関数に渡します。この関数は、ユーザー定義の関数の実行時に、オプションの引数ore.connectを使用してデータベースに接続します。ore.groupApply関数は、変数resとしてore.listオブジェクトを返します。

この例では、返されるリストの最初のエントリを表示します。次に、ore.load関数を呼び出して、顧客がボイス・メール・プランと国際プランの両方を持つ場合のモデルをロードします。

例6-14 複数列でデータをパーティションする場合のore.groupApplyの使用方法

library(C50)
data(churn)
ore.drop("CHURN_TRAIN") 
ore.create(churnTrain, "CHURN_TRAIN")
 
table(CHURN_TRAIN$international_plan, CHURN_TRAIN$voice_mail_plan)

options(width = 80)
head(CHURN_TRAIN, 3)

ore.scriptDrop("my_rpartFunction")
ore.scriptCreate("my_rpartFunction",
  function(dat, datastorePrefix) {
    library(rpart)
    vmp <- dat[1, "voice_mail_plan"]
    ip <- dat[1, "international_plan"]
    datastoreName <- paste(datastorePrefix, vmp, ip, sep = "_")
    dat$voice_mail_plan <- NULL
    dat$international_plan <- NULL
    dat$state <- as.factor(dat$state)
    dat$churn <- as.factor(dat$churn)
    dat$area_code <- as.factor(dat$area_code)
    mod <- rpart(churn ~ ., data = dat)
    ore.save(mod, name = datastoreName, overwrite = TRUE)
    list(voice_mail_plan = vmp,
        international_plan = ip,
        churn.table = table(dat$churn),
        rpart.model = mod)
  })

library(rpart)
datastorePrefix = "my.rpartModel"
 
res <- ore.groupApply(CHURN_TRAIN,
      INDEX = CHURN_TRAIN[, c("voice_mail_plan", "international_plan")],
      FUN.NAME = "my_rpartFunction",
      datastorePrefix = datastorePrefix,
      ore.connect = TRUE)
res[[1]]
ore.load(name=paste(datastorePrefix, "yes", "yes", sep = "_"))
mod

この例のリスト

R> library(C50)
R> data(churn)
R> ore.drop("CHURN_TRAIN") 
R> ore.create(churnTrain, "CHURN_TRAIN")
R>  
R> table(CHURN_TRAIN$international_plan, CHURN_TRAIN$voice_mail_plan)
     
        no  yes
  no  2180  830
  yes  231   92
R>
R> options(width = 80)
R> head(CHURN_TRAIN, 3)
  state account_length     area_code international_plan voice_mail_plan
1    KS            128 area_code_415                 no             yes
2    OH            107 area_code_415                 no             yes
3    NJ            137 area_code_415                 no              no
  number_vmail_messages total_day_minutes total_day_calls total_day_charge
1                    25             265.1             110            45.07
2                    26             161.6             123            27.47
3                     0             243.4             114            41.38
  total_eve_minutes total_eve_calls total_eve_charge total_night_minutes
1             197.4              99            16.78               244.7
2             195.5             103            16.62               254.4
3             121.2             110            10.30               162.6
  total_night_calls total_night_charge total_intl_minutes total_intl_calls
1                91              11.01               10.0                3
2               103              11.45               13.7                3
3               104               7.32               12.2                5
  total_intl_charge number_customer_service_calls churn
1              2.70                             1    no
2              3.70                             1    no
3              3.29                             0    no
Warning messages:
1: ORE object has no unique key - using random order
2: ORE object has no unique key - using random order
R> 
R> ore.scriptDrop("my_rpartFunction")
R> ore.scriptCreate("my_rpartFunction",
+   function(dat, datastorePrefix) {
+     library(rpart)
+     vmp <- dat[1, "voice_mail_plan"]
+     ip <- dat[1, "international_plan"]
+     datastoreName <- paste(datastorePrefix, vmp, ip, sep = "_")
+     dat$voice_mail_plan <- NULL
+     dat$international_plan <- NULL
+     dat$state <- as.factor(dat$state)
+     dat$churn <- as.factor(dat$churn)
+     dat$area_code <- as.factor(dat$area_code)
+     mod <- rpart(churn ~ ., data = dat)
+     ore.save(mod, name = datastoreName, overwrite = TRUE)
+     list(voice_mail_plan = vmp,
+         international_plan = ip,
+         churn.table = table(dat$churn),
+         rpart.model = mod)
+   })
R> 
R> library(rpart)
R> datastorePrefix = "my.rpartModel"
R> 
R> res <- ore.groupApply(CHURN_TRAIN,
+       INDEX = CHURN_TRAIN[, c("voice_mail_plan", "international_plan")],
+       FUN.NAME = "my_rpartFunction",
+       datastorePrefix = datastorePrefix,
+       ore.connect = TRUE)
R> res[[1]]
$voice_mail_plan
[1] "no"
 
$international_plan
[1] "no"
 
$churn.table
 
  no  yes 
1878  302 
 
$rpart.model
n= 2180 
 
node), split, n, loss, yval, (yprob)
      * denotes terminal node
 
 1) root 2180 302 no (0.86146789 0.13853211)  
   2) total_day_minutes< 263.55 2040 192 no (0.90588235 0.09411765)  
     4) number_customer_service_calls< 3.5 1876 108 no (0.94243070 0.05756930)  
       8) total_day_minutes< 223.25 1599  44 no (0.97248280 0.02751720) *
       9) total_day_minutes>=223.25 277  64 no (0.76895307 0.23104693)  
        18) total_eve_minutes< 242.35 210  18 no (0.91428571 0.08571429) *
        19) total_eve_minutes>=242.35 67  21 yes (0.31343284 0.68656716)  
          38) total_night_minutes< 174.2 17   4 no (0.76470588 0.23529412) *
          39) total_night_minutes>=174.2 50   8 yes (0.16000000 0.84000000) *
     5) number_customer_service_calls>=3.5 164  80 yes (0.48780488 0.51219512)  
      10) total_day_minutes>=160.2 95  22 no (0.76842105 0.23157895)  
        20) state=AL,AZ,CA,CO,DC,DE,FL,HI,KS,KY,MA,MD,ME,MI,NC,ND,NE,NH,NM,OK,OR,SC,TN,VA,VT,WY 56   2 no (0.96428571 0.03571429) *
        21) state=AK,AR,CT,GA,IA,ID,MN,MO,NJ,NV,NY,OH,RI,TX,UT,WA,WV 39  19 yes (0.48717949 0.51282051)  
          42) total_day_minutes>=182.3 21   5 no (0.76190476 0.23809524) *
          43) total_day_minutes< 182.3 18   3 yes (0.16666667 0.83333333) *
      11) total_day_minutes< 160.2 69   7 yes (0.10144928 0.89855072) *
   3) total_day_minutes>=263.55 140  30 yes (0.21428571 0.78571429)  
     6) total_eve_minutes< 167.3 29   7 no (0.75862069 0.24137931)  
      12) state=AK,AR,AZ,CO,CT,FL,HI,IN,KS,LA,MD,ND,NM,NY,OH,UT,WA,WV 21   0 no (1.00000000 0.00000000) *
      13) state=IA,MA,MN,PA,SD,TX,WI 8   1 yes (0.12500000 0.87500000) *
     7) total_eve_minutes>=167.3 111   8 yes (0.07207207 0.92792793) *
 
R> ore.load(name = paste(datastorePrefix, "yes", "yes", sep = "_"))
[1] "mod"
R> mod
n= 92 
 
node), split, n, loss, yval, (yprob)
      * denotes terminal node
 
1) root 92 36 no (0.60869565 0.39130435)  
  2) total_intl_minutes< 13.1 71 15 no (0.78873239 0.21126761)  
    4) total_intl_calls>=2.5 60  4 no (0.93333333 0.06666667)  
      8) state=AK,AR,AZ,CO,CT,DC,DE,FL,GA,HI,ID,IL,IN,KS,MD,MI,MO,MS,MT,NC,ND,NE,NH,NJ,OH,SC,SD,UT,VA,WA,WV,WY 53  0 no (1.00000000 0.00000000) *
      9) state=ME,NM,VT,WI 7  3 yes (0.42857143 0.57142857) *
    5) total_intl_calls< 2.5 11  0 yes (0.00000000 1.00000000) *
  3) total_intl_minutes>=13.1 21  0 yes (0.00000000 1.00000000) *

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 ore.rowApply関数の使用方法

この例では、事前にCRANからダウンロードしてあるe1071パッケージを使用します。この例では、次の操作を実行しています。

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

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

  • Naive Bayesモデルnbmodを作成します。

  • 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列を表示します。

library(e1071)
IRIS <- ore.push(iris)
nbmod <- ore.tableApply(
  ore.push(iris),
  function(dat) {
    library(e1071)
    dat$Species <- as.factor(dat$Species)
    naiveBayes(Species ~ ., dat)
  })
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)

この例のリスト

R> library(e1071)
R> IRIS <- ore.push(iris)      
R> nbmod <- ore.tableApply(
+    ore.push(iris),
+    function(dat) {
+      library(e1071)
+      dat$Species <- as.factor(dat$Species)
+      naiveBayes(Species ~ ., dat)
+    })
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

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

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

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

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

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

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

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

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

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

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

関連項目:

この例のore.rowApply関数と同じ結果を生成するSQL 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)

この例のリスト

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

6.2.7 ore.indexApply関数の使用

ore.indexApply関数は、入力関数によって生成されたデータを使用して指定されたユーザー定義の入力関数を実行します。

この関数は、1つ以上のRエンジンが同じまたは異なる計算(タスク)を実行するタスク・パラレル実行をサポートします。ore.indexApply関数に対するtimes引数には、データベース内で入力関数を実行する回数を指定します。必要なすべてのデータは、入力関数内で明示的に生成またはロードされる必要があります。

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

ore.indexApply(times, FUN, ..., FUN.VALUE = NULL, FUN.NAME = NULL, FUN.OWNER = NULL,
               parallel = getOption("ore.parallel", NULL))

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

関連項目:

ore.indexApply関数の使用例は、次の各項で説明します。

6.2.7.1 ore.indexApply関数の簡単な使用例

この例では、ore.indexApplyを呼び出し、入力関数を並行して5回実行することを指定します。

例6-17 ore.indexApply関数の使用方法

この例では、結果のクラスであるore.listを表示した後に、結果を表示します。

res <- ore.indexApply(5,
      function(index) {
        paste("IndexApply:", index)
      },
      parallel = TRUE)
class(res)
res

この例のリスト

R> res <- ore.indexApply(5,
+       function(index) {
+         paste("IndexApply:", index)
+       },
+       parallel = TRUE)
R> class(res)
[1] "ore.list"
attr(,"package")
[1] "OREembed"
R> res
$`1`
[1] "IndexApply: 1"
 
$`2`
[1] "IndexApply: 2"
 
$`3`
[1] "IndexApply: 3"
 
$`4`
[1] "IndexApply: 4"
 
$`5`
[1] "IndexApply: 5"
6.2.7.2 列並行の使用例

この例では、Rのsummary関数を使用して、irisデータセットの最初の4つの数値列でサマリー統計を並行して計算します。

例6-18 ore.indexApply関数の使用方法および結果の結合

この例では、計算を最終結果に結合します。ore.indexApply関数の最初の引数は4で、これは、並行してまとめる列の数を指定します。ユーザー定義の入力関数は1つの引数indexを取り、これは、まとめる列を指定する1から4の値です。

この例では、summary関数を指定した列で呼び出します。summaryの呼出しでは、列のサマリー統計が含まれている単一の行が返されます。この例では、summary呼出しの結果をdata.frameに変換し、そこに列名を追加します。

次に、ore.indexApply関数に対してFUN.VALUE引数を使用して、関数の結果の構造を定義します。結果はその後、その構造とともにore.frameオブジェクトとして返されます。

res <- NULL
res <- ore.indexApply(4,
      function(index) {
        ss <- summary(iris[, index])
        attr.names <- attr(ss, "names")
        stats <- data.frame(matrix(ss, 1, length(ss)))
        names(stats) <- attr.names
        stats$col <- names(iris)[index]
        stats
      },
      FUN.VALUE=data.frame(Min. = numeric(0),
        "1st Qu." = numeric(0),
        Median = numeric(0),
        Mean = numeric(0),
        "3rd Qu." = numeric(0),
        Max. = numeric(0),
        Col = character(0)), 
      parallel = TRUE)
res

この例のリスト

R> res <- NULL
R> res <- ore.indexApply(4,
+       function(index) {
+         ss <- summary(iris[, index])
+         attr.names <- attr(ss, "names")
+         stats <- data.frame(matrix(ss, 1, length(ss)))
+         names(stats) <- attr.names
+         stats$col <- names(iris)[index]
+         stats
+       },
+       FUN.VALUE=data.frame(Min. = numeric(0),
+         "1st Qu." = numeric(0),
+         Median = numeric(0),
+         Mean = numeric(0),
+         "3rd Qu." = numeric(0),
+         Max. = numeric(0),
+         Col = character(0)),
+       parallel = TRUE)
R> res
  Min. X1st.Qu. Median  Mean X3rd.Qu. Max.          Col
1  2.0      2.8   3.00 3.057      3.3  4.4  Sepal.Width
2  4.3      5.1   5.80 5.843      6.4  7.9 Sepal.Length
3  0.1      0.3   1.30 1.199      1.8  2.5  Petal.Width
4  1.0      1.6   4.35 3.758      5.1  6.9 Petal.Length
Warning message:
ORE object has no unique key - using random order
6.2.7.3 シミュレーションの使用例

ore.indexApply関数をシミュレーションで使用しすることで、Oracle Exadataデータベース・マシンなどの高パフォーマンスのコンピューティング・ハードウェアを利用できます。

例6-19 シミュレーションでのore.indexApply関数の使用方法

この例では、ランダムな正規分布の複数のサンプルを使用してサマリー統計の分布を比較します。各シミュレーションは、データベースの別個のRエンジンで、データベースで許可された並列度まで並列に実行されます。この例では、サンプル・サイズの変数、乱数値の平均および標準偏差および実行するシミュレーションの数を定義します。この例では、num.simulationsore.indexApply関数の最初の引数として指定します。ore.indexApply関数は、num.simulationsindex引数としてユーザー定義の関数に渡します。この入力関数はその後、各入力関数の呼出しで異なる乱数値のセットが生成されるように、索引に基づいて乱数シードを設定します。

次に、入力関数は、rnorm関数を使用してsample.sizeランダムな標準値を生成します。乱数のベクターでsummary関数を呼び出し、返される結果としてdata.frameを準備します。ore.indexApply関数には、シミュレーションの結合された結果を構成するore.frameを返すように、FUN.VALUE引数を指定します。res変数は、ore.indexApply関数によって返されるore.frameを取得します。

サンプルの分布を取得するために、この例では、ore.pull関数を使用した結果であるdata.frameboxplot関数を呼び出し、resから選択した列をクライアントに渡します。

res <- NULL
sample.size = 1000
mean.val = 100
std.dev.val = 10
num.simulations = 1000
 
res <- ore.indexApply(num.simulations,
      function(index, sample.size = 1000, mean = 0, std.dev = 1) {
        set.seed(index)
        x <- rnorm(sample.size, mean, std.dev)
        ss <- summary(x)
        attr.names <- attr(ss, "names")
        stats <- data.frame(matrix(ss, 1, length(ss)))
        names(stats) <- attr.names
        stats$index <- index
        stats
      },
      FUN.VALUE=data.frame(Min. = numeric(0),
        "1st Qu." = numeric(0),
        Median = numeric(0),
        Mean = numeric(0),
        "3rd Qu." = numeric(0),
        Max. = numeric(0),
        Index = numeric(0)),
      parallel = TRUE,
      sample.size = sample.size,
      mean = mean.val, std.dev = std.dev.val)
options("ore.warn.order" = FALSE)
head(res, 3)
tail(res, 3)
boxplot(ore.pull(res[, 1:6]),
  main=sprintf("Boxplot of %d rnorm samples size %d, mean=%d, sd=%d",
               num.simulations, sample.size, mean.val, std.dev.val))

この例のリスト

R> res <- ore.indexApply(num.simulations,
+       function(index, sample.size = 1000, mean = 0, std.dev = 1) {
+         set.seed(index)
+         x <- rnorm(sample.size, mean, std.dev)
+         ss <- summary(x)
+         attr.names <- attr(ss, "names")
+         stats <- data.frame(matrix(ss, 1, length(ss)))
+         names(stats) <- attr.names
+         stats$index <- index
+         stats
+       },
+       FUN.VALUE=data.frame(Min. = numeric(0),
+         "1st Qu." = numeric(0),
+         Median = numeric(0),
+         Mean = numeric(0),
+         "3rd Qu." = numeric(0),
+         Max. = numeric(0),
+         Index = numeric(0)),
+       parallel = TRUE,
+       sample.size = sample.size,
+       mean = mean.val, std.dev = std.dev.val)
R> options("ore.warn.order" = FALSE)
R> head(res, 3)
   Min. X1st.Qu. Median   Mean X3rd.Qu.  Max. Index
1 67.56    93.11  99.42  99.30    105.8 128.0   847
2 67.73    94.19  99.86 100.10    106.3 130.7   258
3 65.58    93.15  99.78  99.82    106.2 134.3   264
R> tail(res, 3)
   Min. X1st.Qu. Median   Mean X3rd.Qu.  Max. Index
1 65.02    93.44  100.2 100.20    106.9 134.0     5
2 71.60    93.34   99.6  99.66    106.4 131.7     4
3 69.44    93.15  100.3 100.10    106.8 135.2     3
R> boxplot(ore.pull(res[, 1:6]),
+   main=sprintf("Boxplot of %d rnorm samples size %d, mean=%d, sd=%d",
+                num.simulations, sample.size, mean.val, std.dev.val))

6.3 埋込みRの実行用のSQLインタフェース

Oracle Machine Learning for Rの埋込みRの実行用のSQLインタフェースでは、本番データベースのアプリケーションでR関数を実行できます。

SQLインタフェースには、次のアクションのためのプロシージャがあります。

  • OML4Rスクリプト・リポジトリに対するスクリプトの追加および削除

  • 所有者による他のユーザーに対するスクリプトへの読取りアクセス権の付与または取消し

  • 埋込みRセッションでのRスクリプトの実行

  • OML4Rデータストアの削除

データ・ディクショナリ・ビューは、スクリプトおよびデータストアに関する情報を提供します。

このSQLインタフェースについては、次のトピックで説明しています。

6.3.1 Oracle Machine Learning for RのSQL表関数について

OML4Rでは、埋込みRの実行用のRインタフェース関数のほとんどに相当するSQL表関数が提供されています。

SELECT FROM TABLE文を実行し、いずれかの表関数を指定すると、指定されたRスクリプトが呼び出されます。このスクリプトは、Oracle Databaseサーバー上の1つ以上のRエンジンで実行されます。

埋込みRの実行用のSQL表関数は次のとおりです。

  • rqEval

  • rqGroupEval

  • rqRowEval

  • rqTableEval

表6-1に、Rインタフェース関数およびそれに相当するSQL関数を示します。

rqGroupEval関数の場合、OML4RはSQLでのグループ適用機能の汎用実装を提供します。入力カーソルの後続を取得する表関数を記述する必要があります。

これらの関数の詳細および使用例は、各関数の参照ページを参照してください。

次の各トピックでは、SQL表関数の一般的な側面について説明します。

6.3.1.1 SQL表関数のパラメータ

SQL表関数の中には、共通のパラメータを持つものもあれば、その関数に固有のパラメータを持つものもあります。

SQL表関数のパラメータは次のとおりです。

表6-2 SQL表関数のパラメータ

パラメータ 説明

INP_CUR

EXP_NAMで指定されているR関数への入力となるデータを指定するカーソル。rqEvalを除くすべてのSQL表関数の最初の引数は、R関数の入力データを指定するカーソルです。

PAR_CUR

R関数に渡す引数を指定するカーソル。パラメータ・カーソルは、単一行のスカラー値で構成されます。引数には文字列または数値を指定できます。カーソル内には複数の引数を指定できます。R関数への引数では大/小文字が区別されるため、列名などの名前は二重引用符で囲む必要があります。

カーソル内には、OML4R制御引数やシリアライズされたRオブジェクト(OML4Rデータストア内にある予測モデルなど)の名前をスカラー値として指定することもできます。

R関数への引数も制御引数も渡さない場合は、このパラメータ・カーソルの値をNULLにできます。

OUT_QRY

出力表の定義。この引数の値は、NULLか、EXP_NAMで指定されているR関数により返されたR data.frameの構造を定義する文字列にすることができます。文字列は、SELECT文、'XML'または'PNG'にできます。

GRP_COL

rqGroupEval関数の場合、グループ化列の名前。

ROW_NUM

rqRowEval関数の場合、R関数の各呼出しに渡す行数。

EXP_NAM

OML4Rスクリプト・リポジトリ内のスクリプトの名前。

6.3.1.2 SQL表関数の戻り値

Oracle Machine Learning for RのSQL表関数は、表を返します。

表の構造と内容は、SQL表関数に渡されたR関数の結果と、OUT_QRYパラメータによって決定されます。R関数はdata.frameオブジェクト、他のRオブジェクトおよびグラフィックを返すことができます。R関数の結果を表す表の構造は、次のいずれかのOUT_QRY値によって指定されます。

  • NULL: データ・オブジェクトとイメージ・オブジェクトの両方を含む可能性のあるシリアライズ・オブジェクトを持つ表が返されます。

  • SELECT文で指定された表シグネチャ: 定義された構造の表が返されます。R関数の結果はdata.frameとなる必要があります。イメージは返されません。

  • 文字列'XML': XML文字列での構造化データとグラフ・イメージの両方を含む可能性のあるCLOBを持つ表が返されます。イメージでないRオブジェクト(data.framemodelオブジェクトなど)が最初に提供され、次にbase 64でエンコードされたイメージのPNG表示が続きます。

  • 文字列'PNG': PNG形式のグラフ・イメージを含むBLOBを持つ表が返されます。表には、列名nameidおよびimageが含まれます。

6.3.1.3 埋込みRの実行でのOracle Machine Learning for Rへの接続

埋込みRの実行中にOracle Databaseサーバー上のOML4Rへの接続を確立するには、パラメータ・カーソル内に制御引数ore.connectを指定できます。

これを行うと、埋込みR関数を呼び出したユーザーの資格証明を使用して接続が確立されます。また、自動的にOREパッケージがロードされます。オブジェクトをOML4RのRオブジェクト・データストアに保存する場合や、データストアからオブジェクトをロードする場合は、OML4Rへの接続を確立する必要があります。また、これにより、OML4Rの透過層を明示的に使用できます。

関連項目:

他の制御引数の詳細は、「オプションの制御引数」を参照してください

6.3.2 SQLでのスクリプトの管理

このトピックでは、Rスクリプトを作成および管理するためのPL/SQLプロシージャとOracle Databaseデータ・ディクショナリ・ビューを紹介します。

埋込みRの実行用のSQL APIの関数は、OML4Rスクリプト・リポジトリに格納されている名前付きのスクリプトを引数として必要とします。PL/SQLプロシージャsys.rqScriptCreateおよびsys.rqScriptDropは、スクリプトを作成および削除します。スクリプトを作成する場合やスクリプト・リポジトリから削除する場合は、RQADMINロールが必要です。

sys.rqScriptCreate関数を使用する場合、スクリプトの名前と、1つのR関数定義を含むR関数スクリプトを指定する必要があります。関数sys.rqScriptCreateおよびsys.rqScriptDropのコールは、BEGIN-END PL/SQLブロックでラップする必要があります。スクリプト・リポジトリには、R関数がキャラクタ・ラージ・オブジェクト(CLOB)として格納されるため、関数定義を一重引用符で囲んで文字列として指定する必要があります。

スクリプトの所有者は、rqGrantプロシージャを使用してスクリプトへの読取りアクセス権を別のユーザーに付与したり、rqRevokeプロシージャを使用して権限を取り消すことができます。別のユーザーによってアクセス権を付与されたスクリプトを使用するには、次のように、スクリプトの名前の前に所有者の名前とピリオドを付加して、所有者を指定する必要があります。

select * from table(rqEval(NULL, 'select 1 x from dual', 'owner_name.script_name'));

パブリック・スクリプトやユーザーが所有しているスクリプトには、所有者の接頭辞は必要ありません。

次の各表は、スクリプト・リポジトリ内のスクリプトを管理するためのPL/SQLプロシージャと、スクリプトに関する情報を格納するデータ・ディクショナリ・ビューのリストです。

表6-3 スクリプトを管理するためのPL/SQLプロシージャ

PL/SQLプロシージャ 説明
rqGrant データストアまたはスクリプトへの読取りアクセス権を付与します。
rqRevoke データストアまたはスクリプトへの読取りアクセス権を取り消します。
sys.rqScriptCreate 指定されたR関数を、指定された名前でスクリプト・リポジトリに追加します。
sys.rqScriptDrop 指定されたR関数をスクリプト・リポジトリから削除します。

表6-4 スクリプトのデータ・ディクショナリ・ビュー

データ・ディクショナリ・ビュー 説明
ALL_RQ_SCRIPTS 現行のユーザーが使用可能な、OML4Rスクリプト・リポジトリ内のスクリプトを示します
USER_RQ_SCRIPTS 現行のユーザーが所有している、スクリプト・リポジトリ内のスクリプトを示します。
USER_RQ_SCRIPT_PRIVS 現行のユーザーが読取りアクセス権を付与したスクリプト・リポジトリ内のスクリプトおよびアクセス権が付与されたユーザーを示します。
SYS.RQ_SCRIPTS スクリプト・リポジトリ内のシステム・スクリプトを示します。

例6-20 SQL APIによるスクリプトの作成

この例では、sys.rqScriptCreateプロシージャを使用して、Oracle Machine Learning for Rのスクリプト・リポジトリ内にスクリプトを作成します。

この例では、myRandomRedDots2という名前のユーザー定義関数を作成します。このユーザー定義関数は2つの引数を受け入れ、2つの列を持ち指定の数のランダム標準値を表示するdata.frameオブジェクトを返します。sys.rqScriptCreate関数は、ユーザー定義関数をOML4Rスクリプト・リポジトリに格納します。

-- Create a script named myRandomRedDots2 and add it to the script repository.
-- Specify that the script is private and to overwrite a script with the same name.
BEGIN
  sys.rqScriptCreate('myRandomRedDots2',
    'function(divisor = 100, numDots = 100) {
       id <- 1:10
       plot(1:numDots, rnorm(numDots), pch = 21, bg = "red", cex = 2 )
       data.frame(id = id, val = id / divisor)}',
       v_global => FALSE,
       v_overwrite => TRUE);
END;
/

-- Grant read privilege access to Scott.
BEGIN
  rqGrant('myRandomRedDots2', 'rqscript', 'SCOTT');
END;
 /

-- View the users granted read access to myRandomRedDots2.
select * from USER_RQ_SCRIPT_PRIVS;

NAME                GRANTEE
----------------    -------
myRandomRedDots       SCOTT

-- Revoke the read privilege access from Scott.
BEGIN
  rqRevoke('myRandomRedDots2', 'rqscript', 'SCOTT');
END;
 /

-- Remove the script from the script repository.
BEGIN
  sys.rqScriptDrop('myRandomRedDots2');
 END; 
 /

6.3.3 SQLでのデータストアの管理

Oracle Machine Learning for Rには、SQLでデータストアの基本的な管理を行うためのPL/SQLプロシージャおよびOracle Databaseデータ・ディクショナリ・ビューが用意されています。

次の各表は、これらのプロシージャおよびビューのリストです。

表6-5 データストアを管理するためのPL/SQLプロシージャ

PL/SQLプロシージャ 説明
rqGrant データストアまたはスクリプトへの読取りアクセス権を付与します。
rqRevoke データストアまたはスクリプトへの読取りアクセス権を取り消します。
rqDropDataStore データストアを削除します。

表6-6 データストアのデータ・ディクショナリ・ビュー

ビュー 説明
ALL_RQ_DATASTORES データストアが付与可能かどうかを含め、現行のユーザーが使用可能なデータストアを示します。
RQUSER_DATASTORELIST Oracle Databaseスキーマ内のデータストアを示します。
RQUSER_DATASTORECONTENTS Oracle Databaseスキーマ内のデータストア内のオブジェクトを示します。
USER_RQ_DATASTORE_PRIVS データストア、および現行のユーザーが読取りアクセス権を付与したユーザーを示します。
USER_RQ_DATASTORES データストアが付与可能かどうかを含め、現行のユーザーが所有しているデータストアを示します。