meowの覚え書き

write to think, create to understand

地理的位置に基づく店舗名の(エセ)AND検索

画像引用元: https://tabelog.com/hiroshima/A3401/A340121/34000922/dtlphotolst/3/smp2/

この記事では、↑の写真の撮影場所の特定に挑戦した際に考案した手法について記す。具体的には、店舗名2つを指定すると距離の近い店舗ペアを列挙する手法を実装し、スターバックスコーヒーとFrancFrancが隣接する建物の特定を試みた。

先に述べておくと紹介する手法では場所の特定はできなかった。しかし、今後撮影場所の特定を行う際に流用できる可能性がある。


スポンサードリンク

目次

背景

写真の撮影場所の特定をする際の定石は、大手の検索エンジンが提供する「画像で検索」サービスを使用して類似の写真を探すことである。しかし、その方法は定番すぎてマンネリ感があったため、たまには別の方法で特定に挑戦してみようと考えた。

そこで今回は、たまたまダウンロードフォルダの整理中に見つけた↑の写真を「画像で検索」を使わないで撮影場所の特定を試みた。

アプローチと予備調査

調査の指針としては、 スターバックスコーヒーとFrancFranc の距離が近いことを利用するのが合理的な発想である。そこで、この指針に基づいて予備調査を2つ行った。

1つ目は普通のキーワード検索である。“スターバックスコーヒー FrancFranc 近い“のような自然文でGoogleTwitterで検索した。その結果、候補となるショッピングモールは一部見つかったが、確認した結果そこではなかった。

2つ目はGoogleマップで「スターバックスコーヒー FrancFranc」とAND検索するとどうなるか試した。その結果、自分が現在表示している位置に近い場所しか候補は表示されず、2つの店舗が同時に表示されはするものの数キロ離れた場所がヒットするため(OR検索的な結果のため)使えないことがわかった。

「地理的位置に基づく店舗名の(エセ)AND検索」の手法説明

予備調査2つには網羅性に欠けることと地理的な距離で絞れないという課題があった。そこで、スターバックスコーヒー全店舗とFrancFranc全店舗の地理的位置(座標)をリスト化し、各位置ごとの距離を求め、差が小さいものを列挙する方法を取ることにした。

手順は3ステップである:

  1. マップAPIで店舗名のワード検索を行い。店舗の地理的位置リストを作成する
  2. 2店舗間の地理的距離を求め、しきい値が低い店舗ペアのリストを作成する
  3. 距離の近い店舗の内装を目視で確認し、目当ての店舗かどうかを判定する

1. 店舗の地理的位置リストを作成

店舗名をキーワードとして与えると店舗の一覧を返してくれるAPIを使用する。APIの選定であるが、手っ取り早く使いたかったので今回はYahoo Japan社が提供しているYOLPYahoo!ローカルサーチAPIを利用した。

検索ワードによってヒットする店舗の量が変わるため、一番店舗量が多くヒットする検索ワードを採用する。スターバックスコーヒーは「スタバ」の1,188件、FrancFrancは「フランフラン」の75件あった。なお、ヒットした全店舗数は各企業の公表値よりも少ないため全店舗が登録されているわけではないようである。

APIの結果を整形し、ID、拠点名、位置座標1をtsv形式でリスト化した。FrancFrancの例を下記に示す。

Id   Name    Coordinates
20930169409 フランフランバザー佐野プレミアムアウトレット店   139.604716388889,36.286394444444
22230598835 フランフラン 新静岡セノバ店  138.387307777778,34.975558611111
22830870117 Francfranc 三宮店  135.194144444444,34.692273888889
...

2. 店舗間の距離の算出および近い店舗ペアの抽出

手順1で取得したスターバックスコーヒー、FrancFrancそれぞれの各店舗の位置情報リストを元に、各店舗の距離を計算し、しきい値以内の距離となる2店舗のペアを表示する。

2点の距離計算にはPythonパッケージ『geopy』を利用した2

距離のしきい値として0.2km以内として、近接する店舗ペアを抽出した。例を以下に示す。レコードはスタバの拠点名、FrancFrancの拠点名、距離(km)で構成される。

['スターバックスコーヒー くずはモール店', 'Francfrancくずはモール店', 0.09441566021250594]
['スターバックスコーヒー\u3000アミュプラザ鹿児島店', 'フランフランアミュプラザ鹿児島店', 0.11536821590071877]
['スターバックス コーヒー 札幌ステラプレイス センター1階店', 'パセオ\u3000センターB1Fフランフラン', 0.11784401167930757]
...

1,188*75件の総当りを行うので処理時間を心配していたが、10秒程度であった。今回はFrancFrancの店舗量が少ないので現実的な時間に収まったが、本来ならば高速化のために店舗を都道府県ごとに分けるなどの工夫が必要である。

3. 目視での確認結果

誠に驚いたが、2店舗が0.2km以内に隣接するペアが 64件あった。FrancFrancの3つに2つが店舗の近くにスタバがあるということになる。この知見は興味深いが、今回やりたかったことの観点でいえばFrancFranc全件を確認するのとほとんど変わらない手間であり、狙いが外れたといってよい。

さらに悲しいことに、ペアを1件1件場所をwebで内装写真を見て確認したが、該当のショッピングモールは見つからなかった。隣接しているように見えて階が違うというパターンが多かった。

ここでもとの正解を確認したところ、「広島駅アッセ」というショッピングモールらしい。そして、この建物は2020年3月に閉店していた。当たり前だが閉店した拠点はYOLPでヒットしないようだ。

まとめ

2つの店舗が近接する候補を列挙することで、写真の撮影場所の特定を試みた。結果としては、試みは失敗に終わったが、今後のCTFのOSINT問の解法で使えるかもしれないのでストックしておこうと思う。

この手法の応用例としては、外食の写真をアップロードしているSNSアカウントがあった時に、生活圏を推定する用途に使えるかもしれない。

今回実装したスクリプトPythonで実装しており、githubで公開している。ご興味があればご覧いただければと思う。

github.com


スポンサードリンク


  1. YOLPの仕様上、経度の方が緯度よりも先のフォーマットである。

  2. YOLPにも距離計算用のAPIがあるが、1日あたりの利用制限や通信に伴うオーバヘッドを考慮すると、geopyで十分であると判断した。