データ・モニタリングの例 - データ・ドリフトの検出

データ・ドリフトは、時間の経過に伴ってデータが当初のベースライン・データから離れていく場合に発生します。データ・ドリフトは、ビジネス環境の変化、ユーザーの行動と関心の進化、サード・パーティ・ソースによるデータの変更、データ品質の問題、アップストリームのデータ処理パイプラインに関する問題など、様々な理由で発生します。

モデルを正確に解釈し、そのモデルでビジネス上の問題を解決できることを確認するには、時間の経過とともにデータがどのように進化するかを理解することが重要です。データの変化を理解することはモデルの有効性の変化を理解するうえで非常に重要であるため、モデル・モニタリングを正しく行うためにデータ・モニタリングは欠かせません。データの統計プロパティの変化を迅速かつ確実に検出できれば、自分の機械学習モデルがビジネスの目的と合致していることを確認しやすくなります。

データ・ドリフトは、基本的な記述統計を使用して定量化できます。数値列の場合は、次のものが含まれます:

  • 平均
  • 標準偏差
  • 範囲(最小、最大)
  • NULLの数
カテゴリ列の場合は、次のものが含まれます:
  • 一意の値の数
  • NULLの数

データ・モニタリング・ワークフロー

OML RESTサービスを介してデータをモニタリングするには、次のステップに従います:
  1. アクセス・トークンの取得
  2. データ・モニタリング・ジョブの作成
  3. ジョブ詳細を表示します。
  4. ジョブの更新(オプション)
  5. 実行するジョブの有効化
  6. ジョブ出力の表示

1: アクセス・トークンの取得

OML Servicesにリクエストを送信するには、Oracle Machine Learning (OML)アカウントの資格証明を使用して認証トークンを取得する必要があります。トークンを認証および取得するには、-dオプションを指定したcURLを使用して、Oracle Machine Learningユーザー管理クラウド・サービスRESTエンドポイント/oauth2/v1/tokenにOracle Machine Learningアカウントの資格証明を渡します。次のコマンドを実行して、アクセス・トークンを取得します:

$ curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{"grant_type":"password", "username":"'<yourusername>'", 
"password":"' <yourpassword>'"}'"<oml-cloud-service-location-url>/omlusers/api/oauth2/v1/token"
説明:
  • -X POSTで、HTTPサーバーとの通信時にPOSTリクエストを使用することを指定します
  • -headerで、リクエストに必要なヘッダー(application/json)を定義します
  • -dで、ユーザー名およびパスワードの認証資格証明をPOSTリクエストのデータとしてHTTPサーバーに送信します
  • Content-Typeで、レスポンス形式(JSON)を定義します
  • Acceptでは、レスポンス形式(JSON)を定義します
  • yourusernameは、デフォルトのOML_DEVELOPERロールを持つOracle Machine Learningユーザーのユーザー名です
  • yourpasswordは、ユーザー名のパスワードです
  • oml-cloud-service-location-urlは、テナンシIDおよびデータベース名を含むOracle Machine Learningユーザー管理クラウド・サービスのインスタンスURLのRESTサーバー部分を含むURLです。URLは、Oracle Autonomous Databaseインスタンスのサービス・コンソールの「開発」タブから取得できます。

2: データ・モニタリング・ジョブの作成

データ・モニタリング・ジョブを作成するには、次のPOSTリクエストをOML Servicesの/omlmod/v1/jobsエンドポイントに送信します:データ・モニタリングは、デフォルトではすべての特徴に対して実行されますが、ユーザーが指定した特徴のリストに対して実行することもできます。最大250個の特徴をモニタリングできます。データ・モニタリング・ジョブは非同期的に発行されます。つまり、スケジュールどおりに実行され、ジョブの完了時に結果を取得できます。

ノート:

OML Servicesは、DBMS_SCHEDULERと対話してジョブに関するアクションを実行します。

データ・モニタリングの詳細は、jobPropertiesパラメータで指定されており、次のものか含まれます:

  • データ・モニタリング・ジョブの名前とタイプ
  • Autonomous Databaseサービス・レベル
  • データ・モニタリングの詳細が保存される表
  • ドリフト・アラート・トリガー
  • しきい値
  • 最大実行回数
  • 使用するベースラインおよび新しいデータ
  • パフォーマンス・メトリック
  • newDataで示される表またはビューのDATEまたはTIMESTAMP列に対応した開始日(オプション)および終了日(オプション)。timeColumnフィールドに格納されています。開始日と終了日が指定されていない場合は、timeColumn内の最も早い日時と最も遅い日時が使用されます。

