「これを買っている人はこれも買っています」実装してみた php side

72
「これを買っている人はこれも買っています」 実装してみた デジタルサーカス(株)長谷川智希 side

Upload: tomoki-hasegawa

Post on 11-Apr-2017

614 views

Category:

Software


0 download

TRANSCRIPT

Page 1: 「これを買っている人はこれも買っています」実装してみた PHP side

「これを買っている人はこれも買っています」 実装してみた

デジタルサーカス(株)長谷川智希

side

Page 2: 「これを買っている人はこれも買っています」実装してみた PHP side

長谷川智希とも き

@tomzohとむぞう

趣味 Webサイト開発, iOSアプリ開発レンタルカートレース, ビール, 電子工作 (mbed), …

TOMZOH

デジタルサーカス(株)副団長CTO

Facebook CakePHP iOS

Page 3: 「これを買っている人はこれも買っています」実装してみた PHP side

デジタルサーカス(株)

・Webサイト開発

・スマホアプリ開発

・自社サービス

( )

(iOS, Android)

(http://appbuilder.jp)

Twitter: @tomzoh

Page 4: 「これを買っている人はこれも買っています」実装してみた PHP side

Twitter: @tomzoh

Page 5: 「これを買っている人はこれも買っています」実装してみた PHP side

今日のテーマ:

「これを買っている人はこれも買っています」 実装してみた

side

Page 6: 「これを買っている人はこれも買っています」実装してみた PHP side

Toby Segaran 著 當山 仁健、鴨澤 眞夫 訳

出版社: オライリージャパン 2008年07月 発行 392ページ ISBN978-4-87311-364-7

http://www.amazon.co.jp/dp/4873113644

Page 7: 「これを買っている人はこれも買っています」実装してみた PHP side

2章 推薦を行う

「この映画に高い評価をした人は、こんな映画にも高い評価をしています。」のアルゴリズム。

・自分に似ている人は誰か ・この映画に似ている映画は何か

Page 8: 「これを買っている人はこれも買っています」実装してみた PHP side

# 映画の評者といくつかの映画に対する彼らの評点のディクショナリcritics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 'The Night Listener': 3.0},'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 'You, Me and Dupree': 3.5},'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0, 'Superman Returns': 3.5, 'The Night Listener': 4.0},'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5, 'Superman Returns': 4.0, 'You, Me and Dupree': 2.5},'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0, 'You, Me and Dupree': 2.0},'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns’:4.0}}

Page 9: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 10: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 11: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 12: 「これを買っている人はこれも買っています」実装してみた PHP side

やりたいこと

・ 「このリポジトリにスターした⼈はこんなリポジトリにもスターしています」

・ ⾒ると嬉しいであろうリポジトリをお勧めしてくれるシステム!

Page 13: 「これを買っている人はこれも買っています」実装してみた PHP side

推薦: 2つの⽅法

(1)⾃分に似たユーザを探して、そのユーザがスターしているリポジトリを推薦する。

(2)⾃分がスターしているリポジトリについて、似たリポジトリを探して推薦する。

Page 14: 「これを買っている人はこれも買っています」実装してみた PHP side

「似ている」

どうやって「似ている」と判断するか。

Page 15: 「これを買っている人はこれも買っています」実装してみた PHP side

「似ている」

どうやって「似ている」と判断するか。

「似ている」 = 「近い」

Page 16: 「これを買っている人はこれも買っています」実装してみた PHP side

ユークリッド距離

63

23

Page 17: 「これを買っている人はこれも買っています」実装してみた PHP side

ユークリッド距離

sqrt((6-3)^2 + (2-3)^2) = 3.16…63

23 3.16…

Page 18: 「これを買っている人はこれも買っています」実装してみた PHP side

ユークリッド距離John Steve Tim Philip

The Shawshank Redemption 1 1 2 2

The Man in the Iron Mask 2 1 4 1

ID4 2 3

The Devil Wears Prada 3 5 4

Page 19: 「これを買っている人はこれも買っています」実装してみた PHP side

ユークリッド距離John Steve Tim Philip

The Shawshank Redemption 1 1 2 2

The Man in the Iron Mask 2 1 4 1

ID4 2 3

The Devil Wears Prada 3 5 4

JohnとSteveの距離:

Page 20: 「これを買っている人はこれも買っています」実装してみた PHP side

ユークリッド距離John Steve Tim Philip

The Shawshank Redemption 1 1 2 2

The Man in the Iron Mask 2 1 4 1

ID4 2 3

The Devil Wears Prada 3 5 4

JohnとSteveの距離:sqrt((1-1)^2 + (2-1)^2 + (2-0)^2 + (3-5)^2))

