🔙 Back to Top

Sat Mar 19 15:50:35 JST 2016

都営・メトロ分類器

あらまし

東京に住み着いてもうすぐちょうど6年になるが、今だに地下鉄に乗ってて 「あれ? 私が今乗ってるのって、都営だっけ?メトロだっけ?」ってなる

一応言っておくと、東京に走ってるのはJRかさもなくば地下鉄で、地下鉄は都営地下鉄と東京メトロの二社があり. 都営とメトロとの間の乗り換えは、社を跨ぐので、ほんの少し、乗車賃が上乗せされる.

簡単に、今乗っている「〇〇線」が都営であるかメトロであるかを分類するモデルを書きましょう

あらましその2

2つの語の類似度を測る、なかなか直観的な方法として、 語を並べて某大手検索エンジンに投げたときのヒット数を見るというのがある. 例えば、3つの語 A B C があったときに、「A B」と「A C」でそれぞれ検索してヒット数を比較することで、 B と C、どちらがより A に近いかを見ることが出来る.

この手段は自然言語処理界隈でしばしば見られる. 手頃な論文無いかなあと探そうとした矢先に こんな (Googleなどでのヒット数は言語研究の証拠となるか?|Colorless Green Ideas) 記事を見つけた. 要するに、ヒット数なんてかなり信用できないぞ、ということ.

(一時的に極端にヒット数が変動するなんて初めて知った)

ちなみに言うと、自然言語処理界隈で使われるのはコレ (Normalized Google distance - Wikipedia, the free encyclopedia) みたいなやつです.

でまあ問題点は在るんだけど、 「都営 〇〇線」 「メトロ 〇〇線」 でそれぞれ検索してヒット数の大小を見てみようという発想.

ソースコード

検索エンジンとして

  1. Google
  2. Bing
  3. ニコニコ動画

日本の鉄道だし、ニコニコで調べてもね、きっと上手くいくかもしれないよね? 本当は単にさっき偶然、ニコニコにもAPIが公開されているという事実を知ったから使ってみただけ.

Google

Google と Bing に関しては、礼儀がなっていないが真面目にAPI叩かない. つまり実際にブラウザで検索することを自動化するだけに留める. Ruby で言うところの mechanize. CUI で言うところの w3m -dump (?).

ちなみにこれをやりまくると、GoogleはすぐにBANするので註意 (are you machine? みたいな表示と共にCAPTCHAが表示される).

#!/bin/bash

L=$1
for C in 都営 メトロ; do
  N=$( w3m -dump "http://google.co.jp/search?q=$C $L" | grep '約.*[0-9].*件' | head -1 | tr -cd '[:digit:]' )
  echo $N $C
done

grep ... | head -1 のところはすごく、その人の環境に依存するところ.

三田線について調べてみる:

   ./google.sh 三田線
11500000 都営
7920000 メトロ

三田線は都営である.

Bing

#!/bin/bash

L=$1
for C in 都営 メトロ; do
  N=$( w3m -dump "http://www.bing.com/search?q=$C $L" | grep '[0-9].*results' | head -1 | tr -cd '[:digit:]' )
  echo $N $C
done

Bing に関してはこんなことしても全然BANされない (経験上).

   ./bing.sh 三田線
2020000 都営
2300000 メトロ

三田線はメトロです.

ニコニコ動画

これは API があるので丁寧に叩く. 返ってくるのが json なので jq でヒット数だけ抜き出す.

#!/bin/bash

L=$1
for C in 都営 メトロ; do
  URL=http://api.search.nicovideo.jp/api/snapshot/
  DATA=$( echo '{"query":"' $C ' ' $L '","service":["video"],"search":["title","description","tags"],"join":["cmsid"],"sort_by":"view_counter","issuer":"/c/"}')
  N=$( curl -s -X POST -d "$DATA" $URL | jq '.values[]?.total' | grep -o '[0-9]*' | head -1 )
  echo $N $C
done
   ./nico.sh 三田線
187 都営
32 メトロ

三田線は都営.

三田線は都営であるのが正しい

実験

てゆうか、東京の地下鉄の線なんて有限本しかないので全部試せば良い.

   cat toe-list
三田線
大江戸線
浅草線
新宿線

  cat metro-list
南北線
東西線
銀座線
副都心線
丸の内線
日比谷線
千代田線
有楽町線

Google

   for L in `cat toe-list`;do echo $L; ./google.sh $L; done