ノート:

このコマンドは、LinuxおよびMac OSシステムで使用可能なコマンドラインJSONプロセッサであるjqを使用して、関連するコンポーネントをレスポンスから抽出します。
これらのパラメータを使用したデータ・モニタリング・ジョブ・リクエストの例を次に示します:
$ curl -X POST "<oml-cloud-service-location-url>/omlmod/v1/jobs" \
     --header "Authorization: Bearer ${token}" \
     --header 'Content-Type: application/json' \
     --data '{
         "jobSchedule": {
             "jobStartDate": "2023-03-24T20:30:26Z",            # job start date and time 
             "repeatInterval": "FREQ=HOURLY",                   # job frequency
             "jobEndDate": "2023-03-24T23:30:26Z",              # job end date and time
             "maxRuns": "10"                                    # max runs within the schedule
         },
         "jobProperties": {
             "jobName": "HouseholdPowerDataMonitoring",         # job name
             "jobType": "DATA_MONITORING",                      # job type; DATA_MONITORING
             "disableJob": false,                               # flag to disable the job at submission
             "outputData": "householdPowerConsumption",         # table where the job results will be saved in the format {jobID}_{outputData}
             "baselineData": "HOUSEHOLD_POWER_BASE",            # table/view containing baseline data 
             "newData": "HOUSEHOLD_POWER_NEW",                  # table/view with new data to compare against baseline
             "inputSchemaName": "OMLUSER",                      # database schema that owns the input table/view
             "outputSchemaName": "OMLUSER",                     # database schema that owns the output table/view
             "jobDescription": "Monitor household power",       # job description
             "jobServiceLevel": "LOW",                          # Autonomous Database service level; either LOW, MEDIUM, or HIGH
             "timeColumn": "DATES",                             # date or timestamp column in newData
             "startDate": "2008-01-01T00:00:00Z",               # the start date of the monitoring in the new data
             "endDate": "2010-11-26T00:00:00Z",                 # the end date of the monitoring in the new data
             "frequency": "Year",                               # the time window unit on which monitoring is performed on the new data
             "threshold": 0.8,                                  # threshold to trigger drift alert
             "recompute": false,                                # flag to determine whether to replace the output table
             "caseidColumn": null,                              # case identifier column in the baseline and new data
             "anchorColumn": null,                              # anchor column for bivariate analysis
             "featureList": [                                   # features to perform data monitoring on
                "GLOBAL_ACTIVE_POWER",
                "GLOBAL_REACTIVE_POWER",
                "VOLTAGE",
                "SUB_METERING_1",
                "SUB_METERING_2",
                "SUB_METERING_3"
            ]
         }
     }' | jq
     

このコマンドのパラメータは次のとおりです:

必須パラメータ

必須パラメータは次のとおりです。
  • jobNameで、送信したジョブの名前を指定します。
  • jobTypeには、実行するジョブのタイプを指定します。

    ノート:

    モデル・モニタリング・ジョブの場合、このパラメータはMODEL_MONITORINGに設定されます
  • outputDataは、出力データ識別子です。ジョブの結果は、{jobId}_{ouputData}という名前の表に書き込まれます
  • baselineDataは、モニタリングするベースライン・データを含む表またはビュー名です。モデル・モニタリングには期間当たり少なくとも50行が必要です。それ以外の場合は分析がスキップされます。
  • newDataは、ベースラインと比較する新しいデータを含む表またはビュー名です。データ・モニタリングには期間当たり少なくとも100行が必要です。それ以外の場合は分析がスキップされます。

オプション・パラメータ

