Python+Chat GPTで売上予測をしてみよう

2023年5月27日土曜日

Chat GPT Python

t f B! P L

Chat GPTが便利すぎて、最近はもっぱらベースのソースコードをChat GPTに書いてもらって、微調整を手でしています。今回は、売上データのグラフ化と需要予測をする Pythonのコードを、Chat GPTに作ってもらう方法を紹介します。

売上データの作成

まずは、売上データを以下の条件でランダムに作ってもらいます。売上データは、年間を通りして売れる商品、季節性の商品の2パターンの傾向で作ります。

プロンプトは以下のような感じ。

## 命令書
次の出力条件を満たす売上データのCSVを生成するPythonのコードを作成

## 出力条件
- 「売上日」「品番」「数量」の3つのカラムを持つCSVを作成。
- 品番は「A1」「A2」「A3」の3種類
- 「売上日」の期間は「2022/1/1」-「2022/12/31」までの間とする
- 数量はランダムに生成するが、以下の売上傾向の仕様に従うこと

| 品番 | 売上傾向 |
|--|--|
| A1 | 春はよく売れる。それ以外はあまり売れない |
| A2 | 年間を通して平均的に売れている |
| A3 | 年末にしか売れない |

- CSVのファイル名は「sales_data.csv」とする

すると、こんな感じで売上データのCSVを作成するコードが生成されます。

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import csv
import random

# 売上日の範囲を設定
start_date = datetime(2022, 1, 1)
end_date = datetime(2022, 12, 31)
delta = timedelta(days=1)

# 品番のリストを作成
product_codes = ["A1", "A2", "A3"]

sales_data = []

# 売上日ごとにデータを生成
date = start_date
while date <= end_date:
    for product_code in product_codes:
        quantity = 0

        if product_code == "A1":
            # 春(3月から5月)にはよく売れ、それ以外はあまり売れない
            if date.month in [3, 4, 5]:
                quantity = random.randint(50, 100)
            else:
                quantity = random.randint(0, 50)

        elif product_code == "A2":
            # 年間を通して平均的に売れる
            quantity = random.randint(20, 80)

        elif product_code == "A3":
            # 年末(11月と12月)にしか売れない
            if date.month in [11, 12]:
                quantity = random.randint(50, 100)
            else:
                quantity = random.randint(0, 10)

        # 売上データを追加
        sales_data.append([date.strftime("%Y/%m/%d"), product_code, quantity])

    date += delta

