프로젝트/GA4 분석

[GA4 퍼널 분석] Day5-2 결제 전환율 가설 검증 (Day4 결과 통합)

조성호 2026. 5. 12. 19:04

추가 분석 이유

이전 분석에서는 상품 조회(View Item) 이후 장바구니(Add to Cart) 단계에서 이탈 원인을 Device, User Type, Source, Price Band, Category 관점에서 검토했다. 그러나 실제 구매 퍼널에서 더 큰 손실은 결제 시작(Begin Checkout) 이후 구매 완료(Purchase) 구간에서도 발생할 수 있다. 따라서 Day6에서는 결제 단계 이탈 원인을 다양한 가설 관점에서 탐색하고, 초기 EDA 결과를 바탕으로 영향력이 높은 변수의 우선순위를 재정렬한 뒤 통계 검증을 통해 실제 핵심 요인을 선별하고자 했다.

 

이전 분석에서 어떤 가설을 세웠는가?

가설 왜 봤는가 예상 가능성
Device 모바일 결제 UX / 입력 불편 중간
User Type 신규 유저 신뢰 장벽 높음
Source 구매 의도 높은 유입 여부 중간~높음
Checkout Value 최종 가격 부담 높음
Category 특정 상품군 결제 저항 중간~높음

 

왜 통계 검증이 필요했는가?

보이는 차이와 실제 차이는 다르다

예시)

  • New: 48%
  • Returning: 59%

차이가 있어 보이지만, 표본 수 / 우연 / 분산 영향일 수 있으므로 실제 구조적 차이인지 검증 필요

 

사용한 방법

1. Chi-Square

여러 그룹 전체 차이 검정

  • User Type 전체
  • Device 전체
  • Source 전체
  • Category 전체

2. Two-Proportion Z-Test

두 그룹 직접 비교

  • New vs Returning
  • Mobile vs Desktop
  • Checkout Value 평균·중앙값 구조 비교 (EDA 기반)
  • 특정 Category vs 평균

Device 검증 – 모바일 UX는 실제 핵심 문제인가?

초기 가설은 모바일 환경의 결제 UX 또는 입력 불편이 결제 이탈을 유발할 수 있다는 것이었다.

 

전처리

begin_checkout 세션 대비 purchase 세션을 기준으로 purchase / not_purchase_sessions를 구성해 Device별 contingency table을 생성했다.

Device 전체 비교 (Chi-Square)

device_table = stable_device_df[
    ["purchase_sessions", "not_purchase_sessions"]
].values

chi2, p, dof, expected = chi2_contingency(device_table)

print("=== Device Chi-Square Test ===")
print("Chi-Square:", chi2)
print("p-value:", p)
print("Degrees of Freedom:", dof)

print("\nExpected Frequencies:")
print(expected)

Mobile vs Desktop 직접 비교 (Z-Test)

mobile = stable_device_df[
    stable_device_df["device_category"] == "mobile"
].iloc[0]

desktop = stable_device_df[
    stable_device_df["device_category"] == "desktop"
].iloc[0]

count = [
    mobile["purchase_sessions"],
    desktop["purchase_sessions"]
]

nobs = [
    mobile["checkout_sessions"],
    desktop["checkout_sessions"]
]

stat, pval = proportions_ztest(count, nobs)

print("=== Mobile vs Desktop Z-Test ===")
print("Mobile Rate:", round(mobile["checkout_to_purchase_rate_calc"], 2))
print("Desktop Rate:", round(desktop["checkout_to_purchase_rate_calc"], 2))
print("Z-stat:", stat)
print("p-value:", pval)

해석

Device 전체

p-value < 0.05
통계적으로 차이는 있었지만 효과 크기는 제한적

 

Mobile vs Desktop

Mobile +8.93% Lift
오히려 모바일 전환율이 더 높았음

 

실무적 생각

모바일 UX 병목 가설은 약화되었다.
Device는 완전히 무의미하진 않지만, 핵심 병목이라기보다 보조 변수일 가능성이 높았다.


User Type 검증 – 신규 유저 장벽은 실제 중요한가?

결제 단계에서 가장 직관적인 가설은 신규 유저의 신뢰 장벽이었다.

가설 : 신규 유저는 회원가입, 배송비, 결제 정보 입력, 브랜드 신뢰 부족 등으로 결제 단계에서 더 많이 이탈할 수 있다.

 

전처리

checkout_sessions 대비 purchase_sessions / not_purchase_sessions를 구성해 New vs Returning 비교 구조를 만들었다.

 

User Type 전체 비교 (Chi-Square)

user_table = stable_user_df[
    ["purchase_sessions", "not_purchase_sessions"]
].values

chi2, p, dof, expected = chi2_contingency(user_table)

print("=== User Type Chi-Square Test ===")
print("Chi-Square:", chi2)
print("p-value:", p)
print("Degrees of Freedom:", dof)

print("\nExpected Frequencies:")
print(expected)

New vs Returning 직접 비교 (Z-Test)

new_user = stable_user_df[
    stable_user_df["user_type"] == "New"
].iloc[0]

returning_user = stable_user_df[
    stable_user_df["user_type"] == "Returning"
].iloc[0]

count = [
    new_user["purchase_sessions"],
    returning_user["purchase_sessions"]
]

nobs = [
    new_user["checkout_sessions"],
    returning_user["checkout_sessions"]
]

stat, pval = proportions_ztest(count, nobs)

