narita-lab’s blog

成田ラボ 〜テクノロジーと雑学の観察日記〜

AIと共同で“詐欺メールを潰すプログラム”を作る Day5 手動学習機能編

前回のDay4では、本文解析機能を実装し、

  • 危険ワードの検出
  • スコア化
  • 危険度判定
  • GUIへの解析結果表示

まで進めることができた。

これでようやく、

「メールを読むツール」

から、

「怪しいメールを判定するツール」

らしくなってきた気がする。

ただ、実際に使ってみると、すぐに新しい問題が出てきた。

それが、

ルールの追加が面倒問題

である。

例えば、

「iCloud系のメールも危険判定にしたい」

と思ったら、プログラムを開いてキーワードを追加し、保存して、再起動する必要がある。

新しい迷惑メールが来るたびにこれを繰り返すのは、さすがに面倒だ。

迷惑メールの手口はどんどん変わる。

こちらも、その都度柔軟に対応できないと意味がない。

そこで今回は、

GUIから危険ワードを登録できるようにしてみた。

さらに、登録した内容を rules.json として保存し、次回起動時にも引き継げるようにしている。

つまり今回から、このツールは少しずつ、

「プログラムを書き換えて使うもの」

から、

「使いながら自分用に育てていくもの」

へ進化し始める。

正直、この辺りから急に“自分専用ツールを作っている感”が出てきて、開発がかなり楽しくなってきた。

 

固定ルール方式の限界

Day4の時点では、危険ワードやサービス名をプログラム内に直接書いていた。

例えば、

 
DANGER_KEYWORDS = [
"重要",
"お支払いを完了してください",
"支払い方法を更新",
"本人確認",
"利用制限",
]
 

というような形だ。

最初の実験としては、これで十分だった。

とりあえず動かす。
とりあえず検出する。
とりあえずスコアを出す。

その段階では、コードに直接書いてしまう方が早い。

ただ、使い始めるとすぐに分かった。

これは運用が面倒だ。

例えば、新しく、

 
iCloud
iCloud+
Apple ID
 

を強めに判定したいと思った時、毎回コードを書き換える必要がある。

さらに今後、

  • 新しい詐欺メールの文言
  • 新しい偽装サービス名
  • 差出人に含まれる怪しい単語
  • 件名に含まれる焦らせワード

を追加していくことを考えると、コード直書きはかなり不便だ。

このツールは、迷惑メールのパターンに合わせて少しずつ育てていく必要がある。

それなら、危険ワードはプログラム内に固定するのではなく、外部ファイルに保存した方がいい。

ということで今回は、手動登録したルールを rules.json に保存する方式へ進めることにした。

 

GUIから危険ワードを登録できるようにした

今回追加したのは、GUI上から危険ワードを登録する機能だ。

登録できる種類は、

  • 差出人
  • 件名
  • 本文

の3つに分けた。

例えば、

 
差出人:icloud
件名:【重要】
本文:お支払いを完了してください
 

というように、どこに含まれていたら怪しいと判断するかを分けて登録できる。

これは地味に大事だと思う。

同じ単語でも、差出人に含まれている場合と、本文に含まれている場合では怪しさが違う。

例えば icloud という単語が本文に少し出てくるだけならまだしも、差出人や件名に出てくるなら警戒度は高くていい。

なので今回は、

  • 差出人に一致したら高めに加点
  • 件名に一致したら中程度に加点
  • 本文に一致したら少し加点

という方向で考えている。

GUIには、登録種別を選ぶ欄とキーワード入力欄を用意した。

キーワードを入力して追加ボタンを押すだけで、ルールとして登録される。

これで、新しい迷惑メールを見つけた時に、

「この単語、次から拾いたいな」

と思ったら、その場で登録できるようになった。

コードを書き換えなくていい。

これだけでも、かなり運用しやすくなったと思う。

 

rules.jsonで登録内容を保存する

手動登録機能を入れるなら、登録した内容を次回起動時にも使えるようにする必要がある。

毎回アプリを起動するたびに、

 
【重要】
本人確認
iCloud
楽天カード
 

を登録し直すのはさすがに面倒だ。

そこで今回は、登録したルールを rules.json というファイルに保存するようにした。

仕組みとしてはシンプルで、

  • 起動時に rules.json を読み込む
  • ファイルがなければ初期設定で作成する
  • GUIからルールを追加したら保存する
  • ルールを削除した時も保存する

という流れだ。

JSON形式にしておけば、中身も確認しやすい。

例えば、

 
{
"sender_keywords": [
"icloud"
],
"subject_keywords": [
"重要",
"本人確認"
],
"body_keywords": [
"お支払いを完了してください"
]
}
 

こんな感じで保存される。

これなら、バックアップも簡単だし、別のPCへ移す時も rules.json をコピーすればいい。

少しずつ登録したルールが残っていくので、

“使うほど育つ迷惑メールフィルタ”

に近づいてきた感じがある。

 

初期ルールも最初から登録することにした

さらに今回、最初からある程度のルールを登録しておくことにした。

何も登録されていない状態から始めると、

  • Amazon
  • 楽天カード
  • Apple ID
  • iCloud
  • 【重要】
  • 本人確認

