17 ポイント 投稿者 GN⁺ 2026-05-17 | 4件のコメント | WhatsAppで共有
  • 詐欺検知は、機械学習より前にまずテーブルと結合を正しく押さえ、速度・位置・金額・加盟店・時間帯の異常パターンをSQLで見つけることから始まることが多い
  • Velocity は、短時間に同じカード保有者の取引が集中する区間を見つけるもので、時間ウィンドウ・閾値の調整と誤検知ホワイトリストが必要
  • Impossible travel は、LAG() と距離計算により、Chicagoでの決済の7分後にLos Angelesで決済されたような物理的に不可能な移動を、強いクローンカードのシグナルとして捉える
  • 金額異常は、$1.00$99.99$499.99 のように、カードテストやルール回避を示唆する金額帯を見つけるが、給付取引にはあまり適さない
  • 加盟店の急増、通常時間帯外の取引、ウィンドウ関数の派生カラムを併用すると、取引を複数シグナルでスコア化でき、反復サイクルを数週間から数時間へ短縮できる

取引データから詐欺の兆候を見つけるSQLパターン

  • 詐欺検知は、機械学習やグラフデータベースより前に、正しいテーブルと結合、そして不審な取引パターンを見つけるSQLから始まることが多い
  • クレジットカード、医療請求、電子商取引、POS、政府支援給付プログラムのように、お金が動きログが残るデータに適用できる
  • 新しいデータセットでは通常、Velocity、不可能な移動、金額異常、加盟店集中、異常時間帯、ウィンドウ関数ベースのシグナルの順でパターンを積み上げていく

1. Velocity: 短時間で過剰な取引

  • 盗まれたカードやアカウントを素早く使い切ろうとする場合、同じカード保有者に短時間で取引が集中するパターンが現れる
  • 基本クエリでは直近30日の取引を時間単位でまとめ、cardholder_id ごとの取引数が基準を超える区間を探す
  • 主要な調整値は時間ウィンドウの大きさ取引数の閾値
    • 1分、5分、1時間のバージョンを並列に回して比較できる
    • カードテスト組織は数秒以内に取引を集中させ、給付不正の組織は半日かけて動くこともあるため、スケールが異なる
  • 正常な利用者でも基準を超えることがある
    • 自販機を管理する運営者
    • プリペイドカードを大量にチャージする人
    • 最初の探索後には、こうした誤検知対象のホワイトリストが必要
  • スライディングウィンドウ方式では COUNT(*) OVER (...) RANGE BETWEEN INTERVAL '5 minutes' PRECEDING AND CURRENT ROW によって直近5分以内の取引数を計算する
  • QUALIFYSnowflake, BigQuery, Databricks, Teradata で動作する
    • Postgresではクエリ全体をCTEで包み、外側でフィルタする必要がある

2. Impossible travel: 物理的に不可能な移動

  • 1枚のカードがChicagoで決済され、その7分後にLos Angelesで決済されていたら、どちらか一方は偽物である可能性が高い
  • このパターンはクローンカードを捉える強いシグナルであり、1枚のカードが数分で遠く離れた2地点に存在する正当な理由はほとんどない
  • クエリでは LAG() で直前の取引の時刻と位置を取得し、現在位置と直前位置の間の距離と時間を計算する
  • haversine大圏距離 (great-circle distance) を計算する関数
    • ほとんどのデータウェアハウスが提供している
    • なければ自作できる程度の関数でもある
  • 例の閾値は 600mph
    • 商用ジェット機の巡航速度は約575mphなので、飛行機でも不可能な速度を意味する
    • 100mphに下げると高速な地上移動も検出できるが、実際の航空旅行者や、親が子どもを送迎する通常取引まで引っかかり始める
  • 同系統で追加で見られるシグナルもある
    • 5分以内に同じ州の離れた2都市で取引されていれば、地域クローン組織を示唆する可能性がある
    • 1時間以内に複数のZIPコードで取引されていれば、1つの地域で動くスキマー組織を示唆する可能性がある
    • 10分以内に国境を越える取引は、国際組織のシグナルになり得る

