『食べログ独自の評価基準』の機械学習による再現を試みる

はじめに

 以前の記事に関しては本当にたくさんの反響があり、多くのコメント・ご指摘をいただきました。皆様ありがとうございます。

 この問題の経緯から詳細まで、総まとめの記事がYahooニュースに上がっていたので、ここで紹介しておきます。

https://news.yahoo.co.jp/byline/inoueakito/20191012-00146614/

 この記事(とそれに先行した解析)では、口コミ総数が100以下の店舗も収集対象にしています。さらに、口コミ件数で足切りを行うことで、評価点数の分布に壁(上限)が生じることを示しています。

 以上の結果から、食べログが行っているであろう点数の操作はいわばスパムフィルター的なものであり、点数操作の不正に対処するためのアルゴリズムでなのではないかと述べています。めちゃくちゃ納得しました。

 これでこの問題も終わり!

(前略)ここで問題にしたいのは、つまり、公開データをもとに、ある程度まで食べログ点数を算出する近似計算ができたのなら、食べログは不正をしていない可能性が十分にあるということをある程度まで示せるだろうということです。食べログ内で公開されているパラメーターを可能な限りすべて取得して、Deep learning的なものに放り込めば、公開情報をもとに食べログの公正性を検討することは可能かもしれません。

 …と思っていましたが、機械学習の練習がてら食べログ評価基準の再現をやってみることにします。

(ただし、Deep Learningは使いません)

前置き

 今回の目的は『食べログが不正をしているかどうかを検証する』ことではありません

 本記事の目的は、ネット上で公開されているデータだけから、食べログの評価点を再現する機械学習モデルを構築することです。

収集対象となる店舗の設定

 以前の記事で収集した、全国47都道府県のレビュー総数100以上の店舗6852件、加えて前回収集を忘れていた埼玉の139件を加えた総6991件から機械学習のデータを収集します。(コメントでのご指摘ありがとうございました)

 この全店舗の評価点と、レビュー件数をプロットしたものが以下になります。

f:id:konkon3249:20191015224919p:plain

Fig.1 収集対象の全店舗の評価点とレビュー件数の分布

 このうちの一部、1980店舗機械学習に用いました。一部に分けた理由は、全部取ってくると3.50~3.75あたりにデータが密集してしまうからです。あと、新しく収集するのがめんどくさかった。

 実際に収集するデータの分布は以下の通りです。

f:id:konkon3249:20191015225906p:plain

Fig.2 機械学習のためにデータを収集した店舗の分布

 収集するデータはその店舗を対象とした全口コミと、口コミを投稿したユーザーの情報(過去の投稿数,フォロワー数)、および投稿日時です。

収集したデータの確認

ユーザー評価のヒストグラム

 機械学習に移る前に、収集したデータの確認をします。

 まずは、ユーザー評価点の分布です、食べログ評価点の分布とどのように異なっているでしょうか。

 0.1点刻み(ユーザー評価の最小単位)で作成したヒストグラムは以下のようになります。

f:id:konkon3249:20191015232943p:plain

Fig.3 ユーザー評価点の分布

 左がランチの評価、右がディナーの評価です。それぞれの評価の総数はランチが494336、ディナーが50133件です。

 まずわかるのは、0.5点刻みでレビュー件数がけた違いに増えることです。食べログユーザーは、明らかにキリのいい点数をつけたがる傾向にあります。その気持ちわかる。

 0.5点刻みの部分だけを見れば、ユーザー評価は低評価側に裾が重いものの、正規分布のように見えます。しかし、0.1点刻みで見てみると、食べログ評価のヒストグラムに類似した3.8点付近の壁があることもわかります。

 (今は2つに分けましたが、今後はディナーとランチの評価は平均を取ってユーザーの点数とします)

ユーザー評価平均と食べログ評価点の差異

 食べログでは、店の評価はユーザー評価の平均ではないことが公式から発表されています。

点数・ランキングについて[食べログ]

 では、実際にどのくらい違うのでしょうか。収集したデータから可視化してみます。

f:id:konkon3249:20191016000202p:plain

Fig. 4 食べログ評価点とユーザの平均評価点の分布

 Y軸がユーザーの平均評価点、X軸が食べログの評価点、そしてプロットの色が評価の総数を表しています。

 この図では、右上へ延びる直線に近い点ほど、点数の誤差が小さいことを示しています。食べログ評価と平均評価点の平均絶対誤差は0.1168、二者の相関を表す決定係数(R2)は0.6509となりました。

 また、誤差の分布はほぼ対称的であり、特に食べログの評価点がどちらかに寄る、といった傾向はないことが分かります。このことは、誤差の分布を見ることではっきりします。

f:id:konkon3249:20191015235756p:plain

Fig.5 食べログ評価と平均評価の差の分布

 誤差の分布は、0を中心とした対称な分布となっています。

 また、FIg. 4の色に注目すると、食べログ評価点3.7あたりを境にユーザー評価件数が増加していることが分かります。これは、前述の記事で示されている口コミ数に対応したフィルターの存在を示唆しています。

各店舗の特徴量抽出

 それでは、収集したユーザ評価と、対応したユーザーの過去の投稿数と投稿日時を用いて、店舗ごとの特徴量を作成していきます。

f:id:konkon3249:20191016001735p:plain

Fig. 6 ある店舗のユーザー点数と対応したユーザーの過去の投稿数

 上の図は、ある店舗のユーザー点数と、対応したユーザーの過去の投稿数の分布です。点線はそれぞれ食べログの点数とユーザーの平均点数を表しています。

 店舗を代表する特徴量を、過去の口コミ投稿数が多いユーザーの評価がより優先的に反映されるようにするため、ユーザーの過去の投稿数の重みつき平均化を用いて以下のように作成します。

  1. 各点数(0.1刻み, 40個)において、ユーザーの過去の投稿数を重みつき平均化する。
  2. 平均化した値に、その刻みにおける総投稿数を掛ける。
  3. 値の範囲が[0,1]の間に収まるように正規化する。

 以上の方法で作成した特徴量を重ねてプロットした図を以下に示します。

