Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

ZOZO 前澤社長のお年玉企画リツイート企画はどのくらい世の中に影響を与えたのか? 500万件超えのリツイート情報の取得と分析を個人的に試みる!(仮)

ZOZOタウンの前澤社長が当該ツイートをリツイートしてくれた人の中から100名を対象に100万円(総額1億円)をプレゼントしてくれるという、なんとも太っ腹? な企画が動いていますね。

Twitter上だけでなく、各メディアでも話題になっています。

nlab.itmedia.co.jp

申込みは1月7日12時締切になりまして、私が見たときには550万リツイートツイッターリツイート数世界1位になったみたいです!

私も面白い企画だなーと思って乗ってみたのですが、気になるのは対象100名の決定方法!

いろんな憶測ツイートでも出ている通り、標準のTwitterの機能だと結構制限が厳しいです。 でも、制限が厳しいとやってみたくなりますよね? 

それにこんな面白そうなビッグデータ、なかなか無いのではないか?

せっかくなので、このデータを分析してみたい! どんなユーザーがリツイートしているのか知りたい! ボットはどのくらい居そう? リツイートの影響数はどのくらい? この企画の期間中にツイッターアカウントを作成した人はどのくらい? 

そんないろいろと気になる疑問があったので、解決方法を探ってみました!

取得結果!

いきなりですが、結果報告です!

取得方法は後述しますが、大量にツイートが取得できる Twitter Premium API を利用して、直近のツイートを20万件取得できました!(それでも、全体の3.6%・・・orz。なのでタイトルが(仮)となっています)

じつは、仕様的には500万件までOKなのですが、30万円ちかく必要なことがわかり、私の財布でまかなえる範囲の20万件取得に落ち着きました・・・。

それでも面白いものは見えてきましたので、ご紹介したいと思います!

こちらがざっと分析してみた Microsoft Power BI のレポートです。(あまりクレンジングしていないので、概算値として見てください。また分母は「#月に行くならお年玉」でツイートしている人たちです。リツイート以外にも含まれています。)

f:id:sugimomoto:20190108082128p:plain

リツイートしている人たちのフォロー数、フォロワー数、リスト登録の総計

もうちょっと絞り込みは必要かなーとは感じていますが、単純の総計してみた数字ですが、68Mというのは驚異的かなと。これが全件まで含めるとなると、25倍ほどにはなる計算です。

ユーザーで重複排除はしていないので、仮に最大元リーチしていた場合、このくらいの数字になる、という感じですねぇ。

偽物アカウント

これは面白かったです。20万件中302件は偽物の前澤社長ツイッターリツイートしている情報でした。

ちなみに、偽物アカウントは7名。

screen_nameが「yuusuck2020」だったり「maezawaofficia1」だったりと工夫が見られて面白いですw

イベント開始時以降にツイッタアカウントを作成したユーザー

これは13,000ユーザーと、驚くほど存在しましたねぇ。

今回のデータの取得が、締切後なのもあるので、余計数が多く感じるかもです。

フォロー数、フォロワー数の分布を見ても、200以下がほとんど。ぱっとみ、1がほとんどでした。

そんなわけで、550万件どうするか問題

目標としては、リツイートだけでなく、「#月に行くならお年玉」全体で取得して、分析してみたいので、おそらく700万ツイート近くは必要じゃないかなぁと考えています。

個人的にはやっぱり全件取得して、すっきり分析してみたい! でも、ちょっとお金が厳しい・・・!

なので、こんな企画に賛同してくれる方、面白いなー! と思ってくれる方から投げ銭PayPal)を募集中です!

www.paypal.me

溜まった金額に応じて、ツイートを取得して、分析を試み、最終的にこのBlogで公開したいなーと思っています!

ぜひぜひご協力いただけますと嬉しいです! 目標金額は50万です。


どうやって取得するの?

それでは、技術的なところを抑えていこうと思います。

通常のTwitter APIだと、下記リファレンスにもある通り制約が厳しいです。

Standard search API — Twitter Developers

アプリ認証で 15分/450ツイート 1時間で1800ツイート

つまり、単純計算で600万件を処理する場合は約2,800時間(116日!?)ほどかかる計算になります。

そんなんじゃ話にならない!

なので、2017年11月に発表された Twitter API の有料プラン、Premium APIを使うことで取得を試みます!

gigazine.net

このTwitter Premium Plan を使うことで、リクエストリミットの緩和が図れます。 しかし!

