セクシー女優の美女ランキングを作ったらいい感じになったからアルゴリズムを紹介する

はじめに
=======

個人開発で、**[Facemish ――みんなで作る、セクシー女優美女ランキング――](https://www.facemish.com)** という超イケてるサービスを作ってしまった。
このサービスの元となったのは、Facebook のルーツとなった、マーク・ザッカーバーグが学生時代に作った Facemash という伝説的サービスだ。その件に関しては、[**以前に投稿した記事**](https://qiita.com/kenta_eros/items/84f2db2257b991b67105)で詳細を書いたため、そちらを読んでいただければと思う。

このサービスは、表示される二人のセクシー女優のうち、どちらの顔がタイプか順に選んでいくゲームである。既に 1000 人以上の多くの人に遊んで頂けているゲーム自体もそれだけで結構楽しいのだが、**このサービスのコア機能は、ゲームを通して集まったユーザの選択実績（いわば投票）によって、セクシー女優の美女度がランキングされるというところなのである**（実質的には、顔の人気ランキングなので、まぁいってしまえば顔ランキング的なものだ）。
なお、ランキングページを閲覧するためには、一回だけゲームをプレイして頂く必要があるが、これは**ゲームの楽しさをなるべく知っていただきたいからであり**、決して悪質な考えのもとゲームをプレイしてもらうわけではないことを申し添えておく。しかし URL 直打ちすればランキングページは誰でも見れるため、ランキングページだけとりあえず見たいという方は **[こちらのリンク](https://www.facemish.com/ranking)** から見て頂ければと思う。
今回は、サービスの中心的機能と言えるこの**美女ランキングのランキングアルゴリズム**について解説する。


開発したサービスの紹介
============

まずは軽くサービスの紹介をば。
多分 **[実際に見ていただいた方が早い](https://www.facemish.com)** ため、ここでは GIF 動画のみ記載する。技術的な詳細などについても、[**以前の記事**](https://qiita.com/kenta_eros/items/84f2db2257b991b67105)に書いたため、興味がある方はそちらを参照されたい。

![facemish_20220317.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2571111/023fad31-c206-bbcd-e0f0-2bd0ae3898e6.gif)


なお、ちょっとエロ系かもしれないと警戒している方には、**プライベートウィンドウでの閲覧を推奨**する。プライベートウィンドウを立ち上げて頂いて、↓ の URL をコピペして頂ければと思う。Chrome であれば、Ctrl + Shift + N 、FireFox であれば Ctrl + Shift + P でプライベートウィンドウはすぐに立ち上がってくれる。ちなみに、**エロいコンテンツは基本的に表示されないようになってるはず**。といいつつ電車の中でエロいのが表示されてしまったら申し訳ない。**ちなみに毎日のようにこのゲームをプレイする私でも、電車の中ではこのサイトは開かない。**

[https://www.facemish.com](https://www.facemish.com)


ランキングアルゴリズム
==================

Facebook の創業時を描いた映画『ソーシャルネットワーク』で、マーク・ザッカーバーグが Facemash というサイト（今回作ったサービスの元になったサービス）を作る際、マークは友人のエドゥアルド・サベリンにこのように言う。

```
"I need the algorithm you used to rank chess players.
 We're ranking girls."
（「君がチェスプレイヤーをランク付けする時に使っていたアルゴリズムが必要なんだ。
　　女の子のランキングを作ってるんだ。」）
```

**これである。まさにこれである**。この後、サベリンは寮の窓に計算式を書き出す。[^algo]

![Screenshot from 2022-03-25 21-43-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2571111/c2441040-d77c-00bf-e6f4-cb62655598a2.png)
![Screenshot from 2022-03-28 10-20-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2571111/2aefbd38-e716-7045-7606-9d8830a49cb3.png)


この数式は、二人のプレイヤー A と B が、対戦の勝ち負けによって、レーティングと呼ばれる「強さを表す数値」がどのように変化するかを示したものだ[^rate]。

実はこの式は、**イロレーティング (Elo rating) という有名なレーティングシステム**の計算式そのものであって、サベリンが考えたアルゴリズムでもなんでもない。[Wikipedia の イロレーティングのページ](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%AD%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0) にも下記の式が掲載されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2571111/07eb7a4c-10ae-72ef-228b-bef80ca93345.png)
（上記 Wikipedia ページより引用）

**しかもだ、サベリンが窓に書き出した数式は、10 の指数であるべき部分が指数表記に読めない点で間違っていると言わざるを得ない。**

まぁそんなことはさておき、**イロレーティングの本質は、2プレイヤーの対戦型のゲームで、強さを表すレーティングから互いの勝利確率を計算し、その勝利確率に基づいて対戦後のレーティングが更新される**という点である。すなわち、

- 強いはずの者と弱いはずの者の対戦であれば、強い方が勝つ確率が高くなる。
    - 強い方が勝てば、対戦後のそれぞれのレーティングの変化は少しであるべき
    - 弱い方が勝った場合は、レーティングの変化は大きくなるべき
    - ただし、一回の対戦には運の要素もあるため、いきなり大きなレーティングの差が逆転するほどの変化でもおかしい
- 同じくらいの実力同士の対戦であれば、勝敗確率は五分五分
    - 勝った方、負けた方はそれぞれある程度のレーティングが変化するべき。

このような自然な考えに基づいたレーティングの計算となる。
イロレーティングは、実際に**国際チェス連盟の公式記録や、サッカーの FIFA ランキング**などにも使われている。

**つまりだ、サベリンがチェスプレイヤーをランク付けする時に考え出したアルゴリズムではなく、国際チェス連盟がプレイヤーのランキングアルゴリズムとして使っていたということだ。**

さあ話を戻そう。$R_A$ のレーティングのプレイヤー $A$ と、 $R_B$ のレーティングのプレイヤー $B$ が対戦したとき、プレイヤー $A$ の勝率 $W_{AB}$ を

```math
W_{AB} = {\frac{1}{10^{(R_B-R_A) / 400} + 1}}
```

とする。その時、対戦後のプレイヤー $A$ のレーティング $R\'_A$ は、

　　　勝った場合
```math
R'_{A} = R_A + K (1 - W_{AB}) 
```
　　　負けた場合
```math
R'_{A} = R_A + K (0 - W_{AB}) 
```
とする。ここで $K$ は定数値で、一般的には 32 が採用されることが多いらしい。$A$ の勝率 $W_{AB}$ が高ければ高いほど、勝った場合のレーティングの増加分は少なく、負けた場合のレーティングの減少分は多くなるといった感じだ。

なお、プレイヤー $A$ の勝率 $W_{AB}$ とプレイヤー $B$ の勝率 $W_{BA}$ には $W_{AB} + W_{BA} = 1$ が成り立つため、それぞれのレーティングの更新は $A$ が勝利した場合には、
```math
R'_{A} = R_A + K \times W_{BA} \\
R'_{B} = R_B - K \times W_{BA}
```

上記の計算式は、弊サービス Facemish の内部でも実際に使われている。ちなみに、Facemish では若干派生したものとなっており、上記のレーティング更新時の係数 $K$ も変数としている。

弊サービス Facemish でのレーティング
-----------------------------------

上記 $K$ が弊サービス上はなんの変数かと言うと、**「どのユーザが投票を行ったか」** ということによって変動する値である。
ユーザさんにも色々な方がいる。セクシー女優さんにも色々な方々がいるのと同様である。**非常に世間一般的な感覚を持った方から、ちょっとマイノリティな好みを持つ方まで様々**だ。
その「好みの軸」を変数としている。すなわち、**より大衆的な好みを持つユーザさんはこの値が高くなり、世間一般とは少し変わった趣味を持った方（いわゆる「ブス専」）は少しこの値が小さくなる**。
これはすなわち、「世間一般とは少し変わった趣味を持った方」がやたらにゲームをプレイして下さり、他のユーザのプレイ数を圧倒するようなこととなった場合に、ランキングがそのユーザさんの趣向に沿ったものになってしまうことを避けるためだ。

この値の算出は簡単で、上記のように各対戦では各プレイヤーの勝率が算出されるため、その**勝率に沿う選び方をするかどうかによって値を変動**させればよい。例えば、勝率が 10% 未満のプレイヤーを何回か連続で選んだ場合、ちょっと世間一般とは変わった趣味であることが分かるため $K$ は小さくなるべきである。逆に、**勝率が高い方を選び続けている場合には、かなり大衆的な好み**を持つユーザさんであることが分かるため $K$ は多少大きくなって然るべき、となる。

細かい計算式はここには掲載しないが（なぜならまだ試行錯誤しているから）、ある程度うまく動作していることは確認済だ。

レーティングの更新はリアルタイムでは行っておらず、現在は日次のバッチで更新している。**更新されるのは基本的に夜22時〜23時頃だ**。ただし、ある程度アクセスがたまってきたら決められたタイミング以外でも手動でバッチを実行するようにしているため、アクセスが多いときには、一日数回の更新がある日もある。

なお、この派生アルゴリズムを自分は **エロレーティング（Ero rating）** と名付け、システムの内部でもその名称を採用している（関数名など）。

ちなみに、ログインしていないユーザさんに関しては、セッションが変わってしまうと同一ユーザであることの確認はできない仕組みになっているおり、そしてログインしていないユーザが大半であるため（こんなクソサービスなので当たり前だ。ただ、お気に入り保存とかは結構いい機能だと思っているので、捨てアカウントを Gmail で作ってログインしてくれてもいいかもしれない。Gmail のアカウント追加は[こちらのページ](https://www.google.co.jp/mail/help/intl/ja/about.html?vm=r)右上の「アカウントを作成」からどうぞ）、実質この $K$ の値はほとんど変動しない。

おわりに
=======

いかがでしたでしょうか。（よくあるアレなページの決まり文句、一回書いてみたかった。）

この記事では、弊サービス Facemish の画期的な美女ランキングのアルゴリズムについて述べた。というか、ほぼイロレーティングの紹介をしただけだ。

ちなみにイロレーティングの上記の説明は全部 Wikipedia に乗っている。つまりイロレーティングの説明は、ただ Wikipedia に乗っている情報を読んで理解してまとめただけだ（いや、そもそも本当に全て理解できているかは怪しい）。
**つまり私はイロレーティングを語っているものの、全く詳しくない。ただエロに詳しいだけである。**

なお、イロレーティングの「イロ」は、このアルゴリズムを考えたアルパド・イロに由来しているらしい。Facemish で使っている派生の**エロレーティングは「エロ」という私の本名（本質）に由来**している。エロレーティングもいつか Wikipedia に記載されることを切に望みながら、この記事の締めとしたい。

長文をお読み頂き、誠にありがたい。実際に **[サービスを訪れて楽しんで頂ければもっとありがたい](https://www.facemish.com)**。
どうかよろしくお頼み申しあげる。

[^algo]: ちなみに計算式を窓に書き出す前、サベリンは "You think this is such a good idea?"（そんなことしてだいじょぶか？）とマークをたしなめる。私にそんなことを言ってくれる友人は、もちろんいない。

[^rate]: 厳密にはこの式はレーティングの変化の計算式ではなく、勝負が始まる際の互いのレーティングに基づく勝利の確率である。