データ・モニタリングの例 - データ・ドリフトの検出
データ・ドリフトは、時間の経過に伴ってデータが当初のベースライン・データから離れていく場合に発生します。データ・ドリフトは、ビジネス環境の変化、ユーザーの行動と関心の進化、サード・パーティ・ソースによるデータの変更、データ品質の問題、アップストリームのデータ処理パイプラインに関する問題など、様々な理由で発生します。
モデルを正確に解釈し、そのモデルでビジネス上の問題を解決できることを確認するには、時間の経過とともにデータがどのように進化するかを理解することが重要です。データの変化を理解することはモデルの有効性の変化を理解するうえで非常に重要であるため、モデル・モニタリングを正しく行うためにデータ・モニタリングは欠かせません。データの統計プロパティの変化を迅速かつ確実に検出できれば、自分の機械学習モデルがビジネスの目的と合致していることを確認しやすくなります。
データ・ドリフトは、基本的な記述統計を使用して定量化できます。数値列の場合は、次のものが含まれます:
- 平均
- 標準偏差
- 範囲(最小、最大)
- NULLの数
- 一意の値の数
- NULLの数
データ・モニタリング・ワークフロー
- アクセス・トークンの取得
- データ・モニタリング・ジョブの作成
- ジョブ詳細を表示します。
- ジョブの更新(オプション)
- 実行するジョブの有効化
- ジョブ出力の表示
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: データ・モニタリング・ジョブの作成
/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
が指定されていない場合、startDate
はfrequency
が指定されているかどうかによって異なります。frequency
が指定されていないと、timeColumn
の最も早い日付がstartDate
として使用されます。startDate
とfrequency
の両方が指定されていないと、timeColumn
の最も早い日付か、最新のサイクルの10番目の開始日のどちらか早いほうがstartDate
とみなされます。endDate:
newData
のモニタリングの終了日またはタイムスタンプ。endDate
には、列timeColumn
か必須です。endDate
を指定しないと、timeColumn
の最新の日付が使用されます。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
エンドポイントにリクエストを送信します。
$ 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: この例の再作成(オプション)
ここで説明したデータ・モニタリングの例を再作成するには、次のステップに従います:
- OMLノートブックのR段落で次のコマンドを実行し、表が存在する場合はを削除して、警告を抑制します:
%r options(warn=-1) try(ore.drop(table="HOUSEHOLD_POWER_BASE")) try(ore.drop(table="HOUSEHOLD_POWER_NEW"))
-
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")
-
ここで、ベースライン・データ
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")
-
ベースライン・データ
HOUSEHOLD_POWER_BASE
を表示するには、ノートブックのSQL段落で次のSQLコマンドを実行します:%sql SELECT * FROM HOUSEHOLD_POWER_BASE FETCH FIRST 5 ROWS ONLY;
-
次のSQLコマンドを実行して、新しいデータ
HOUSEHOLD_POWER_NEW
を表示します:%sql SELECT * FROM HOUSEHOLD_POWER_NEW FETCH FIRST 5 ROWS ONLY;