기업의 마케팅, 영업, 서비스 기획 부서에서 가장 중요하게 다루는 지표 중 하나는 바로 ‘고객 행동 데이터’입니다. 모든 고객에게 동일한 비용의 마케팅을 집행하는 것은 효율성이 떨어지기 때문에, 매출 기여도가 높은 ‘우수 고객(VIP)’을 선정하여 혜택을 강화하거나, 활동이 뜸해진 ‘이탈 고객(Churn)’을 정의하여 복귀 프로모션을 진행하는 지표 설계가 필요합니다.
이러한 가공 과정은 현업 데이터 분석의 핵심 일과이며, 빅데이터분석기사(빅분기) 실기 시험에서도 여러 수치 조건을 복합적으로 결합하여 특정 고객 그룹의 통계량을 산출하는 형태로 자주 출제됩니다. 이번 글에서는 가상의 로우(Raw) 데이터를 정제하여 우수 고객과 이탈 고객을 판별하는 전처리 파이프라인을 다뤄보겠습니다.
1. 실습용 가상 고객 행동 데이터셋 구축
실습을 위해 고객ID, 최근방문일, 누적구매금액, 가입일 정보를 포함하는 가상의 데이터프레임을 정의하겠습니다.
import pandas as pd
# 가상 고객 데이터 생성
customer_raw = {
'고객ID': ['C101', 'C102', 'C103', 'C104', 'C105', 'C106'],
'최근방문일': ['2026-07-15', '2026-04-10', '2026-07-18', '2026-01-20', '2026-07-01', '2026-05-12'],
'누적구매금액': [1500000, 300000, 850000, 50000, 2100000, 120000],
'가입일': ['2025-01-10', '2025-06-15', '2026-02-20', '2024-11-05', '2025-03-01', '2026-01-15']
}
df = pd.DataFrame(customer_raw)
print(df)
2. 날짜 데이터 타입 변환 및 기준 시점 설정
고객이 최근에 언제 방문했는지를 정량적으로 계산하려면 문자열 상태인 날짜 컬럼을 시계열 객체로 변경해야 합니다.
2.1. 시계열 타입 변환 (pd.to_datetime)
14화에서 배운 방식을 적용하여 날짜 컬럼들을 datetime64 자료형으로 변환합니다.
# 날짜 컬럼들의 타입을 시계열 객체로 일괄 변환
df['최근방문일'] = pd.to_datetime(df['최근방문일'])
df['가입일'] = pd.to_datetime(df['가입일'])
2.2. 분석 기준일(Reference Date) 정의
이탈 여부를 판단하기 위해 ‘현재 분석을 진행하는 시점’을 정의해야 합니다. 본 실습에서는 데이터상의 가장 최근 날짜인 2026년 7월 18일을 기준일로 설정하고, 각 고객의 최근방문일로부터 며칠이 지났는지 경과일수(Recency)를 계산해 보겠습니다.
# 분석 기준일 설정 및 경과일수 파생변수 생성
analysis_date = pd.to_datetime('2026-07-18')
df['미방문기간'] = (analysis_date - df['최근방문일']).dt.days
3. 분위수와 조건 분기를 활용한 우수 고객(VIP) 정의
누적구매금액이 높은 고객을 분류할 때 상위 30%에 해당하는 금액 기준선을 동적으로 구하여 우수 고객을 식별해 보겠습니다.
3.1. 사분위수 및 특정 분위수 추출 (quantile)
판다스의 quantile() 함수를 사용하면 특정 백분위수에 위치한 경계 수치를 얻을 수 있습니다. 상위 30% 선을 구하기 위해 인자로 0.7을 전달합니다.
# 누적구매금액의 상위 30% 경계 수치 계산
vip_threshold = df['누적구매금액'].quantile(0.7)
print(f"VIP 선정 기준 금액: {vip_threshold}원")
3.2. np.where를 이용한 우수 고객 마킹
22화에서 다룬 np.where()를 활용하여 해당 기준 금액 이상인 고객을 ‘VIP’, 그렇지 않은 고객을 ‘일반’으로 일차 분류합니다.
import numpy as np
# 기준 금액 기반 우수 고객 파생변수 생성
df['고객등급'] = np.where(df['누적구매금액'] >= vip_threshold, 'VIP', 'General')
4. 경과일수 기준을 활용한 이탈 고객(Churn) 선별
이번에는 기준일로부터 미방문기간이 90일(약 3개월)을 초과한 고객을 서비스 이탈 위험 고객으로 분류해 보겠습니다.
# 미방문기간이 90일을 초과하면 이탈(Churn), 아니면 유지(Active)
df['이탈여부'] = np.where(df['미방문기간'] > 90, 'Churn', 'Active')
print(df[['고객ID', '미방문기간', '누적구매금액', '고객등급', '이탈여부']])
[출력 결과]
고객ID 미방문기간 누적구매금액 고객등급 이탈여부
0 C101 3 1500000 VIP Active
1 C102 99 300000 General Churn
2 C103 0 850000 General Active
3 C104 180 50000 General Churn
4 C105 17 2100000 VIP Active
5 C106 67 120000 General Active
결과 표를 통해 C102 고객과 C104 고객은 미방문기간이 각각 99일, 180일에 달하여 이탈 그룹(Churn)으로 분류되었습니다. 반면 C105 고객은 미방문기간이 17일로 짧으면서 누적구매금액이 기준선을 넘어 ‘VIP’이면서 ‘Active’ 상태인 핵심 자산 고객임을 분석할 수 있습니다.
5. 빅데이터분석기사 실기 시험 환경에서의 실전 활용 포인트
빅데이터분석기사 실기 시험(특히 작업형 제1유형)에서는 여러 조건이 복합적으로 얽힌 대상자들의 통계값을 단일 수치로 도출하라는 문제가 주로 출제됩니다.
5.1. 다중 논리 연산자를 이용한 서브셋 필터링
예를 들어 “고객 데이터셋에서 고객등급이 ‘General’이면서 이탈여부가 ‘Churn’인 고객들의 누적구매금액 평균을 구하시오”라는 문제가 있다면, 앞서 생성한 파생변수들과 7화에서 다룬 불리언 인덱싱을 결합하여 가독성 높은 형태로 해결할 수 있습니다.
# [시험장 실전 대응 프로토콜]
# 두 개의 조건을 소괄호로 묶고 & 연산자로 연결
churn_general = df[(df['고객등급'] == 'General') & (df['이탈여부'] == 'Churn')]
# 필터링된 그룹의 누적구매금액 평균 연산
result = churn_general['누적구매금액'].mean()
print(int(result))
5.2. 데이터 누수 방지를 위한 타임스탬프 처리 주의점
작업형 제2유형의 머신러닝 모델링 환경에서 날짜 데이터를 다룰 때는, 예측 모델이 미래의 시점 정보를 미리 학습하지 않도록 주의해야 합니다. 경과일수 파생변수를 만들 때 기준이 되는 analysis_date는 반드시 데이터셋 내부 혹은 문제 지문에서 제공된 범주 내에서 일관되게 정의해야 변수 왜곡에 따른 오버피팅(과적합)을 예방할 수 있습니다.
요건에 맞게 고객 데이터를 정교하게 분류하고 세분화하는 논리 구조를 확보하는 것은 실기 시험에서 실점 확률을 낮추고 안정적인 스코어를 얻는 밑바탕이 됩니다.
6. 요약 및 다음 화 안내
quantile(비율): 데이터의 분포 특성을 파악하여 동적인 경계 임계값을 산출하도록 지원합니다.Timedelta일수 변환: 두 날짜 객체의 차이에.dt.days속성을 연결하여 연속형 기간 변수로 계량화합니다.- 다중 조건 매핑:
np.where와 불리언 인덱싱의 논리곱(&) 연산을 조합해 특정 비즈니스 타깃 그룹을 선별합니다.
다음 [판다스 27화]에서는 디지털 마케팅 및 사용자 경험(UX) 데이터 분석에서 유저의 행동 로그를 분석하기 위해 필수적인 로그 데이터 분석 실습: 사용자 행동 데이터 분석하기에 대해 상세히 학습해 보겠습니다. 대용량 로그 스트림을 정제하는 실전 기술을 함께 다뤄봅시다.