楽天APIで欲しい商品を予算内で最適な商品を求めてみた話

スポンサーリンク
tech系(python)
スポンサーリンク

はじめに

皆さんは楽天APIを使ったことがありますでしょうか?

楽天APIでは商品情報を取得できます。

上手い使い方ができないだろうかと思ってたのですが、ナップザック問題で最適な商品を求められるんじゃないかと思ってやってみました。

ナップザック問題とはナップサックの中にいくつかの品物を詰め込み入れた品物の総価値を最大にするという問題のことです。

楽天APIを使ってみる

まずは、楽天APIを使ってみます。(楽天APIキーの取得方法はググってみてください)

例えば、歯磨き粉の商品一覧を取得するのは以下のようなコードになります。(「xxxxxxxxxx」のところは各自のAPIキーを入れてください)

import requests
import numpy as np
import pandas as pd

REQUEST_URL = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706"
APP_ID="xxxxxxxxxx"

serch_keyword = '歯磨き粉'

serch_params = {
    "format" : "json",
    "keyword" : serch_keyword,
    "applicationId" : [APP_ID],
    "availability" : 0,
    "hits" : 30,
    "page" : 1,
    "sort" : "-updateTimestamp"
}

response = requests.get(REQUEST_URL, serch_params)
data = response.json()
print(data)

これで歯磨き粉の商品情報が30件出てきます。

ナップザック問題で最適解を求めてみる

さて、それでは本題に移ろうと思います。

今回は歯磨き粉以外にも、米とボディソープを買う場合を想定します。

さらに3,000円以内で歯磨き粉と米とボディソープを買うことを条件とします。

この条件の基、評価値を3,000円の範囲内で最大にするにはどうするかという問題を解きます。

以下がコードです。(「xxxxxxxxxx」のところは各自のAPIキーを入れてください)

import requests
import numpy as np
import pandas as pd
from itertools import product


REQUEST_URL = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706"
APP_ID="xxxxxxxxxx"

serch_keywords = [
    '歯磨き粉', 
    '米',
    'ボディソープ'
]

item_info = []

buget = 3000

for keyword_item in serch_keywords:
    serch_params = {
        "format" : "json",
        "keyword" : keyword_item,
        "applicationId" : [APP_ID],
        "availability" : 0,
        "hits" : 30,
        "page" : 1,
        "sort" : "-updateTimestamp"
    }

    response = requests.get(REQUEST_URL, serch_params)
    data = response.json()

    for i in range(len(data['Items'])):

        item_price = data['Items'][i]['Item']['itemPrice']
        item_review = data['Items'][i]['Item']['reviewAverage']
        item_name = data['Items'][i]['Item']['itemName']

        item_info.append(
            {
                'Price': item_price,
                'Review': item_review,
                'Name': item_name,
                'keyword': keyword_item
            }
        )

# ジャンルごとのアイテムをグループ化
grouped_items = {'歯磨き粉': [], '米': [], 'ボディソープ': []}
for item in item_info:
    grouped_items[item['keyword']].append(item)

# 各ジャンルから1つのアイテムを選んで総当たり
best_value = 0
best_combination = None
cost = 0

for combination in product(*grouped_items.values()):
    total_value = sum(item['Review'] for item in combination)
    total_price = sum(item['Price'] for item in combination)

    if total_price <= buget:
        if total_value > best_value:
            best_value = total_value
            best_combination = combination
            cost = total_price

print(f"最適な組み合わせ: {best_combination}")
print(f"総額: {cost}")
print(f"総価値: {best_value}")

上記を実行すると以下のように、最適な商品の組み合わせを出力することができました。

最適な組み合わせ: ({'Price': 1260, 'Review': 4.86, 'Name': '★ お一人様2セットまで【選べる組み合わせ/2本セット】【メール便/送料無料】 [LION]ライオン チェックアップ ジェル 60g 医薬部外品 Check-Up バナナ\u3000ピーチ グレープ レモンティー 歯科専売品 子供 ハミガキ フッ素', 'keyword': '歯磨き粉'}, {'Price': 914, 'Review': 5, 'Name': 'パール金属|PEARL METAL HB-5422 袋のまま保存米びつ 10kg用 1合カップ付', 'keyword': '米'}, {'Price': 610, 'Review': 5, 'Name': 'ハダカラ ボディソープ 液体 オイルinタイプ ピュアローズ 本体(480ml)【ハダ カラ(hadakara)】', 'keyword': 'ボディソープ'})
総額: 2784
総価値: 14.86

以上です。

タイトルとURLをコピーしました