Page 21: 「これを買っている人はこれも買っています」実装してみた PHP side

ユークリッド距離John Steve Tim Philip

The Shawshank Redemption 1 1 2 2

The Man in the Iron Mask 2 1 4 1

ID4 2 3

The Devil Wears Prada 3 5 4

JohnとSteveの距離:sqrt((1-1)^2 + (2-1)^2 + (2-0)^2 + (3-5)^2))

( - )^2 +( - )^2 +( - )^2 +( - )^2

Page 22: 「これを買っている人はこれも買っています」実装してみた PHP side

John Steve Tim Philip

John - 3 4.2 2

Steve * - 5.9 3.3

Tim * * - 5.8

Philip * * * -

Page 23: 「これを買っている人はこれも買っています」実装してみた PHP side

John Steve Tim Philip

John - 3 4.2 2

Steve * - 5.9 3.3

Tim * * - 5.8

Philip * * * -

John Steve Tim Philip

John - 3 4.2 2

Steve * - 5.9 3.3

Tim * * - 5.8

Philip * * * -

TimにはJohnが⾒た映画を推薦すれば良さそう

Page 24: 「これを買っている人はこれも買っています」実装してみた PHP side

John Steve Tim Philip

The Shawshank Redemption 1 1 2 2

The Man in the Iron Mask 2 1 4 1

ID4 2 3

The Devil Wears Prada 3 5 4

Page 25: 「これを買っている人はこれも買っています」実装してみた PHP side

John Steve Tim Philip

The Shawshank Redemption 1 1 2 2

The Man in the Iron Mask 2 1 4 1

ID4 2 3

The Devil Wears Prada 3 5 4

John Steve Tim Philip

The Shawshank Redemption 1 1 2 2

The Man in the Iron Mask 2 1 4 1

ID4 2 3

The Devil Wears Prada 3 5 4

Page 26: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 27: 「これを買っている人はこれも買っています」実装してみた PHP side

良い映画ですよね😇

Page 28: 「これを買っている人はこれも買っています」実装してみた PHP side

観てない?

Page 29: 「これを買っている人はこれも買っています」実装してみた PHP side

http://www.amazon.co.jp/dp/B0083RQI0S

BUY NOW

Page 30: 「これを買っている人はこれも買っています」実装してみた PHP side

話を戻して…

Page 31: 「これを買っている人はこれも買っています」実装してみた PHP side

推薦: 2つの⽅法

(1)⾃分に似たユーザを探して、そのユーザがスターしているリポジトリを推薦する。

(2)⾃分がスターしているリポジトリについて、似たリポジトリを探して推薦する。

Page 32: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 33: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 34: 「これを買っている人はこれも買っています」実装してみた PHP side

⭐ Repo88,811 twbs/bootstrap

45,137 vhf/free-programming-books

44,106 angular/angular.js

43,279 mbostock/d3

37,667 nodejs/node-v0.x-archive

36,648 jquery/jquery

31,681 h5bp/html5-boilerplate

31,461 FreeCodeCamp/FreeCodeCamp

31,080 facebook/react

29,881 robbyrussell/oh-my-zsh

29,651 meteor/meteor

29,413 github/gitignore

28,336 rails/rails

27,248 torvalds/linux

27,111 Homebrew/homebrew

Page 35: 「これを買っている人はこれも買っています」実装してみた PHP side

User mvied dcwatson christophwille rpoisel victoriafrench runcom brynary marceloemanoel ysrb Caged anotherjesse kevwil rsanheim BrianTheCoder lancecarlson kvnsmth josh

⭐ Repo88,811 twbs/bootstrap

45,137 vhf/free-programming-books

44,106 angular/angular.js

43,279 mbostock/d3

37,667 nodejs/node-v0.x-archive

36,648 jquery/jquery

31,681 h5bp/html5-boilerplate

31,461 FreeCodeCamp/FreeCodeCamp

31,080 facebook/react

29,881 robbyrussell/oh-my-zsh

29,651 meteor/meteor

29,413 github/gitignore

28,336 rails/rails

27,248 torvalds/linux

27,111 Homebrew/homebrew

Page 36: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHubのデータ数

Page 37: 「これを買っている人はこれも買っています」実装してみた PHP side

リポジトリ 約1千400万

Page 38: 「これを買っている人はこれも買っています」実装してみた PHP side

リポジトリ 約1千400万 ユーザ 約1千600万

Page 39: 「これを買っている人はこれも買っています」実装してみた PHP side

mvied dcwatson rpoisel ysrb

twbs/bootstrap

vhf/free-programming-books

angular/angular.js

:

⭐ ⭐

⭐ ⭐⭐

Page 40: 「これを買っている人はこれも買っています」実装してみた PHP side

mvied dcwatson rpoisel ysrb

twbs/bootstrap

vhf/free-programming-books

angular/angular.js

:

ユーザ 約1千600万

⭐ ⭐

⭐ ⭐⭐

Page 41: 「これを買っている人はこれも買っています」実装してみた PHP side

mvied dcwatson rpoisel ysrb

twbs/bootstrap

vhf/free-programming-books

angular/angular.js

:

ユーザ 約1千600万リポ

ジトリ

約1千

400万

⭐ ⭐

⭐ ⭐⭐

Page 42: 「これを買っている人はこれも買っています」実装してみた PHP side

リポジトリとリポジトリの距離を計算 (14,000,000 x 14,000,000 - 14,000,000) / 2 = 100兆回の組合せ計算 計算1回あたり 16,000,000回の2乗計算

mvied dcwatson rpoisel ysrb

twbs/bootstrap

vhf/free-programming-books

angular/angular.js

:

ユーザ 約1千600万リポ

ジトリ

約1千

400万

⭐ ⭐

⭐ ⭐⭐

Page 43: 「これを買っている人はこれも買っています」実装してみた PHP side

リポジトリとリポジトリの距離を計算 (14,000,000 x 14,000,000 - 14,000,000) / 2 = 100兆回の組合せ計算 計算1回あたり 16,000,000回の2乗計算

mvied dcwatson rpoisel ysrb

twbs/bootstrap

vhf/free-programming-books

angular/angular.js

:

ユーザ 約1千600万リポ

ジトリ

約1千

400万

⭐ ⭐

⭐ ⭐

😱つらい

Page 44: 「これを買っている人はこれも買っています」実装してみた PHP side

じゃあどうしたか

Page 45: 「これを買っている人はこれも買っています」実装してみた PHP side

リポジトリ ⭐ スターを付けたユーザの一覧

twbs/bootstrap 88,811 mvied dcwatson ysrb …

vhf/free-programming-books 45,137 mvied dcwatson rpoisel …

angular/angular.js 44,106 dcwatson ysrb …

:

Page 46: 「これを買っている人はこれも買っています」実装してみた PHP side

リポジトリ ⭐ スターを付けたユーザの一覧

twbs/bootstrap 88,811 mvied dcwatson ysrb …

vhf/free-programming-books 45,137 mvied dcwatson rpoisel …

angular/angular.js 44,106 dcwatson ysrb …

:

リポジ

トリ35

0件 ☆

6,700

以上

ぐらい

Page 47: 「これを買っている人はこれも買っています」実装してみた PHP side

リポジトリ ⭐ スターを付けたユーザの一覧

twbs/bootstrap 88,811 mvied dcwatson ysrb …

vhf/free-programming-books 45,137 mvied dcwatson rpoisel …

angular/angular.js 44,106 dcwatson ysrb …

:

リポジ

トリ35

0件 ☆

6,700

以上

ぐらい

ユーザ 最⼤88,811

Page 48: 「これを買っている人はこれも買っています」実装してみた PHP side

リポジトリ ⭐ スターを付けたユーザの一覧

twbs/bootstrap 88,811 mvied dcwatson ysrb …

vhf/free-programming-books 45,137 mvied dcwatson rpoisel …

・ スターを付けている: 1 付けていない: 0

