LoginSignup
13
10

More than 3 years have passed since last update.

「スタバなう」でアップロードされたtwitterの画像をGoで収集してS/N比を調べる

Last updated at Posted at 2019-08-03

というわけで、「スタバなう」と呟きながら関係ない画像を投稿するのが流行っているようです。

実際にどれぐらいS/N比が悪化しているのか、画像を収集して調べてみます。

golang+anacondaでtwitter APIを叩く

golangのtwitter SDKは、ChimeraCoder/anaconda: A Go client library for the Twitter 1.1 APIを使うのが良いっぽいです。(pythonの仮想環境を作るanacondaとは関係ない)

以下のような感じでツイートを取得することができます。

api := anaconda.NewTwitterApiWithCredentials(
    accessToken, accessTokenSecret, consumerKey, consumerSecret,
)
v := url.Values{}
v.Set("count", "100") // 取得する件数(最大100件)
v.Set("max_id", maxIdStr) // ここで指定した数値以下のIDをもつツイートを検索対象とする
v.Set("since_id", sinceIdStr) // ここで指定した数値より大きいIDをもつツイートを検索対象とする
query := "スタバなう OR #スタバなう exclude:retweets filter:images"
searchResult, _ := api.GetSearch(query, v)

今回は、「スタバなう」というツイートがハッシュタグを含むツイートのうち、画像が添付されていてリツイートではないものだけを取得したいので、queryは"スタバなう OR #スタバなう exclude:retweets filter:images"としています。このようなフィルタリングは、anacondaではなくtwitterのsearch API自体の仕様です。

画像のダウンロード

まず与えられたURLからファイルをダウンロードしてローカルに保存する関数を定義します。

func DownloadFile(fileUrl, downloadPath string) (err error) {
    response, err := http.Get(fileUrl)
    if err != nil {
        return xerrors.Errorf("failed to request http get to %s: %w", fileUrl, err)
    }
    defer func() {
        cerr := response.Body.Close()
        if cerr == nil {
            return
        }
        err = xerrors.Errorf("failed to close http response body: %w", err)
    }()

    file, err := os.Create(downloadPath)
    if err != nil {
        return err
    }
    defer func() {
        cerr := file.Close()
        if cerr == nil {
            return
        }
        err = xerrors.Errorf("failed to close file(%s): %w", downloadPath, err)
    }()

    if _, err := io.Copy(file, response.Body); err != nil {
        return xerrors.Errorf("failed to write download file to local file(%s): %w", downloadPath, err)
    }
    return nil
}

ツイートに添付された画像はanaconda.Tweet.ExtendedEntities.Mediaに配列として入っています。
anaconda.Tweet.Entities.Mediaというのもあるのですが、こちらは何枚画像が添付されていても1枚しか入っていません。

tweets := searchResult.Statuses
tweet := tweets[0]
for i, entityMedia := range tweet.ExtendedEntities.Media {
    mediaRawUrl := entityMedia.Media_url_https
    _ := DownloadFile(mediaRawUrl, "image.jpg")
}

これで検索した画像をローカルに保存できるようになりました。

実際に画像を収集してみる

上記のコードは分かりやすさを優先して書いていますが、実際には以下を考慮しておいたほうが良いです。

  • 検索結果のファイルへの書き出し
    • だいたい後から画像のメタデータを取りたくなります
  • 検索/ダウンロードのレジューム機能
    • 完了まで時間がかかるので、途中でうっかり落ちても続きから実行できるようになっていると安心です
    • 一度実行してからの最新画像の差分を取得するのも効率的にやりたい
  • 画像ダウンロードのインターバル
    • twitter APIは叩きまくってもlimitに引っかかるだけなので良いですが、画像ダウンロードは普通にクローリングしてるだけなので、適切なインターバルを入れてtwitter社に迷惑をかけないようにしましょう。

というわけで、twitterデータ収集用のCLIを書きました。

こういう感じで画像をダウンロードできます。

$ twitter search \
  ---db-path tweets.db \
  -query スタバなう \
  --exclude retweets \
  --filter images 
# -> ツイート情報がtweets.dbに保存される

$ twitter download images --db-path tweets.db --dir images
media is downloaded to images/1157466034606972928-0-EBAlOGZUcAA2do9.jpg
media is downloaded to images/1157493760533471232-0-EBA-aqcUEAIdY8T.jpg
...
# -> tweets.dbに保存された画像から画像URLを取り出してimagesディレクトリに保存する

$ tree images | head -n 5
images
├── 1152831484220170240-0-D_-uHqzVUAAwTC2.jpg
├── 1152832631391657985-0-D_-vKCfU0AAk2xR.jpg
├── 1152846684981829632-0-D_-78LbUIAExWaV.jpg
├── 1152860261876822016-0-D__ISFVVAAApkg7.jpg

一晩ほっとくと4000枚ぐらいの画像が集まりました。

スタバ画像にアノテーション付け

では集まった画像のうち本当にスタバで撮影された画像を数えます。
こういう用途の便利なツールが多分あるんだろうなーと思いつつ、今回はmacのタグ機能で、地道にやっていきます。
まずfinderの環境設定を開いて、よく使うタグにアノテーション用のタグを登録しておきます。
今回は「スタバ」というタグを登録しました。

image.png

finder上でファイルを選択してctrl+1~7を押すと、よく使うタグの場所に対応するタグをそのファイルへ付与することができます。
あとはダウンロードした画像が入ったディレクトリをfinderで開いて、スタバの画像にタグを付与していきます。

image.png

最後に、finderの検索でスタバタグを指定すれば、画像の枚数がわかります。

(余談ですがmacのタグ機能は挙動がかなり怪しくて、アルファベット表記のタグが検索で引っかからなかったり(日本語UIにしてるから?)、自分の環境ではctrl+3-7は動作するけど1と2はしなかったりします...できればちゃんとしたアノテーションツールを使うほうが安心だと思います。)

結果

4時間ぐらいで4064枚のアノテーション付けをやったところ、結果は以下のようになりました。

分類 枚数
全体 4064
スタバ画像 973

真のスタバ画像は全体のだいたい24%ぐらいのようです。
これはどうなんでしょうかね。個人的には思ったよりちゃんとスタバの画像をアップしてる人いるなという感想です。
ちなみにラーメンの画像は617枚で、約15%です。
ただし、画像の集計時期は2019/07/21-2019/08/03で、7/26に冒頭のツイートがされている影響でおそらく通常よりもノイズが多いことにご留意ください。

おわり

今回はS/N比を知りたかっただけなんですが、結果的にアノテーション済みのスタバ画像(とラーメン画像)がわりと集まったので、スタバなうムーブメントに激怒している機械学習界隈の方がいらっしゃればメタデータを差し上げますのでお声がけください。

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10