3. Amount anomalies: 特定金額帯の異常取引

  • 詐欺ではよく現れるが、通常利用では珍しい金額パターンがある
  • 例の条件では次の金額帯を探す
    • $1.00, $5.00, $10.00
    • $99.50 以上 $100.00 未満
    • $499.50 以上 $500.00 未満
  • 小さな整数ドル金額は、たいていカードテストのシグナル
    • カード番号ダンプで得た番号が実際に使えるか確認した後、再販売しようとする流れである
    • 実際のカード保有者がちょうど $1.00 の商品を買うケースはまれ
    • コーヒーは $4.73、給油は $52.81 のように、ちょうど丸い金額ではない可能性が高い
  • 閾値のすぐ下の金額には別の意味がある
    • $99.99 は、多くの場所で $100 以上から本人確認を求めるラインを避けようとする形かもしれない
    • $499.99 は、$500 の1日あたりATM上限を避けようとする形かもしれない
    • 取引者がルールを理解し、その直下にとどまっているシグナルになる
  • 給付取引では丸い金額パターンはあまり役に立たない
    • 給付は同じやり方でカードテストされない
    • 通常は重複受給者のほうが重要なシグナルになる

4. Suspicious merchants: 加盟店単位の不審な集中

  • 給油機のカードリーダーのように、特定のリーダーがスキマーに感染すると、1件ではなく数十件の詐欺につながることがある
  • そのリーダーを数週間使ったすべてのカードが、誰かのデータベースに入る可能性がある
  • 加盟店の観点では、短期間に互いに関連のないカード数が平常より大きく増え、取引金額も大きくなる形で現れる
  • 単純な基準の例では、直近7日間について加盟店と時間単位でまとめ、次を計算する
    • ユニークカード数
    • 総取引数
    • 総取引金額
    • ユニークカード数が20を超え、総額が $5000 を超える時間帯を探索する
  • 静的閾値には規模補正の問題がある
    • Costcoなら90秒以内にこの基準を超えることがある
    • 古書店ではほとんど超えない
  • より良い方法は、各加盟店をその加盟店自身の過去ベースラインと比較すること
    • 直近60日の取引を時間単位でまとめる
    • 各加盟店の過去168個の時間バケットを基準に、平均ユニークカード数を計算する
    • 現在のユニークカード数が過去平均の3倍を超える区間を探す
  • 168個の時間バケットは過去7日間の時間単位区間
    • 日次・週次の季節性が重要だからである
    • 同じコーヒーショップでも火曜14時と土曜9時ではベースラインが異なる
  • 出発点としては平常時の3倍を使える
    • アラートが過剰にあふれない程度に緩い
    • 実際に不審な時間帯を捉えるには十分に厳しい

5. Off-hours: 個人の通常利用時間帯外の取引

  • ほとんどの人には支出習慣がある
  • 9時から5時まで働く人が突然午前3時に給油し始めたら、カードが他人に使われているか、旅行中である可能性がある
  • 旅行中かどうかは、別のシグナルで追加確認できる
  • クエリでは直近90日についてカード保有者ごと・時間帯ごとの取引数を求め、その時間帯に2回以上取引があった場合だけを通常時間帯として認める
  • その後、新しい取引の時刻がそのカード保有者の earliest_hourlatest_hour の範囲外なら検知する
  • 内部クエリの「その時間帯に2件以上」という条件が重要
    • 3か月前に偶然あった深夜給油1件が通常時間帯に含まれるのを防ぐ
    • 基準を「一度あったこと」ではなく実際の習慣に合わせる
  • 欠点は履歴データが必要なこと
    • 新規アカウントにはベースラインがない
    • 新規アカウントには全体ユーザーの時間帯パターンを使うか、数か月分たまるまでこのパターンをスキップできる

6. ウィンドウ関数でシグナルを組み合わせる

  • ウィンドウ関数パターンは、独立した詐欺タイプというより、前の5つのパターンを組み合わせ可能なシグナルにするための準備作業である
  • 取引ごとに次の派生カラムを作っておける
    • 直前取引からの経過時間: timestamp - LAG(timestamp)
    • 加盟店が変わったかどうか: 直前の merchant_id と現在の merchant_id を比較
    • 直近24時間の累積金額: SUM(amount) OVER (...)
    • その日の何件目の取引か: ROW_NUMBER()
  • こうしたカラムをマテリアライズしておけば、詐欺ルールは単純なフィルタ式にまで縮小される
  • カードテスト組織は次の条件で見つけられる
    • その日の5件目以降の取引
    • 直前取引から60秒未満
    • 加盟店が直前取引と異なる
  • 新しい詐欺仮説をエンジニアリングチケットではなくSQLフィルタで表現できれば、反復サイクルは数週間から数時間へ短縮される
  • 結果として、より多くの詐欺をより速く捉えられる

