0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon Fraud Detector (AFD)のスコアリング結果を、Ruby on Rails SDK使用して取得する方法

Posted at

前書き

現在、Amazon Fraud Detector (AFD) を活用した不正検知システムを開発しています。
本記事では、Ruby on RailsSDK を使用してAFDのスコアリング結果を取得する方法について、備忘録も兼ねてまとめます。

Amazon Fraud Detector (AFD)の概要

  • 機械学習を活用して不正行為をリアルタイムで検出するAWSのサービス
  • 開発者は、過去の不正データを基にカスタムモデルを作成し、不正取引やアカウント乗っ取りなどを検出できる
  • 高度な不正検知システムを簡単に導入できる

主な特徴

  • 自動機械学習(AutoML):コード不要で不正検知モデルの構築が可能
  • リアルタイムで不正リスクを判定:ユーザーのアクションごとにAIが即座に不正リスクをスコア化
  • カスタムルールで自動対応:事前に設定したルールを基に、不正の疑いがある場合にアラートやブロックを実行
  • 他のAWSサービスとの連携:Amazon S3AWS LambdaAmazon SNS等と連携可能

活用例

  • 決済詐欺の防止
  • 偽アカウントの検出
  • プロモーション不正の抑制

前提条件

  • Ruby on Railsの環境が構築済み
  • AFD上で、モデルとディテクターが構築済み

構築手順

注意

  • 本記事では、AFDに送信するデータを「メールアドレス」と「IPアドレス」のみに限定し、それらの情報を基にスコアリングを算出する構成としている
  • その他の属性は送信せず、本記事の範囲外とする

設定関連

Gemfile

  • Gemfileに下記のGemを追加した後、bundle exex installを行う
# aws-sdk
gem 'aws-sdk-frauddetector'

マイグレーション

  • AFDの結果を保存する為、マイグレーションファイルを作成する
rails generate migration CreatAfdScores
  • マイグレーションファイルを修正した後、マイグレーションを実行する
20250321000000_create_afd_scores.rb
class CreatAfdScores < ActiveRecord::Migration[8.0]
  def change
    create_table :afd_scores do |t|
      t.integer :score, null: false
      t.string :judgment_result, null: false
      t.timestamps
    end
  end
end
  • マイグレーションの実行コマンド
rails db:migrate

環境変数(credentials.yml.enc)

  • credentials.yml.encに、以下の設定を追加する
credentials.yml.enc
afd_aws:
  region:            AFDが使用できるリージョン
  access_key_id:     A******************7
  secret_access_key: I**************************************S

構築関連

コントローラーの設定

  • 以下の処理を任意のコントローラーのnew or createメソッド内に記載する
    (通常、新規データの作成時にスコアリングを行う為、newcreateでの実装が推奨される)
任意のcontroller.rb
# AfdClientのインスタンスを作成
afd_client = AfdClient.new
result = afd_client.get_score(
  email:      base.email,
  ip_address: base.ip
)

# afd_socersテーブルにデータを保存する
AfdScore.create!(
  score:           result[:score],
  judgment_result: result[:judgment_result]
)

サービスレイヤーの設定

  • app/services/afd_client.rb ファイルを作成する
  • 以下のコードをafd_client.rbに記載する
afd_client.rb
require 'aws-sdk-frauddetector'

class AfdClient

  # RailsとAFDの相互通信を行う為の認証処理。
  def initialize
    @client = Aws::FraudDetector::Client.new(
      # credentials.yml.encからAWSの認証情報を取得
      region: Rails.application.credentials.afd_aws[:region],
      credentials: Aws::Credentials.new(
        Rails.application.credentials.afd_aws[:access_key_id],
        Rails.application.credentials.afd_aws[:secret_access_key]
      ),
      http_open_timeout: 10, # 接続開始までのタイムアウトを設定
      http_read_timeout: 10  # データ読み取りのタイムアウトを設定
    )
  end

 def get_score(email:, ip_address:)
 
    begin
    # AFDに通信して、結果を取得
    response = @client.get_event_prediction(
      detector_id: "構築したdetector_idを記載",
      event_id: SecureRandom.uuid,
      event_type_name: "構築したイベントの名前を記載", 
      event_timestamp: Time.now.utc.strftime("%Y-%m-%dT%H:%M:%SZ"),
      entities: [
        {
          entity_type: "AFDで構築したエンティティタイプ名を記載", 
          entity_id: "エンティティタイプ名_#{Digest::SHA256.hexdigest(email)}" 
        }
      ],
      event_variables: {
        "email"      => email,
        "ip_address" => ip_address
      }
    )
    rescue Aws::FraudDetector::Errors::ServiceError, Net::OpenTimeout, Net::ReadTimeout => e
      Rails.logger.error(e.message, email, ip_address)
      return { score: 0, judgment_result: "error" }
    end    

    score = response.model_scores.first&.scores.values.first || 0
    result = response.rule_results.first&.outcomes&.first || "unknown"

    return { 
      score: score,
      judgment_result: result
    }

  rescue => e
    Rails.logger.error("AFD Error: #{e.message}")
    { score: 0, judgment_result: "error" }
  end

end

get_event_predictionメソッドで設定するパラメータと説明

パラメータ 説明
detector_id
型 : String
AFDに設定したDetector ID。どの不正検知モデルを使用するかを指定する

入力例
"my_fraud_detector_v1"
event_id
型 : String
各リクエストごとに一意のIDを割り当てる為の識別子。通常、SecureRandom.uuidを使用する

入力例
"123e4567-e89b-12d3-a456-426614174000"
event_type_name
型 : String
AFDに設定したイベントの種類。どのイベント定義を使用するかを指定する

入力例
"transaction_event"
event_timestamp
型 : String
イベントが発生した時刻

入力例
"2025-03-13T12:34:56Z"
entities
型 : Array(Hash化)
不正検知の対象となる ユーザーや取引(エンティティ) を識別する為の情報を設定する

入力例
[ { entity_type: "customer", entity_id: "customer_abcdefg" } ]
event_variables
型 : Hash
不正リスクを判定する為に、取引やアクセス情報(イベント変数)をAFDに送信する

入力例
{ "email" => "test@example.com", "ip_address" => "192.168.1.1" }

補足
app/services/の用途

  • モデル (app/models/) に直接書くべきでない複雑な処理を分ける
  • MVCの「サービス層」として利用し、コードの再利用性と可読性を向上させる
  • Fat Controller(肥大化したコントローラ)やFat Modelを防ぐ為に使用する

参考資料

感想

今回は、AFDを活用した Railsの処理を構築しました。
特に、例外処理の実装が難しく、試行錯誤を重ねました。

また、本記事では触れていませんが、RSpecのテスト実装に最も苦戦しました。
RSpecについては、今後も引き続き学習し、理解を深めていきたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?