三田線
11500000 都営
7920000 メトロ
大江戸線
15800000 都営
11900000 メトロ
浅草線
11400000 都営
8200000 メトロ
新宿線
15500000 都営
13100000 メトロ

都営のほうが数字が大きいのが正しい. というわけで都営は全部OK.

   for L in `cat metro-list`;do echo $L; ./google.sh $L; done
南北線
7770000 都営
9140000 メトロ
東西線
10400000 都営
13800000 メトロ
銀座線
8410000 都営
12300000 メトロ
副都心線
348000 都営
8320000 メトロ
丸の内線
552000 都営
489000 メトロ
日比谷線
4300000 都営
13100000 メトロ
千代田線
7930000 都営
10400000 メトロ
有楽町線
1680000 都営
13300000 メトロ

今度はメトロだけ大きいのが正しい. よく見ると丸ノ内線だけ誤っている.

(実験が終わるまでにBANされなくてよかった)

Bing

   for L in `cat toe-list`;do echo $L; ./bing.sh $L; done
三田線
2020000 都営
2300000 メトロ
大江戸線
2380000 都営
2400000 メトロ
浅草線
2430000 都営
2810000 メトロ
新宿線
3170000 都営
5750000 メトロ

   for L in `cat metro-list`;do echo $L; ./bing.sh $L; done
南北線
1520000 都営
2300000 メトロ
東西線
1660000 都営
2790000 メトロ
銀座線
2500000 都営
4160000 メトロ
副都心線
985000 都営
1710000 メトロ
丸の内線
2140000 都営
2990000 メトロ
日比谷線
2030000 都営
2570000 メトロ
千代田線
2300000 都営
3000000 メトロ
有楽町線
2060000 都営
2780000 メトロ

ぜーんぶメトロ!

ニコニコ動画

   for L in `cat toe-list`;do echo $L; ./nico.sh $L; done
三田線
187 都営
32 メトロ
大江戸線
179 都営
43 メトロ
浅草線
341 都営
25 メトロ
新宿線
235 都営
43 メトロ

   for L in `cat metro-list`;do echo $L; ./nico.sh $L; done
南北線
32 都営
110 メトロ
東西線
36 都営
480 メトロ
銀座線
26 都営
232 メトロ
副都心線
18 都営
445 メトロ
丸の内線
20 都営
169 メトロ
日比谷線
28 都営
139 メトロ
千代田線
21 都営
327 メトロ
有楽町線
13 都営
205 メトロ

まとめ

Google はさすが (1件だけ誤り).

Bing は全然ダメ. そもそも性質が違うのかなって感じ. 「都営」、「メトロ」単体で検索したときのヒット数で正規化するとかしたら良い. 一応、都営の数字をほんのちょっと増やす (1.1倍にするとか) と多少、正解率が上がるが、それでも所詮って感じ.

ニコニコは全部正解した. 検索対象の性質としてノイズと成るものが少ないんだろう. 他が一つのwebページなのに対して、謂わばそれの要約になっている (タイトル+説明文+タグ) からだ、とか主張できそう.

マヂレスすると都営の路線は4本しかないんだから覚えろって話

その他

二値分類なので、都営でもメトロでもない線について調べてもしょうがない. ところで、でも、違う呼び名というものがある. 例えば「東京メトロ副都心線」は「地下鉄13号線」である. 「都営浅草線」は「地下鉄1号線」である. 都営かメトロに関係なく勝手にナンバリングされてる. 「都営地下鉄大江戸線」という路線名が決まるまでに「東京環状線」という名称が候補にあった.

   cat phantom-list
地下鉄1号線
地下鉄13号線
東京環状線

順に、都営、メトロ、都営 が正しい.

   for L in `cat phantom-list`;do echo $L; ./google.sh $L; done
地下鉄1号線
131000 都営
372000 メトロ
地下鉄13号線
273000 都営
409000 メトロ
東京環状線
469000 都営
508000 メトロ

   for L in `cat phantom-list`;do echo $L; ./bing.sh $L; done
地下鉄1号線
2450000 都営
5990000 メトロ
地下鉄13号線
2790000 都営
16700000 メトロ
東京環状線
265000 都営
1080000 メトロ

   for L in `cat phantom-list`;do echo $L; ./nico.sh $L; done
地下鉄1号線
0 都営
1 メトロ
地下鉄13号線
0 都営
0 メトロ
東京環状線
1 都営
0 メトロ

全滅.