【AtCoderを分析】Webデータを分析して公開するための基本を網羅してみた

AtCoderのWebデータの分析〜公開を、短期間に3種類ほど行いましたので、関連のノウハウをまとめてみました。3種のアウトプットでそれぞれ異なる技術要素を使っていますので、網羅性の高い記事になっているのではと思われます。

> 本記事にしたがって実際に試してみた結果、発生した不具合や、AtCoder社他の利用規約その他法令に違反する行為があった際など、あらゆる場合に対して、筆者は何も保証しません。

以下が、実際に分析した結果です。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/AHC016?src=hash&amp;ref_src=twsrc%5Etfw">#AHC016</a> <a href="https://twitter.com/hashtag/HTTF?src=hash&amp;ref_src=twsrc%5Etfw">#HTTF</a> <br>全人類が待望した相対スコア計算&amp;最終順位算出を、独自にやってみました<br><br>画面だと45位までなので、rawクリックしてください<br><br>なお200位までのデータを使っているので、200位近辺の人は、200位超の人に抜かれた場合、少し悪化する可能性があります<a href="https://t.co/nOrKIO6JeU">https://t.co/nOrKIO6JeU</a></p>&mdash; toast-uz (@ToastUz) <a href="https://twitter.com/ToastUz/status/1594723295211184128?ref_src=twsrc%5Etfw">November 21, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/AtCoder?src=hash&amp;ref_src=twsrc%5Etfw">#AtCoder</a> AHCのメタな統計情報Webサービスを作ってみました<a href="https://t.co/8bpHQVYT6E">https://t.co/8bpHQVYT6E</a> <a href="https://t.co/mjJwqgqMZq">pic.twitter.com/mjJwqgqMZq</a></p>&mdash; toast-uz (@ToastUz) <a href="https://twitter.com/ToastUz/status/1598957938491953152?ref_src=twsrc%5Etfw">December 3, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/AtCoder?src=hash&amp;ref_src=twsrc%5Etfw">#AtCoder</a> よく見るアレの2022年末版を作ってみました。おそらく初のヒューリスティック版付き<br>（ヒューリスティックの色修正しました😅） <a href="https://t.co/L7b8k1RHhy">pic.twitter.com/L7b8k1RHhy</a></p>&mdash; toast-uz (@ToastUz) <a href="https://twitter.com/ToastUz/status/1607382171123343360?ref_src=twsrc%5Etfw">December 26, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 0. はじめに

## 0.1. Webデータ分析〜公開のすゝめ

こういったWebデータ分析〜公開をすることで、以下のメリットが得られます。

+ 自分の関心があるテーマについて、定量的に新たな発見を得られる。
+ 新たな発見を一般に共有することで、さまざまな反応を得られる。
+ 大量のWebデータを使った半自動的なデータ分析について、技術を習得できる。
+ 自分の公開手段によっては、Webフロントエンドの最新技術を習得できる。

## 0.2. 本記事の全体の流れ

本記事の全体の流れを、以下に示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156600/447621cd-954d-26d8-04de-8b89c9d5f55a.png)


## 0.3. 筆者の公開実績ごとの採用技術

筆者の公開実績ごとの採用技術を、この後の各章のテーマに沿って、以下に示します。

|公開実績|章テーマ|採用技術|
|--|--|--|
|AHC016相対スコア|収集|Selenium|
||分析|Python|
||表示|（グラフ描画なし）|
||公開|GitHubGist|
||宣伝|Twitter|
|AHC統計情報Web|収集|WebAPI、手作業|
||分析|Python|
||表示|Webサービスコンポーネント(Recharts)|
||公開|Vercel(Next.js/React.js)|
||宣伝|Twitter、AtCoder Clans|
|よく見るアレ|収集|WebAPI、手作業|
||分析|Python|
||表示|LibreOffice|
||公開|GitHubGist|
||宣伝|Twitter、AtCoder Clans|

# 1. 収集

AtCoderのサイトをはじめとして、様々なWebからデータを収集します。

## 1.1. WebAPI

最も効率的なデータ収集手段として、WebAPIがあります。
AtCoderでは、公式仕様ではないものの、いくつかのページURLに`/json`を加えることで、該当ページのデータをjson形式のファイルで取得することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156600/99c867de-5d56-c26f-d515-d69fe4d25f25.png)

