[업무 지식]/Python
[Cohort Analysis] 첫 거래후 다른 카테고리 확장 구매 고객 vs 동일 카테고리에 머무른 고객
에디터 윤슬
2025. 2. 13. 11:08
고객 세그먼트
# 첫 거래후 특정 카테고리로 확장 구매를 한 고객 vs 동일 카테고리에 머무른 고객
first_purchase = merged_df.sort_values('transaction_date').drop_duplicates(subset=['customer_id'])
after_purchase = merged_df[~merged_df.index.isin(first_purchase.index)]
# 첫 거래 카테고리와 이후 카테고리 비교
def has_category_expansion(customer_id):
first_category = first_purchase.loc[first_purchase['customer_id'] == customer_id, 'subCategory'].values[0]
subsequent_categories = after_purchase.loc[after_purchase['customer_id'] == customer_id, 'subCategory'].unique()
return any(category != first_category for category in subsequent_categories)
# 확장 구매 여부 판별
first_purchase['expanded_category'] = first_purchase['customer_id'].apply(has_category_expansion)
# 결과 분류
expanded_customers = first_purchase[first_purchase['expanded_category'] == True]
non_expanded_customers = first_purchase[first_purchase['expanded_category'] == False]
전체 고객 코호트
def CohortAnalysis(dataframe):
# 최근 1년 이내 가입 고객 필터링
yearago = dataframe['first_join_date'].max() - pd.DateOffset(years=1)
mask = dataframe['first_join_date'] > yearago
dataframe = dataframe[mask]
# 필요한 컬럼만 추출 및 중복 제거
data = dataframe[['customer_id', 'first_join_date', 'transaction_date']].drop_duplicates()
# 월 단위로 변환
data['order_month'] = data['transaction_date'].dt.to_period('M')
data['cohort'] = data['first_join_date'].dt.to_period('M')
# 고객별로 월 단위 첫 거래만 남기기
data = data.sort_values('transaction_date').drop_duplicates(subset=['customer_id', 'order_month'])
# 코호트 데이터 생성
cohort_data = (
data.groupby(['cohort', 'order_month'])
.agg(n_customers=('customer_id', 'nunique'))
.reset_index()
)
# 기간 번호 계산
cohort_data['period_number'] = (cohort_data.order_month - cohort_data.cohort).apply(attrgetter('n'))
# 피벗 테이블 생성
cohort_pivot = cohort_data.pivot_table(
index='cohort', columns='period_number', values='n_customers'
)
# 코호트 크기 및 유지율 계산
cohort_size = data.groupby('cohort')['customer_id'].nunique()
retention_matrix = cohort_pivot.divide(cohort_size, axis=0)
# 시각화
with sns.axes_style('white'):
fig, ax = plt.subplots(
1, 2, figsize=(12, 8), sharey=True, gridspec_kw={'width_ratios': [1, 11]}
)
# 유지율 히트맵
sns.heatmap(
retention_matrix,
mask=retention_matrix.isnull(),
annot=True,
cbar=False,
fmt='.0%',
cmap='coolwarm',
ax=ax[1],
)
ax[1].set_title('Monthly Cohorts: User Retention', fontsize=14)
ax[1].set(xlabel='# of periods', ylabel='')
# 코호트 크기 히트맵
white_cmap = mcolors.ListedColormap(['white'])
sns.heatmap(
pd.DataFrame(cohort_size).rename(columns={0: 'cohort_size'}),
annot=True,
cbar=False,
fmt='g',
cmap=white_cmap,
ax=ax[0],
)
ax[0].set_title('Cohort Size', fontsize=14)
ax[0].set(ylabel='Cohort')
fig.tight_layout()
CohortAnalysis(merged_df)