使用 Google Cloud 適用的 ABAP SDK,在 SAP 中讀取 BigQuery ML 預測資料

1. 簡介

在本程式碼研究室中,您將在 BigQuery 中建立機器學習 (ML) 模型,並透過 Google Cloud 適用的 ABAP SDK 取得這個模型的預測結果。

您將使用下列 Google Cloud 服務:

  • BigQuery
  • Cloud Shell

建構項目

您將建立下列項目:

  • BigQuery 機器學習 (ML) 模型。
  • 具備 BigQuery API 工作使用者角色的服務帳戶。
  • 一個 ABAP 程式,用於呼叫 BigQuery API,並從機器學習模型中取得預測結果。

2. 需求條件

  • 瀏覽器,例如 ChromeFirefox
  • 已啟用計費功能的 Google Cloud 專案,或是為 Google Cloud Platform 建立 90 天免費試用帳戶
  • 在您的系統中安裝 SAP GUI (Windows 或 Java)。如果您的筆電已安裝 SAP GUI,請使用 VM 外部 IP 位址做為應用程式伺服器 IP 連線至 SAP。如果您使用的是 Mac,也可以點選這個連結,安裝 Java 適用的 SAP GUI。

3. 事前準備

6757b2fb50ddcc2d.png

  • 在 Cloud Shell 中執行下列指令,為您的帳戶進行驗證,並將預設專案設為 abap-sdk-poc。範例使用的是 us-west4-b 區域。視需要在下列指令中變更專案和可用區。
gcloud auth login
gcloud config set project abap-sdk-poc
gcloud config set compute/zone us-west4-b
  • 您必須能夠存取已安裝 Google Cloud 適用的 ABAP SDK 的 SAP 系統。
  • 您必須先完成程式碼研究室 1 (在 Google Cloud Platform 上安裝 ABAP 平台試用 1909 並安裝 ABAP SDK for Google Cloud),以及程式碼研究室 2 (使用適用於 Compute Engine VM 上的 SAP Hosted 的權杖設定 ABAP SDK 驗證),再進入這個程式碼研究室。
  • 如果您已完成程式碼研究室 1 和程式碼研究室 2,本來應該就能在 Google Cloud 上佈建 ABAP 平台試用 1909 系統,以及驗證和連線所需的設定。
  • 如果您尚未完成程式碼研究室 1 和程式碼研究室 2,這將缺少必要的基礎架構和連線,因此無法執行本程式碼研究室提供的步驟。因此,您必須先完成程式碼研究室 1 和程式碼研究室 2,才能繼續使用這個程式碼研究室。

4. 在 Google Cloud 專案中啟用 BigQuery API V2

  1. 在 Cloud 控制台中,按一下右上角的「啟用 Cloud Shell」

6757b2fb50ddcc2d.png

  1. 在 Cloud Shell 中執行下列指令以啟用 BigQuery API:
gcloud services enable bigquery.googleapis.com

成功執行後,您應該會看到如下顯示的訊息

b5f52859df2c2f56.png

您現在應該已經在 Google Cloud 專案中啟用 BigQuery API。

5. 建立服務帳戶來確保 BigQuery 的存取權安全無虞

如要安全地從 BigQuery ML 模型取得機器學習預測結果,您必須建立具有 BigQuery 工作使用者BigQuery 資料檢視者角色的服務帳戶。這個角色可讓程式在專案中執行查詢 (以工作的形式),並從資料表中讀取資料。這個角色僅授予建立工作及讀取資料的必要權限,可將安全性風險降至最低。

建立服務帳戶

如要建立具有必要角色的服務帳戶,請執行下列步驟:

  1. 在 Cloud Shell 終端機中執行下列指令:
gcloud iam service-accounts create abap-sdk-bigquery-jobuser --display-name="Service Account for BigQuery Job user"
  1. 接著,將必要角色新增至在上一步建立的服務帳戶:
gcloud projects add-iam-policy-binding abap-sdk-poc --member='serviceAccount:abap-sdk-bigquery-jobuser@abap-sdk-poc.iam.gserviceaccount.com' --role='roles/bigquery.jobUser'

gcloud projects add-iam-policy-binding abap-sdk-poc --member='serviceAccount:abap-sdk-bigquery-jobuser@abap-sdk-poc.iam.gserviceaccount.com' --role='roles/bigquery.dataViewer'

上述指令使用 abap-sdk-poc 做為 Google Cloud 專案的預留位置。將 abap-sdk-poc 替換為您的專案 ID。

  1. 如要確認角色已新增,請前往「IAM」頁面。畫面上會列出您建立的服務帳戶,以及使用者已獲派的角色。

