やりたいこと
有名人を検索すると「他の人はこちらも検索」という結果が表示されるのを見たことがあるかと思います。
例えば Yahoo でタモリさんを検索すると
以下のようなリストも表示されました。(結果は日々変わります)
なお Google で検索しても、同様のリストが表示されます。 (写真が載っていたので画像を加工しています。)
このリストから、タモリさんを検索している人は岡村隆史さんやビートたけしさんも検索する傾向があることが分かります。
これは検索機能の利用者が、タモリさんと岡村さん、あるいはたけしさんとの間に何かしらの関係性を感じているためです。 例えばそれは番組共演かもしれませんし、お笑いビッグスリーという関係性かもしれません。
これら有名人同士の関係性を可視化すれば、周囲が考える有名人同士の繋がりが見えてくるかもしれません。
ただし大事な点として、タモリさん本人が感じている繋がりではない点には注意が必要です。
とにかくはじめます🍛
収集する
今回は冒頭で述べたように Yahoo から「他の人はこちらも検索」のリストを取得します。
方法は単純で、とある有名人を検索してその人の「他の人はこちらも検索」を取得します。
そして今度はその「他の人はこちらも検索」で得られた有名人を検索して、同じくその人の「他の人はこちらも検索」を検索します。
これを繰り返すことで有名人ネットワークを構築していきます。
- 今回は約7万人の有名人を収集しました(実際にはまだまだ存在します)
- 際限が無いので外国人と思われる有名人はそこで探索終了
なお Yahoo からスクレイピングする際にはくれぐれも、過度な負荷をかけないようご注意下さい。 というより連続してアクセスすると、Yahooサイドからアクセス制限がかかる仕組みになっているようです。
[参考] Gooogle を利用しない理由
以下が Google のrobots.txt
です。1
https://www.google.com/robots.txt
これにより検索結果である/search
はDisallow
となっているため今回は利用を見送りました。
誰をスタートにするか
仕組みは関連する有名人をひたすら検索するだけですが、誰を一番最初のスタート地点にすれば良いのでしょうか?
あまりに無名だと続かない可能性があったので、日本の有名人知名度のTOP100をスタート地点としました。2
- タモリ
- 和田アキ子
- 安倍晋三首相
- ビートたけし
- 明石家さんま
- :
ネットワークを可視化する
収集したデータを可視化するために networkx と呼ばれるライブラリを使用しました。
まず収取された結果を以下のような辞書形式で表現します。
key
: 検索した有名人value
: keyで検索した際の「他の人はこちらも検索」の有名人
value
は最大7人ですが、それより少ない場合もあります。
results = {
'武田鉄矢': ['山田洋次', '高倉健', '西田敏行', '泉谷しげる', '浅野温子', '武田真治', '小山ゆう'],
'小池百合子': ['蓮舫', '舛添要一', '安倍晋三'],
'きゃりーぱみゅぱみゅ': ['最上もが', '北乃きい', '中田ヤスタカ', '益若つばさ', 'Fukase', '浜崎あゆみ', '橋本環奈'],
'阿部寛': ['妻夫木聡', '仲間由紀恵', '夏川結衣', '北村一輝', '木村拓哉', '西島秀俊', '是枝裕和'],
'渡辺謙': ['南果歩', '渡辺大', '杏', '真田広之', '小雪', '章子怡', 'キャスリン・ニュートン'],
'東出昌大': ['杏', '長澤まさみ', '小日向文世', '渡辺謙', '渡辺大', '唐田えりか', '宮沢氷魚'],
'小雪': ['松山ケンイチ', '多部未華子', '伊藤沙莉', '渡辺謙', 'デヴィ・スカルノ', '真田広之', '余貴美子'],
:
}
このkey
を頂点、key-value
間を辺とする有効グラフとして表現することで可視化を行います。
矢印の向きはkey
からvalue
方向に対応しています。
この図で言えば
- [東出昌大]さんを検索している人は[渡辺謙]さんを検索している
- [渡辺謙]さんを検索している人は[小雪]さんを検索している
- [小雪]さんを検索している人は[渡辺謙]さんを検索している
[参考] ソースコード
ちなみにグラフ構築部分のコードイメージは以下です。
edges = []
for celeb, members in results
for m in members:
edges.append([c, m])
celeb_names = set(np.ravel(edges))
i2n = {i:c for i, c in enumerate(celeb_names)}
n2i = {c:i for i, c in enumerate(celeb_names)}
G = nx.DiGraph()
for i, n in i2n.items():
G.add_node(i, name=n)
G.add_edges_from([(n2i[i], n2i[j]) for i, j in edges])
- 名前はインデックス番号に変換して管理
- 名前は頂点の属性として保持
全体像
最終的にノード数は全部で7万ほど収集しました。
そのためそのネットワーク図をそのまま描画したところで、数が多すぎてあまり意味が分かりません。
試しに全体の1/6程度のノードのみを描画してみますが、この通りです。 (矢印の向きなどほぼ見えないので無向グラフに変換して描画しています)
まとめ
検索結果の「他の人はこちらも検索」を利用して、有名人のつながりをnetworkxを用いて可視化してみました。
networkxにより比較的簡単にネットワーク図を描くことができました。
なお検索結果は日々変わっていくため、私と同じような結果が得られる保証はありません。
次回以降はもっと意味のある可視化を行っていきます。