この記事は「Wake Up, Girls! Advent Calendar 2019」18日目の記事です
この記事では推しの声優の情報を自動的に収集する仕組みである @yoppinews bot の開発や運用についてご紹介します。
1. はじめに: 趣味を自動化して怠惰なファン活動をしよう
声優のファン活動のなかで、どのような作品やイベントに出演するのかといった情報をおさえておくのは重要でありながら意外にも時間やコストを要します。
**チケットの争奪戦が予想される場合、オタクはひっそりと情報を仕入れそっと eplus で抽選に申し込みます。**気づけば行きたかったイベントの抽選は終わっているなんてことが初期にはよくありました(遠い目)。
だいたい同じ演者を追っている人間を twitter でフォローしておくと関連する情報が入ってきてベンリですが、声優オタク人生は山あり谷あり他界ありで、「お前が一番!」とか言ってたオタクは大体わりと早期に他界します(当社調べ)。
私が現在活動を追っている 青山吉能 さんは 2019年3月に解散した Wake Up, Girls! という声優ユニットに所属していました。
ユニットの解散から四半世紀が経った今、一つのものを追いかけていたタイムラインのオタクはゆるやかに散り散りになりつつあります。
このようなことは予見できたため、自分自身が怠惰にオタク活動を継続するために、自前で青山吉能さんのみの情報が得られる独立した情報収集の仕組みとして Twitter Bot: @yoppinews を作ることにしました。
モノとしてはあくまで自分のために作っており、第三者に情報を拡散するようなことを目的とはしていませんでしたが、成果物に対する反応は改善を行うモチベーションにもなるため公開しています。
この記事では、声優の情報を収集する仕組みの要件、実際のシステムの構成、および成果物の利用方法について解説を垂れ流しますが、かなり愚直な実装で大したものではありませんので、興味のある方は覗いてみてください。
2. どんな情報をどのように収集/配信したいのか
@yoppinews を作成するにあたり、どんな情報をどのように配信したいのかを考えました。以下それぞれの内容について見ていきます。
2.1. 収集/配信したい情報
昨今の声優業界では、twitter、ブログ、Webサイト、プレスリリース、ニュースサイトのいずれかの形で最新情報が告知されることがほとんどであるため、以下のような監視を行えば8割以上の情報をキャッチできそうです。
ツイートの監視: yoppinews-bot
- 監視対象
- 本人のアカウント
- 関連する作品・ユニット・番組などのアカウント
- 共演者、制作スタッフ、放送作家などのアカウント
- ニュースサイト・プレスリリース配信アカウント
- どのような監視を行うか
- ツイートテキストのキーワードマッチ
- ツイートに含まれる画像内の顔検出と比較
- ツイートに含まれる URL の内容に対するキーワードマッチ
📷 関連画像を自動検出(類似度: 94.68%) https://t.co/tk3ZwMNhgJ
— yoppinews (非公式) (@yoppinews) October 15, 2019
🌍 関連URLを自動検出(検知キーワード: 青山吉能) https://t.co/jsRedkWdu8
— yoppinews (非公式) (@yoppinews) November 25, 2019
ウェブサイト/新着記事更新の監視: yoppinews-web-monitor
- 監視対象
- RSS フィード(ブログやニュースの新着記事)
- 特定のウェブサイト(プロフィールページなど)
✏️ 関連新着投稿を検出: (検出キーワード: 青山吉能)
— yoppinews (非公式) (@yoppinews) November 5, 2019
『青山吉能・山下七海のトークショー ななよぴとーく』 ご来場ありがとうございました!https://t.co/G4mDfv6sFn
なお、残念ながら インスタグラムはスクレイピングなどによる自動化が規約上難しい ため、ネイティブアプリの通知機能などを利用して人力で情報を拾う必要があります(なんか良い手を知ってる方いたら教えて欲しい)。
不正な方法を用いて、アカウントの作成、情報へのアクセス、または情報の取得を試みることは禁止されています。
これには、弊社から明示的な許可を得ることなく、自動化された手段を用いてアカウントを作成したり、情報を取得したりする行為が含まれます。
スケジュールの配信: yoppinews-calendar-bot
また放送・配信・イベント・キャラクターの誕生日などの日程を忘れがちなため、リマインダーとなるようなツイートを行う機能があると便利そうです。
- 開始直前のリマインダ
- イベントのスケジュール
- 放送・配信のスケジュール
- キャラクターの誕生日
- その日のスケジュールのサマリ
🗓 2019/11/7 のイベント予定
— yoppinews (非公式) (@yoppinews) November 6, 2019
14:00 toshiLOG vol.4 朗読劇「あの星に願いを」 11/7 14:00回
19:00 toshiLOG vol.4 朗読劇「あの星に願いを」 11/7 19:00回#青山吉能 https://t.co/m8HhBD0UIF
2.2. 想定する運用
どのような運用にて前述のような情報が得られることが理想か現実と折り合いをつけながら検討した結果が以下のようなものになります。
-
お金は推しに落としたい ため、とにかく経済的にも時間的にも 省コスト運用 となるよう徹底
- これを実現する手段として サーバーレスアーキテクチャを採用
- 継続した運用を行うため基本的に 放置運用 できるような仕組みとする
- イベント終了後や作品の鑑賞後は bot の更新作業より うまい酒を飲みたい
- 省力運用 = 自動化/半自動化 となるため、管理者の意図が介在しづらい運用 にもなる
- アプリケーションの設定変更を出先で行えるようにする
3. システムはどのように構成されているか
それぞれのシステムでどんな技術やコンポーネントを使い、どのように構成しているかをざっくりご説明しますが、やってる内容はかなり地味です。
3.1. 採用技術
-
実装言語: Python 3.7 (mypy, pytest)
- Python に苦手意識があったため学習目的で採用(ほぼ書いたことなし)
- 言語への抵抗感はなくなったが、やはり静的型が恋しい(mypy を導入したが少し物足りない)
- 正直もうちょっと手慣れてる言語で書いたらもう少し楽に開発できた
-
利用しているリソース: 以下のようなお金のかからないコンポーネントを利用している
- コンピューティング: Lambda
- システム間連携: SNS, SQS, CloudWatch Events
- 画像処理: Rekognition
- データストア: S3, DynamoDB
-
リソース管理: AWS Serverless Application Model
- Serverless Framework と迷ったが AWS 公式のものを採用
3.2. ツイート監視システム: yoppinews-bot
前述のような要件や運用想定のもと、関連ツイート検知の仕組みとして yoppinews-bot を運用しています。このシステムの概要は以下のようなものです
- ツイートを収集し、必要な情報を自律的に判断し twitter に投稿するだけの簡単なシステム
-
あらかじめ設定ファイルに指定した twitter リストの未取得ツイートを拾い、関連性があると判断した場合にリツイートする
- twitter リストベースでの監視対象設定なのでデプロイいらずで、出先などからリストへの追加・削除を行うことでツイート監視対象の管理作業ができる
- ツイートの関連性は次のような判断基準に対応している
- 本人あるいは本人関連番組アカウントからのツイート検知
- 単純なキーワード検知
- アカウントごとのキーワード検知
- 顔検出および比較による画像検知
- 関連 URL 検知
3.2.1. システムの全体像
システムの全体像は概ね下図のとおりです。太線が主なデータの流れ。点線が関連する API コールやシステム間連携となります。
毎分実行されるジョブのデータフローはおおよそ以下のようなものとなります。
- CloudWatch Events にてツイートを取得する Lambda 関数(CollectTweets)を毎分起動
- CollectTweets 関数は単純に設定ファイルに書かれた Twitter リストからツイートを取得して DynamoDB にキャッシュし、新規のツイートを SNS トピック(CollectTweetTopic)を通して SQS キュー(CollectTweetQueue)に送り込む
- Stream 系 API を利用する場合、常駐するプロセスが必要となるが、ツイート検知のリアルタイム性を犠牲にし 1〜2 分前後のレイテンシを許容するならばバッチ実行で十分
- タイムライン系の API に比べて Twitter リストツイート取得 API はリクエスト制限が緩く、スケールしやすい
- Twitter リストを使うことにより、出先で Twitter クライアントからリストに追加・削除で手軽ツイート検知対象を変更できる
- DetectRelatedTweet 関数は、新規ツイートが溜まっている CollectTweetQueue よりツイートを取得し、関連のあるツイートかどうか以下のようなチェックを行う(設定ファイルによってどの判定を行うかリストごとに指定できる)
- 特定のアカウントからのツイートか
- 特定のキーワードを含むツイートか
- そのアカウントにおいてのみ検知したいキーワードを含むツイートか
- 本人の顔写真を含む画像が添付されたツイートか: DetectRelatedImage 関数を通して背後にある Rekognition API を呼び出して判定
- 特定のキーワードを含む URL が記載されたツイートか: DetectRelatedURL 関数を通して該当 URL にヘッドレスブラウザを通してコンテンツを取得
- 関連するツイートと判断した場合、SNS トピック(RetweetTopic)に通知を行い、その背後にある Retweet 関数が、Twitter API を叩きリツイートを行う
実装コードは GitHub リポジトリ: yoppinews/yoppinews-bot にて MIT ライセンスで公開していますが、2019年3月までほぼ Python でアプリケーションを書いたことがない人間が学習目的で Python を書いたため、標準的でなかったり、わかりにくいコードがあるかもしれません。ボコスカにする Pull Request をお待ちしております。
3.2.2. 監視対象アカウントの運用について
前述のとおり yoppinews-bot は本質的には Twitter リストに追加したアカウントを対象に関連キーワード/画像/URL 検出を行うという単純な仕組み の bot です。
しかしながら、例えば オタクのツイートをリツイートする何らかのコンテンツの公式アカウント が存在する場合、必要性の薄い情報がノイズとして発生 します(たとえばコンテンツに対するオタクの感想をひたすらリツイートし続ける公式アカウントなど)。
あるいは、演者本人や演者がメインキャストを務める作品のツイート はプライオリティの高い情報で 常にリツイートしたい などといった要求が生じます。
そこで yoppinews-bot には クロール対象の Twitter リストを複数設定できるようにし、かつ各 Twitter リスト単位でどのようなレベルの検知を行うか といったことを細かく設定できるようになっています。
実際に現在本番環境で運用しているリスト は以下のようなものです。検知オプションのバリエーションとして 6 種類の Twitter リストを運用 しています。
リスト名 | 常にRT | RT を評価 | リプを評価 | 引用 RT を評価 | 画像を評価 | URL を評価 |
---|---|---|---|---|---|---|
always_retweet | ○ | ○ | ○ | ○ | - | - |
trusted | - | ○ | ○ | ○ | 常に評価 | - |
main | - | ○ | ○ | ○ | 必要な場合のみ | - |
sub | - | - | ○ | ○ | 必要な場合のみ | - |
officail | - | - | ○ | ○ | - | ○ |
press_release | - | - | ○ | ○ | - | - |
このような設定は YAML 形式のアプリケーションの設定ファイル: config.yaml にて設定が可能性で、一例としてalways_retweet リストの設定は以下のようなに記述されています。
twitter_config:
target_lists:
# 常にリツイートするアカウント用 Twitter リスト
# 演者本人や演者の冠番組のアカウントをリストインする
-
owner_screen_name: yoppinews
slug: always-retweet
always_retweet: true # この値が true だと常にリツイートされる
include_retweet: true # この値が true だと RT も評価される
include_reply: true # この値が true だとリプライも評価される
include_quoted_text: true # この値が true だと引用 RT のテキストも評価される
evaluate_image: NONE # 関連画像検知を有効にするか
evaluate_url: NONE # 関連 URL 検知を有効にするか
count: 10
基本的に日々の運用作業は、Twitter リストの更新作業となります。例えば、作品への出演が決まったら適切なリストに該当作品の公式アカウントを追加するという形になります。Twitter リストは出先からでも手軽に更新できるため便利です。
3.2.3. 関連キーワード検知の仕組み
監視対象アカウントのツイートに対して、最も有力かつ単純な検知の仕組みがキーワード検知 になります。例えば演者本人の名前が含まれるツイートは、ほぼ間違いなく関連する情報であるため検知したいはずです。
また、一般に担当する キャラクターの名前を含むツイートも関連する情報である可能性が非常に高い と考えられますが、キャラクター名によっては誤検知が大量に発生する 可能性があります。たとえば、青山吉能さんが演じる「恋愛暴君」のグリは、カタカナ2文字で非常に誤検知が発生しやすいキーワードになっています。もし「恋愛暴君」公式アカウントや原作者が「グリ」を含むツイートを行った場合、ほぼ関連する情報であると考えられるため、yoppinews-bot では 特定のアカウントに対してのみ検知を行うキーワードの設定ができる ようになっています。
そのほか、監視対象アカウントが乗っ取りなどの被害を受け、スパムツイートを行うような場合の誤検知を防ぐため、禁止キーワードの設定も行える ようになっています。
前述のような検知キーワード、アカウント特有の検知キーワード、禁止キーワードは、アプリケーションの設定ファイル上で以下のように記述できます。
keyword_config:
# 無視するキーワード設定
ignored_keywords:
- レイバン
- Rayban
# 検知対象のキーワード設定
keywords:
- 青山吉能
- "青山 吉能"
- 七瀬佳乃
- 青山つばさ
# アカウント特有のキーワード設定
user_related_keywords:
boukun_PR:
- 恋愛暴君
- グリ
megane2702:
- 恋愛暴君
- グリ
renaiboukun:
- 恋愛暴君
- グリ
3.2.4. 関連画像検知の仕組み
関連画像検知に関しては、顔比較が簡単に行える Rekognition API を利用しています。
これは非常に手軽なもので、比較元と比較先の画像を指定すると、同一人物である可能性が高い顔が存在するかどうか、類似度はどの程度かを JSON 形式でレスポンスしてくれるサービスとなっています。
本来はイベント終了後や収録などの際に演者の関係者が撮影した写真を自動で検知するために作成した機能ですが、イベントや放送への出演決定の際のビジュアルに宣材写真が含まれることが多く、意外にもそういう性質の画像を検知するのに役に立った実例があります。これは当初の想定をうわまって便利だと感じました。
3.2.5. 関連 URL 検知の仕組み
ツイート内に含まれる URL は関連する情報が記載されている可能性が高いのですが、当然のことながらツイートの検索だけでは関連する情報かどうかの判断が難しいものとなります。
例えば、ファミ通やアニメイトの記事の告知ツイートには演者の名前が入っていなくても、記事本文には記載があるというケースは多々あります。
こういったケースのためにツイートに記載された URL の内容を確認し、関連するツイートであるか判断するという機能を作成しています。
仕組みとしては単純で対象の URL をヘッドレスブラウザにて読み込み、関連キーワードが含まれるかどうかを判断するというものとなります。
単純にページ全体のキーワードを検知対象とすると関連記事などのタイトルも拾ってしまうため、正規表現にマッチする URL だった場合に特定の CSS セレクタでキャプチャできる要素内のテキストのみを検知対象とする工夫をいれています。この点については設定ファイル config.yaml
をみると理解しやすいかと思います。
detect_related_url:
selectors:
'https://prtimes.jp': '.content .rbody'
'http(s)?://www.nicovideo.jp/watch/': '.VideoDescription-html'
'http(s)?://ch.nicovideo.jp/\w+/blomaga/': '.main_blog_txt'
'http(s)?://cho-animedia.jp': '.contents'
'http(s)?://www.animatetimes.com/news/details.php': '.news-content'
'http(s)?://www.animatetimes.com/tag/details.php': '.tag-content'
'http(s)?://www.youtube.com/watch': '#description'
'http(s)?://seigura.com/news/': '.entry-content'
'http(s)?://note.mu/': 'p-article__content'
ignored_urls:
- 'http(s)?://www.animatetimes.com/comment/details.php'
- 'http(s)?://example.com'
3.3. サイト更新監視システム: webmonitor-bot
関連 URL 検知の仕組みとほぼ同じような形でヘッドレスブラウザを用いて、サイトの更新を監視するモジュール: yoppinews-web-monitor があります。仕組みとしては非常に単純で面白くないので、詳細については割愛します
3.4. スケジュール管理システム: yoppinews-calendar-bot
Google カレンダーに登録したスケジュールをツイートする yoppinews-calendar-bot があります。機能としては、その日のイベントや放送・配信情報をツイートする サマリー機能 を持つ Lambda 関数と、イベントや放送・配信開始時刻直前にツイートする スケジュール予告機能 を持つ Lambda 関数の 2 つがあります。
なお @yoppinews で利用している Google カレンダーは https://yoppinews.github.io にて公開しています。
なお、スケジュール予告機能についてはツイートされる文面にこだわりがなければ IFTTT を使って実現することも可能です。@yoppinews では初期のころに IFTTT を利用していましたが自前での実装に差し替えました。
4. 運用状況の統計データ
前述のようなシステムにいったいどれだけの費用がかかっていて、どれだけの有効な情報を収集することができるようになったのかというデータも公開します。声優オタクも KPI を重視する時代(KPI って言いたかっただけ)。
4.1. 運用費用の推移
本格的に運用に乗り始めた2019年4月以降の運用費用はおおむね以下のような推移となっています
- Rekognition の費用が支配的
- 途中から Lambda の無料利用枠に余裕があるためレイテンシを犠牲にして ap-northeast-1 ではなく us-east-1 のエンドポイントを叩く変更を入れました
- 画像検知対象アカウントをじわじわ増やしているため費用は増加傾向にあります
- このサービスにだいぶ助けられているのでお金を払う価値はあります
- Lambda の環境変数情報を暗号化するための KMS キーに固定で $1 かかっている
- その他のサービスはほぼ無料利用枠におさまっている
- 5月から費用がぐっと安くなっているのは無駄なリクエストをなくすよう全体のコードを書き直したため
4.2. 処理したツイートの統計データ
twitter から API を通して取得した監視対象のツイート件数の推移は以下のようなものとなります
- 監視対象のツイートとして、平日は概ね 2500 ツイート/日 前後処理を行っていることがわかります
- 月間 55,000 ツイート前後になります
- 2019年11月に処理件数が増加したのは「あの星に願いを」や「アイドル倶楽部」の関係者、「なつなぐ!」関連のアカウントを監視対象に追加した影響だと思われます
4.3. 配信したツイートの統計データ
処理したツイートのなかから実際にプログラムが関連ツイートであると判定し、ツイートやリツイートにより情報の配信を行った件数の推移は以下のようなものとなります
- 手動で拾っているツイートもあるので、@yoppinews から配信されているツイート件数は実際にはこれよりも多い
- 日によってブレが大きい
- おおよそ 200 リツイート/月、50 ツイート/月 で推移している
5. 現状の課題と今後の野望
まだまだ自動化したい内容がたくさんあります。一例として以下のようなものを作りたいのですが、イベントやコンテンツに時間を使っており、手がつけられてません。
-
関連動画検出
- すぐできる見立てはあるのですが、面倒で実装してない
- 正月休みにやるか(酒飲んで終わりそう)
-
関連ツイートの学習
- 現状はあらかじめ想定されるような対象およびキーワードを中心としたツイート検知での運用だが、当然ながらそこから外れると情報が拾えない
- 新規の関連要素を検知するなんらかの仕組みを2020年中に稼働させたい(勉強中)
-
アニメ出演情報検知システム
- メインキャスト以外での出演情報、取りこぼしがち
- 放送されているすべてのアニメの OP/ED 映像から検知対象のキャストの名前を検知したい
- 録画サーバーを立てなきゃいけないのでコスト面で見送り中だが、ちょっと実験してみた感じ、ある程度の精度でイケそうではある
-
出演ラジオ/生放送全文検索システム
- ラジオ/生放送において、あの話題はどの回で出た話だったか、などを確認するのは大変
- 出演しているラジオ/生放送の音声を書き起こし、検索できる状態にしておきたい
-
AI よぴちゃん bot
- よぴちゃれ/あな番のアレ
- 音声入力可能なウェブアプリ
- イベント/放送配信スケジュールとかも確認できると便利そう
- 暇なときに遊びで作ります
-
草ブレード画像検出
- 誰得なんだろう、これ...
- できてはいるけど精度上げたい
6. まとめ
- 青山吉能さん という声優さんが素敵なのでみなさんもファンになってください
- 推し駆動開発は楽しいのでみなさんも是非
補足: 青山吉能さんとは
本日は #白猫ちちぶ祭 にお集まりくださりありがとうございました☺️
— 青山吉能 (@Yopipi555) December 15, 2019
モニカの活躍…期待しても…いいよね…!ね!!!🔥
皆様もわたしたちも寒い中でしたから、体調にはいつも以上に気を使ってあげてくださいね!
ミレイユ役のゆなと待ち時間めっちゃくちゃ写真撮った🤳盛れみ! pic.twitter.com/Jk4w9Hx8Gu
2020年1月クールアニメ「なつなぐ!」「群れなせ!シートン学園」に出演するのでみてください
- 熊本県出身の 81 プロデュース所属の声優
- 2014年にアニメ「Wake Up, Girls!」で声優としてデビュー
- 声優ユニット「Wake Up, Girls!」のリーダーとして2019年3月まで活動
- 主な出演作品
- Wake Up, Girls!(七瀬佳乃)
- 恋愛暴君(グリ)
- きかんしゃトーマス(ニア)
- 灼熱の卓球娘(由良木ゆら)
- 歌が上手い、声がきれい、顔がいい、朝に弱い