Skip to content

Instantly share code, notes, and snippets.

@fvh-P
Last active March 5, 2018 15:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fvh-P/18c2aa58d410afbe6ce7699618782acd to your computer and use it in GitHub Desktop.
Save fvh-P/18c2aa58d410afbe6ce7699618782acd to your computer and use it in GitHub Desktop.
im@stodonでトレンドタグ機能を作った話

まえがき

この記事は、Mastodon 2 Advent Calendar 2017の21日目です。

どうも、ふぁぼ原です。ただの情報系B3です。

さて、この文を書いている時点で既に21日の20時20分です。いやこのカレンダーを見つけた時にはもう今日しか残っていなかったんですが、自分のスケジュール的に大学のレポートやゼミの発表などでちょうど昨日まで忙しく、仕方なく当日執筆という運びになってしまいました。。。

この記事では自分がim@stodonでどんな活動をしてきたかと、つい最近追加された独自機能、トレンドタグをどのように作ったかをお話しします。

今年のマストドンに関する活動

im@stodonはフサギコ氏によって運営されている、アイドルマスターに興味がある皆さん(プロデューサー)のためのマストドンです。

自分は開設後すぐに登録し、結構入り浸っています。また、im@stodonのgithubリポジトリのほうでは最近Collaboratorになりました。

im@stodonは当初からプログラミングやWebに明るい方が多く、定期的に「あれここは技術インスタンスかな?」という感じのLTLになるような感じになっています。

そんなこともあって、個人運営のマストドンの中では結構多くの改造が施されています。最初はロケールとしてアイマス語を追加し、UIなどの文言をアイドルマスター用語などに置き換えるという試みから始まりました。

自分は本当にただの大学生で、プログラミングはできますが実務経験なし、Webサービスの開発経験も全くのゼロでした。

そんな自分がim@stodonにいろいろとコミットしていくようになったきっかけは、上でも述べたアイマス語の追加のときに、設定の追加がうまく反映できないという話を聞いて、興味本位でソースコードを覗き見たことです。

Ruby on Rails自体はRails Tutorialを一通りやったことはあるのでその時から雰囲気理解はできましたが、膨大な量のソースファイルViewの記述に使用されているJSXとかいう謎の記法などに圧倒されていました。

im@stodonへの自分の最初のPull Requestは初めましての方に向けたメッセージボックスを折りたたみ式にしたというものでした。

全く初めて触るReactに関しては、Reactの解説サイトなどを見ましたが今一つ分からなかったので、マストドン内の他のReactのコードを見てどうにかするという荒業で乗り切りました。

このコミット自体はRevertされていますが、同様の機能は今でもずっとWebUI上でせっせと働いています。

