使用 Google Cloud 的 ABAP SDK 在 SAP 中讀取 BigQuery ML 預測結果

1. 簡介

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

您將運用下列 Google Cloud 服務:

  • BigQuery
  • Cloud Shell

建構項目

您將建立下列項目:

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

2. 需求條件

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

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
  • 您必須有權存取已安裝 ABAP SDK for Google Cloud 的 SAP 系統。
  • 請先完成程式碼實驗室 1 (在 Google Cloud Platform 上安裝 ABAP Platform Trial 1909,並安裝 ABAP SDK for Google Cloud) 和程式碼實驗室 2 (使用權杖設定 ABAP SDK 驗證機制,適用於 Compute Engine VM 託管的 SAP),再繼續進行本程式碼實驗室。
  • 如果您已完成程式碼實驗室 1 和程式碼實驗室 2,應該已在 Google Cloud 上佈建 ABAP Platform Trial 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 模型安全地取得 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 Machine Learning 模型

在本程式碼研究室中,我們將建立 k-means 模型,將倫敦自行車租用資料集分群。您可以套用 k-means 演算法,將資料分組成各個叢集。監督式機器學習是關於預測性分析,而非監督式學習著重在描述性分析,也就是瞭解您的資料,好讓您能做出資料導向的決策。

建立資料集

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

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

3fbc072041bfa313.png

  1. 在「建立資料集」頁面中,執行下列操作:
  • 在「Dataset ID」(資料集 ID) 中輸入 bqml_tutorial。
  • 針對「Location type」(位置類型) 選取「Multi-region」(多區域),然後選取「EU (multiple regions in European Union)」(歐盟 (多個歐盟區域))。倫敦自行車租用公開資料集存放在歐盟多區域。因此您的資料集也必須存放在同一位置。
  • 其餘設定請保留預設狀態,然後按一下「建立資料集」。建立資料集頁面。

建立 k-means 模型

資料集設定完成後,下一步就是使用資料建立 k-means 模型。您可以使用 CREATE MODEL 陳述式和 model_type=kmeans 選項,建立及訓練 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 用來執行分群作業的 3 個車站屬性。結構定義應如下所示:

5f1feb313bd0f6a5.png

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

8f9b53971e33dc08.png

7. 使用 ABAP SDK for Google Cloud 取得 BigQuery ML 預測結果

您已在 Google Cloud 端設定必要條件,現在可以完成 SAP 系統中的步驟,使用 ABAP SDK for Google Cloud 從機器學習模型取得預測結果。

建立用戶端金鑰設定

如要進行驗證和連線相關設定,ABAP SDK for Google Cloud 會使用 /GOOG/CLIENT_KEY 和 /GOOG/SERVIC_MAP. 資料表。

如要在 /GOOG/CLIENT_KEY 表格中維護設定,請按照下列步驟操作:

  1. 在 SAP GUI 中輸入交易代碼 SPRO。
  2. 按一下「SAP Reference IMG」。
  3. 依序點選「ABAP SDK for Google Cloud」>「Basic Settings」>「Configure Client Key」

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. 在下一個彈出式視窗中,選取「本機物件」或提供適當的套件名稱。
  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.png6405542a597ed09f.png

8. 恭喜

恭喜完成「使用 ABAP SDK for Google Cloud,從 BigQuery 機器學習 (ML) 模型取得預測結果」程式碼實驗室!

您已成功從 SAP 系統中,直接擷取 BigQuery Machine Learning 模型的預測結果!您已解鎖 ABAP 與 Google Cloud 服務之間的新整合層級。如要進一步瞭解 ABAP SDK for Google Cloud,請參閱其他精彩的程式碼實驗室:

  • 搭配使用 Translation API 與 ABAP SDK for Google Cloud
  • 使用分塊上傳功能,將大型物件上傳至 Cloud Storage bucket
  • 使用 ABAP SDK for Google Cloud 從 Secret Manager 擷取憑證/密鑰
  • 從 ABAP 呼叫 Vertex AI test-bison

9. 清理

如不想繼續進行與 ABAP SDK for Google Cloud 相關的額外程式碼研究室,請繼續進行清理作業。

刪除專案

  • 刪除 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