[BG/NBD] ๊ณ ๊ฐ ๊ฑฐ๋ ํ๋ ์์ธก ๋ชจ๋ธ
BetaGeoFitter๋?
๊ณ ๊ฐ ์ดํ ์์ธก ๋ฐ ๊ตฌ๋งค ํ๋ฅ ๋ชจ๋ธ๋ง์ ์ฌ์ฉ๋๋ ํต๊ณ ๋ชจ๋ธ ์ค ํ๋๋ก, ๊ณ ๊ฐ ์ดํ ๋ฐ ๊ตฌ๋งค ํ๋ฅ ์ ์์ธกํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
์ด ๋ชจ๋ธ์ ๊ธฐ์กด ๊ณ ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์๋ํ๋ฉฐ, ํนํ ๊ตฌ๋งค ํ์์ ์ฌ๊ตฌ๋งค ๊ฐ๊ฒฉ์ ๊ณ ๋ คํ๋ค.
BetaGeoFitter ๋ชจ๋ธ์ ๊ตฌํํ๋ ค๋ฉด Python์ lifetimes ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์๋๋ BetaGeoFitter ๋ชจ๋ธ์ ์ฌ์ฉ ์์์ด๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ import
lifetimes ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๊ณ ๊ฐ์ ธ์จ๋ค.
!pip install lifetimes
import pandas as pd
from lifetimes import BetaGeoFitter
from lifetimes.datasets import load_cdnow_summary
์์ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ
lifetimes ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์์ ๋ฐ์ดํฐ์ ์ด ํฌํจ๋์ด ์๋ค.
์ด ๋ฐ์ดํฐ๋ ๊ณ ๊ฐ ID, ๊ตฌ๋งค ๋ ์ง, ๊ตฌ๋งค ๊ธ์ก ๋ฑ์ ํฌํจํ๊ณ ์๋ค.
data = load_cdnow_summary(index_col=[0])
print(data.head())
BetaGeoFitter ๋ชจ๋ธ์ ์ด๊ธฐํํ๊ณ ํ์ต
- ๋ชจ๋ธ์ ํ์ตํ๊ธฐ ์ํด์๋ 3๊ฐ์ง ์งํ๊ฐ ํ์ํ๋ค. ๋ชจ๋ธ์ ํ์ตํ๋ฉด ๊ณ ๊ฐ ์ดํ ๋ฐ ์ฌ๊ตฌ๋งค ํ๋ฅ ์ ์์ธกํ ์ ์๋ค.
- `frequency`: ๊ณ ๊ฐ์ ๊ตฌ๋งค ๋น๋ (์ด ๊ตฌ๋งค ํ์)
- `recency`: ๊ณ ๊ฐ์ ์ต๊ทผ ๊ตฌ๋งค๊น์ง ๊ฒฝ๊ณผํ ์๊ฐ
- `T`: ๋ฐ์ดํฐ ํฌ์ธํธ์ ์๋ช (๊ณ ๊ฐ์ ์ฒ์ ๊ตฌ๋งค๋ถํฐ ๊ฐ์ฅ ์ต๊ทผ ๊ตฌ๋งค๊น์ง์ ์๊ฐ)
bgf = BetaGeoFitter(penalizer_coef=0.0)
bgf.fit(data['frequency'], data['recency'], data['T'])
๊ณ ๊ฐ ๊ตฌ๋งค ํ์ ์์ธก(1๋จ์ ์๊ฐ ๊ธฐ์ค)
- ๊ฐ ๊ณ ๊ฐ์ ๋ํด ๋ฏธ๋ 1 ๋จ์์ ์๊ฐ ๋์ ์กฐ๊ฑด๋ถ ์์ ๊ตฌ๋งค ํ์๋ฅผ ๊ณ์ฐ =>> ์ฃผ์ด์ง ์๊ฐ๋์ ์ผ๋ง๋ ์์ฃผ ๊ตฌ๋งคํ ๊น?
- ์ด๋ฅผ ํตํด ์์ ์ดํ๋ฅ ๋ ํ์ธํ ์ ์๋ค.
predicted_churn = bgf.conditional_expected_number_of_purchases_up_to_time(1, data['frequency'], data['recency'], data['T'])
print(predicted_churn.head())
๊ณ ๊ฐ ์ฌ๊ตฌ๋งค ํ๋ฅ ์์ธก(1๋จ์ ์๊ฐ ๊ธฐ์ค)
- ์ฃผ์ด์ง ์๊ฐ ๋์ ์ฌ๊ตฌ๋งค๋ฅผ ํ ํ๋ฅ ์ด ์ด๋ป๊ฒ ๋ ๊น?
- ์ญ์, ๊ณ ๊ฐ์ดํ๋ฅ ์ ์์ธกํ ์ ์๋ค.
# ์์ธก ์ฌ๊ตฌ๋งค ํ๋ฅ
t = 1 # ์์ธก์ ํ๊ณ ์ ํ๋ ์๊ฐ ๋จ์
predicted_repurchase = bgf.predict(t, data['frequency'], data['recency'], data['T'])
์๊ฐํ
- `plot_period_transactions` ํจ์๋ Lifetimes ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ผ๋ถ์ธ ํจ์๋ก์,
- ์ฃผ์ด์ง ๋ชจ๋ธ์ ๊ตฌ๋งค ๋ฐ ์ดํ ํจํด์ ํ์ํ๊ธฐ ์ํด ์๊ฐํ๋ฅผ ์์ฑํ๋ค.
- ์ด๋ฅผ ํตํด ๊ณ ๊ฐ์ ๊ตฌ๋งค ์ฃผ๊ธฐ, ์ฌ๊ตฌ๋งค ํ๋ฅ ๋ฐ ์ดํ ํ๋ฅ ๊ณผ ๊ฐ์ ์ ๋ณด๋ฅผ ์๊ฐ์ ์ผ๋ก ์ดํดํ ์ ์๋ค.
- ๊ณ ๊ฐ ์ดํ ๋ฐ ์ฌ๊ตฌ๋งค ์์ธก ๋ชจ๋ธ์ ์๊ฐํํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. ์ฃผ์ ๋งค๊ฐ๋ณ์๋ ๋ค์๊ณผ ๊ฐ๋ค.
1. `model`: Lifetimes ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ฌ์ฉ๋ ๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ค. ์ฃผ๋ก BGF (Beta-Geometric/Beta-Negative Binomial) ๋ชจ๋ธ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
2. `max_frequency`: ์ด ๋งค๊ฐ๋ณ์๋ ๊ณ ๊ฐ ๊ตฌ๋งค ๋น๋์ ์ต๋ ๊ฐ์ผ๋ก ์ค์ ๋๋ค.
- ์๋ฅผ ๋ค์ด, `max_frequency=7`๋ก ์ค์ ํ๋ฉด 7๋ฒ ์ดํ์ ๊ตฌ๋งค ๋น๋๋ฅผ ๊ฐ์ง ๊ณ ๊ฐ๋ง์ ๋์์ผ๋ก ์๊ฐํ๊ฐ ์์ฑ๋๋ค.
- ์ด๋ ๊ฒ ํจ์ผ๋ก์จ ๊ณ ๊ฐ ์ค์ฌ์ ๋ถ์์ ํน์ ๋น๋ ๋ฒ์๋ก ์ ํํ ์ ์๋ค.
3. `title`: ๊ทธ๋ํ์ ์ ๋ชฉ์ ์ค์
4. `xlabel`: x ์ถ ๋ ์ด๋ธ์ ์ค์
5. `ylabel`: y ์ถ ๋ ์ด๋ธ์ ์ค์
plot_period_transactions(BGF, max_frequency=7)
plt.show()
โถ๏ธ x์ถ
- ๊ตฌ๋งค ์ฃผ๊ธฐ(๊ณ ๊ฐ์ด ๋๋ฒ์งธ ๊ตฌ๋งค๋ฅผ ํ ๋๊น์ง ๊ฑธ๋ฆฌ๋ ํ๊ท ์๊ฐ) ๋๋ ๊ตฌ๋งค ๋น๋(ํน์ ๋น๋ ๋ฒ์ ๋ด์์์ ๊ณ ๊ฐ ์)๋ก, ๊ณ ๊ฐ๋ค์ด ์ผ๋ง๋ ์์ฃผ ๊ตฌ๋งคํ๋์ง ๋ณด์ฌ์ค๋ค.
- x ์ถ์ max_frequenct ์ดํ์ ์ ์๊ฐ์ ๊ฐ์ง๋ค
- ์๋ฅผ ๋ค์ด, x์ถ์ด 1์ด๋ฉด ๊ณ ๊ฐ์ด ํ๊ท 1๋ฒ์ ๊ตฌ๋งค ์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ด๋ค.
โถ๏ธ y์ถ
- ์ฌ๊ตฌ๋งค ํ๋ฅ ๋๋ ์ดํ ํ๋ฅ
- ์ฌ๊ตฌ๋งค ํ๋ฅ : ์ฃผ์ด์ง ๊ตฌ๋งค ์ฃผ๊ธฐ ๋๋ ๋น๋ ๋ฒ์์ ํด๋นํ๋ ๊ณ ๊ฐ์ด ๋ค์ ๊ตฌ๋งค๋ฅผ ํ ํ๋ฅ ๋ก, ๋ ๋์ y ๊ฐ์ ๋ ๋์ ์ฌ๊ตฌ๋งค ํ๋ฅ ์ ๋ํ๋ธ๋ค.
๐ ์ด์ฒ๋ผ ํด๋น ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ๊ณ ๊ฐ ์ดํ ์์ธก ๋ฐ ๋ง์ผํ ์ ๋ต์ ๊ฐ๋ฐํ ์ ์๋ค.
๋น์ฐํ ํ์ํ ๊ฒฝ์ฐ ์ ์ฒ๋ฆฌ ๋ฑ์ ์ถ๊ฐ๋ก ์ํํ๋ฉด ์ข๋ค.