今まで自分が出したPull Rquestは、

  • PNG画像をJPGに変換する機能(#23, #27)
  • タグTLにUnlisted投稿を流すようにする(#32)
  • Aboutページに表示されるTLを連合からLTLに変更(#39)
  • WebUIでのデフォルトのカラムの順番を変更(#58)
  • お気に入りタグ登録・解除のAPIを作成(#69)
  • 公開範囲設定に関するバグを解消(#75)
  • タグカラムの設定にお気に入りタグ登録・解除ボタン、ローカルストリーミングへの切り替えスイッチ、正規表現フィルタの追加(#96)
  • トレンドタグ機能の実装(#109, #119)

くらいですかね。あとそれに付随して投稿に含まれるURLの自動リンクに関するPRを本家に出しているのと、im@stodonのFAQサイトの作成にも携わっています。

自分のコーディング、記憶力がガバガバだったりで結構穴だらけ(1分前に「あれも変更しなきゃな」って思ったところをすっかり忘れたままPR出したり、Reviewerさんのご指摘を受けてコミットを修正したら今まで問題なかった部分が動かなくなったのに気づかなかったりするちゃんと検証しろよ自分)なので、いろいろな方の手を煩わせていますが、これからもできる範囲で貢献していこうと思っています。

トレンドタグ機能について

背景

im@stodonでは、ラジオ番組などの実況をするときにはハッシュタグを付けてUnlistedで行うことが推奨されています。これによって、LTLでは実況以外の話を続けることができます。

Unlistedは本家ではタグTLには表示されませんが、タグTLを実況で使うためにim@stodonではタグ付きのUnlisted投稿はタグTLに表示されます。

しかし、そうするとLTLに実況タグが流れなくなり、今どんなことが盛り上がっているのか・何の実況が行われているのかがLTLではわからなくなってしまうという問題が考えられます。

そこで、im@stodonで盛り上がっているハッシュタグを何らかの形で提示できないかという提案がありました。

統計の取得

既にDBにはstatuses_tagsという中間テーブルが存在するため、ある一定期間中に使用されたハッシュタグの統計を取ること自体はあまり難しくありません。

問題は、得た統計をどうやって保存するか盛り上がりをどうやって可視化(数値化)するかいつ集計してどうやって発表するかの3点です。

どうやって保存する?

一番最初に考えつくのは、DBに新しいテーブルを作るか、既存のテーブル(この場合はtagsかな?)に新しいカラムを作ることです。

しかし、im@stodonの特性上一度に盛り上がるタグはせいぜい3種類くらいだし、単発で使われてそれ以降全く見かけなくなるネタタグも多数存在します。

そのため、DBにいろいろ追加してしまうというのはコストがデカい上に無駄が多いという結果になってしまう恐れがあります。

そこでRedisを使うことにしました。RedisはオンメモリのKVSで小さいものを保存しておくにも適していること、すでにMastodonでも使われているため特別なインストールなど不要で使えるというのが決め手でした。

盛り上がりをどうやって可視化(数値化)する?

これも結構厄介な問題です。単位時間当たりのタグの使用回数をそのままスコアとして使用すると、確かに盛り上がっているものはスコアが高くなりますが、ずっと同じようなペースで使われているタグの評価が適切とは言えなくなってしまいます。(ずっと同じペースということは盛り上がっているとは言えない)

また、実況が多いというim@stodonの特性上番組が終わるとそのタグがパッタリ使われなくなることが多いのですが、番組終了後もある程度の時間残っているというのがトレンドらしい挙動であると考えられるので、使用回数をそのまま使用するのではなく、データを加工して用いる必要があります。

つまり、必要とされる数値化手法の特性は

  • 基本は使用回数に基づくこと
  • 使用回数が急上昇したものほど高スコアを得ること
  • 使用回数が急降下した場合でも下落はある程度緩やかにすること

です。

PRのページ(#109, #119)を見ていただければ今までの議論と数値化の仕様の変遷が追えると思いますので、今までの変遷の話は割愛しますが、最初は現在の方法とは違う方法で算出していました。

線形回帰を使ってみたり、ニューラルネットに落とし込んだりできないか考えてみたりと色々試行錯誤をしていく中で、トレンドタグを"ハッシュタグの需要"と考えることで"需要予測"の手法が使えるのではないかという着想を得ました。

その中で二重指数平滑法という手法を用いることで、上述の要求を満たす数値化が可能になりました。

二重指数平滑法について簡単に説明すると、

  • 水準関数トレンド関数という2つの関数の返す値の合計をスコアとする
  • 水準関数は前回集計時のスコア(予測値) と、今回集計時の使用回数(実績値) の加重平均を計算する
  • トレンド関数は与えられたパラメータに基づいて使用回数が上昇していく局面では正の値使用回数が下降して行く局面では負の値を返すことでスコアを補正する。

しかし、スコア自体が負の値にはなってほしくないので、トレンド関数について使用回数が下降して行く局面で返す値を0とすることでスコアが必ず正の値になるようにした上、使用回数が急降下した場合でも下落はある程度緩やかにすることという要求をよく満たすようになりました。

im@stodonのトレンドタグのスコアは需要予測の結果であり、つまり次の集計期間における当該タグの使用回数の予測になっています。予測としての精度は低いですが、トレンドの数値化としてはある程度満足できる結果が得られていると思います。

もっと良いトレンドの数値化手法があるぞ!というのはいつでも募集中ですのでお願いします。

いつ集計してどうやって発表する?

集計に関しては、ちょっとした工夫があります。

アイドルマスターの関連番組は30分番組が多いため、集計期間は30分だと長すぎるということで10分ごとに集計しています。

さらに、アイドルマスターの関連番組は0分開始・30分開始が多いため、単純に毎時0分,10分,20分,...に集計すると番組開始と同時に集計されてしまい、番組が始まったのにあまり盛り上がりが反映されず、番組終了と同時に集計されてしまうため集計では盛り上がっているのに番組は既に終わっているということが起こってしまいます。

よって、集計は毎時5分,15分,25分,...に行うことにしました。

定時ジョブの管理にはこれもMastodonで以前から使われていたSidekiq Schedulerを使用しています。

発表の仕方はまだ模索中です。

一応自由に取得して使えるようにAPIを用意しましたが、WebUIに常設で表示させるかどうかという点については検討中です。

現在は自分のデスクトップPCBotを動かして10分おきに集計結果を投稿しています。

最後に

以上、自分の今年のMastodonに関する活動のまとめと、トレンドタグ機能の詳細でした。

DBからデータを取ってきて処理してAPIに出すというWebサービスとしては基本的なことですが、自分で1機能をほぼ全部作ったのは初めてなので非常にいい経験になりました。

トレンドタグ機能についてレビューやリファクタリングをしてくださったフサギコさん・ななせさん・猫ロキさん・りんすきさん、およびim@stodon上でいろいろな意見をくださったPのみなさんにあらためて感謝申し上げます。

まだまだim@stodonの改善や機能追加をやっていきたいと思っていますので、来年もよろしくお願いします。来年...4年次...就活...卒論...ウッ頭が

あ、ついでに、今「アイドルマスターミリオンライブ シアターデイズ」内で行われているドラマ配役投票では、ぜひ「テーマ2 "三姉妹カフェ" の "次女" 」役に「最上静香」で投票お願いします!

次へ

ここを書いている時点で23時17分です。。。大変申し訳ない。

明日の記事はitsumonotakumiさん「ユーザーの立場から見るマストドン」と、Ki4TheMechanicさん「しむどん(@sximada)独占インタビュー PART.3」です。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment