こんにちは、minne 事業部エンジニアの @keokentt です。今回はペパボ研究所と共同で minne のとあるコンテンツの改修をしましたので、その取り組みをご紹介をさせていただきます。
はじめに
ペパボ研究所とは
ペパボ研究所(略称「ペパ研」)は、事業を差別化できる技術を作り出すために「なめらかなシステム」というコンセプトの下で研究開発に取り組む組織です。アカデミックな水準における新規性・有効性・信頼性を追求する研究を行うとともに、研究開発した技術を実際のシステムとして実装・提供することを通して、事業の成長に貢献します。
このままの通りで部署・サービスを横断して問題の解決、事業を差別化できる技術を作り出す凄腕エンジニアが所属している部門です。
解決したい課題
CtoCのハンドメイドマーケットとしてユーザが求める作品と出会いやすくすることは尽きることのない課題といえます。ユーザが関心のありそうな作品を次々に提示することにより、ユーザが求める作品と出会える確率を上げることができます。ここで重要となるのは「ユーザが関心のありそうな作品」を導き出す手法です。既に minne には作品の購買履歴・お気に入り等の情報から導き出した作品を関連作品として提示するコンテンツが存在します。今回、さらに作品と出会える確率を上げるべく「その作品に類似した画像を持つ作品」を関連する作品として提示するようにコンテンツを生まれ変わらせることにしました。
類似画像による関連作品検索システム
「その作品に類似した画像を持つ作品」をどのように抽出するかについては、ペパボ研究所の三宅研究員(@monochromegane)が研究を行い、類似画像による関連作品検索システムを開発しました。システムの詳細は論文・発表資料をあわせて見ていただくと良いと思います。
特徴抽出器の学習と購買履歴を必要としない類似画像による関連商品検索システム [論文] [発表資料]
システムを minne へ導入するにあたり、三宅研究員と minne エンジニアで以下のように作業を分担しました。
三宅研究員: 類似画像による関連作品検索システムを構築する(1~2)
minne エンジニア: 類似画像による関連作品検索システムを minne で利用する(3~5)
- 作品画像を特徴量に変換するモデルを構築する
- 特徴量を近似近傍探索データベース・APIサーバを構築する
- 作品画像をRGB値の配列に変換する
- RGB値の配列を2048次元の特徴量に変換する
- 近似近傍探索APIサーバを参照し、類似画像作品のIDを取得する
1. 作品画像を特徴量に変換するモデルを構築する
深層畳み込みニューラルネットワークの Inception-v3 モデルにおける識別層直前のプーリング層(Pool3)を特徴抽出器として利用します。詳しくは三宅研究員の論文の第3章3.1節「学習済ネットワークの選定と特徴量変換の実装」を御覧ください。
この画像を特徴量に変換するモデルを Google Cloud ML Engine 上に構築し、minne からAPIとして利用できるように公開します。
2. 特徴量を近似近傍探索データベースとAPIサーバを構築する
近似近傍探索ライブラリである Annoy を利用し、特徴量と作品のIDを近似近傍探索データベースに保存します。さらに近似近傍探索データベースをHTTPリクエスト経由で扱えるように mruby-annoy, と ngx_mruby を利用して近似近傍探索APIサーバを構築しています。
詳しくは三宅研究員の論文の第3章3.2節「類似特徴量検索の実装」を御覧ください。
3. 作品画像をRGB値の配列に変換する
1
で構築されたAPIは array[画像の縦サイズ][画像の横サイズ][RGB(0~255の値が3個)] の配列を入力値として受け付けています。minne では RMagick を利用して作品画像をRGB値に変換します。
blob = open('作品画像URL').read
image = Magick::Image.from_blob(blob).first
columns = image.columns # 横
rows = image.rows # 縦
rgb_values = (0...rows).inject([]) do |row_values, row|
row_values[row] = (0...columns).inject([]) do |column_values, column|
pixel = image.pixel_color(row, column)
column_values << [pixel.red, pixel.green, pixel.blue].map { |value| 255 * value / QuantumRange }
end
row_values
end
4. RGB値の配列を2048次元の特徴量に変換する
3
のRGB値の配列をHTTPクライアント経由で1
で公開されたAPIにPOSTリクエストします。レスポンスから得られる特徴量は以下のような2048次元の浮動小数点数のベクトルとなっています。
irb(main):000:0> features = response.body['feature'].flatten
=> [0.1661113053560257,
0.08008259534835815,
0.30703088641166687,
0.20111140608787537,
0.03168810158967972,
0.31271618604660034,
0.0,
0.06877624988555908,
0.0563560426235199,
1.57260262966156,
.
.
.
0.3343021273612976,
0.0]
irb(main):001:0> features.size
=> 2048
5. 近似近傍探索APIサーバを参照し、類似画像作品のIDを取得する
近似近傍探索データベースは作品のカテゴリごとにデータベースが分かれているので「作品のカテゴリに対応したデータベース名」と「作品のID」をパラメータとして近似近傍探索APIにGETリクエストすることで類似画像作品のIDを取得できます。
以下、近似近傍探索APIクライアントのメソッドを実行し、類似画像作品のIDを取得している例です。
irb(main):000:0> response = NnsClient.search(database: '作品のカテゴリに対応したデータベース名', key: '作品のID', limit: 10)
irb(main):001:0> response.body
=> [3475357, 3475503, 3475414, 4662897, 3475602, 3475224, 5798066, 3945581, 2857902, 6281249]
性能評価
ここまででご紹介した類似画像による関連作品検索システムにより抽出した「その作品に類似した画像を持つ作品」を関連作品としてユーザへ提示します。
minne にはすでに別のロジックで関連作品を提示している「この作品を見ている人におすすめ」のコンテンツがあります。このコンテンツを A: 従来のロジック, B: 類似画像による関連作品検索システムとして A/B テストをしました。
対象の作品「コーヒードリッパースタンド ナラ(ポット用)」
A: 従来のロジック | B: 類似画像による関連作品検索システム |
---|---|
Aパターン、Bパターンの CTR, CVR はそれぞれ以下のよう結果となりました。
A | B | |
---|---|---|
CTR | 0.51% | 0.76% |
CVR | 0.21% | 0.28% |
カテゴリで絞り込んで計測をするとAパターンの方が数値が良いカテゴリもありましたが、概ねBパターンの方が良い結果となりました。 性能評価については三宅研究員の論文の第4章「実験と考察」に詳しく記載がありますので、そちらも御覧ください。
まとめ
今回はペパ研と共同で minne に導入した類似画像による関連作品検索システムについてご紹介しました。コンテンツを生まれ変わらせたことにより、数値が下がったカテゴリはあるものの全体として CTR・CVR を向上させることができました。
現在はある時点での作品情報のみを利用して近似近傍探索データベースを作成したため、新しい作品の関連作品検索ができない、新しい作品を関連作品の結果に含めることができないといった問題があります。近似近傍探索データベースの随時更新については現在開発を進めています。
これからさらにペパ研と協力して事業を差別化する技術を取り入れ、ユーザに新しい価値を提供していきたいと思います。
おまけ
類似画像による関連作品検索システムを導入するにあたり、minne 事業部のメンバー数名と三宅研究員で島根県松江市に開発合宿に行ってきました。
※ 松江市が取り組まれている「お試しサテライトオフィス」を体験する目的も含まれています。
開発合宿の形を取ることで日頃の業務から離れ、開発のみに集中できました。 また普段は東京と福岡で離れて仕事をしている minne 事業部メンバーと三宅研究員ですが、同じ空間で開発を行うことにより円滑な知識の共有とコミュニケーションを取ることができました。
新しい施策や大きめの案件を進めるときには積極的に開発合宿をしていきたいと思いました。
※ あくまで開発合宿です