また、AtCoderのWeb公開データ分析をもとにしたWebサービスとして著名な[AtCoder Problems](https://kenkoooo.com/atcoder/)においても、いくつかAPIを公開しています。AtCoderではAPI提供していない情報も取得可能です。

APIで公開されているデータは、以下のような手段で収集できます。

+ Webブラウザ（そのまま表示、結果をダウンロード）
+ curlなどのコマンドラインコンソールアプリ
+ Python requestsなどの言語ライブラリ

AtCoderで得られたjsonデータについては、Web画面には非表示だったりWeb画面の値と異なっていたりして、解釈方法が公開されていないものもあるため、適宜解釈を推定することが必要です。以下は順位表データ（`https://atcoder.jp/contests/{コンテスト名}/results/json`）の例です。

+ "Rating"は、アルゴのレートであるが、コンテスト時点ではなく、データ取得時点のものである。
+ "Performance"は、該当コンテストのパフォーマンスであるが、内部パフォーマンスであり、Web表示されるパフォーマンスとは異なる場合がある。

参考: [AtCoderのレート計算式](https://www.dropbox.com/sh/zpgcogxmmu84rr8/AADcw6o7M9tJFDgtpqEQQ46Ua?dl=0)

なお、AtCoderのAPIには認証がかかっていないため、取得の難易度は低いです。

## 1.2. スクレイピング

残念ながら、欲しいデータが必ずしもAPIで提供されるわけではありません。その場合、Web画面からデータを収集する必要があります。これを、Webスクレイピング、と呼びます。

Webスクレイピングは、おおまかに2種類の流儀があります。

+ 前項の手段でWeb画面データをダウンロードし、BeautifulSoupなどのスクレイピング専用ライブラリを利用する。
+ Seleniumなどの、ブラウザを外部からスクリプト動作させるツールを利用する。

前者の方法が簡便ですが、以下のような「ブラウザの高度な機能が必要である」場合には後者の方法が必須になってきます。

+ 入手したいWeb画面データが、スクリプトとWebAPIのフェッチによって、ブラウザ側で動的にレンダリングされている。そのため、得たい情報を表示させるためには、実際のブラウザが必要になる。
+ 該当のWeb画面に遷移する条件として、実際のブラウザの挙動が必要になってくる。

AtCoderの場合は、フォーム認証を通過する必要があるものの、各ページは直接にURL指定で表示でき、かつ表データはWeb画面データに含まれており、前者の方法で大丈夫です。

なお、スクレイピングは、その特性から、ターゲットとなるWebページの画面デザイン変更に弱く、プログラムのメンテナンスが大変です。

## 1.3. 手作業

スクレイピングの手間を考えると、特にアドホック性の高い収集においては、手作業でWeb情報をコピーするのも、有効かつ実践的な手段です。

Web画面の表を、スプレッドシートに表のままコピー&ペーストすることが可能です。それをcsvファイル等に保存します。

筆者のアウトプットの例では、大学名を名寄せするにあたって、大学の和名・英名の一覧表をWebで検索し、画面の表をコピーしてcsvに保存しました。

# 2. 分析

得られたデータを分析して、あらたな発見を得ます。

## 2.1. スプレッドシート

ほとんどのデータは表形式で表現されますので、Excel、Libre Office、Google Sheetsなどのスプレッドシートを使うことで、集計や比較といった分析が可能です。

その際、IF文（SUMIF、COUNTIFを含む）の扱いに慣れておくとよいでしょう。

## 2.2. Python

少し複雑な分析は、プログラミング言語で行います。この用途には、Pythonが最も適している言語の1つです。以下のような操作が可能です。

+ csv、json、スプレッドシートなどのデータの読み出し（書き込み）
+ 正規表現や辞書によるマッチング、変換を含む、さまざまな文字列操作
+ 標準機能や、Pandasライブラリを使った複雑な集計分析、複数の表の横断分析
+ 統計ライブラリや機械学習ライブラリの活用

Pythonでの分析は、スプレッドシートの簡便な分析と一長一短がありますので、使い分け組み合わせをすると良いです。大規模・複雑・固定的な分析をPythonで、小規模・簡単・アドホックな分析をスプレッドシートで、という役割分担です。

なお、後述するように「公開」する技術としてPythonは利用しにくいです。そのため、分析までをPythonで行い、一旦ローカルファイルとして分析結果を保存してから、そのファイル含めて公開は別技術で行う、というパターンにすることがあります。

# 3. 表示

得られた結果をグラフ表示します。

## 3.1. グラフの種類

グラフはさまざまなものがありますが、大きく2種類を使えれば十分です。

## 3.1.1. 棒・折れ線グラフ

最も基本的なグラフであり、値の比較や構成内容の説明が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156600/861a15a9-ef82-029d-418d-8c2166e7a0c7.png)


## 3.1.2. 散布図

値が2軸（円の大きさを入れると3軸）にどのように分布しているのか、一目で理解できます。2軸の相関がわかるとともに、密な部分と疎な部分を把握するヒートマップとして利用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156600/65ca79da-198d-87a3-5c54-0e6f96514fa5.png)