・ リポジトリ間のユークリッド距離を計算

Page 49: 「これを買っている人はこれも買っています」実装してみた PHP side

twbs/bootstrap vhf/free-programming-books angular/angular.js …

twbs/bootstrap - 0.01904850 0.00492629

vhf/free-programming-books * - 0.00492461

angular/angular.js * * -:

ユークリッド距離

Page 50: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHub recommenderhttp://ghrec.hasegawa-tomoki.com

・ GitHubのユーザ名を⼊⼒するとおすすめリポジトリを表⽰

・ APIで⭐を付けているリポジトリ取得 → そのリポジトリに似ているリポジトリを推薦

Page 51: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 52: 「これを買っている人はこれも買っています」実装してみた PHP side

アーキテクチャ

Page 53: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHubのユーザ名

Page 54: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHub recommenderhttp://ghrec.hasegawa-tomoki.com

Page 55: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHub recommenderhttp://ghrec.hasegawa-tomoki.com

・ 取得: ⭐数上位6,800リポジトリ

Page 56: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHub recommenderhttp://ghrec.hasegawa-tomoki.com

・ 取得: ⭐数上位6,800リポジトリ

・ 計算: ⭐数上位350リポジトリ

Page 57: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHub recommenderhttp://ghrec.hasegawa-tomoki.com

・ 取得: ⭐数上位6,800リポジトリ

・ 計算: ⭐数上位350リポジトリ

・ 計算量ナメてて間に合わなかった

Page 58: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHub recommenderhttp://ghrec.hasegawa-tomoki.com

・ 取得: ⭐数上位6,800リポジトリ

・ これが O(n^2) というやつか…

・ 計算: ⭐数上位350リポジトリ

・ 計算量ナメてて間に合わなかった

Page 59: 「これを買っている人はこれも買っています」実装してみた PHP side

わかったこと・ APIでデータを取るのにすごく時間がかかる。 ・ リポジトリ間の距離を計算するのにすごく時間がかかる。 ・ このクラスの計算量になると最初からまじめにプログラム

をチューニングしないといつまでたっても終わらない。 ・ memcachedの圧縮は素晴らしい。 ・ 超簡単な割にそれなりにそれっぽい結果が出るので楽

しい。

Page 60: 「これを買っている人はこれも買っています」実装してみた PHP side

おまけ

Page 61: 「これを買っている人はこれも買っています」実装してみた PHP side

どの程度「それらしい」か

Page 62: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 63: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 64: 「これを買っている人はこれも買っています」実装してみた PHP side
Page 65: 「これを買っている人はこれも買っています」実装してみた PHP side

切り出したい!

Page 66: 「これを買っている人はこれも買っています」実装してみた PHP side

GitHub API・ 時間あたりの利⽤可能数が制限されている。

・ レイテンシは1秒ぐらい。

・ 全てのレコードが取得できる訳では無い。 ・ ページ数を指定して取得することになるけど「これ以上は取れないよ」とレ

スポンスが帰ってくる。

・ 「リポジトリをスター数の降順で」は結構⾯倒。 ・ 検索条件にリポジトリ作成⽇時、スター数を⼊れて複数回コール。

Page 67: 「これを買っている人はこれも買っています」実装してみた PHP side

⭐を取得するAPI

https://api.github.com/repos/twbs/bootstrap/stargazers

Page 68: 「これを買っている人はこれも買っています」実装してみた PHP side

⭐を取得するAPI

https://api.github.com/repos/twbs/bootstrap/stargazers

Page 69: 「これを買っている人はこれも買っています」実装してみた PHP side

⭐を取得するAPI

https://api.github.com/repos/twbs/bootstrap/stargazers

Page 70: 「これを買っている人はこれも買っています」実装してみた PHP side

こういうのを作って 計算状況がわかる様にすると 精神衛⽣上良い。

Page 71: 「これを買っている人はこれも買っています」実装してみた PHP side

2次会やります!

この近くのシャレオツな(?) お店で終電前まで

Page 72: 「これを買っている人はこれも買っています」実装してみた PHP side

ありがとうございました

@tomzoh

デジタルサーカス(株)

Drupal & スマホエンジニア

絶賛 募集中!