10.5.3 pyqTableEvalファンクション(オンプレミス・データベース)

このトピックでは、オンプレミスOracle Databaseで使用されるpyqTableEvalファンクションについて説明します。pyqTableEvalファンクションは、Oracle Database表のデータに対してユーザー定義Python関数を実行します。

INP_NAMパラメータを使用して、データをPython関数に渡します。PAR_QRYパラメータを使用して、引数をPython関数に渡すことができます。

Python関数は、booleandictfloatintliststrtupleまたはpandas.DataFrameオブジェクトを返すことができます。OUT_QRYパラメータを使用して、返される値の形式を定義します。

構文

pyqTableEval (
    INP_NAM     VARCHAR2       IN
    PAR_QRY     VARCHAR2       IN
    OUT_QRY     VARCHAR2       IN
    EXP_NAM     VARCHAR2       IN)

パラメータ

パラメータ 説明

INP_NAM

EXP_NAMパラメータで指定されたPython関数に渡すデータを指定する表またはビューの名前。別のユーザーが所有する表またはビューを使用する場合は、<owner name>.<table/view name>という形式を使用します。指定された表またはビューに対する読取りアクセス権が必要です。

PAR_QRY

EXP_NAMパラメータで指定されたユーザー定義Python関数に渡す追加パラメータが含まれるJSON文字列。oml_で始まる特殊な制御引数は、EXP_NAMで指定された関数に渡されるのではなく、関数の呼出し前後の動作を制御します。

たとえば、入力データ型をpandas.DataFrameとして指定するには、次を使用します。

'{"oml_input_type":"pandas.DataFrame"}'

OUT_QRY

ファンクションによって返される出力の形式。次のいずれかになります。

  • ファンクションによって返された表の列名およびデータ型を指定するJSON文字列。イメージ・データは破棄されます。
  • プロトタイプとして使用する表またはビューの名前。別のユーザーが所有する表またはビューを使用する場合は、<owner name>.<table/view name>という形式を使用します。指定された表またはビューに対する読取りアクセス権が必要です。
  • 文字列'XML'。返される表にXML文字列であるCLOBが含まれることを指定します。XMLには構造化データとイメージの両方が含まれる可能性があり、最初に構造化または半構造化のPythonオブジェクトが含まれ、続いてPython関数によって生成されたイメージが含まれます。
  • 文字列'PNG'。返される表に、Python関数によって生成されたイメージを格納するBLOBが含まれることを指定します。イメージはPNG表示のbase 64エンコーディングとして返されます。

EXP_NAM

OML4Pyスクリプト・リポジトリ内のユーザー定義Python関数の名前。

戻り値

ファンクションpyqTableEvalは、OUT_QRYパラメータ値で指定された構造を持つ表を返します。

例10-16 pyqTableEvalファンクションの使用方法

この例では、ユーザー定義Python関数をcreate_iris_tableという名前でOML4Pyスクリプト・リポジトリに格納します。この関数を使用して、pyqEvalファンクションを呼び出した結果としてデータベース表を作成します。線形回帰モデルを入力データに適合させて、モデルをOML4Pyデータストアに保存する別のユーザー定義Python関数を作成します。この例では、pyqTableEvalファンクションを呼び出すSQL SELECT文を実行して、myLinearRegressionModelという名前でスクリプト・リポジトリに格納されている関数を呼び出します。

PL/SQLブロックで、Python関数create_iris_tableを定義し、create_iris_tableという名前でスクリプト・リポジトリに格納し、同じ名前でスクリプト・リポジトリに格納されている既存のユーザー定義Python関数を上書きします。

create_iris_table関数は、irisデータ・セットをインポートしてロードし、2つのpandas.DataFrameオブジェクトを作成した後、これらのオブジェクトの連結を返します。

BEGIN
  sys.pyqScriptCreate('create_iris_table',
    'def create_iris_table():
       from sklearn.datasets import load_iris
       import pandas as pd
       iris = load_iris()
       x = pd.DataFrame(iris.data, columns = ["Sepal_Length",\
             "Sepal_Width", "Petal_Length", "Petal_Width"])
       y = pd.DataFrame(list(map(lambda x: {0:"setosa", 1: "versicolor",\
                                 2: "virginica"}[x], iris.target)),\
                        columns = ["Species"])
       return pd.concat([y, x], axis=1)',
    FALSE, TRUE); -- V_GLOBAL, V_OVERWRITE
END;
/
CREATE TABLE IRIS AS
(SELECT * FROM pyqEval(
      NULL,
      '{"Species":"VARCHAR2(10)","Sepal_Length":"number",
        "Sepal_Width":"number","Petal_Length":"number",
        "Petal_Width":"number"}',
      'create_iris_table'
));

Python関数fit_modelを定義し、myLinearRegressionModelという名前でプライベート関数としてスクリプト・リポジトリに格納し、その名前で格納されている既存のユーザー定義Python関数を上書きします。

fit_model関数は、回帰モデルを入力データdatに適合させ、適合モデルをmodelName引数で指定されたオブジェクトとしてdatastoreName引数で指定されたデータストアに保存します。fit_model関数は、適合モデルを文字列形式で返します。

デフォルトでは、Pythonオブジェクトは、指定されたdatastoreNameで新しいデータストアに保存されます。オブジェクトを既存のデータストアに保存するには、oml.ds.save呼出しでoverwriteまたはappend引数をTrueに設定します。

BEGIN
   sys.pyqScriptCreate('myLinearRegressionModel',
      'def fit_model(dat, modelName, datastoreName):
         import oml
         from sklearn import linear_model
         regr = linear_model.LinearRegression()
         regr.fit(dat.loc[:, ["Sepal_Length", "Sepal_Width", \
                             "Petal_Length"]], dat.loc[:,["Petal_Width"]])
         oml.ds.save(objs={modelName:regr}, name=datastoreName, overwrite=True)
         return str(regr)', 
       FALSE, TRUE); 
END;
/

pyqTableEvalファンクションを呼び出すSELECT文を実行します。pyqTableEvalファンクションのINP_NAMパラメータでは、Python関数に渡すデータとしてIRIS表を指定します。PAR_QRYパラメータでは、Python関数に渡すモデルおよびデータストアの名前を指定し、ユーザー定義Python関数の呼出し時にデータベースへのOML4Py接続を確立するためのoml_connect制御引数を指定します。OUT_QRYパラメータではXML形式で値を返すことを指定し、EXP_NAMパラメータではスクリプト・リポジトリのmyLinearRegressionModel関数を、呼び出すPython関数として指定します。XML出力はCLOBです。set long [length]をコールすると、詳細出力を取得できます。

SELECT *
FROM table(pyqTableEval(
  'IRIS',
  '{"modelName":"linregr",
    "datastoreName":"pymodel",
    "oml_connect":1}',
  'XML',
  'myLinearRegressionModel'));

出力は次のようになります。

NAME  VALUE
----- ------------------------------------------------------------
      <root><str>LinearRegression()</str></root>