Twitter社のソースコードが公開されたので
早速覗いてみました

解説動画はこちら


 
Twitter社のソースコードが
Githubにオープンソースとして公開されましたね

Twitterのgithub

今回公開されたのは
レコメンドアルゴリズム
だそうです

自分もフリーランスで
レコメンドエンジンを開発したりしていますが
非常に興味深いものです

今回は彼らの技術ブログの内容も併せて
解説していきたいと思います
Twitterの技術ブログ



レコメンドアルゴリズム

公式ブログによれば
「おすすめ」タイムラインに表示されるツイートは
次の3段階のプロセスを経て決定されているようです

system-diagram

1.Fetch the best Tweets from different recommendation sources in a process called candidate sourcing.

2.Rank each Tweet using a machine learning model.

3.Apply heuristics and filters, such as filtering out Tweets from users you’ve blocked, NSFW content, and Tweets you’ve already seen.

1.`candidate sourcing`と呼ばれる機能で
様々な基準から個人に対して
最適なツイート候補を抽出する

2.機械学習モデルによって
それぞれのツイート候補をランク付けする

3.有害なツイートを除外したりする
フィルタリングを行なって出力候補を決める


この辺りは一般的なレコメンドエンジンにも
適用出来る内容であるかなと思います



それぞれの詳細を見ていきましょう



1.ツイート候補の抽出

Twitter自体はすごいユーザー数がいます
その中からユーザーにとって最適なツイートを
表示させるのは大変です

そこでまず初めにツイート全体から
各個人への候補を絞り込みが行われています


この機能では数億のツイートから
1500ツイートが抽出されているようです

・フォローしているユーザー(ネットワーク内)から50%
・フォローしてないユーザー(ネットワーク外)から50%

ネットワーク内のソースは
Real Graph(リアルグラフ)と呼ばれる
ユーザー間のエンゲージメントを予測するモデルで
計算されているようです

このReal Graph が高いほど
より多くツイートが候補に含まれるようです


次にネットワーク外のソースは
Social Graph(ソーシャルグラフ)と
Embedding Spaces(埋め込みスペース)
と呼ばれるアプローチ方法を採用しているようです


Social Graph(ソーシャルグラフ)は
フォローしている人々が最近エンゲージしたツイート
似たツイートを気に入った人は誰か、というような
計算されたツイート候補を生成しています(15%)


Embedding Spaces(埋め込みスペース)

ユーザーの関心とツイートコンテンツの
類似性を計算したものです


SimClusters:
行列分解アルゴリズム
(custom matrix factorization algorithm)

ユーザーとツイートをコミュニティ空間で表現し
ユーザーは複数のコミュニティに属する
各コミュニティでのツイートの
現在の人気度を調べて結果を埋め込むようです

これらのアルゴリズムを用いて
ツイート候補を絞り込みするのが第一段階です



2.機械学習モデルのランク付け

HEAVY RANKER と呼ばれる
ニューラルネットワークで構成された
スコア計算機を使っています

前段から抽出したデータを基にした特徴量や
重み付の設定からツイートのスコアを計算しています

現在の重み付けとしては
scored_tweets_model_weight_fav: 0.5
scored_tweets_model_weight_retweet: 1.0
scored_tweets_model_weight_reply: 13.5
scored_tweets_model_weight_good_profile_click: 12.0
scored_tweets_model_weight_video_playback50: 0.005
scored_tweets_model_weight_reply_engaged_by_author: 75.0
scored_tweets_model_weight_good_click: 11.0
scored_tweets_model_weight_good_click_v2: 10.0
scored_tweets_model_weight_negative_feedback_v2: -74.0
scored_tweets_model_weight_report: -369.0

「いいね」される:0.5
ツイートをリツイートされる:1.0
ツイートを開き、リプライまたは「いいね」される:13.5
プロフィールを確認し、ツイートにまたは「いいね」される:12
リプライに対し、投稿者によって返信または「いいね」またはリツイートされる:75
「このツイートに興味がない」ブロックまたはミュートされる:-74
「ツイートを報告」される:-369

という形で指定されている様です
この辺りも日々変わっているようでが
これらを加味して `0-1` のスコアを計算しています

3.フィルタリング


ツイート候補のスコア付を行ったら
最後にフィルタリングを行って
最終的な出力ツイートを選出します

home-mixer と呼ばれる
Scalaで書かれたシステムによって
最終候補が決定されています

次のようなフィルタリングが行われているっぽいです

Author Diversity
Content Balance (In network vs Out of Network)
Feedback fatigue
Deduplication / previously seen Tweets removal
Visibility Filtering (blocked, muted authors/tweets, NSFW settings)

著者の多様性
コンテンツ バランス
(ネットワーク内 vs ネットワーク外)
フィードバック疲労
重複除去 / 以前に見たツイートの削除
可視性フィルタリング
(ブロック、ミュートされた作成者/ツイート、NSFW 設定)


主に出力されるツイートのバランスを保ち
見たくないツイートの除外を行なっています



おすすめに載るポイント


ソースから見える、スコアリングの仕組みや
フィルタリングの仕組みから
おすすめに載るポイントとなる点を挙げてみました

この辺りも本日現在のものになり
日々更新されるものなので
最近版はソースを見て下さいね


・フォロー数とフォロワー数の比率

フォロワー数 < フォロー数 は
低く評価される仕組みの様です

フォロワーを増やすか
フォロー数を減らすしかないですね
ExtractTweepcred.scala
reduce pagerank for users with low followers compared to number of followings


・Twitter Blueへの加入

課金ユーザーはフォロワーの「おすすめ」タイムラインで 4倍
非フォロワーのタイムラインでは 2倍 のブーストされるようです

課金しろってことですね
HomeGlobalParams.scala

object BlueVerifiedAuthorInNetworkMultiplierParam
      extends FSBoundedParam[Double](
        name = "home_mixer_blue_verified_author_in_network_multiplier",
        default = 4.0,


object BlueVerifiedAuthorOutOfNetworkMultiplierParam
      extends FSBoundedParam[Double](
        name = "home_mixer_blue_verified_author_out_of_network_multiplier",
        default = 2.0,

・リプライされる

現在のスコア計算の重み付けより
リプライ の重み付けが高いです

リプライされる様なツイートしましょう


・画像や動画をつける

画像や動画などのメディアを含むツイートは
通常のツイートと比較して 2倍 のブースト

画像を付けると良いですね
RelevanceSearchUtil.scala

      tweetHasImageUrlBoost = 2.0,
      tweetHasVideoUrlBoost = 2.0,


・ツイートの評価は時間が経つと下がる仕組み

次の様なソースコードがあります
ranking.thrift

struct ThriftAgeDecayRankingParams {
  // the rate in which the score of older tweets decreases
  1: optional double slope = 0.003
  // the age, in minutes, where the age score of a tweet is half of the latest tweet
  2: optional double halflife = 360.0
  // the minimal age decay score a tweet will have
  3: optional double base = 0.6
}(persisted='true')

360分(6時間)経つとhalflife
ツイートの寿命のようなものが減る様です

なので常に呟いているのが
良いんじゃないかと思います

なお呟きすぎても
同じユーザーのツイートは
除外される仕組みでは有るので
程々にでしょうね


Twitterのような大企業の
ソースコードが垣間見えるのは
我々一般ユーザーにとっても
なかなか興味深いですね

読み込めばもっと
ツイッター攻略出来るかもしれません


今回はここまでです
それでは