オプションのパラメータは次のとおりです。
  • disableJob: 送信時にジョブを無効にするフラグ。設定しないと、デフォルトではfalseになり、発行時にジョブが有効になります。
  • inputSchemaName: 入力表またはビューを所有するデータベース・スキーマ。指定しないと、要求トークンのユーザー名と同じ入力スキーマになります。
  • outputSchemaName: 出力表を所有するデータベース・スキーマ。指定しないと、出力スキーマは入力スキーマと同じになります。
  • jobDescription: ジョブの説明。
  • jobServiceLevel: ジョブのサービス・レベル。LOW、MEDIUMまたはHIGHのいずれかを指定できます。
  • timeColumn: 新しいデータの日付またはタイムスタンプ列の名前。指定しないと、newData:全体が1つの期間として処理されます。
  • startDate: newData列のモニタリングの開始日またはタイムスタンプ。startDateには、列timeColumnか必須です。startDateが指定されていない場合、startDatefrequencyが指定されているかどうかによって異なります。frequencyが指定されていないと、timeColumnの最も早い日付がstartDateとして使用されます。startDatefrequencyの両方が指定されていないと、timeColumnの最も早い日付か、最新のサイクルの10番目の開始日のどちらか早いほうがstartDateとみなされます。

    ノート:

    サポートされている日時書式は、ISO-8601日時書式です。たとえば、2022-05-12T02:33:16Zです
  • endDate: newDataのモニタリングの終了日またはタイムスタンプ。endDateには、列timeColumnか必須です。endDateを指定しないと、timeColumnの最新の日付が使用されます。

    ノート:

    サポートされている日時書式は、ISO-8601日時書式です。たとえば、2022-05-12T02:33:16Zです
  • frequency: 新しいデータに対してモニタリングが実行される時間ウィンドウの単位を示します。"day""week""month"または"year"を指定できます。指定しないと、"new"のデータ全体が単一の期間として使用されます。
  • threshold: ドリフト・アラートをトリガーするためのしきい値。
  • recompute: すでに計算済の期間を更新するかどうかを示すフラグ。デフォルト値はFalseです。つまり、出力結果テーブルに存在しない期間だけが計算されます。
  • caseidColumn: ベースラインおよび新しいデータのケース識別子列。これにより、結果の再現性が向上します。
  • featureList: モニターする特徴のリスト。リストの最大特徴数のデフォルトは250です。特徴リストを指定しないと、すべての特徴がモニタリングされます。特徴は数値またはカテゴリ型である必要があります。
  • anchorColumn: ベースラインのアンカー列および2変量分析に使用する新しいデータ。モニター対象の問題のターゲット列を、アンカー列として渡すことができます。

データ・モニタリング・ジョブ作成リクエストのレスポンス

ジョブが正常に発行されると、jobidがレスポンスとして届きます。ジョブ詳細を取得したり、ジョブに対して他の処理を実行するための送信リクエストで使用するために、jobIdをメモしておきます。データ・モニタリング・ジョブ作成のレスポンス例を次に示します:

{
  "jobId": "OML$7ABB6308_1664_4CB4_84B1_598A6EA599D1",
  "links": [
    {
      "rel": "self",
      "href": "<OML Service URL>/omlmod/v1/jobs/OML%247ABB6308_1664_4CB4_84B1_598A6EA599D1"
    }
  ]
}

3: 発行済ジョブの詳細の表示

発行済ジョブの詳細を表示するには、/omlmod/v1/jobs/{jobID}エンドポイントにGETリクエストを送信します。ここで、jobIdは、前のステップでデータ・モニタリング・ジョブの正常発行に対するレスポンスとして表示されたIDです。

次のコマンドを実行すると、ジョブの詳細が表示されます:

$ export jobid='OML$7ABB6308_1664_4CB4_84B1_598A6EA599D1'  # save the job ID to a single-quoted variable

$ curl -X GET "<oml-cloud-service-location-url>/omlmod/v1/jobs/${jobid}"  \
       --header 'Accept: application/json' \
       --header 'Content-Type: application/json' \
       --header "Authorization: Bearer ${token}" | jq

ジョブ詳細リクエストのレスポンス

次に、ジョブ詳細リクエストのレスポンスを示します。ジョブがすでに以前に1回実行されている場合は、最後のジョブ実行に関する情報が返されます。

{
  "jobId": "OML$7ABB6308_1664_4CB4_84B1_598A6EA599D1",
  "jobRequest": {
    "jobSchedule": {
      "jobStartDate": "2023-03-24T20:30:26Z",
      "repeatInterval": "FREQ=HOURLY",
      "jobEndDate": "2023-03-24T23:30:26Z",
      "maxRuns": 3
    },
    "jobProperties": {
      "jobType": "DATA_MONITORING",
      "inputSchemaName": "OMLUSER",
      "outputSchemaName": "OMLUSER",
      "outputData": "householdPowerConsumption",
      "jobDescription": "Monitor household power",
      "jobName": "HouseholdPowerDataMonitoring",
      "disableJob": false,
      "jobServiceLevel": "LOW",
      "baselineData": "HOUSEHOLD_POWER_BASE",
      "newData": "HOUSEHOLD_POWER_NEW",
      "timeColumn": "DATES",
      "startDate": "2008-01-01T00:00:00Z",
      "endDate": "2010-11-26T00:00:00Z",
      "frequency": "Year",
      "threshold": 0.8,
      "recompute": false,
      "caseidColumn": null,
      "featureList": [
        "GLOBAL_ACTIVE_POWER",
        "GLOBAL_REACTIVE_POWER",
        "VOLTAGE",
        "SUB_METERING_1",
        "SUB_METERING_2",
        "SUB_METERING_3"
      ],
      "anchorColumn": null
    }
  },
  "jobStatus": "CREATED",
  "dateSubmitted": "2023-03-24T20:23:31.53651Z",
  "links": [
    {
      "rel": "self",
      "href": "<OML Service URL>/omlmod/v1/jobs/OML%247ABB6308_1664_4CB4_84B1_598A6EA599D1"
    }
  ],
  "jobFlags": [],
  "state": "SCHEDULED",
  "enabled": true,
  "runCount": 0,
  "nextRunDate": "2023-03-24T20:30:26Z"
}

4: データ・モニタリング・ジョブの編集(オプション)

このタスクはオプションです。非同期ジョブを発行した後に、ジョブを更新することもできます。ジョブを更新するには、updatePropertiesパラメータに更新済オプションを指定して、/omlmod/v1/jobs/{jobID}エンドポイントにPOSTリクエストを送信します。

次に、データ・モニタリング・ジョブを更新するPOSTリクエストの例を示します。ここでは、次のパラメータがupdatePropertiesで更新されています:

  • startDate
  • endDate
  • threshold
  • recompute
  • featureList
$ curl -i -X POST "<oml-cloud-service-location-url>/omlmod/v1/jobs/${jobid}" \
         --header "Authorization: Bearer ${token}" \
         --header 'Content-Type: application/json' \
         --data '{
            "updateProperties": {
                "startDate": "2022-01-01T19:40:24Z",
                "endDate":   "2023-01-01T19:20:24Z",
                "threshold":  0.80,
                "featureList": ["GLOBAL_ACTIVE_POWER", "GLOBAL_REACTIVE_POWER", "VOLTAGE"]
            }
         }'

この例では、一部のパラメータが更新されたので、初期リクエストで設定された元のパラメータと異っています。ジョブが正常に送信されると、本文なしの204レスポンスが届きます。

5: データ・モニタリング・ジョブに関するアクションの実行(オプション)

OML Servicesは、DBMS_SCHEDULERと対話してジョブに関するアクションを実行します。/omlmod/v1/jobs/{jobid}/actionエンドポイントに送信できるアクションには、4つのオプションがあります:

  • DISABLE: 発行時にジョブを無効にします。このアクションでforceプロパティを使用すると、実行中のジョブを強制的に中断できます。
  • ENABLE: ジョブを有効にします。無効なジョブを有効にすると、スケジューラによってスケジュールどおりにジョブが自動的に実行され始めます。
  • RUN: ジョブをテストするか、スケジュール外で実行する方法として、即時にジョブを実行します。
  • STOP: 現在実行中のジョブを停止します。

ノート:

disableJobフラグをtrueに設定することで、ジョブの発行時にDISABLEDに設定できます。

デフォルトでは、ジョブが正常に発行されると、その状態がENABLEDに設定されます。つまり、DISABLEDなど、別の状態に変更されないかぎり、ジョブの発行時に指定したスケジュールに従って実行されます。状態を変更するには、/omlmod/v1/jobs/{jobid}/actionエンドポイントにリクエストを送信します。

次に、ジョブ・ステータスをDISABLEDに変更する例を示します。ジョブが正常に送信されると、本文なしの204レスポンスが届きます。
$ curl -i -X POST "<oml-cloud-service-location-url>/omlmod/v1/jobs/${jobid}/action" \
       --header "Authorization: Bearer ${token}" \
       --header 'Content-Type: application/json' \
       --data '{
            "action": "DISABLE"
         }'

6: データ・モニタリング・ジョブの出力の表示

