AIと位置情報分析でクレジットカード詐欺と闘う

[Fighting Credit Card Fraud Through AI and Geospatial Analysis \- The Databricks Blog](https://databricks.com/blog/2021/04/13/identifying-financial-fraud-with-geospatial-clustering.html)の翻訳です。

多くの金融機関(FSI)における不正検知システムは、様々なコンポーネントからなる複雑なエコシステムになってしまう場合があります。従来型のルールベースの検知とAI、つぎはぎのオンプレミスのシステム、ベンダーのフレームワークとオープンソースのクラウドテクノロジーの組み合わせ。厳格な規制の要件(モデルの説明可能性など)、高ガバナンスのフレームワーク、低いレイテンシーと高可用性(カード取引における秒以内のレスポンス)に対応することで、これらのシステムは、運用コストが高く、メンテナンスが困難、そして、不正を働く人の振る舞いの変化に追従することも難しくなっています。[リスクマネジメント](https://databricks.com/blog/2020/05/27/modernizing-risk-management-part-1-streaming-data-ingestion-rapid-model-development-and-monte-carlo-simulations-at-scale.html)と同様に、近代の不正対策戦略はアジャイルであるべきであり、DataOps、DevOps、MLOpsのようなコード、データ、機械学習(ML)に対する確立されたデリバリー戦略を伴う、コラボレーティブかつデータ中心のオペレーションモデルを持つべきです。前回の[ソリューションアクセラレータ](https://databricks.com/blog/2021/01/19/combining-rules-based-and-ai-models-to-combat-financial-fraud.html)では、MLflowの助けを借りて、一般的なオーケストレーションフレームワークで、ルールベースとAIを組み合わせるという課題に取り組みました。

お客様がこれまで以上にデジタル技術を活用するようになるに従い、大規模FSIはお客様による購買活動に関わるリアルタイムのGPS情報にアクセスするようになりました。毎年400億回のカードトランザクションが発生しているアメリカの消費者向け銀行においては、GPS機能付きのバンキングアプリケーションを使用しているお客様のトランザクションの振る舞いをより理解するために活用できる大量のデータを保有しています。データは膨大かつ複雑であるため、従来型のデータウェアハウスやリレーショナルデータベースではうまく実行できないため、地理情報分析を実行するためには最新のライブラリや膨大な計算リソースが必要となります。
![](https://databricks.com/wp-content/uploads/2021/04/geo-ai-fraud-det-img-1.jpg)
*顧客購買行動を識別するための位置情報クラスタリング*

本ソリューションは位置情報分析に焦点を当てており、Databricksのレイクハウスプラットフォームを活用して、"誰がどのようにお金を使ったのか"という観点で、企業がお客様の購買活動をより深く理解できるようになるのかを示します。これは、万能の(one-size-fits-all)モデルではありませんが、まさにパーソナライズされたAIと言えます。結局のところ、不自然な行動を識別するためには、何が正常なのかを理解するところから始める以外に方法はありません。これを数百万人のお客様でやろうとしたら、様々な課題に直面することになり、データとAIを同一環境で処理できるプラットフォームが必要となります。
![](https://databricks.com/wp-content/uploads/2021/04/geo-ai-fraud-det-img-2.png)
*不正対策戦略における位置情報クラスタリング*

現実世界において活用できるソリューションとして、大量の位置情報から顧客行動を識別し、時系列変化を追跡することで、不正なカードトランザクションを検知するために、我々は新たなオープンソースの位置情報ライブラリ[GEOSCAN](https://github.com/databrickslabs/geoscan)をリリースしました。詰まるところ、ここでは[Delta Lake](https://delta.io/)、Apache Spark、[MLflow](https://mlflow.org/)に下支えされたLambdaインフラストラクチャによって、厳密なSLAを達成するODS(オンラインデータストア)上の分析環境から、金融機関がどのように不正を炙り出すのかをデモンストレーションします。

# クレジットカードトランザクションの位置情報クラスタリング

> 訳者追記
[DBSCAN \- Wikipedia](https://ja.wikipedia.org/wiki/DBSCAN)

[DBSCAN](https://www.aaai.org/Papers/KDD/1996/KDD96-037.pdf) (density-based spatial clustering of applications with noise:ノイズを伴う密度ベースの位置情報クラスタリングアプリケーション)は、隣接する点をグルーピングする際に用いられる一般的な手法です。他のクラスタリング手法と異なり、事前にクラスターの数を指定する必要はなく、形やサイズが異なるクラスターを検知し、密集したエリアに属さない外れ値を効果的に検知できます。これはクレジットカードトランザクション分析、潜在的不正の検知において有望な選択肢となります。しかし、この手法には対価が求められます。密集した隣接領域を検知するためには、DBSCANは全てのデータポイント同士を比較する必要があり、FSIが処理すべき大量データにおいては大きな制限となります。数十万以上の規模、数百万のお客様のデータを処理できる有効なソリューションが存在しなかっため、我々は自身で[オープンソースのAIライブラリ:GEOSCAN](https://github.com/databrickslabs/geoscan)を開発しました。GEOSCANは、大規模データに適用してDBSCANアルゴリズムによる位置情報クラスタリングを実現できるようにした我々の実装であり、ScalaとPythonのAPIを有しています。
![](https://databricks.com/wp-content/uploads/2021/04/geo-ai-fraud-det-img-3-1.png)
*密度に基づくクラスタリング(DBSCAN)*

隣接する(少なくとも一つのH3ポリゴンを共有している)データポイントのみをグルーピングするために、[UberのH3ライブラリ](https://eng.uber.com/h3/)を活用し、[GraphX API](https://spark.apache.org/docs/latest/graphx-programming-guide.html)を用いることで、大量データにおいても密集したエリアを検知することが可能となり、ニアリアルタイムで顧客の購買行動を理解し、異常なトランザクションを検知できるようになりました。
![](https://databricks.com/wp-content/uploads/2021/04/geo-ai-fraud-det-img-4-2.png)

我々のフレームワークの妥当性を検証するために、ニューヨークエリアにおけるカードトランザクションデータを合成しました。このデータセットは、トークン化されたユーザーと位置情報(緯度経度)、タイムスタンプ、トランザクションの量のみを保持します。現実世界においては、トランザクションの文脈を表す追加情報(店舗情報、MMCコードなど)やブランド情報(こちらは将来[ソリューションアクセラレータ](https://databricks.com/solutions/accelerators)で紹介します)があります。このデモでは、高級ショッピングモールなどにおける高額トランザクションエリアに該当する高密度クラスターを抽出します。

GEOSCANでは以下の2つのモード、分散、擬似分散モードが実装されています。

1. 分散モードでは、データフレーム全体(例：全てのユーザーベースから)からクラスターを抽出します
1. 擬似分散モードでは、条件ごとのグループからクラスターを抽出します。これにより数百万の顧客に対応する数百万のモデルを並列にトレーニングできます。パーソナライズされた不正対策戦略において、顧客の購買高度を理解するのに、両方のモードは有効と言えます。

## ショッピングエリア密度の検知

完全に分散して処理を行えるように、GEOSCANアルゴリズムのコアにおいては、`distance < epsilon`(メーター単位)と`neighbors > minPoints`を満たすポイントを検出するためにGraphXを活用します。

**Python**

```python
from geoscan import Geoscan

geoscan = Geoscan() \
   .setLatitudeCol('latitude') \
   .setLongitudeCol('longitude') \
   .setPredictionCol('cluster') \
   .setEpsilon(200) \
   .setMinPts(20)

model = geoscan.fit(points_df)
clusters_df = model.transform(points_df)
```

オープンスタンダードに準拠するために、GEOSCANは出力モデルとして[RFC7946](https://tools.ietf.org/html/rfc7946)(GeoJSON)をサポートしており、多くの位置情報ライブラリで(`geopandas`)、GISデータベース(`geomesa`)、可視化(`folium `)において、そのまま取り扱うことができます。以下に示すように、MLflowはモデルアーティファクトとしてGeoJSONをネイティブにサポートしています。
![](https://databricks.com/wp-content/uploads/2021/04/geo-ai-fraud-det-img-5-1024x585.jpg)
*MLflowにおけるGeoJSONファイルの表示*

実際のGEOSCANの活用例を見てみましょう。このソリューションにおいては、ニューヨーク市エリアにおいて高密度でクレジットカードのトランザクションがあった地理的な領域を抽出します。上で示したように、我々が指定したパラメーターは、ニューヨークのほぼ全体をカバーする大きな領域になっています。minPtsを減らしたり、epsilonを大きくすることで形状を改善できるかもしれませんが、そうした場合、ブルックリンのウイリアムズバーグのような密度の低いエリアに影響が出ます。この記事の最後にあるノートブックに記載したように、モデルをチューニングし、性能を改善するために、ここでは主にドメイン特有の別のアプローチを探索することにしました。

## モデル構築及びクラスターのタイリング

GEOSCANのロジックのコアは、H3ポリゴンを活用しているため、モデル構築において[ポリゴンの検索](https://en.wikipedia.org/wiki/Point_in_polygon)を行う際に新たなGISの依存性を持ち込むのではなく、同じものを用いるのが自然です。我々のアプローチは、優れたDelta Lakeの最適化技術(例えば[ZORDER](https://docs.databricks.com/spark/latest/spark-sql/language-manual/delta-optimize.html)インデクシング)の活用、複雑な位置情報クエリーをシンプルなSQLオペレーションとして提供、元々のデータフレームと容易に結合できるH3ヘキサゴンによるクラスターの"タイリング"から構成されています。
![](https://databricks.com/wp-content/uploads/2021/04/geo-ai-fraud-det-img-6-1024x538.jpg)
*H3ヘキサゴンによる地理形状のタイリング*

## パーソナライズされたクラスタリング

GEOSCANがどのように全てのデータセットに用いられるのかをデモンストレーションしました。しかし、ここでの狙いはニューヨークの形状を学習することでも、ショッピングに適した場所を探すことでもなく、一定期間における顧客の購買行動を追跡し、最も重要なことですが、特定の顧客において最もトランザクションが起こりえない場所を特定することであり、このためには地理情報クラスタリングにおけるパーソナライゼーションが必要となります。

**Python**

```python
from geoscan import GeoscanPersonalized

geoscan = GeoscanPersonalized() \
   .setLatitudeCol('latitude') \
   .setLongitudeCol('longitude') \
   .setPredictionCol('cluster') \
   .setGroupedCol('user') \
   .setEpsilon(500) \
   .setMinPts(3)

model = geoscan.fit(points_df)
clusters_df = model.transform(points_df)
```

我々の分散アプローチ同様、標準的なSpark ML APIによるモデルの格納、取得が可能です。このモードでは、それぞれのカード保持者の購買行動の地理的パターンを格納するファイルではなく、GeoJSONオブジェクトから構成されるデータフレームが返却されます。

## 特定の顧客行動パターンの理解

これまでに得られた洞察に対して、一歩下がって考えを巡らせることが重要です。全体の顧客ベースに対する理解を深めた(分散アプローチ)ので、この情報を活用して個人特有の振る舞いをより深く理解することができます。多くの人が同じ場所で買い物をしているのであれば、その場所は特定のユーザーにとって大きな意味を持ちません。真のパーソナライズドバンキングの実現に向け、顧客をより理解するために、共通のエリアとどの程度オーバーラップしているのかに基づいて、「パーソナライズされた」ゾーンを検知することが可能となります。

それぞれのユーザーを最も特徴付けるエリアを検知するということは、自然言語処理ユースケースにおいて、最も文章を特徴づけるキーワードを検知するということに似ています。共通エリアの重みを減らしつつ、ユーザー固有の場所の重みを増加させるアプローチとして、単語の出現頻度(Term Frequency) / 逆文書頻度(Inverse Document Frequency)を計算するTF/IDFを活用できます。
![](https://databricks.com/wp-content/uploads/2021/04/geo-ai-fraud-det-img-7.jpg)
*特定ユーザーの地理的購買パターン*

> 訳者追記
[tf\-idf \- Wikipedia](https://ja.wikipedia.org/wiki/Tf-idf)

ここで我々は、顧客の購買行動に関して素晴らしい洞察を得ました。このユーザーの多くのトランザクションは、チェルシー、ニューヨークの金融街で生じていますが、5thアベニューのプラザホテルとウィリアムズバーグで起きているトランザクションの方がこのユーザーをより良く定義すると言えそうです。特定のユーザー、場所において、このフレームワークはカードのトランザクションが特定の時間、日、曜日における既知の購買パターンなのかどうかを理解するために活用することができます。

# パーソナライズされたAIによる不正対策

前章では、位置情報データ分析が顧客の振る舞い、傾向に関して多くの情報を提供してくれること、そのため、高精度な不正対策戦略において、不正検知のための重要なコンポーネントになり得ることを示しました。この章では、これらの洞察を活用して、どのようにリアルタイムで疑わしい振る舞いを検知するのかをデモンストレーションします。多くの場合、不正検知システムは、データの機密性(個人情報)、規制の要件(PCI/DSS:クレジットカードのセキュリティ基準)、モデルの重要性(高いSLA)から、分析環境の外で実行されます。このため、ここで得られた洞察を活用するために、MLflowによる自己完結モデルから、Redis、MongoDB、Redshift、ElastiCacheなどのリレーショナル、NoSQLオンラインデータストアなど実現可能性がある複数の戦略を検討します。

## 不正の抽出

ここでは、パーソナライズされたMLモデルをDeltaテーブルにH3ポリゴンとして格納しているので、シンプルなJOIN操作でそれぞれのトランザクションに情報を追加できます。以下の例では、ユーザー定義関数に埋め込んだ特定のH3解像度([解像度テーブル](https://h3geo.org/docs/core-library/restable)を参照ください)を与えることで不正(対象ユーザーの既知のパターンに該当しないトランザクション)を検知することができます。

**Python**

```python
from pyspark.sql import functions as F

anomalous_transactions = (
 spark
   .read
   .table('geospatial.transactions')
   .withColumn('h3', to_h3('latitude', 'longitude', 10))
   .join(tiles, ['user', 'h3'], 'left_outer')
   .filter(F.expr('cluster IS NULL'))
```

50万トランザクションに対して、81レコードを5秒以内に抽出しました。必ずしも不正とは言えませんし、疑わしいものでもないかもしれません、しかし、これらのトランザクションはユーザーの「普通の」振る舞いに合致しないため、高精度不正対策フレームワークの一部としてフラグが立てられるべきであり、将来的なルール、モデルに組み込まれていくものになります。我々が学習したユーザー特性から、日曜午後に発生しているものと水曜午前に発生しているものは同じと言えるでしょうか？

数百万のトランザクションと低いレイテンシーの要件から、リアルタイムで大規模なデータセットをJOINすることは現実的ではありません。全てのクラスター(対応するH3タイル)をメモリーにロードすることは可能ですが、異なる日、時間における複数のモデル、異なるセグメント、異なるトランザクション指標(異なるブランドカテゴリ、[MMCコード](https://en.wikipedia.org/wiki/Merchant_category_code))、数百万の顧客に対する評価を行った結果、数百万の変数に対する効率的な検索が必要となる複雑なシステムになってしまうかもしれません。

## Bloomフィルタリング

> 訳者追記
[ブルームフィルタ \- Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%AB%E3%83%BC%E3%83%A0%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF)

ここで[Bloomフィルター](https://en.wikipedia.org/wiki/Bloom_filter)、全てのデータセットをメモリーに格納することなしに特定レコードの存在をテストできる効率的な確率論的データ構造の出番です。Bloomフィルターの歴史は古いですが、残念なことにその利用はデータベース最適化エンジン、実行計画(Deltaエンジンは内部でBloomフィルタリング最適化技術を活用しています)などの難しいエンジニアリング技術にとどまっています。しかし、この技術は、現在のデータサイエンスにおいても活用できるものです。

Bloomフィルターの考え方は、一連のレコードを一連のハッシュ値に変換し、それぞれのバイト列表現を1から0のベクトルとしてオーバーレイするというものです。特定のレコードの有無のチェックは、ビットが1に設定されていることをチェックすることになります。Bloomフィルターのメモリー効率性においては、不正検知の文脈において無視できない欠点があります。Bloomフィルターにおける偽陰性(存在しないと誤って判別するケース)は0となりますが、非ゼロの偽陽性(ハッシュの衝突により間違って存在すると判別してしまうケース)が存在しています。これは配列の長さとハッシュ関数の数でコントロールできます。

ここでは、Pythonのライブラリ`pybloomfilter`を使用して、本アプローチの妥当性を検証し、全てのユーザーの既知のH3タイル全てそれぞれに対してBloomフィルターをトレーニングします。理論上、我々のフィルターは数百万件のレコードを保持しますが、高い実行スピードのために1%の不正トランザクション(我々の偽陽性の比率です)を犠牲にすることで、確率論的検索を可能にし、物理的には1バイトの配列のみをメモリに蓄えるだけで済みます。

**Python**

```python
import pybloomfilter

def train_bloom(records):
 num_records = len(records)
 cluster = pybloomfilter.BloomFilter(num_records, 0.01)
 cluster.update(records)
 return cluster

records = list(tiles.filter(F.col('user') == user).toPandas().h3)
bloom = train_bloom(records)
```

特定のカードトランザクションが発生した位置が存在するか、存在しないのかのテストを一瞬で実行することができます。

**Python**

```python
anomalies = transactions[transactions['h3'].apply(lambda x: x not in bloom)]
```

本記事で紹介されているノートブックでは、データサインエンティストが、高いスループット要件に応えられるように、外部API、バッチ、ストリーミングに対応できるMLflowのエクスペリメントに、ビジネスロジックをどのように埋め込んでいるのかをデモンストレーションしています([MLflowデプロイメント](https://www.mlflow.org/docs/latest/python_api/index.html)を参照ください)。

**Python**

```python
import mlflow
model = mlflow.pyfunc.load_model('models:/bloom/production')
anomalies = model.predict(transactions)
anomalies = anomalies[anomalies['anomaly'] != 0]
```

しかし、このアプローチにおいては、変化するユーザーの振る舞いに合わせて、新たなモデルを定期的に再トレーニングし、再度デプロイする必要があるため、大規模な金融サービス機関に重大な課題を突きつけることになります。

ユーザーが休日に外出する例を考えましょう。最初のクレジットカードのトランザクションは異常(必ずしも疑わしいとは言えません)として検知されるかもしれませんが、多くのトランザクションが観測されるにつれて、新たな"正常"として学習する必要があります。新たなトレーニングデータで同様のプロセスを経ることで、リリースされる新バージョンのモデルを取得し、エキスパートチームによるレビューを受け、然るべき担当者の承認を受けたのち、最終的には不正検知のエンドポイントでモデルがアップデートされることになります。これは技術的には可能ですし、Databricksのデータ管理に対するコラボレーティブアプローチによってさらに容易になりますが、このアプローチは多くのケースで現実的とは言えないかもしれません。

## オンラインデータストア

金融機関が分析プラットフォームとは別にオンラインデータストアを持つことは一般的と言えます。KafkaやEvent Hub(Azure)、Kinesis(AWS)のようなエンタープライズメッセージブローカーによってアクセスされる、カードのトランザクションのリアルタイムのフローは、リファレンスとなるデータポイントとリアルタイムで比較されます。上記アプローチの代替案としては、オンランのデータストア(例：MondoDB)を使用して、通常のビジネスプロセスのように(ITシステムの変更時間外に)リファレンスデータをライブのエンドポイントに"プッシュ"し続けるというものがあります。全ての入力トランザクションデータは、一連のルールに対して照合され、定期的に更新されることで、1秒未満のクエリーでアクセス可能となります。例えば、ここでは[MongoDBコネクター](https://docs.mongodb.com/spark-connector/current/)を活用して、どのようにして、低いレイテンシーの高度分析技術による予測のパワーと、従来のルールベースのシステムの説明可能性を組み合わせて、位置情報クラスターのデータフレームをリアルタイムに提供するのかを説明します。

**Python**

```python
import com.mongodb.spark._

tiles
 .withColumn("createdAt", current_timestamp())  
 .write
 .format("mongo")
 .mode("append")
 .option("database", "fraud")
 .option("collection", "tiles")
 .save()
```

上の例では、新たなリファレンスデータ(カードトランザクションのH3位置)を、数百万のカード保持者ごとにMongoDBのコレクション(テーブル)に一定時間間隔で追加しています。この場合、新たなトランザクションは、簡単な問い合わせでMongoDBに格納されたリファレンス履歴情報と付き合わせることができます。あるユーザーとトランザクション位置(H3ポリゴン)において、このカードトランザクションは既知のユーザーパターンと言えるでしょうか？

```
mongo > use fraud
mongo > db.tiles.find({"user": "Antoine", "tile": "8A2A1008916FFFF"})
```

このソリューションの一部として、MongoDBの別の機能である[Time to Live](https://docs.mongodb.com/manual/tutorial/expire-data/)(TTL)を活用したいと考えました。コレクションを維持し続けなくて良いというオペレーション上の利点に加え、ユーザーの変化するパターンに追従するために、モデルに対して時限的なディメンジョンを追加することができます。例えば、1週間のTTLと、毎日のDatabricks上でのモデルトレーニングによって、新たなトランザクションが観測されるたびに不正に対する戦略を動的に適合させ、意図的にモデルをユーザーの変化する振る舞いに合わせるようにモデルをずらしていき、クラスターを追跡することができます。

[![Screen Shot 2021-04-19 at 20.45.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/cac216ee-8810-ee57-1d16-acfb4ba0525b.png)](https://vimeo.com/535079477)
*顧客の振る舞いの変化をどのように追跡するのかの例(画像をクリックしてリンク先の動画を参照ください)*

上の可視化では、顧客のトランザクションの変化をどのように追跡できるのかを示しています(MongoDBのリアルタイムのTTLとDeltaのタイムトラベル機能のおかげです)。ここでは、観測された位置情報がX日の期間はアクティブであり続けるため、異常なトランザクションをリアルタイムで検知できます。

# 結び：顧客中心銀行における位置情報分析

万能の(one-size-fit-all)モデルで、不正なカードトランザクションを対策することはできないでしょうが、高精度の不正対策戦略の一部として、別の抑制手段から得られる分離されたインジケーターを常に関連づけるべきです。これはしばしば、先進的なモデリング技術(例：ニューラルネットワーク)とルールベースのシステムの組み合わせ、先進技術と従来プロセスの組み合わせ、クラウドベースのインフラとオンプレミスのシステムの組み合わせが必要となり、加えて厳密な規制の要件、高いSLAに応えなくてはなりません。我々のソリューション自身は不正トランザクションの検知を狙いとしたものではありませんが、新たなオープンソースライブラリ[GEOSCAN](https://github.com/databrickslabs/geoscan)のリリースを通じて、位置情報分析がタイムリーかつ低コスト(セルフメンテナンス)、自己説明可能な形で、異常イベントの検出にどのように貢献するのかをデモンストレーションしました。このアプローチは、効率的にルールとAIの戦略を組み合わせたものであり、金融の不正行為と戦うための有効な武器となり得ます。

この取り組みの一環で、金融サービスにおいて同様に重要なことを発見しました。ここで、我々は従来型のバンキングから、デモグラフィック情報(誰なのか)ではなく購買パターン(どのように行動するのか)に基づくパーソナライズドバンキングに移行するためのレイクハウスのインフラストラクチャーの能力を示し、より顧客中心で包括的な個人向けバンキングへの道筋をつけました。

# 次の一歩

あなたの不正対策の開発戦略を加速するために、Databricksで以下のノートブックを試してみてください。そして、同様のユースケースを持つお客様をどのようにサポートするのかを知りたいのでしたら、[お問い合わせ](https://databricks.com/jp/company/contact)ください。

- [Stage 0: Geospatial clustering context](https://databricks.com/notebooks/geoscan/00_geofraud_context.html)
- [Stage 1: Using a novel approach to geospatial clustering with H3](https://databricks.com/notebooks/geoscan/01_geofraud_clustering.html)
- [Stage 2: Detecting anomalous transactions as ML enriched rules](https://databricks.com/notebooks/geoscan/02_geofraud_fraud.html)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)