1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kaggleの「Retailrocket recommender system dataset」でDID(差分の差分法)を練習してみた

Posted at

はじめに

今回は、「ChatGPTにハンズオンを作らせてみた」の第3弾で、DID(差分の差分法)を勉強しました。

第2弾はこちら↓

DID(差分の差分法)

「あるグループに何かしらの介入(政策や施策など)を実施したとき、実施しなかったグループと比べてどのくらい変化したのか?」を分析するための因果推論手法です。
処置群(介入を受けたグループ)の変化と対照群(介入を受けていないグループ)の変化の差分をとることで、DIDの推定値を算出するため、差分の差分法とも呼ばれます。

使用データ

Kaggleのデータセットにある、「Retailrocket recommender system dataset」というEコマースのレコメンデーションシステムで使用される商品プロパティの情報を記録したデータセットを用いました。その中でも、今回は次の3つの変数をピックアップして使用しました。

変数 説明
timestamp イベントの発生時刻(ミリ秒単位)
event ユーザーの行動(viewaddtocarttransaction
transactionid 購入が発生した場合に記録される取引ID(NaNでない場合は購入)

また、このデータを用いて、次の変数を作成しました。

変数 説明
discounted 割引対象かどうか(0=対象外、1=対象)
post_discount 割引後かどうか(0=割引前、1=割引後)
interact DIDの交互作用項(割引後かつ割引対象の商品)

やること

  • Eコマースのデータから、取引データ(実際に購入されたデータ)のみを抽出
  • 介入するグループ(割引対象)を定義
  • 介入のタイミングを定義
  • 介入を受けたグループの売上の変化介入を受けなかったグループの売上の変化の差分を取り、割引の効果があったかを測定

使用コード

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.api as sm
import seaborn as sns
# データ読み込み
df = pd.read_csv("data/Retailrocket recommender system dataset/events.csv")

# ミリ秒のUNIX時間を日付に変換
df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")

# 日付のみに変換
df["date"] = df["timestamp"].dt.date

今回のデータは、取引データ以外も含まれているため、取引データのみを抽出します。

# 取引データのみを抽出
df_sales = df[df["event"] == "transaction"]

今回のデータでは、どの商品が割引対象かどうかが分からないので、こちら側が手動で割引対象の商品を定義します。(商品IDが10000から20000の間にある商品とします。)

# 割引を受けた商品(処置群)を定義
df_sales["discounted"] = df_sales["itemid"].apply(lambda x: 1 if 100000 <= x <= 200000 else 0)

image.png

割引が開始されたタイミングについても手動で定義していきます。(2015年7月1日を基準に設定します。)

# 割引開始日
discount_start_date = pd.to_datetime("2015-07-01").date()

# 割引前・後のフラグ
df_sales["post_discount"] = df_sales["date"].apply(lambda x: 1 if x >= discount_start_date else 0)

処置群(介入を受けたグループ)と対照群(介入を受けなかったグループ)に分けて、売上回数をカウントして、一度可視化してみます。

# 商品ごとに売上回数をカウント
df_did = df_sales.groupby(["date", "discounted", "post_discount"]).size().reset_index(name="sales")
# 割引前後の売上トレンド
sns.lineplot(data=df_did, x="date", y="sales", hue="discounted")
plt.axvline(discount_start_date, color='red', linestyle="--", label="Discount Start")
plt.legend(title="Discounted Product")
plt.xticks(rotation=45)
plt.show()

image.png

DIDでは、単純に「割引前と割引後の売上」を比較するのではなく、「通常商品の売上の変化」と「割引商品の売上の変化」を比較することが重要なため、交互作用項を追加したうえで、DIDを実装します。

# 交互作用項の作成
df_did["interact"] = df_did["discounted"] * df_did["post_discount"]

# 回帰モデルの構築
X = sm.add_constant(df_did[["post_discount", "discounted", "interact"]])
y = df_did["sales"]

model = sm.OLS(y, X).fit()
print(model.summary())

image.png

分析結果

post_discountdiscountedは、それぞれ単純な「割引前後の売上比較」と「商品ごとの比較」になってしまうため、交互作用項であるinteractのみに注目する。

  • 係数: 1.11
    • 割引導入後の売上の変化はほぼゼロに近い
  • P値: 0.896
    • 割引の影響は統計的に優位ではない(P<0.05であれば有意と判断)
  • 解釈: この結果から、割引が売上に明確な影響を与えたとは言えない

おわりに

今回は、Kaggleのデータセットから、割引対象と割引開始のタイミングを完全に手動で決めたので、有意な結果が出なくて当然かなと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?