print("=== New vs Returning Z-Test ===")
print("New Rate:", round(new_user["checkout_to_purchase_rate_calc"], 2))
print("Returning Rate:", round(returning_user["checkout_to_purchase_rate_calc"], 2))
print("Z-stat:", stat)
print("p-value:", pval)

해석

p-value < 0.001

신규 vs 재방문 유저 차이는 매우 유의미

Returning vs New

+22.57% Lift
+10.84%p 차이

실무적 생각

결제 단계 핵심 병목은 Device보다 User Type 가능성이 훨씬 높았다.

즉, “어떤 기기인가?”보다 “신뢰가 형성된 유저인가?”가 더 중요했다.

가능한 액션

 

  • 게스트 결제
  • 첫 구매 할인
  • 무료배송
  • 신뢰 배지
  • 결제 프로세스 단순화

Source 검증 – 유입 품질은 실제 중요한가?

Source는 구매 의도와 채널 품질 차이를 반영할 가능성이 있다.

전처리

Source별 checkout_sessions / purchase_sessions 기반으로 Source 전체 비교 구조를 만들었다.

 

Source 전체 비교 (Chi-Square)

source_table = stable_source_df[
    ["purchase_sessions", "not_purchase_sessions"]
].values

chi2, p, dof, expected = chi2_contingency(source_table)

print("=== Source Quality Chi-Square Test ===")
print("Chi-Square:", chi2)
print("p-value:", p)
print("Degrees of Freedom:", dof)

print("\nExpected Frequencies:")
print(expected)

Direct vs Google 직접 비교 (Z-Test)

direct = stable_source_df[
    stable_source_df["source"] == "(direct)"
].iloc[0]

google = stable_source_df[
    stable_source_df["source"] == "google"
].iloc[0]

count = [
    direct["purchase_sessions"],
    google["purchase_sessions"]
]

nobs = [
    direct["checkout_sessions"],
    google["checkout_sessions"]
]

stat, pval = proportions_ztest(count, nobs)

print("=== Direct vs Google Z-Test ===")
print("Direct Rate:", round(direct["checkout_to_purchase_rate_calc"], 2))
print("Google Rate:", round(google["checkout_to_purchase_rate_calc"], 2))
print("Z-stat:", stat)
print("p-value:", pval)

Best vs Worst Source 직접 비교 (Z-Test)

best = stable_source_df[
    stable_source_df["source"] == "(data deleted)"
].iloc[0]

worst = stable_source_df[
    stable_source_df["source"] == "google"
].iloc[0]

count_best = [
    best["purchase_sessions"],
    worst["purchase_sessions"]
]

nobs_best = [
    best["checkout_sessions"],
    worst["checkout_sessions"]
]

stat_best, pval_best = proportions_ztest(
    count_best,
    nobs_best
)

print("=== Best vs Worst Z-Test ===")
print("Best Rate:", round(best["checkout_to_purchase_rate_calc"], 2))
print("Worst Rate:", round(worst["checkout_to_purchase_rate_calc"], 2))
print("Z-stat:", stat_best)
print("p-value:", pval_best)

해석

Best vs Worst

+15.39% Lift
p-value < 0.05

 

But,

Cramér’s V = 0.0547
효과 크기 작음

실무적 생각

일부 채널 차이는 있었지만, Source는 핵심 구조 변수라기보다 보조 변수 가능성이 높았다.

즉, “어디서 왔는가?”보다 “누가 왔는가?”가 더 중요했다.


Checkout Value 검증 – 가격 장벽은 실제 중요한가?

Day5에서 가격은 장바구니 진입 핵심 변수였다.
Day6에서는 가격이 결제 직전에도 동일하게 작동하는지 확인하고자 했다.

 

데이터 구조 한계

현재 CSV는 세션별 raw 데이터가 아니라 Purchased / Not Purchased 평균값 구조였기 때문에 Chi-Square / Z-Test 대신 평균·중앙값 비교 중심으로 해석했다.

 

해석

평균

Not Purchased +131.67%

중앙값

Not Purchased -51.32%

 

핵심 해석

전체 가격 장벽이라기보다 일부 초고가 이상치 세션이 평균을 끌어올린 가능성이 컸다.

즉, 일반 가격 문제라기보다 특정 고가 세그먼트 문제 가능성

 

실무적 생각

  • 고가 상품 상세페이지
  • 장바구니 할인
  • 무료배송 임계값
  • 가격 저항 세그먼트 추가 분석 필요

 

최종 우선순위 재정렬

Tier 1

User Type

Tier 2

Checkout Value (Raw session-level price 데이터 부재로 구조적 검정 한계 존재)

Tier 3

Source / Device

 

핵심 인사이트

Day5에서 “무슨 상품을 보는가(Price + Category)”가 중요했다면,
Day6에서는 “누가 결제하는가(User Type)”가 훨씬 중요할 가능성이 나타났다.

장바구니 단계 : 상품 경쟁력

결제 단계 : 신뢰 장벽

 

그래서 무엇을 해야 하는가?

User Type

  • 신규 유저 신뢰 강화
  • 첫 구매 혜택
  • 결제 단순화

Checkout Value

  • 고가 이탈 세그먼트 분석

Category

  • Day5 Bags 구조가 결제 단계에서도 이어지는지 심층 검토

 

결제 단계에서는 단순 UX보다 신규 유저의 신뢰 장벽이 핵심 병목일 가능성이 높았다.

다음 단계에서는 심층 분석을 통해 “어떤 상황의 신규 유저가 실제 문제인가?”를 구조적으로 검증할 예정이다.