6. 建立 BigQuery 機器學習模型

在本程式碼研究室中,我們會建立一個 k-means 模型,用來叢集倫敦單車租借資料集。您可以套用 k-means 演算法,將資料分組成叢集。監督式機器學習是關於預測分析,非監督式學習與描述性分析不同。也就是瞭解您的資料,以便您做出資料導向的決策。

建立資料集

如要建立 BigQuery 資料集來儲存機器學習模型,請執行下列步驟:

  1. 前往 Google Cloud 控制台的「BigQuery」頁面。前往 BigQuery 頁面
  2. 在「Explorer」窗格中,按一下專案名稱。
  3. 按一下 5cf3b742649f1e2c.png「查看動作」。建立資料集

3fbc072041bfa313.png

  1. 在「建立資料集」頁面中執行下列操作:
  • 在「Dataset ID」(資料集 ID) 中輸入 bqml_tutorial
  • 在「位置類型」部分,依序選取「多區域」和「歐盟 (多個歐盟地區)」。倫敦自行車租用公開資料集儲存在歐盟的多區域,資料集必須位於相同位置。
  • 其他設定維持不變,然後點選「建立資料集」建立資料集頁面。

建立 k-means 模型

現在資料集已設定完成,下一步是使用資料建立 k-means 模型。您可以使用含有 model_type=kmeans 選項的 CREATE MODEL 陳述式建立及訓練 k-means 模型。

如要執行查詢並建立 k-means 模型,請執行下列步驟:

  1. 前往「BigQuery」BigQuery頁面。前往 BigQuery
  2. 在編輯器窗格中,執行下列 SQL 陳述式:
CREATE OR REPLACE MODEL `bqml_tutorial.london_station_clusters`
  OPTIONS(model_type='kmeans', num_clusters=4) AS
WITH
  hs AS (
  SELECT
    h.start_station_name AS station_name,
  IF
    (EXTRACT(DAYOFWEEK
      FROM
        h.start_date) = 1
      OR EXTRACT(DAYOFWEEK
      FROM
        h.start_date) = 7,
      "weekend",
      "weekday") AS isweekday,
    h.duration,
    ST_DISTANCE(ST_GEOGPOINT(s.longitude,
        s.latitude),
      ST_GEOGPOINT(-0.1,
        51.5))/1000 AS distance_from_city_center
  FROM
    `bigquery-public-data.london_bicycles.cycle_hire` AS h
  JOIN
    `bigquery-public-data.london_bicycles.cycle_stations` AS s
  ON
    h.start_station_id = s.id
  WHERE
    h.start_date BETWEEN CAST('2015-01-01 00:00:00' AS TIMESTAMP)
    AND CAST('2016-01-01 00:00:00' AS TIMESTAMP) ),
  stationstats AS (
  SELECT
    station_name,
    isweekday,
    AVG(duration) AS duration,
    COUNT(duration) AS num_trips,
    MAX(distance_from_city_center) AS distance_from_city_center
  FROM
    hs
  GROUP BY
    station_name, isweekday)
SELECT
  * EXCEPT(station_name, isweekday)
FROM
  stationstats
  1. 在導覽面板的「Resources」(資源) 部分,展開專案名稱,按一下 [bqml_tutorial],然後再按一下 [london_station_clusters]
  2. 按一下 [Schema] (結構定義) 分頁標籤。模型結構定義會列出 BigQuery ML 用來執行分群的三個車站屬性。結構定義應如下所示:

5f1feb313bd0f6a5.png

  1. 按一下 [Evaluation] (評估) 分頁標籤。此分頁以視覺化方式呈現 k-means 模型識別的叢集。在「數字特徵」下方,長條圖可顯示每個群集中心的最重要數值特徵值 (最多 10 個)。您可以從下拉式選單中選取要視覺化的地圖項目。

8f9b53971e33dc08.png

7. 使用 Google Cloud 適用的 ABAP SDK 取得 BigQuery ML 預測資料

您已經在 Google Cloud 上完成必要條件,可以開始在 SAP 系統中完成相關步驟,使用 Google Cloud 適用的 ABAP SDK 從機器學習模型取得預測結果。

建立用戶端金鑰設定

對於驗證和連線相關設定,Google Cloud 適用的 ABAP SDK 會使用表格 /GOOG/CLIENT_KEY/GOOG/SERVIC_MAP.