# CSVに出力
with open('sales_data.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(["売上日", "品番", "数量"])
    writer.writerows(sales_data)

これを実行すると、プロンプトで指定した「売上日」「品番」「数量」のカラムを持つCSVファイルが生成されます。

売上日,品番,数量
2023/05/19,A2,1630
2023/05/13,A5,1313
2023/05/17,A1,1211
2023/05/01,A5,1110
・・・

売上推移をグラフ表示

作成した売上データのCSVをグラフに表示してみる。

プロンプトは以下のとおり。

品番ごとに売上推移をグラフに表示するコードを生成

作成されたコードです。
matplotlibのデフォルトフォントは日本語に対応していないので、Hiragino Sansのフォントを設定するコードは後から手で足しています。

import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'Hiragino Sans'

# CSVファイルからデータを読み込む
df = pd.read_csv('sales_data.csv')

# 売上日を datetime オブジェクトに変換
df['売上日'] = pd.to_datetime(df['売上日'])

# 品番ごとにデータを分割
df_A1 = df[df['品番'] == 'A1']
df_A2 = df[df['品番'] == 'A2']
df_A3 = df[df['品番'] == 'A3']

# 品番ごとの売上推移をプロット
plt.figure(figsize=(12, 6))
plt.plot(df_A1['売上日'], df_A1['数量'], label='A1')
plt.plot(df_A2['売上日'], df_A2['数量'], label='A2')
plt.plot(df_A3['売上日'], df_A3['数量'], label='A3')

# ラベルとタイトルを設定
plt.xlabel('Date')
plt.ylabel('Quantity')
plt.title('Sales Trend by Product Code')
plt.legend()

# グラフを表示
plt.show()

コードを実行すると、次のような売上推移グラフが得られます。
enter image description here

ちゃんと次のプロンプトに従って、売上数を生成してくれていることが分かります。

- 数量はランダムに生成するが、以下の売上傾向の仕様に従うこと

| 品番 | 売上傾向 |
|--|--|
| A1 | 春はよく売れる。それ以外はあまり売れない |
| A2 | 年間を通して平均的に売れている |
| A3 | 年末にしか売れない |

もし、商品の種類が増えた場合、1つのグラフに全部の売上推移を表示するのは無理があるので、品番別にグラフを作成するプロンプトに変えてみます。

作成した売上データをグラフに表示するコードを生成。品番ごとに別々にグラフを表示して。

すると、こんな感じでコードを作り直されます。

import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'Hiragino Sans'

# CSVからデータを読み込む
sales_data = pd.read_csv("sales_data.csv")
sales_data['売上日'] = pd.to_datetime(sales_data['売上日'])

# 品番ごとにグラフを作成
for product_code in product_codes:
    plt.figure(figsize=(10,6))
    plt.plot(sales_data[sales_data['品番'] == product_code]['売上日'],
             sales_data[sales_data['品番'] == product_code]['数量'])
    plt.title(f'品番 {product_code} の売上データ')
    plt.xlabel('売上日')
    plt.ylabel('数量')
    plt.show()

生成されたコードを実行すると、次のように品番別にグラフを作成しています。

「品番A1」のグラフ
enter image description here
「品番A2」のグラフ
enter image description here
「品番A3」のグラフ
enter image description here

売上予測

次は、過去の売上実績を基に売上予測を行うコードを作ってもらいます。

売上予測の方法は多種に渡り、簡単なものでは移動平均法、指数平滑法などがあり、少し難しいものでは学習モデルを使った回帰計算などがあります。どの計算モデルを使用するかは、扱う商品のトレンドによって大きく変わるため一概には言えません。

いくつかの計算モデルをChat GPTに作ってもらいます。

移動平均法

まず、移動平均法で需要予測をしてみます。プロンプトは以下のとおり。

ここまで作成した売上実績のデータを基に「2023/1/1」-「2023/12/31」の売上予測を行ってください。

## 計算条件
- 売上予測には移動平均法を使用
- ウィンドウサイズは20とする

## 出力条件
以下の2つの系統をグラフに表示
- 売上実績
- 売上予測

こんな感じでコードが作られます。

from datetime import date

# CSVからデータを読み込む
sales_data = pd.read_csv("sales_data.csv")
sales_data['売上日'] = pd.to_datetime(sales_data['売上日'])

# 品番ごとにグラフを作成
for product_code in product_codes:
    # 品番に応じたデータを抽出
    product_data = sales_data[sales_data['品番'] == product_code]

    # 移動平均を計算
    product_data['移動平均'] = product_data['数量'].rolling(window=20).mean()

    # 売上予測
    # 2023年1月1日から2023年12月31日までのデータを作成
    forecast_dates = pd.date_range(start='2023-01-01', end='2023-12-31')
    forecast_data = pd.DataFrame(forecast_dates, columns=['売上日'])

    # 予測データに移動平均をマッピング(2022年のデータを使用)
    forecast_data['売上予測'] = forecast_data['売上日'].apply(
        lambda x: product_data[product_data['売上日'].dt.dayofyear == x.dayofyear]['移動平均'].values[0]
        if not product_data[product_data['売上日'].dt.dayofyear == x.dayofyear]['移動平均'].empty else 0
    )

    # グラフの描画
    plt.figure(figsize=(10,6))
    plt.plot(product_data['売上日'], product_data['数量'], label='売上実績')
    plt.plot(product_data['売上日'], product_data['移動平均'], label='移動平均')
    plt.plot(forecast_data['売上日'], forecast_data['売上予測'], label='売上予測')
    plt.title(f'品番 {product_code} の売上データと予測')
    plt.xlabel('売上日')
    plt.ylabel('数量')
    plt.legend()
    plt.show()

実行すると、次のようなグラフが得られます。(オレンジが移動平均、緑色の系統が需要予測)

【品番=A1】のグラフ
enter image description here

【品番=A2】のグラフ
enter image description here

【品番=A3】のグラフ
enter image description here

指数平滑法

指数平滑法は、トレンド・季節性を意識した予測モデルです。

指数平滑法で需要予測のコードを作成するプロンプトは以下のとおり。

ここまで作成した売上実績のデータを基に「2023/1/1」-「2023/12/31」の売上予測を行ってください。

## 計算条件
- 売上予測には指数平滑法を使用
- 季節性を考慮

## 出力条件
以下の2つの系統をグラフに表示
- 売上実績
- 売上予測

生成されたコードは以下。

import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.holtwinters import ExponentialSmoothing

# CSVからデータを読み込む
sales_data = pd.read_csv("sales_data.csv")
sales_data['売上日'] = pd.to_datetime(sales_data['売上日'])
sales_data = sales_data.sort_values('売上日').set_index('売上日')

# 商品ごとに売上予測
for product_code in product_codes:
    # データの選択
    data = sales_data[sales_data['品番'] == product_code]

    # モデルの定義とフィッティング
    model = ExponentialSmoothing(data['数量'], seasonal='add', seasonal_periods=12).fit()

    # 2023年までの売上予測
    forecast = model.predict(start=datetime(2023, 1, 1), end=datetime(2023, 12, 31))

    # グラフ描画
    plt.figure(figsize=(10,6))
    plt.plot(data.index, data['数量'], label='実績')
    plt.plot(forecast.index, forecast.values, label='予測')
    plt.title(f'品番 {product_code} の売上データと予測')
    plt.xlabel('売上日')
    plt.ylabel('数量')
    plt.legend()
    plt.show()

実行すると、次のようなグラフが得られます。(オレンジが需要予測)

【品番=A1】のグラフ
enter image description here

【品番=A2】のグラフ
enter image description here

【品番=A3】のグラフ
enter image description here

計算方法が、単純指数平滑法になっているのか、季節性が考慮されていない需要予測の結果となってしまいました。

まとめ

今回、Chat GPTで生成したコードだけで、需要予測を行う方法を紹介しました。一部、うまくいっていない部分がもありますが、ノーコードでここまで実装できるのは恐怖すら感じます。1からコードを生成する時代は終わったかもしれません。

スポンサーリンク
スポンサーリンク

このブログを検索

Profile

自分の写真
Webアプリエンジニア。 日々新しい技術を追い求めてブログでアウトプットしています。
プロフィール画像は、猫村ゆゆこ様に書いてもらいました。

仕事募集もしていたり、していなかったり。

QooQ