Premium search APIs — Twitter Developers

Premium Plan と言えど、以下のドキュメントのRate Limit にもあるとおり、制限はあります。(さすがに全ツイートを取得しようとしたら、そりゃあ蹴られますよね。)

https://developer.twitter.com/en/docs/tweets/search/api-reference/premium-search.html#DataEndpoint

Request rate limits at both minute and second granularity. The per minute rate limit is 60 requests per minute (30 with Sandbox environment). Requests are also limited to 10 per second. Requests are aggregated across both the data and counts endpoints. Monthly request limits are also applied. Sandbox environments are limited to 250 requests per month, and paid access can range between 500 and 10,000 requests.

ざっくり書くと

・1回のリクエストで取得できるツイート数:500ツイート

・1ヶ月あたりの最大リクエスト制限:10,000リクエスト(Premium 最上位プランの利用)

・1分間あたりのリクエスト制限:60リクエス

上記から算出すると、1ヶ月の間に取得できる最大ツイート数は「500 X 10,000」で500万ツイート取得可能!

取得にかかる時間はおよそ「10,000 / 60リクエスト / 60分」でおそらく3時間いかないくらい!

これを2回繰り返せば余裕で取得できそうだなーというのがわかります。

ただし・・・それでも、プライシングがボトルネック・・・!

https://developer.twitter.com/en/pricing/search-fullarchive

f:id:sugimomoto:20190106232325p:plain

一番安いプランなら、149ドル(16,170.97 円)なのですが500リクエストまで・・・。

500万件取得するためのに必要な10,000リクエストできる最上位プランを選ぼうとすると2,499ドル(271,216.47 円)かかってしまいます・・・!

全体を取得しようとすると、その倍・・・! く、くるしいぃ・・・。

・・・

とりあえず

本当は全部取得したいけど、とりあえず最低プランで実現可能か検証してみましょう!(自腹) という感じで実施した結果が上記のとおりです。

実現アプローチ

f:id:sugimomoto:20190108060437p:plain