パターンを組み合わせて使う方法

  • どれか1つのパターンだけでは十分ではない
  • 各パターンには明確な限界がある
    • Velocityには、自販機運営者のような誤検知がある
    • 地理的に不可能な移動は、1つの大都市圏内で起こる詐欺を見逃す
    • 金額異常は、カードテスト文脈以外ではあまり適合しない
    • 異常時間帯ルールには履歴が必要
  • 実務では、すべてのパターンを回し、各取引を複数シグナルにまたがってスコア化するやり方が有効
  • 3つまたは4つのシグナルにかかる取引は、ほぼ常に詐欺である
  • 1つのシグナルにしかかからない取引は、旅行中の正規カード保有者による珍しい利用かもしれない
  • 詐欺検知をこれから始めるなら、Velocityから始めるのがよい
    • 有用な量の詐欺をあぶり出せる
    • 正常な活動は比較的少なくしか引っかからない
    • 実行コストも低い
  • すでに1から5までを備えているなら、次の投資先はウィンドウ関数ベースの生カラム
    • 一度作ればチームのすべてのアナリストが使える
    • 次の詐欺パターン追加が別プロジェクトではなくなる

注意点

  • NULL処理

    • 実際の取引テーブルでは、SQL入門書のように NULL を使わない場合が多い
    • 多くのレガシーシステムでは、「終了日なし」に 9999-12-31、「開始日なし」に 0001-01-01 のようなセンチネル値を使う
    • IS NULL でフィルタすると、こうした行を静かに見落とすことがある
    • 特定テーブルの慣習を確認してから WHERE 句を書く必要がある
  • 誤検知

    • どのルールでも、異常ではあるが合法的な行動をする実際のカード保有者を捕まえる可能性がある
    • フラグが立った案件には人によるレビューが必要
    • 実際の詐欺とそうでないものを基準に閾値を調整するフィードバックループが必要
    • 単一ルールで自動ブロックすると顧客を失う可能性がある
  • 個人情報

    • データにPIIがあるなら、適用されるデータ利用ポリシーを守らなければならない
    • まず匿名化またはサンプルデータで作業し、本番データは承認後に使うべき
  • コスト

    • 大きなパーティションでのウィンドウ関数は安くない
    • まず日付範囲をフィルタしてからウィンドウ関数を適用すべき
    • データセット全体の2年分の取引に対して先に LAG() を回し、後から WHERE を付けると、ウェアハウスクレジット予算を大きく消費しかねない

4件のコメント

 
kaydash 2026-05-17

