Product Information
SAP HANA Cloudで航路を辿ろう:マルチモデル分析を実践
SAP HANAは今や世界中の基幹システムで使われ、様々な企業の情報をリアルタイムで保存、処理できる単一のデータプラットフォームです。
効率的且つ安全にデータを格納するデータベースは他にもたくさん提供されています。
では、SAP HANAにしかない独自の価値は何でしょうか?
- インメモリー情報管理:全ての情報をカラム型で保持、圧縮し、高速で処理する技術
- トランザクション(大量のデータ更新)にも、分析(大量のデータ参照)にも対応
- マルチモデルデータ処理
他にも、基幹システムを支えるために必要不可欠な機能を沢山備えています:ACID特性、データ暗号化、細かい権限管理、堅朗なバックアップや高可用性の仕組みもありますが、これらは独自の価値ではありません。
1. インメモリー情報管理、2.トランザクション/分析の2つのワークロードへの対応に関してはすでに多くのメディアで紹介されています。本ブログではマルチモデル分析がビジネスにもたらす価値についてご紹介します。
マルチモデル分析
マルチモデルデータベースは、さまざまな種類のデータの保存、アクセス、処理により複数タスクを実行できるデータベースです。特定目的ごとに個別テクノロジーを使用するのではなく、さまざまデータタイプやモデルを 1 つのソリューションに統合します。
SAP HANAでは具体的に構造化データ、地理空間データ、グラフデータ、JSONデータ、テキストデータ、そしてストリーミングデータを扱うことが可能です。
それらのデータタイプを単一のデータベースで格納し、重複することなく様々な業務で活かせることこそ、SAP HANAの価値です。
特に、SAPの業務アプリケーションで発生したデータに対して高度な統計分析を同じデータベース内で行い、分析結果を業務アプリケーションを通して担当者に提供する。無駄のない、効率的なアーキテクチャで業務の行動化・自動化をはかることができます。
下記のフローでは、SAP HANAデータベース内機械学習の一連の流れを描いています。
組み込まれている関数を活用すると、データ取得からモデル作成、スコアリングまでSAP HANAでクラスタリング、時系列予測や分類が可能です。
船舶位置データの分析
SAP TechEdでは毎年新しい技術を世界中の開発者向けに披露しています。
2021年はDAT262セッションでSAP HANA Cloudの地理空間情報処理、グラフ処理、検索、JSON処理、機械学習について詳細に説明しています。解決する課題、およびコードは全てGitHubにチュートリアル形式で掲載されているため、誰でも再現できます!再現するにはSAP HANA Cloudシステム、そしてSQLの知識が必要です。本ブログではDAT262で紹介されている内容の価値をIT以外の分野の担当者向けに解説することを目的にしています。
アメリカのMarine Cadastreの自動識別システム(AIS)で公開されている船舶の位置観測データを用いてSAP HANA Cloudのマルチモデル機能を紹介します。
- シカゴ付近、五大湖の船舶位置情報を2ヶ月間分SAP HANA Cloudにインポートします。
- 緯度経度情報を基に船舶の経路や速度を計算します。
- 位置データを集計(クラスタリング)し、船舶の密度を計算します。
- グラフ機能を使用して最適航路を特定します。例として、船舶用運河の閉塞をシミュレーションし、適切な代替ルートを自動的に特定します。
- 空間クラスタリングの拡張機能を使用して「時空間キューブ」を導出し、HANAの組み込みの予測分析ライブラリ(PAL)を使用して船舶交通量を予測します。
- 検索モデルを作成し、いくつかの検索クエリを実行し、検索UIを確認します。
1. データ確認
シカゴ付近の船舶位置データをSAP HANA Cloudにインポートし、SQLで中身を確認してみましょう:
SELECT "MMSI","TS","LAT","LON","SHAPE" FROM AIS_DEMO.AIS_2017;
シカゴ付近を通った全ての船舶(貨物船・旅客船)の位置情報が時系列に沿って格納されています。
- MMSI (Maritime Mobile Service Identity):船の一意的なID
- TS:タイムスタンプ(時間)
- LAT:緯度
- LON:軽度
- SHAPE:地理空間情報(点や線や多角形)右側に地図上で表示されています。
アメリカの国立公園では立ち入りが制限されています。上記の位置情報を使えばどの船が国立公園の境界を越えていたかをすぐに確認することができます。
SELECT "MMSI" FROM "AIS_2017", "PARK_BOUNDARIES"
WHERE "AIS_2017"."SHAPE".ST_Within("PARK_BOUNDARIES"."SHAPE") = 1;
SAP HANAに組み込まれている空間関数 ST_Withinを利用すると船の位置を確認できます:
船が国立公園の内側に位置する場合は結果が1です。船が国立公園の外にある場合は結果が0です。
ST_Withinの結果が1であった船だけを選択することで侵入した船を特定します。自動的に侵入者に通知する仕組みを作ることも可能です。
2. 航路、距離、速度の計算
SQLで軌跡、移動距離、移動速度、加速度を計算していきます。
時系列で連続する船舶位置の時間差(DELTA_T)と距離(DELTA_S) を順番に計算します。
DELTA_SとDELTA_Tから、船舶の速度を導き出します。速度の変化を見て、加速度を計算します。
PARTITION BY “MMSI”を使うと、船舶ごとに情報を分けています。
組み込まれている空間関数ST_Makelineを利用して、点と点を繋いで、線を作成します。
順番を返す関数RANK()と、パーティション内の次のレコードへアクセスする関数LAG()を使用しています。
SELECT "MMSI", "SHAPE", "TS",
CAST("SHAPE".ST_DISTANCE(LAG("SHAPE", 1) OVER(PARTITION BY "MMSI" ORDER BY "TS"), 'meter') AS DECIMAL(10,2)) AS "DELTA_S",
SECONDS_BETWEEN(LAG("TS", 1) OVER(PARTITION BY "MMSI" ORDER BY "TS"), "TS") AS "DELTA_T",
ST_MAKELINE(LAG("SHAPE", 1) OVER(PARTITION BY "MMSI" ORDER BY "TS"), "SHAPE") AS "LINE",
RANK() OVER(PARTITION BY "MMSI" ORDER BY "TS") AS "FWD_RANK",
RANK() OVER(PARTITION BY "MMSI" ORDER BY "TS" DESC) AS "BWD_RANK"
FROM "AIS_2017"
船舶の移動距離と経過時間を足し算して、距離を時間で割ると速度を計算します。
SELECT SUM("DELTA_S") OVER(PARTITION BY "MMSI" ORDER BY "TS" ASC) AS "TOTAL_DISTANCE",
SUM("DELTA_T") OVER(PARTITION BY "MMSI" ORDER BY "TS" ASC) AS "TOTAL_TIMESPAN",
"DELTA_S"/"DELTA_T" AS "SPEED_M/S", *
FROM "V_MOTION_STATS_1"
上記のデータ準備の結果、例えば7日間の貨物船の軌道を生成できます。色が異なれば船も異なります。
3. 船舶密度の計算
空間クラスタリング手法を使用して、船舶の密度を詳しく見ていきましょう。
SAP HANAでは標準のクラスタリングアルゴリズムとして長方形グリッド、六角形グリッド、DBScan、およびKMeansを提供しています。どの手法でも簡単にSQLのGROUP CLUSTER BYで使うことができます。
SELECT ST_CLUSTERID() AS "ID",
ST_CLUSTERCELL() AS "SHAPE",
COUNT(*) FROM "AIS_2017" AS "COUNT"
GROUP CLUSTER BY "SHAPE" USING HEXAGON Y CELLS 400;
上記のSQLでデータをY軸400のへクス(六角形の升目)に分けて、集計します。
COUNT(*)では各へクスに位置した船の合計を計算しています。
各マスのCOUNTはそのマスの船舶密度です:同じ船が複数回通ると複数回足し算されます。
下記の地図では、旅客船数を色別で表示しています:青色は密度が低く、赤色は密度が高いです。
クラスタリングは様々な分野で応用されています:顧客分類、商品推奨、不正検知、ゲノム解析などです。
今回はSAP HANAが提供する地理空間クラスタリングを用いたフリート管理を紹介します:船舶密度が低いルートを時間帯別で識別し、混まないルートを経由して荷物を発送します。
4. 最適航路の特定
HANAグラフエンジンを利用して、貨物船に適した航路を見つけていきます。
グラフ理論におけるグラフはVertex(頂点)とEdge(辺)で構成されるネットワークです。
まずVertex(頂点)のテーブル”ROUTE_NETWORK_VERTICES”を作成し、計算に必要なデータを格納します。空間クラスタリングの結果を再利用します:今回使用するネットワークの頂点は、水上の平面を充填する六角形のマスです。
ST_Centroid関数でマスの中心点を計算し、格納します。
INSERT INTO "ROUTE_NETWORK_VERTICES" ("ID", "HEXAGON", "CENTROID", "COUNT")
(SELECT ST_CLUSTERID() AS "ID",
ST_CLUSTERCELL() AS "HEXAGON",
ST_CLUSTERCELL().ST_CENTROID() AS "CENTROID",
COUNT(*) AS "COUNT"
FROM "AIS_2017" GROUP CLUSTER BY "SHAPE" USING HEXAGON Y CELLS 400);
単純にマスとマスの間の距離を測って、最短距離を計ることも可能ですが、シカゴ港付近は交通量が非常に多いため、なるべく貨物船が通らない航路を進んだ方が速いです。
頂点テーブルに”CARGO_TRANSIT_COST_FACTOR”混み具合の項目を追加します。
各マスの貨物船のCOUNTの最大値(MAX)を混み具合の指数として扱います。混み具合という属性を頂点テーブルに追加しておくと、最短経路を求めるときに考慮することが可能です。
--CARGO_TRANSIT_COST_FACTORで混み具合を追加
MERGE INTO "ROUTE_NETWORK_VERTICES" R USING (
SELECT R."ID",
1/MAX(C."COUNT") AS "CARGO_TRANSIT_COST_FACTOR" FROM "ROUTE_NETWORK_VERTICES" AS R
INNER JOIN "CLUSTER_CARGO"
ON "ROUTE_NETWORK_VERTICES"."CENTROID".ST_INTERSECTS("CLUSTER_CARGO"."SHAPE") = 1
GROUP BY R."ID") AS C
ON R."ID" = C."ID"
WHEN MATCHED THEN UPDATE SET R."CARGO_TRANSIT_COST_FACTOR" = C."CARGO_TRANSIT_COST_FACTOR";
Edge(辺)のテーブルに計算に必要なデータを格納していきます。
ミシガン湖には道路がないため、船舶位置データを使用してネットワークを生成します。
船舶が通常移動する水域をEdgeとして扱います。
もう一度ST_MAKELINE関数を活用します:へクスの中心点を隣接する6つのヘクスを繋いだ線を作り、Edgeテーブルの属性”LINE”として格納します。
INSERT INTO "ROUTE_NETWORK_EDGES"("SOURCE", "TARGET", "LINE", "LENGTH", "AVG_COUNT", "AVG_CARGO_TRANSIT_COST_FACTOR")
SELECT T1.ID AS "SOURCE",
T2.ID AS "TARGET",
ST_MAKELINE(T1."CENTROID", T2."CENTROID") AS "LINE",
CASE WHEN T1.ID != T2.ID THEN ST_MAKELINE(T1."CENTROID", T2."CENTROID").ST_LENGTH() ELSE 0 END AS "LENGTH",
(T1."COUNT" + T2."COUNT")/2 AS "AVG_COUNT",
(T1."CARGO_TRANSIT_COST_FACTOR" + T2."CARGO_TRANSIT_COST_FACTOR")/2 AS "AVG_CARGO_TRANSIT_COST_FACTOR"
FROM "ROUTE_NETWORK_VERTICES" AS T1, "ROUTE_NETWORK_VERTICES" AS T2
WHERE T1."CENTROID".ST_WITHINDISTANCE(T2."CENTROID", 1322, 'meter') = 1;
グラフワークスペースを作成します。
グラフワークスペースは、1つ以上の頂点テーブルと1つ以上の辺テーブルで構成されます。
各頂点は、関連付けられる属性と頂点キーによって一意に識別されます。同様に、各辺はエッジキーによって一意に識別されます。グラフワークスペースを定義すると、グラフ関数を使用できるようになります。
CREATE GRAPH WORKSPACE "ROUTE_NETWORK_GRAPH"
EDGE TABLE "ROUTE_NETWORK_EDGES"
SOURCE COLUMN "SOURCE"
TARGET COLUMN "TARGET"
KEY COLUMN "ID"
VERTEX TABLE "ROUTE_NETWORK_VERTICES"
KEY COLUMN "ID";
ネットワークの辺を地図上に図示します。赤い色は、貨物船が頻繁に通る辺を示しています。
貨物船の最小コストの航路を特定します。
特定のマスから特定のマスまで最小コストの経路を算出する F_SHORTEST_PATH関数をカスタムで作ります。詳細に関してはDAT262 Exercise 5 – Vessel Routesをご確認ください。SAP HANA Cloudの標準最短パスアルゴリズムをカスタマイズします。
例として、Menominee市(マス 29117番)からChicago市(マス28448番)までの最短パスを算出します。
SELECT * FROM F_SHORTEST_PATH(29117, 28448, 0.4)
ご覧の通り、細い運河を通過して進みます。
最後に、運河の閉塞をシミュレーションします。ネットワークを「中断」してからもう一度同じアルゴリズムを実行します。自動的に代替ルートを計算してくれます。
5. 船舶交通量の予測
将来の船舶交通量を予測するため、場所と時間ごとの交通量の定義が必要です。
3. 船舶密度の計算で作った空間クラスターを再利用します。
今回は各マスに時間軸を追加します。時間軸を追加するで特定の場所ごとに船の交通量の変化を一目瞭然で評価できるようになります。各マスの時系列データから季節性を検出し、過去の実績値から将来の交通量をある程度予測できます。
時間軸を含めたマスを「時空間キューブ」と呼んでいます。時空間キューブを計算する関数をDAT262 Exercise 6 – Spatio-Temporal Clustering で紹介しています。空間の粒度(マスの大きさ)および時間の粒度(間隔)を自由に選ぶことができます。今回の分析では1321メートルの六角形と4時間の間隔を使います。
時空間キューブを確認してみましょう:例えば下記が4時間ごとにシカゴ港付近のマス(562番)の船舶交通量の実績値です。
SELECT * FROM "ST_CUBE" WHERE "CLUSTER_ID" = 562;
各マスの過去の時系列の船舶データに基づいて「自動指数平滑化」Auto Exponential Smoothingと呼ばれる時系列予測アルゴリズムを実行します。
Auto Exponential Smoothingにはいくつかの変数があります。それらを明示的に定義してから CALL文で実行します。
「FUNCTION」を’MAESM’に設定します。Massive Auto Exponential Smoothing:時系列ごとに最適な指数平滑化バリアント(シングル、ダブル、トリプル)を自動的に選択します。 「FORECAST_NUM」を12に設定すると、12の間隔を予測することを示します。
DO BEGIN
-- 変数を設定
DECLARE lt_param0 TABLE("PARAM_NAME" VARCHAR (100), "INT_VALUE" INTEGER, "DOUBLE_VALUE" DOUBLE, "STRING_VALUE" VARCHAR (100));
:lt_param0.INSERT(( 'FUNCTION', NULL, NULL,'MAESM'), 1);
:lt_param0.INSERT(( 'THREAD_RATIO', NULL, 1.0, NULL), 2);
:lt_param0.INSERT(( 'FORECAST_NUM', 12, NULL, NULL), 3);
:lt_param0.INSERT(( 'MODELSELECTION', 1, NULL, NULL), 4);
:lt_param0.INSERT(( 'MAX_ITERATION', 500, NULL, NULL),5);
:lt_param0.INSERT(( 'MEASURE_NAME', NULL, NULL,'MAPE'),6);
-- 変数、データを定義
lt_param = SELECT DAT."GROUP_ID", P.* FROM :lt_param0 AS P CROSS JOIN (SELECT DISTINCT "CLUSTER_ID" AS "GROUP_ID" FROM "UES_DATA") AS DAT;
lt_data = SELECT "CLUSTER_ID", "ELEMENT_NUMBER", "OBSERVED_VALUE" FROM "UES_DATA";
-- Uniied Exponential Smoothing 時系列予測アルゴリズムを実行
CALL _SYS_AFL.PAL_UNIFIED_EXPONENTIALSMOOTHING(:lt_data, :lt_param, t_forecast, t_stats, f_errmsge, pl1, pl2);
--結果を保存
INSERT INTO "UES_FORECAST" ("CLUSTER_ID", "ELEMENT_NUMBER", "FORCASTED_VALUE", "PI1_LOWER", "PI1_UPPER", "PI2_LOWER", "PI2_UPPER")
SELECT "GROUP_ID" AS "CLUSTER_ID",
"TIMESTAMP" AS "ELEMENT_NUMBER",
"VALUE",
"PI1_LOWER",
"PI1_UPPER",
"PI2_LOWER",
"PI2_UPPER"
FROM :t_forecast;
-- 統計情報
SELECT "GROUP_ID", "STAT_NAME", "STAT_VALUE" FROM :t_stats WHERE "STAT_NAME" IN ('FORECAST_MODEL_NAME', 'MSE');
END;
時系列予測の結果がこちらです。4時間ごとにシカゴ港付近のマスの船舶交通量を示しています。青色が実績値、オレンジ色が予測値です。12間隔(つまり48時間)先に予測値を選出しています。
6. 検索
船舶データに対して検索モデルを定義します。
検索モデルは、検索する列と、検索UIでの結果の表示方法を検索エンジンに指示します。
検索モデルは組み込みプロシージャESH_CONFIGで定義します。
CALL ESH_CONFIG('
[{"uri": "~/$metadata/EntitySets", "method": "PUT",
"content":{
"Fullname": "AIS/V_ESH_VESSELS",
"EntityType": {
"@Search.searchable": true,
"@EnterpriseSearch.enabled": true,
"@EnterpriseSearchHana.passThroughAllAnnotations":true,
"@EnterpriseSearchHana.processing.ignoreInvalidSearchOptions": true,
"Properties": [
{
"Name": "MMSI",
"@UI.identification": { "position": 1 },
"@EnterpriseSearch.key": true,
"@Search.defaultSearchElement": true
},{
"Name": "VESSELNAME",
"@UI.identification": { "position": 2 },
"@EnterpriseSearch.highlighted.enabled": true,
"@Search.defaultSearchElement": true,
"@EnterpriseSearch.defaultValueSuggestElement": true,
"@Search.fuzzinessThreshold": 0.8,
"@EnterpriseSearch.searchOptions": "similarCalculationMode=substringsearch"
},{
"Name": "VESSELTYPE",
"@UI.identification": { "position": 3 },
"@EnterpriseSearch.highlighted.enabled": false,
"@Search.defaultSearchElement": true,
"@EnterpriseSearch.filteringFacet.default": true,
"@EnterpriseSearch.filteringFacet.displayPosition": 1,
"@Search.fuzzinessThreshold": 0.8,
"@EnterpriseSearch.searchOptions": "similarCalculationMode=substringsearch"
}, ...]}}}]',?);
決まった構文で簡単に強力な検索モデルを定義することができます。
検索対象項目を定義し、各項目に属性を与えます。
例えば@Search.fuzzinessThresholdでは曖昧検索の許容範囲を定義します。上記の例ではVESSELNAMEに対して80%以上類似している言葉で検索しても、結果がヒットします。
また、VESSELTYPEでは@EnterpriseSearch.filteringFacetを有効化すると、項目をFiori UIのフィルターとして使うことができます。
ユーザーが情報を検索するときは組み込みのプロシージャESH_SEARCHを使います。フィルターにはODATA構文が使われます。
SQLコードでESH_SEARCH:
CALL SYS.ESH_SEARCH('[ "/v20411/AIS_DEMO/$all?$filter=Search.search(query=''ann'')" ]', ?);
同じESH_SEARCHプロシージャをユーザーインターフェースから実行します。
結果を左側でフィルタリングし、地図上に可視化しています。ODATAで指定されたクエリがSAP HANAデータベース内で処理されます。
マルチモデル分析についてさらに詳しく
本ブログではフリート管理、航路分析、最短航路計算、交通量予測を通して、船舶位置データを基にSAP HANA Cloudが提供するマルチモデル分析機能を紹介しました。
地理空間分析、グラフ分析、機械学習、検索、それぞれに機能に対してデータを移動やコピーすることなく、単純なSQLで処理を行いました。本ブログで紹介されているような処理を企業全体の規模で柔軟にスケールできることこそがSAP HANA Cloudの価値です。
他のユースケースや日本語チュートリアルを読みたい方にはSAP HANA Cloud 関連文書まとめをご利用ください。
特に、マルチモデル分析では下記がオススメです。
- Mapping Risk in a Stormwater Network using SAP HANA Spatial and Graph
- Augment your Python Analysis with Multi-Model data in SAP HANA Cloud
- Discovery Mission: Visualize Hazards & Truck Routes using SAP HANA Cloud
最後まで読んでいただきありがとうございました。
Maxime SIMON
Is there a way to build SAP language translator ???