まず、REST APIをプログラム(.NET C#)から素直に叩いて、1回で取得できるJSONをそのままファイル形式でローカルに格納しました。そのままデシリアライズしてもいいのですが、コストや今後の加工性も考えて、そのまま保存しています。

ただ、この状態だと1ファイルに複数ツイートが格納された状態なので、分析しづらいです。

{
    "results":
      [
           {--Tweet 1--},
           {--Tweet 2--},
           ...
           {--Tweet 500--}
      ],
    "next":"NTcxODIyMDMyODMwMjU1MTA0",  
    "requestParameters":
      {
        "maxResults":500,
        "fromDate":"201711010000",
        "toDate":"201711030000"
      }
 }

なので取得したJSONファイルをフラット化して、片っ端からRDB(今回はすでにローカルにインストールしていたSQL Server)に登録することで、最終的な分析のしやすさを実現します。

なので、テーブル形式でJSONを簡単にフラット化して、複数ファイル横断した取得ができ、かつローカルDBにもレプリケートできる、私の会社で開発している以下のライブラリを使用しちゃいます。

https://www.cdata.com/jp/drivers/json/odbc/

これで、JSONスキーマを自動的に定義して、かつSQLでデータを取得できるようにしてしまいました。

f:id:sugimomoto:20190108052955p:plain

数万件程度ならこのまま分析にかけるのもいいのですが、都度ローカルファイルを捜索してしまうので、このテーブル化した状態のものをRDBに持っていくことでパフォーマンスを改善します。(本当はBigQueryに持っていきたいのですが、まあ今の所20万件なのでよしとしましょう。)

Twitter側の準備

Twitter は Developer 登録をしてから、アプリの登録とPremium API利用の準備を実施します。

Premium API の場合はクレジットカードも必要になるので要注意です。

1.アプリの登録

Twitterのアプリ登録は以下の記事を参考にどうぞ。

kageura.hatenadiary.jp

https://developer.twitter.com/en/account/get-started

2.Dev Enviroment の作成

次にDev Enviroment という、Premium API を使うにあたって、事前に登録しておく接続用の環境を作成します。

f:id:sugimomoto:20190107001651p:plain

一番上の30 days の環境を作成します。

f:id:sugimomoto:20190107001756p:plain

任意の名前を「Dev enviroment label」で指定します。これが後ほど、リクエストURLでも指定することになるので注意してください。また、Appには事前に作成したアプリを指定します。

f:id:sugimomoto:20190107001820p:plain

3. Premum API への Upgrade

最後に、Premium API Plan への Upgradeです。「Manage / Upgrade your access level」をクリックすると

f:id:sugimomoto:20190107001931p:plain

以下のようなAPI利用上の画面が出てくるので、ここから「Upgrade」を選択

f:id:sugimomoto:20190107002057p:plain

Premium API から、任意のプランを選択し、クレジットカードを指定すれば、

f:id:sugimomoto:20190107002216p:plain

登録完了です!

f:id:sugimomoto:20190107002500p:plain

やっちゃっいました! 以下のようにPremium で登録されていることがわかります。

f:id:sugimomoto:20190107002559p:plain

試しにPOSTMANから叩いてみたり。もちろんリクエスト数を消費するので要注意。必要に応じてサンドボックスも取得しましょう。

f:id:sugimomoto:20190108054801p:plain

認証周り要注意

認証はclient_credentialsで取得できる BearerTokenを使用する必要があります。

Authorization Headerで指定するBasic はAPI KeyとAPI Secret Keyを「:」でつないで、Base64エンコードしたものを指定します。

POST /oauth2/token HTTP/1.1
Host: api.twitter.com
Authorization: Basic XXXXXXXXXX==
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
cache-control: no-cache
grant_type=client_credentials

Premium API リクエストアプローチ

Premium API で使用する Search用APIはちょこちょこ通常のものと違うので要注意。

使っている人も少ないので、ちゃんとリファレンスを読みましょう。

Premium search APIs — Twitter Developers

ざっくりですが、今回の場合は、以下のような感じで指定して取得しています。(あと認証部分)

GET https://api.twitter.com/1.1/tweets/search/30day/dev.json?maxResults=500&query=%23%E6%9C%88%E3%81%AB%E8%A1%8C%E3%81%8F%E3%81%AA%E3%82%89%E3%81%8A%E5%B9%B4%E7%8E%89

ページングはレスポンス要素に含まれる「next」のトークンをURL Parameterに追加することで対応できます。これはリクエストごとに変わることはなく、おなじページを取得したい場合は、同じNextトークンを利用できます。

{
    "results":
      [
           {--Tweet 1--},
           {--Tweet 2--},
           ...
           {--Tweet 500--}
      ],
    "next":"NTcxODIyMDMyODMwMjU1MTA0",  
    "requestParameters":
      {
        "maxResults":500,
        "fromDate":"201711010000",
        "toDate":"201711030000"
      }
 }

私はちょこちょこC#で書いて、500回リクエストを実施し、20万レコード取得しました。

f:id:sugimomoto:20190108054137p:plain

f:id:sugimomoto:20190108054038p:plain

だいたい8分ほど。Premium API はやっぱり早いです。これで以下のような感じでJSONファイルを保存しました。

f:id:sugimomoto:20190108060652p:plain

JSONをフラット化して、DBに連携

最後に、格納されたJSONファイルをフラット化して、DBに連携します。

実は特に小難しい設定はいりません。

以下のCData JSON Driver をインストールして

https://www.cdata.com/jp/drivers/json/ado/

以下のようなJSONが格納された対象フォルダ、フラット化のアプローチ、DBレプリケート用のキャッシュ設定を入れるだけです。

URI=C:\Work\ZozoTweets\;
DataModel=Document;
Cache Driver=cdata.jdbc.sql.SQLDriver;
Cache Connection='jdbc:sql:user=sa;password=Password!;Server=localhost;Database=ZozoTweetDB';

これで、ローカルフォルダに格納されたJSONファイルにSQLでアクセスできるようになり、かつDBにもレプリケートできます。

f:id:sugimomoto:20190108061651p:plain

あとは、Power BI から対象のDBにアクセスして分析できる状態が整います。

もうちょっと詳しくこの辺のアプローチを知りたい方は、以下の記事も公開していますので、どうぞ。

qiita.com

終わりに

APIは専門分野なんですが、これだけ大量のデータを扱うのは初めてだったので、大変でした!

状況次第で、もっと大変になるかと思いますが。

でも、全リツイート分析してみたいな! と思いますので、ぜひご協力をお願いできればと思いますー。

ちなみに、余談ですが、こんな感じでひたすらAPIと格闘する私の会社、CData Software Japan ではエンジニアを募集中です。面白そうなことをやってるなーと思ってくれたら、ぜひご連絡ください。

www.wantedly.com