スケジュールまたはRUNアクションでジョブが実行されたら、ジョブ・リクエストにoutputDataパラメータで指定した表にジョブの出力を表示できます。表のフルネームは{jobid}_{outputData}です。次に示すように、詳細を表示するリクエストを送信することで、ジョブが完了しているかどうかを確認できます。

ノート:

ジョブが少なくとも1回実行されている場合は、lastRunDetailフィールドにその実行に関する情報が表示されます。

次に、この例に関連付けられている出力表を問い合せる例を示します。問合せを実行したら、ドリフトがモニタリングされているデータセットの特徴ごとに出力表をスクロール・ダウンして、baseline期間およびnewdata期間の情報があるかどうかを確認します。データ・モニタリングはベースライン・データではなく新しいデータで実行されるため、baseline行の列の多くは空である可能性があります。

%sql


SELECT START_TIME, END_TIME, IS_BASELINE, THRESHOLD, HAS_DRIFT, round(DRIFT, 3), 
       FEATURE_NAME, ROUND(IMPORTANCE_VALUE, 3) 
FROM OML$7ABB6308_1664_4CB4_84B1_598A6EA599D1_householdPowerConsumption
ORDER BY FEATURE_NAME, IS_BASELINE DESC

7: データ・モニタリング・ジョブの削除

以前に発行したジョブを削除するには、jobIdとともにDELETEリクエストを/omlmod/v1/jobsエンドポイントに送信します。

DELETEリクエストの例を次に示します:

$ curl -X DELETE "<oml-cloud-service-location-url>/omlmod/v1/jobs/${jobid}"  \
       --header 'Accept: application/json' \
       --header 'Content-Type: application/json' \
       --header "Authorization: Bearer ${token}" | jq

8: この例の再作成(オプション)

ここで説明したデータ・モニタリングの例を再作成するには、次のステップに従います:

  1. OMLノートブックのR段落で次のコマンドを実行し、表が存在する場合はを削除して、警告を抑制します:
    %r
    
    options(warn=-1)
    
    try(ore.drop(table="HOUSEHOLD_POWER_BASE"))
    try(ore.drop(table="HOUSEHOLD_POWER_NEW"))
    
  2. R段落で次のコマンドを実行し、データを読み取って変換します:
    %r
    
    test <- read.csv("https://objectstorage.us-sanjose-1.oraclecloud.com/n/adwc4pm/b/OML_Data/o/household_power_consumption.txt", sep=";")
    
    test <- transform(test, Date = as.Date(Date, format = "%d/%m/%Y"))
    test <- transform(test, Global_active_power = as.numeric(Global_active_power))
    test <- transform(test, Global_reactive_power = as.numeric(Global_reactive_power))
    test <- transform(test, Voltage = as.numeric(Voltage))
    test <- transform(test, Global_intensity = as.numeric(Global_intensity))
    test <- transform(test, Sub_metering_1 = as.numeric(Sub_metering_1))
    test <- transform(test, Sub_metering_2 = as.numeric(Sub_metering_2))
    test <- transform(test, Sub_metering_3 = as.numeric(Sub_metering_3))
    
    colnames(test) <- c("DATES", "TIMES", "GLOBAL_ACTIVE_POWER", "GLOBAL_REACTIVE_POWER", "VOLTAGE", "GLOBAL_INTENSITY", "SUB_METERING_1", "SUB_METERING_2", "SUB_METERING_3") 
  3. ここで、ベースライン・データHOUSEHOLD_POWER_BASEおよび新しいデータHOUSEHOLD_POWER_NEWを作成します。そのために、次のRスクリプトを実行します:
    %r
    
    test_base <- test[test$DATES < "2008-01-01",]
    test_new <- test[test$DATES > "2007-12-31",]
    
    # Create OML proxy objects
    
    ore.create(test_base, table="HOUSEHOLD_POWER_BASE")
    ore.create(test_new, table="HOUSEHOLD_POWER_NEW")
  4. ベースライン・データHOUSEHOLD_POWER_BASEを表示するには、ノートブックのSQL段落で次のSQLコマンドを実行します:

    %sql
    
    SELECT * FROM HOUSEHOLD_POWER_BASE
    FETCH FIRST 5 ROWS ONLY;
  5. 次のSQLコマンドを実行して、新しいデータHOUSEHOLD_POWER_NEWを表示します:
    %sql
    
    SELECT * FROM HOUSEHOLD_POWER_NEW
    FETCH FIRST 5 ROWS ONLY;