乙Py先生のプログラミング教室
初学者のためのプログラミング学習サイト

Twitter

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

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


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

今回はTwitterで出回っていた
電車の中吊り広告にあった
数学の問題をプログラムで解いて見ました。

解説動画はこちら



さて、問題は・・・

GAKKOUの6文字を並び替えてできる
360個の文字列を辞書式に並べるとき
100番目の文字列を求めよ


ということで
マジで難しい!!!

自分如きでは見当もつきません!!

こんな時はプログラムの力を借りて
解いてみることにしましょう。


Pythonでは文字列の組み合わせを作ってくれる
ライブラリがあるのでこれをimportしておきます。
import itertools

まず、データとして文字列を
リスト型で定義しておきます。
s = ['G','A','K','K','O','U']

次に文字列の組み合わせを作ります。
辞書形式ということですが
ここでは重複排除のできるSET型で
文字列の組み合わせを作ります。

itertools.permutations(データ,個数)
で順列を求めることができます。

第一引数は先ほど作った文字列のリスト
この中から6個の文字を取るので
第二引数は6になります。
res = {a for a in itertools.permutations(s,6)}

これで文字列の組み合わせが出来上がったので
最後に並び替えですね。

並び替えはsorted関数が使えます。
リスト形式にしてインデックス値の99番目が
100番目にくる文字列になるはずです。
''.join(list(sorted(res))[99])

答えは

・・
・・・


受験生にとって一番良い答えですね


Python言語はコードを書く量が少なくて済むのが
利点の一つでもあります。

このコードも1行で出来るようにしてみましょう。
こんな感じになりました。
import itertools;sorted({''.join(r) for r in itertools.permutations('GAKKOU',6)})[99]

はい

他の言語でもだいたいは1行でいけちゃいますね。
どの言語が書く文字数が少ないのか
調べて見たいものですね。

プログラムできる方は
是非考えて見て下さい。


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

このページのトップヘ