f:id:konkon3249:20191016002330p:plain

Fig. 7 ユーザーの過去の投稿数の重みつき平均化

 この処理を、対象となる1998店舗すべてに行い、特徴量として重み付きの平均投稿数を得ます。以下に、例として25の店舗の分布を示します。

f:id:konkon3249:20191016003908p:plain

Fig. 8 25店舗のユーザー投稿数の分布とその重みつき平均化

 さらに、同様の処理をレビューの新規度(投稿してからの経過日時の逆数)に対しても同様に行います。こちらも最小で1、最大で0となるように正規化します。

f:id:konkon3249:20191016003349p:plain

Fig. 9 投稿の新規度の重みつき平均化

 ここで、重み付き平均を用いた特徴量は値を正規化しているため、口コミ投稿数の情報が入っていません。

 そこで、投稿数を正規化したものを末尾に加えて、合計81次元(40+40+1)のベクトルを作成します。店舗No. 1778の場合、このベクトルは以下のようになります。

f:id:konkon3249:20191016004524p:plain

Fig. 10 店舗no.1778の特徴ベクトル

 この特徴量ベクトルを1998個作成して機械学習に用いました。

機械学習による食べログ評価モデルの再現

 Fig.4, Fig.5の辺りではユーザー評価の平均値と食べログ評価値を比較し、平均絶対誤差は0.1168、決定係数(R2)は0.6509となることを示しました。

 今回は、この誤差を基準とし、機械学習によってどれだけ食べログ評価に近づけられるかを検証します。

 機械学習のモデルには、決定木をベースの分類器としたAdaBoostを用いました。手法に関して詳しくは以下を参照してください。学習にはPythonのscikit-learnを用いています。

Decision Tree Regression with AdaBoost — scikit-learn 0.21.3 documentation

 準備したデータは学習用データとテストデータに8:2で分割し、グリッドサーチで簡単なパラメータ最適化を行いました。その結果得られたパラメータは以下のように なります。

 {'base_estimator': DecisionTreeRegressor(criterion='mse', max_depth=6), 'learning_rate': 1.5, 'n_estimators': 400}

 この条件で学習を行った結果を以下に示します。テストデータに対する食べログ評価値の予測結果です。

f:id:konkon3249:20191016025513p:plain

Fig. 11 食べログ評価点の機械学習による予測結果とユーザー平均の比較

 ユーザーによる点数の平均が青色で、機械学習による予測がピンク色でプロットされています。明らかにユーザー平均よりも誤差が小さくなっていることが分かります。

 点数が高い部分(>4.0)ではあまり予測ができてないように見えますが、これはデータ点が少ないことが原因だと思われます。データ収集の時点で低評価側をある程度絞ったのですが、それでも少なすぎました。

 以下に、テストデータ(396店舗)の平均絶対誤差と決定係数を示します。

  ユーザー平均 機械学習による予測値
決定係数(R2)
0.6550
0.8313
平均絶対誤差(MAE)
0.0672
0.0464

 機械学習にはあまり明るくないのではっきりしたことは言えませんが、そこそこ良くなったのではないでしょうか?

 最後に、ヒストグラムの比較を載せておきます。

f:id:konkon3249:20191016033721p:plain

Fig. 12 ユーザー平均, 予測値のヒストグラム食べログ評価値との比較

 機械学習による予測は、ユーザー平均と比較して食べログ評価と似たようなヒストグラムになっています。しかし、3.8点辺りの分布の変化と、3.6点での数の増大は再現できていないように見えます。

まとめ

 まず、食べログに記載されている店舗の口コミをそれぞれ収集し、その評価点と投稿ユーザーの過去の投稿数、投稿日時、および総口コミ数を用いて店舗ごとの特徴ベクトルを作成しました。

 そしてその特徴ベクトルを用いて機械学習を行い、いわゆる『食べログ独自の評価基準』による採点を再現することを試みました。

 その結果、ユーザーの平均評価よりも、食べログ評価に近い点数を再現する予測器を作ることができました。

 しかしながら、話題になったような食べログ評価の特徴的な部分、3.8点で減り3.6点で増えるような分布を再現することはできませんでした。今後の課題です(やらない)。

最後に

 ちなみに、教師データとして与える店舗ごとの特徴量ベクトルに、その店が有料会員か否かの情報を与えることもできます(非課金 ⇒ 0, 有料会員 ⇒ 1 といった感じ)。

 この会員情報を入れた時と入れなかった時の予測器の性能比較は以下の通り。

  ユーザー平均 予測値(会員情報なし) 予測値(会員情報あり)
決定係数(R2)
0.6550
0.8313
0.8357
平均絶対誤差(MAE)
0.0672
0.0464
0.0458

 ちょっとだけよくなりましたが、ほとんど変わりません。MAEで見ると0.001ぐらいです。食べログ評価点の刻み幅は0.01だからこの差は見えません。

 この結果だけから断定することはできませんが、店舗がお金を払っているかどうかは、やっぱり食べログ評価を定めるにあたって重要な特徴ではなさそうです。

 具体的に課金の有無が点数に及ぼす影響に関してはこちらで詳しく調べられています、気になる方は参照してください。

 もっと教師データの量を増やしたり、店舗を代表するデータの種類を増やしたり、特徴量の取り方を工夫したり、予測器の性能を上げる余地はたくさんあると思いますが、根詰めてやることでもなさそうなのでこれぐらいにします。

 

konkon