AAA~ZZZの間で「名称・略称として使われていない組み合わせ」をスクレイピングで調べる
概要
Wikipediaに対してスクレイピングを行い、「AAA」~「ZZZ」までの17,576通りの文字列に対し個別の項目が存在するかどうかを調べたところ、約4割にあたる7,746通りについて個別の項目があることがわかった。
緒言及び方法
世の中にはアルファベットからなるたくさんの名称・略称が溢れている。AAA*1もあるしZZZ*2もある。しかしアルファベット3文字からなるイニシャルの中で「存在しないイニシャル」というのはあり得るのだろうか? ありえなさそうな組み合わせ、例えばQZXなんてどうだろう。しかしこれも、今調べたら山登りのアプリが出てきた。
これを真面目に考えると「名称が存在しているのとはどういうことか?」となり難しい問題となる。今私が考えたばかりの架空の団体は存在しているのか? 同好会の名前だったら? どこかで線引きをする必要がある。ここは少しハードルが高いが「(日本の)Wikipediaに項目があるか」ということを基準にしたい。アルファベットは26種類あるので、2文字だったら通り、3文字だったら通りの組み合わせに対して個別のURLにアクセスすれば調査できるが、人間がやるには無理のある量である。プログラムにやってもらうとしよう。
以下のようなプログラムをpythonで組んだ。とりあえず2文字バージョンで。
import re import requests #アルファベットのリストを作成 alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #文章を作成してからそれをリスト化 chars = list(alphabets) #ちゃんと26文字あるか確認 print (chars) print (len(chars)) #HITとMISSのカウント初期値 hit = 0 miss = 0 #2文字のイテレーション for s in chars: for t in chars: #ソースを取得 url = "https://ja.wikipedia.org/wiki/" + s + t content = requests.get(url).text #項目があるかをソース中の文章で判断 if content.find("この名前の項目はありません") == -1: hit += 1 pattern = re.compile(r'<title>(.*?) - Wiki') #タイトルを正規表現で抽出 match = re.search(pattern,content) print(match.group(1) + "という項目があります ",end="") else: miss += 1 print(s + t + 'という概念はja/wikipedia上に存在しないようです ',end="") print(str(hit) + " " + str(miss))
これを実行すると以下のような結果が得られる。回線速度にもよるが、実際に実行すると5分ぐらいかかるので注意。
右にある数字の内、前者は(日本の)Wikipediaに項目があるもの、後者はないものを指す。さすがに2文字だったらAAからZZまで使われていない組み合わせはなかった。
複数の候補がある項目(おそらく大半がそうだろう)は単なる一覧ページになるのでタイトルはアルファベットそのものだが、1個しかヒットしないページは専用の項目が出てくる。上の画像で言うとZL,ZM,ZNがそうで、それぞれズウォティ*3、ザンビア*4、亜鉛*5となっている。こういう「ユニーク名称」をいちいち調べていたら雑学博士になれそうだが、まあ時間がないので割愛する。
では本番で3文字。17,576行も出力されるので結果をもう少し細かく分けたい。全体のヒット数とは別に、一番最初のアルファベットによる個別のヒット数もつけることにした。多分Aだと多くヒットしてQだとヒットが少ないだろうみたいな予測のもと。
ソースコードは以下の通り。上のコードにあったコメントやテスト用の命令は一部省いている。
import re import requests alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" chars = list(alphabets) hit = 0 miss = 0 #1文字目は個別に集計を取る parthit = 0 partmiss = 0 #後で集計する用の配列 parthits = [] partmisses = [] #3文字のイテレーション for s in chars: for t in chars: for u in chars: url = "https://ja.wikipedia.org/wiki/" + s + t + u content = requests.get(url).text if content.find("この名前の項目はありません") == -1: hit += 1 parthit += 1 pattern = re.compile(r'<title>(.*?) - Wiki') match = re.search(pattern,content) print(match.group(1) + "という項目があります ",end="") else: miss += 1 partmiss += 1 print(s + t + u + 'という概念はja/wikipedia上に存在しないようです ',end="") print(str(hit) + " " + str(miss)) print(s + 'から始まるイニシャルを検索し終わりました。(' + str(parthit) + " " + str(partmiss) + ')') parthits.append(parthit) partmisses.append(partmiss) parthit = 0 partmiss = 0 print('合計' + str(hit) + " " + str(miss)) #1文字目ごとの個別累計を返す for i in range(0,len(chars)): print('1文字目が' + str(chars[i]) + " " + str(parthits[i]) + " " + str(partmisses[i]))
これを実行すると結果のようになる。回線速度にもよるが、実際に実行すると数時間かかるので注意。
結果及び考察
まず全体の結果として、全組み合わせ17,576通りの内、ヒットした(Wikipediaに項目があった)アルファベットの組み合わせは7,746通り、そうでないものは9,830通り存在した。ヒットしないものの方が多い! ただ、これは「Wikipediaに項目がある」という高いハードルを越えたものが半分近くあるということで、当然項目がなくても存在・認知されている名称・略称は無数に存在する。この9,830通りはただの「使われていない可能性があるもの」であり、中小企業名(明らかな使用例と考えて良いであろう)等もここには入って来ないことから考えると、実際はそのほとんどに明らかな使用例が存在すると考えるのが自然だろう。
次に開始文字の結果。ベスト3とワースト3を並べると以下のようになる。
順位 | 文字 | ヒット数 |
---|---|---|
1位 | A | 554 |
2位 | C | 503 |
3位 | S | 455 |
~ | ||
24位 | X | 91 |
25位 | Z | 78 |
26位 | Q | 67 |
予想通りAのヒット数が多く最大の554、また最小も予想通りでQの67。念のため言っておくと答えを先に見ていた訳ではない。人気組はAのほかにCとS、不人気組はQのほかにZとX、まあそうだよね……という感じである。
ここらの発展として「本当にその組み合わせの使用例が存在しないか」を検証しようとすると難しい。例えば、より正確らしい手段として「Googleの検索クエリに投げてみて、『もしかして』を提案されなければ存在」という実装が考えられるが、世の中は検索結果が全てではないし、アマチュア小説の固有名詞みたいなものをどうカウントしていいかは判断が分かれるだろう。今後の研究の発展に期待したい(発展するのか?)。
おまけ
解析の様子を抜粋したやつ