## 3.2. グラフ表示ツール

グラフ表示ツールもいくつかの選択肢があり、目的にあって使いやすいものを選択します。

+ スプレッドシート: アドホックに作りやすい。表現力が高い。
+ 言語ライブラリ: Python matplotlib、統計分析専門言語であるRで著名なggplot2（Pythonからも利用可能）など。利用に習熟が必要。簡易なものから高度なものまで様々。
+ Webサービスコンポーネント: アニメーション表示や、マウスカーソルをプロット領域に置いた時のヒント表示（下図例）など、インタラクティブ性が高い。
+ BIツール: さまざまな分析の切り口の変更や、注目するデータ範囲の絞り込みなどが自由にでき、分析〜表示をセットで試行錯誤的に進め、意味ある分析結果を探索したい場合に有用である。一般的には有償で、かつ個人向けではない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156600/c3b1c200-fd5e-b2dc-735f-9fa2a2f673fe.png)


# 4. 公開

グラフなどをインターネットに公開するにあたって、最適な手段を選択・組み合わせします。

## 4.1. ファイル共有

分析後のcsvやjsonファイルを、そのまま共有公開します。さまざまなファイル共有サービスがありますが、筆者は[GitHubGist](https://gist.github.com/)を愛用しています。

## 4.2. Google Sheets

[Google Sheets](https://www.google.com/intl/ja_jp/sheets/about/)を使うと、分析後のデータをスプレッドシートファイルとして公開したり、スプレッドシートのグラフを公開したりすることができます。

## 4.3. Webサービス

ユーザ名によって表示する内容を変えたりする、インタラクティブ性を求めるのであれば、Webサービスとして公開することが必要です。準備の手間と難易度は高まりますが、その分、技術習得が可能です。

残念ながら、PythonのWebフレームワークであるFlaskやDjangoをサービス提供している無料サイトは無く、公開するための技術は、VueやReact.js/Next.jsなどのJavaScript/TypeScript系が主流となります。

### 4.3.1. フロントエンド単独

HTML/CSS/JavaScriptを自力で作るほか、React.js、Vue.jsなどのSPAフレームワークを使うことで、ブラウザ側で動的にページ構成することが可能です。この場合、サーバー側はhttpsを単純配信できれば十分なので、様々な無料ホスティングを利用して、Webサービスを提供することが可能です。

代表的なホスティングサイトとして、[GitHub Pages](https://pages.github.com/)があります。

利用例として、wleiteさんのAHC各コンテストの詳細統計情報が有名です。
[AHC016の例](https://tc-wleite.github.io/ahc016.html)

### 4.3.2. Vercel

単純なWebホスティングだと、サーバーサイドの複雑な処理はできません。ある程度、サーバーサイドの処理が可能なWebホスティングとして、[Vercel](https://vercel.com/)があります。Vercelは、Next.jsをそのままホスティング可能です。Next.jsは、サーバーサイドのレンダリングと、クライアントサイドのレンダリング（SPA）を最適に組み合わせて提供できるようにした、React.js上のフレームワークです。サーバーサイドのレンダリングの機能の中で、サーバーサイドでやや複雑な処理をさせることが可能です。

後述するように、バックエンドありパターンが使いにくくなった現在、Vercelを使うパターンが急増するのでは、と考えています。また、Next.jsは現時点で最新のWeb技術が使われており、技術的にも習得意義があるものになっています。

利用例として、[筆者のもの](https://ahcstats.vercel.app/)を示します。

### 4.3.3. バックエンドあり

フロントエンドとは独立して、バックエンドも用意することで、複雑なWebサービスを提供可能です。2022年途中までは、セールスフォースドットコムが提供するHerokuが、無料枠である程度のバックエンド処理をできるため主流でしたが、実質有料化されてしまいました。よって、基本的には、この方式を選択する場合、有料でのコスト負担が必要です。そのため、多くのWebサービスサイトが、寄付を募集しています。

なお、バックエンドとしてコンテナを含むIaaSを選択すれば、スクラッチで何でもインストール可能ですので、Pythonを動かすことも可能です。

利用例として、[AtCoder Problems](https://kenkoooo.com/atcoder/)があります。

> なお、2023年5月より、VercelでPostgresが使えるようになり、バックエンドを一部統合できるようになりました

# 5. 宣伝

最後に、できあがった公開情報を宣伝して、いろいろな人に見てもらいます。これも、複数の手段を組み合わせると効果的です。

## 5.1. ブログ掲載

ここQiitaや、Zennなどに、記事として掲載します。ブログサービスに附属する宣伝ツール（ツイッターを含む）によって、広く宣伝されます。

## 5.2. ツイート

Twitterに、キャッチーなグラフを貼り付けたメディアツイートをします。筆者のツイート例を、本記事冒頭に貼り付けしています。フォロワーの属性に合った情報であれば素早く拡散するとともに、インフルエンサーに反応してもらえると、大きく拡散します。

## 5.3. SEO

Google検索にヒットしやすくなるSEOは、よほどの大規模サイトでない限り無縁かつ効果ありません。SEOの勉強としてやるのでない限り、無意味です。

なお、[AtCoder Clans](https://kato-hiro.github.io/AtCoderClans/)という、AtCoder関連情報もろもろを収集しているサイトがあります。有用な情報を公開すると、こちらに掲載されますので、間接的にGoogle検索でヒットするようになります。

# 6. 注意点

本記事全体についての注意点をまとめます。

## 6.1. 利用規約や法令への準拠

Webで取得する行為そのものや、取得するデータについて、各サイトの利用規約の確認が必要です。

AtCoderの利用規約においては、以下に注意する必要があります。

```
ユーザの責任
2. ユーザは、本サービスの利用に際して当社に対して損害を与えた場合、自己の責任と費用において当該損害を賠償する義務があることを承諾します
3. ユーザは、本サービスの利用に際して他の会員又は第三者に対して損害を与えた場合、自己の責任と費用において当該損害を賠償するものとし、かつ弊社を免責する義務があることを承諾します

知的財産権
1. 本サービスに対して投稿されたプログラムの所有権と著作権は、そのプログラムを作成したユーザに帰属します
2. 本サービスを構成する文章、画像、プログラムその他のデータ等についての一切の権利（所有権、知的財産権、肖像権、パブリシティー権等）は、ユーザ自身が作成したものを除き、弊社又は当該権利を有する第三者に帰属しています
3. ユーザ自身が作成した著作物を本サービスを通じて掲載した場合、弊社が宣伝告知等に利用することを許諾するものとします。また、かかる使用に際して、当該ユーザは著作者人格権を行使しないものとします

会員情報及び登録情報の利用
4. 弊社は、本サービス申込時に会員が登録した会員情報を、弊社及びこれに関連する事業を運営する目的のために利用することができるものとします
```

上記は以下のように解釈可能です。（※本解釈は筆者の想定であり、保証するものではありません）

+ データ収集のためにAtCoder社のサービスに過度の負荷をかける等、サービス運営に影響を与えることは禁止されている。「過度」の裁量はAtCoder社にあるほか、万一サービス運営に実害を与えた場合、個人といえども損害賠償の対象になる。
+ プログラムの著作権はユーザにあり、それを宣伝目的に利用する権利はAtCoder社にしかないため、プログラムの内容に踏み込んだ分析二次利用は、ユーザから提訴される可能性がある。
+ IDや所属などの会員情報は、AtCoder社が認めた目的のもとのみ利用できる。そのため、これらを利用した統計情報の公開には、AtCoder社の暗黙の同意が必要である。逆に、AtCoder社が好ましくないと判断する利用方法については、AtCoder社が停止を命令する権限があるとともに、風評含めた実害がある場合、損害賠償の対象になる。

その他、上記以外でも著作権法や個人情報保護法はもちろんのこと、インターネットで全世界に公開する際には、各国の法令に従うことが求められます。

> 著作権があるデータの全てまたは一部をそのまま利用するのは違法です。しかしながら、著作権があるデータをもとに学習した機械学習モデルおよびその出力は「合法」であるというのが、現在の日本や各国の著作権法のスタンスです（必然的に統計情報は合法となります）。これに対して、クリエイターの画像データと雰囲気が酷似した画像を自動生成する技術が進展し、機械学習への利用は本当に適正なのか、議論が起き始めています。プログラムの二次利用は、慎重にしておく必要があります。

## 6.2. Don't be evil

前節ではホラーストーリーを紹介しましたが、世間的に当たり前とされる技術要素を踏まえ、基本的には善良に振る舞えば、問題を起こすことは考えにくいです。

### 6.2.1. 過剰負荷防止

収集において、対象サイトに過剰負荷を与えることはしないようにしましょう。

+ リクエストした結果は、ローカルにキャッシュ保存して、同じリクエストを繰り返さない。
+ 原則、リクエストとリクエストの間は1秒以上のsleepを入れる。
+ データ量が多くなりがちなWebスクレイピングはなるべく避け、WebAPIを利用する。
+ 大量に収集する場合、まずは少量でトライアルしてみて、総データ量を見積もるとともに、バグ混入のまま自動運転してしまうことを防止する。
+ 自動的な更新監視は、定期的なリクエスト発生になるため、実施しない。

また、Webサービスとして公開する場合、利用者へのダウンロードデータ量が過剰になりすぎないように配慮しましょう。

+ 公開前にChromeデベロッパーツールのNetworkタブで、transferedデータ量を確認する（下図）。さらに、リロードボタンを長押しして、キャッシュ無効時も確認する。
+ クライアントサイドに全データがダウンロードされるアーキテクチャー（json全データをimportし、SPAでクライアントサイドレンダリングをする等）を回避する。具体的には、Vercel/Next.jsを利用するか独自のWebバックエンドを構成し、必要な分だけのデータをAPI経由でフェッチするようにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156600/369fa157-68a7-c3f4-1f20-e155f938d61e.png)

### 6.2.2. 正当な目的での利用

AtCoderおよびユーザへのリスペクトの元に、ユーザ満足度を向上させたり、普及を促進したりする目的で、データの利用を行いましょう。

### 6.2.3. 正確性・透明性

せっかくの分析公開も、間違った内容だと逆効果です。細心の注意のもとに分析するとともに、万一間違いが見つかった場合は、速やかに訂正しましょう。

また、分析過程（生データ、分析ロジック等）を公開することで、正しい分析かどうかを第三者が確認できるようにする、透明性も重要です。

## 6.3. セキュリティ

特にホスティングに頼らずに、自力でWebサービスを作る場合は、セキュリティに注意が必要です。自分でWebサーバーやアプリサーバをインストールして提供していて脆弱性を放置すると、不正アクセスによりサイトが改ざんされる危険があります。Webサイトが改ざんされると、不正アクセスのためのボットにされたり、クロスサイトスクリプティングなどの間接的な不正アクセスの踏み台にされたりします。

Vercelなど、WebサービスのPaaSとして、利用者でのミドルウェアのメンテナンスが不要なサービスを使うのであれば安心です。しかしながら、サービスそのものが不正アクセスされる可能性もないとは言えません。

また、ユーザログインを前提としてユーザ情報を記録するサイトを作成する場合、該当行為のユーザへの許可取得や、情報そのものの漏洩に細心の注意を払う必要があります。

## 6.4. 課金

自力でバックエンドを構築する場合、その多くは従量制料金になっています。プログラムのバグなどにより大量のDBアクセスをしてしまい、課金が爆発してしまうこともありますので、細心の注意が必要です。完全従量ではなく、上限キャップがついているタイプのサービスを選択することも必要です。