などを毎回手作業で登録する必要がある。

もちろん、一度だけの作業ではある。

ただ、初回起動直後に何も判定できないのは少し寂しい。

そこで今回は、rules.json が存在しない場合に限り、初期ルールを自動生成するようにした。

例えば、

 
【重要】
本人確認
利用制限
アカウント停止
異常ログイン
お支払いを完了してください
楽天カード
Amazon
Apple ID
iCloud
 

この辺りは最初から入れておく。

もちろん、これが正解という訳ではない。

人によって、

  • Amazonを使っている
  • 楽天カードを使っている
  • iCloudを使っている

など、環境は全く違う。

なので最終的には、自分の使い方に合わせて調整していく必要がある。

ただ、何もないところから始めるよりは、

「とりあえず動く」

状態からスタートできた方が、かなり取っ付きやすいと思う。

そして必要に応じて、

「このワードは不要だから削除しよう」

「このサービスは使っていないから強めに判定しよう」

と育てていけばいい。

この辺りから、プログラムというより、

自分専用の迷惑メールフィルタを育成している

感覚が強くなってきた。

 

実際に使ってみた感想

実際に動かしてみると、手動登録機能はかなり便利だった。

これまでは、

「このワードも拾いたいな」

と思ったら、プログラムを開いてリストに追加する必要があった。

しかし今回からは、GUI上でキーワードを入力して追加するだけでいい。

この差はかなり大きい。

例えば、iCloud系の迷惑メールが「注意」判定止まりだった場合でも、

 
差出人:icloud
件名:icloud
本文:icloud
 

のように登録すれば、次回からより強めに判定できる。

しかも登録内容は rules.json に保存されるので、アプリを閉じても消えない。

一度登録すれば、次回以降もそのルールが反映される。

迷惑メールは、同じような文言や同じような偽装サービス名で何度も届くことが多い。

つまり、一度登録したルールは後から効いてくる。

この辺りが、手動登録式の強みだと思う。

最初の登録作業は少し面倒かもしれない。

ただ、一度育て始めると、

「またこのパターンか」

というメールを拾いやすくなる。

自分用ツールとしては、かなり実用的な方向に進んできた気がする。

 

今後の課題と次回やりたいこと

Day5では、GUIから危険ワードを登録できるようになり、登録内容を rules.json に保存するところまで実装できた。

ここまで来ると、かなり「使えるツール」らしくなってきたと思う。

ただ、まだ改善したい部分もある。

例えば、今は危険ワードを手動で追加しているが、

「このメールを迷惑メールとして登録」

みたいなボタンがあっても面白そうだ。

ボタンを押したら、

  • 差出人
  • 件名
  • 本文

から特徴的な単語を抽出し、登録候補として表示する。

そこから必要なものだけ選んで追加する。

そんな機能があれば、さらに楽になりそうだ。

また、現在のルールは「危険ワードを追加する」方向だけだ。

逆に、

 
Amazonは使っている
PayPayは使っている
この差出人は安全
 

のようなホワイトリスト機能も、そのうち必要になるかもしれない。

そして最終的には、

  • 自動で迷惑メールフォルダへ移動する
  • 一定スコア以上は削除候補にする

なんて機能も考えられる。

……とはいえ、そこはまだ先の話。

いきなり自動削除を入れると、誤判定した時が怖い。

まずは、

「しっかり判定できること」

を目標に、少しずつ精度を上げていきたい。

次回は、この手動登録機能をさらに使いやすくするか、それともホワイトリスト機能へ進むか。

少し考えながら、またのんびり育てていこうと思う。

 

Day5時点のまとめ

Day5では、

  • GUIから危険ワードを登録
  • rules.json に保存
  • 次回起動時に自動読み込み
  • 自分専用のルールを少しずつ育てる

ところまで実装できた。

最初は、

「Yahooメールへ接続できるかな?」

くらいの軽い気持ちで始めたこのツールだが、気付けばそれなりに“迷惑メール解析ツール”っぽくなってきた。

特に今回実装した手動登録機能は、自分でもかなり気に入っている。

最初の登録作業は少し面倒だ。

ただ、一度ルールを作ってしまえば、その後の運用はかなり楽になる。

新しい迷惑メールが来ても、

「あ、この単語を追加しておこう」

くらいの感覚で育てていける。

何より、

自分の環境に合わせて最適化できる

というのが面白い。

Gmailのような巨大な迷惑メールフィルタではなく、

「自分だけのルールで動くフィルタ」

を作っている感覚があって、なかなか楽しい。

まだまだ完成には遠い。

でも、

  • メール受信
  • GUI化
  • 本文取得
  • 本文解析
  • 危険度判定
  • 手動学習

と、一歩ずつ積み上げてきた。

次回は、ホワイトリスト機能を追加するか、手動学習をさらに便利にするか。

少し考えながら、またのんびり育てていこうと思う。


そして何より、このシリーズ。

最初は「Yahooメールの迷惑メールが多すぎるから何とかしたい」という、ほぼ八つ当たりみたいな理由で始まったのだが、意外と面白い開発記録になってきた。

詐欺メールとの戦いは、まだ続く。