[업무 지식]/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)

전체 고객 코호트

 

확장 고객

비확장 고객