如要保留 /GOOG/CLIENT_KEY 資料表中的設定,請執行下列步驟:

  1. 在 SAP GUI 中,輸入交易代碼 SPRO
  2. 按一下「SAP 參考資料」
  3. 按一下 [ABAP SDK for Google Cloud]基本設定 >設定用戶端金鑰

25871e639293b9ee.png

  1. 將下列值與列出的欄位保持不變,並將其他所有欄位留空:

欄位

Google Cloud 金鑰名稱

BIGQUERY_ML

Google Cloud 服務帳戶名稱

abap-sdk-bigquery-jobuser@abap-sdk-poc.iam.gserviceaccount.com

Google Cloud 範圍

https://www.googleapis.com/auth/cloud-platform

專案 ID

abap-sdk-poc

授權類別

/GOOG/CL_AUTH_GOOGLE

建立 ABAP 報表,透過 BigQuery ML 模型取得預測結果

如要建立 ABAP 報表,請按照下列步驟操作:

  1. 在 SAP GUI 中前往交易代碼 SE38,建立名為 ZDEMO_BIGQUERY_ML_PREDICT. 的回報計畫
  2. 在隨即出現的彈出式視窗中,提供詳細資料,如下圖所示:

4cb32d50427df294.png

  1. 在下一個彈出式視窗中,選取「Local Object」,或視情況提供套件名稱。
  2. 在 ABAP 編輯器中新增下列程式碼:
REPORT zdemo_bigquery_ml_predict.

types:
  begin of lty_query_result,
    centroid_id     type i,
    station_name    type string,
    isweekday       type string,
    num_trips       type i,
    distance_from_city type string,
  end of lty_query_result,
  ltt_query_result type standard table of lty_query_result.

DATA:
  lv_project_id TYPE string,
  ls_input      TYPE /goog/cl_bigquery_v2=>ty_103,
  ls_output     TYPE lty_query_result,
  lt_output     TYPE ltt_query_result.

CONSTANTS:
  lc_newline TYPE c VALUE cl_abap_char_utilities=>newline.