銀行の勘定系やチャネル系で過去に借用されていた方法ですね

 
GN⁺ 2026-05-17
Hacker Newsのコメント
  • 実際のカード所有者がちょうど $1.00 の買い物をほとんどしないという基準は、結局のところ販売者がどう価格設定するか次第ではないかと思う
    盗んだクレジットカードを試すためにウェブサイトで何かを買うとしても、購入者が価格を自由に決められるわけではない
    それに、米国のように価格に税金が含まれていない状況を前提にしすぎているようで、他の地域では きっちりした価格 はごく普通だ
    他の基準もうまく機能するのか疑問だ。たとえば直近90日で、普段2件以上取引していた時間帯の外で取引した人をフラグするとしたら、半分くらいの人が引っかかるのではないかと思う
    複雑な専門知識を過度に単純化したSQLクエリに落とし込んだ記事なのか、全部推測と創作なのか判然としない。「取引詐欺を捕まえるための6つのSQLパターン」と「ここには私が実際に手がけたことや見たことは何もない」という文が矛盾している

    • 「普段の時間帯外の取引」はかなり初歩的な基準に見える
      普通は午前2時にガソリンやコーヒーや軽食を買ったりしないが、ごくまれにそういうことがあるなら個人的な緊急事態である可能性が高く、その最中に銀行へ電話したいとは思わない
      日和見的な泥棒もその時間に活動しうるのは分かるが、誤検知コスト も確実に存在する
    • それよりひどい。私の経験ではコーヒーはたいてい きっちりした金額 のことが多いし、給油時にわざとちょうどの金額を入れる人もいる
      それに、10、20、50ユーロのようにあらかじめ決めた金額を要求するガソリンスタンドもある
    • ある夜、バーでお腹が空いてポテトチップスを1袋買おうとしたのだが、カードの最低決済額が £5 だと言われたので、そのまま £5 で決済してくれと頼んだ
      すると詐欺の疑いがあるとしてカードが止められ、かなり腹が立った。午前2時に酔った状態で対処したいことではなかった
      もしかすると自分自身から守ってくれたのかもしれないが、それでも不便だった
    • 今も使われているのかは分からないが、以前はホテルやレンタカーのような業種で、部屋の予約や車の貸し出し前に $1.00の取引 でクレジットカードの有効性を確認することがあった
    • この方法は、テスト取引に少し ゆらぎ を入れるだけで簡単に回避できるし、きちんとした統計分析で容易に改善もできる
      それに、ほぼ100%の精度を期待しないこうしたヒューリスティックなパターン認識こそ、AIが得意であるべき領域ではないかと思う
  • 「10分以内の国境越えは国際組織」という基準は、ヨーロッパの国境近接地域 に住む普通の人たちにも当てはまりうる
    カード非対面取引は除外するとしても、すべての加盟店所在地が正確に設定され、すべての販売が実店舗で行われ、移動販売のようなものはなく、すべての取引がオンライン処理されると誤って想定しているように見える

    • 数週間前にアメリカからカナダへ渡ったときも、たぶん 10分 くらいだった
  • 最後まで読むと、中身が薄く、互いに矛盾する助言が露呈する。ほぼ確実に LLM生成記事 っぽい
    「あなたのチーム」はどの単一パターンにも依存すべきでないと言いながら、パターン1だけでも「有用な量の詐欺」を明らかにできると言っている
    「チームのすべてのアナリストはそれら、つまりウィンドウ関数が手に入れば使うだろうし、次の詐欺パターンを追加することがプロジェクトではなくなる」といった妙な文もある
    また、ほぼすべての例が IS NULL を使っていないのに、IS NULL フィルタリングが適用されないことがあるという無関係な話が出てきて、唯一使っている例も別の文脈だ
    全体として 質が低くて長すぎる記事

  • Hacker News、これは指摘しておくべきだ
    「Fixel Smith」は AIが作った人物 で、記事は詐欺分析とほとんど関係がない。この名前はミュージシャン(1)、小説家(2)、詐欺アナリスト(3)、インフルエンサー(4)など、想像できるほぼあらゆる人格として使われている
    220点以上ついてコメントも70件を超えているのに、この投稿がかなり偽物っぽいと気づいた人はほとんどおらず、AI生成の人物だと見抜いた人もいない

    1. https://www.amazon.it/Forged-Soundtrack-Explicit-Fixel-Smith...

    2. https://fixelsmith.com

    3. https://analytics.fixelsmith.com/

    4. https://www.instagram.com/fixeltales/

    • Hacker Newsは最近、こういう 低品質なAI投稿 を載せてしまう苛立たしい癖がついているようだ
      このAIの洪水がコミュニティの判断力について不快な真実を示しているのか、それとも既存の防御策の失敗で、変えさえすれば済む話なのか気になる
    • 携帯で記事を確認していて、コメントを少し眺めただけだった。どの記事がAI生成で、どれが編集されたものかを常に判断するのは簡単ではないが、ここでは引用文を見るだけで一目で明らかだった
      すべてのコメントが善意で書かれたものだと仮定するなら、ここですら AIリテラシー が低いのはかなり心配だ
    • ざっと見ても、非常に多作な個人かボットのように見える
      小説は分析記事とほとんど関係がなく、分析記事は LLM文体 を帯びているようで、全体として怪しい。元記事のテーマが詐欺だと考えると皮肉だ
    • ほとんどの人が、読む記事の著者を習慣的に調べると言われたら、むしろそちらのほうが驚くだろう
      正直、私はたいてい署名欄すら見ないし、サイトの他の部分はなおさら見ない
    • これは間違いなく実在する記事だ。たしかに LLMが書いたように は見えるが、その記事に対してできる最悪の批判がLLMっぽく見えることだけなら、実質的な批判がないとも言える
      内容が作り話かどうかは不明だが、LLMが書いたのか小説なのかを推測しなくても、記事の中身自体を批判することはできる。もっと具体的な欠陥がいくらでもある
  • 私たちはオープンソースのセキュリティフレームワーク tirreno を開発している
    ここで説明されているアプローチには疑問がある。たとえば不可能移動は正当で広く使われる手法だが、これはIPアドレスベースのオンラインユーザー行動に関するものだ
    tirrenoには、IPがApple RelayやVPN/Tor由来であることが明らかな場合のための別ルールがあり、それらは別個のフラグになっている
    一部または全部の例はLLM生成だと思う。文脈が混ざっているし、カード決済でGPS位置情報を大規模に収集しているところは実際には存在しないからだ

    1. https://github.com/tirrenotechnologies/tirreno
  • これは「根拠データなしにSQLクエリへエンコードした ルールベースロジック 」に近い
    閾値は山ほどあるが、その閾値に意味があることを示すデータはない

  • 「取引データの詐欺検知はたいていSQLであり、機械学習でもグラフデータベースでもGartnerが今年持ち上げている何かでもない」というような断定は、プログラムインテグリティ 業務全体を扱う場合にのみ正当化できるだろう
    問題領域を解決するなら、もっと単純で粗い方法のほうがよいこともある
    フィンテックの顧客は通常、今まさに起きている取引が不正かどうかを知りたがり、高次元データに対して数ミリ秒以内の回答を求める。リレーショナルデータベースでは、この種のリアルタイム制約に対応するには規模的に難しい作業であり、その代わり履歴データの積み込みのような別用途で使われる
    だからこそインメモリデータベース、ストリーム処理エンジン、そして機械学習まで登場する
    それでも筆者のいくつかの指摘は妥当で、特にノイズの多いアラートを扱う問題は性能エンジニアリングを超えた一般的な課題なので、次の記事には期待している

    • 私の経験では、説明されているものはより正確には詐欺検知より 詐欺防止 と呼ぶべきだ。成熟した構成では両方が共存し、互いを補完する
      防止では常にレイテンシ要件、利用可能なデータ、不完全なユーザー行動像に制約される。機械学習とルールで高速な判断を下して大半のケースを処理するが、そうした制約のため、すべての不正を正確に防ぐことはできない
      検知はその後の結果を扱う。承認済み取引をアナリストチームが分析して不正の兆候を探すのが一般的だ。チャージバックや顧客苦情のような外部シグナルがないタイプの不正では、特に重要になる。プラットフォームインテグリティがその一例であり、フィンテックのマネーロンダリング対策システムも不正を見つけに行かなければならない
      両者が補完的なのは、検知された取引が次の防止モデルを学習・評価するための ラベル になるからだ
  • シカゴでカードがスワイプされ、7分後にロサンゼルスでまたスワイプされたら、どちらか一方は偽物だという話だったが、オンラインショッピング ではどう機能するのか気になる
    ソファに座ってAmazonで買い物したら、住所はどこに登録されるのだろう?
    それに、夫婦がオンラインアカウントを共有していて、一方が旅行中に保存済みカード情報で購入するような境界事例もありそうだ

    • カードをスワイプ、挿入、タップするのは カード対面取引 だ。オンラインショッピングのようにカード番号を入力するのはカード非対面取引だ
      小売業者と銀行はこの違いを区別できる
    • 取引メタデータで区別できる。クレジットカード会社で働いたことがある
    • システムが カード対面 とカード非対面を区別すると理解している
  • 「この方式は履歴が蓄積されるまで機能せず、新規アカウントにはベースラインがない」というのは、過小評価されている 顧客体験 の要素だ
    新しい顧客だったり、新しいパターンを示したりするときにカードが拒否されれば、ソフトウェアはうまくやっているように感じる
    しかし、自分が認証した過去履歴があるのに取引を拒否されると、単純で被害妄想的なアルゴリズムのせいで腹が立つ

    • 銀行のインセンティブは 不正を減らすこと にある
      不正取引は最終的に取消しや返金で銀行が損失を被る。拒否された取引は怒った顧客を1人作るだけで、顧客は文句を言ったあとすぐ忘れる。だから外部化されたコストの負担は顧客へ向かう
      したがって銀行には、より慎重な側に誤る、つまり誤検知があっても取引を拒否するインセンティブがある
  • 機械学習の本質は、こうしたルールをデータから学ぶことではないかと思う
    正しいアプローチは、機械学習モデルで不正に対応するパターンを見つけ、その中で意味のあるものがあるか評価することだと思う。そうすれば 新しい仮説 を発見できるかもしれない

    • 説明可能でなく、決定論的に反復改善できないものは、金融取引の拒否業務には危険すぎる
      人間のアナリストは、特定の取引がなぜ拒否されたのか、そして不利な決定を避けるには何を変えるべきだったのかを、コンプライアンスチームに 5分で読めるメール 1通で説明できなければならない
      機械学習で1つ問題を直すと、まだ顕在化していない新しい問題が2つ生まれることがよくある。時間とともに変化したときの回帰や予期しない副作用という点では、SQLのほうがたいてい驚きが少ない
 
aliveornot 29 일 전

「きりのいい金額」って何かと思ったら、roundedのことだったんですね。

 
xguru 29 일 전

なぜそのように翻訳したのでしょうか… 修正しておきました。