TRY.
    "Initialize Bigquery object, pass the client key name that you have configured in /GOOG/CLIENT_KEY table
    DATA(lo_bq) = NEW /goog/cl_bigquery_v2( iv_key_name = 'BIGQUERY_ML' ).

    "Populate relevant parameters
    lv_project_id = lo_bq->gv_project_id.

    ls_input-default_dataset-project_id = 'abap-sdk-poc'.
    ls_input-default_dataset-dataset_id = 'bqml_tutorial'.

    "This query gets predictions from
    ls_input-query =
                | WITH | && lc_newline &&
                | hs AS ( | && lc_newline &&
                | SELECT | && lc_newline &&
                | h.start_station_name AS station_name, | && lc_newline &&
                | IF | && lc_newline &&
                | (EXTRACT(DAYOFWEEK | && lc_newline &&
                | FROM | && lc_newline &&
                | h.start_date) = 1 | && lc_newline &&
                | OR EXTRACT(DAYOFWEEK | && lc_newline &&
                | FROM | && lc_newline &&
                | h.start_date) = 7, | && lc_newline &&
                | "weekend", | && lc_newline &&
                | "weekday") AS isweekday, | && lc_newline &&
                | h.duration, | && lc_newline &&
                | ST_DISTANCE(ST_GEOGPOINT(s.longitude, | && lc_newline &&
                | s.latitude), | && lc_newline &&
                | ST_GEOGPOINT(-0.1, | && lc_newline &&
                | 51.5))/1000 AS distance_from_city_center | && lc_newline &&
                | FROM | && lc_newline &&
                | `bigquery-public-data.london_bicycles.cycle_hire` AS h | && lc_newline &&
                | JOIN | && lc_newline &&
                | `bigquery-public-data.london_bicycles.cycle_stations` AS s | && lc_newline &&
                | ON | && lc_newline &&
                | h.start_station_id = s.id | && lc_newline &&
                | WHERE | && lc_newline &&
                | h.start_date BETWEEN CAST('2015-01-01 00:00:00' AS TIMESTAMP) | && lc_newline &&
                | AND CAST('2016-01-01 00:00:00' AS TIMESTAMP) ), | && lc_newline &&
                | stationstats AS ( | && lc_newline &&
                | SELECT | && lc_newline &&
                | station_name, | && lc_newline &&
                | isweekday, | && lc_newline &&
                | AVG(duration) AS duration, | && lc_newline &&
                | COUNT(duration) AS num_trips, | && lc_newline &&
                | MAX(distance_from_city_center) AS distance_from_city_center | && lc_newline &&
                | FROM | && lc_newline &&
                | hs | && lc_newline &&
                | GROUP BY | && lc_newline &&
                | station_name, isweekday ) | && lc_newline &&
                | SELECT | && lc_newline &&
                | * EXCEPT(nearest_centroids_distance) | && lc_newline &&
                | FROM | && lc_newline &&
                | ML.PREDICT( MODEL `bqml_tutorial.london_station_clusters`, | && lc_newline &&
                | ( | && lc_newline &&
                | SELECT | && lc_newline &&
                | * | && lc_newline &&
                | FROM | && lc_newline &&
                | stationstats | && lc_newline &&
                | WHERE | && lc_newline &&
                | REGEXP_CONTAINS(station_name, 'Kennington'))) |.

    "Call API method: bigquery.jobs.query
    CALL METHOD lo_bq->query_jobs
      EXPORTING
        iv_p_project_id = lv_project_id
        is_input        = ls_input
      IMPORTING
        es_output       = DATA(ls_response)
        ev_ret_code     = DATA(lv_ret_code)
        ev_err_text     = DATA(lv_err_text)
        es_err_resp     = DATA(ls_err_resp).

    IF lo_bq->is_success( lv_ret_code ).
      "API Call successful, loop through the data & display the result
      IF ls_response-job_complete = abap_true.
        LOOP AT ls_response-rows ASSIGNING FIELD-SYMBOL(<ls_row>).
          LOOP AT <ls_row>-f ASSIGNING FIELD-SYMBOL(<ls_value>).
            ASSIGN <ls_value>-v->* TO FIELD-SYMBOL(<ls_field_value>).
            CASE sy-tabix.
              WHEN 1.
                ls_output-centroid_id = <ls_field_value>.
              WHEN 2.
                ls_output-station_name = <ls_field_value>.
              WHEN 3.
                ls_output-isweekday = <ls_field_value>.
              WHEN 4.
                ls_output-num_trips = <ls_field_value>.
              WHEN 5.
                ls_output-distance_from_city = <ls_field_value>.
            ENDCASE.
          ENDLOOP.
          APPEND ls_output TO lt_output.
          CLEAR ls_output.
        ENDLOOP.
        IF lt_output IS NOT INITIAL.
          cl_demo_output=>new( )->begin_section( 'ML.Predict Query Details'
                               )->write_text( ls_input-query
                               )->write_text( 'Dataset: bigquery-public-data.london_bicycles'
                               )->end_section(
                               )->begin_section( 'ML.Predict Query Results'
                               )->write_data( lt_output
                               )->end_section(
                               )->display( ).
        ENDIF.
      ENDIF.
    ELSE.
      "Display error message in case the API call fails
      MESSAGE lv_err_text TYPE 'E'.
    ENDIF.

    "Close HTTP Connection
    lo_bq->close( ).

  CATCH /goog/cx_sdk INTO DATA(lo_exception).
    MESSAGE lo_exception->get_text( ) TYPE 'E'.
ENDTRY.
  1. 儲存並啟用報表。
  2. 執行報表 (F8)。

如果成功執行,報表輸出內容應如下所示:

739e5685511fc9fc.png

6405542a597ed09f.png

8. 恭喜

完成「使用 Google Cloud 適用的 ABAP SDK 從 BigQuery 機器學習 (ML) 模型取得預測結果」做得很棒。codelab!

您已順利從 SAP 系統擷取 BigQuery 機器學習模型的預測結果!您已提升 ABAP 與 Google Cloud 服務的整合程度。參加其他有趣的 ABAP SDK for Google Cloud 程式碼研究室,盡享無限可能:

  • 將 Translation API 與 Google Cloud 適用的 ABAP SDK 搭配使用
  • 使用分塊功能將大型物件上傳至 Cloud Storage 值區
  • 使用 Google Cloud 適用的 ABAP SDK 從 Secret Manager 擷取憑證/密鑰
  • 透過 ABAP 呼叫 Vertex AI 測試 Bison

9. 清除所用資源

如果不想繼續完成其他與 Google Cloud 適用的 ABAP SDK 相關的程式碼研究室,請繼續進行清除作業。

刪除專案

  • 刪除 Google Cloud 專案:
gcloud projects delete abap-sdk-poc

刪除個別資源

  1. 刪除運算執行個體:
gcloud compute instances delete abap-trial-docker
  1. 刪除防火牆規則:
gcloud compute firewall-rules delete sapmachine
  1. 刪除服務帳戶:
gcloud iam service-accounts delete \
    abap-sdk-bigquery-jobuser@abap-sdk-poc.iam.gserviceaccount.com