0. 세팅
import pandas as pd
import numpy as np
import time
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib as mpl
plt.rc('font', family='AppleGothic')
mpl.rcParams['axes.unicode_minus'] = False # 한글깨짐방지
JavaScript
복사
# 고객 테이블에 연령대 컬럼 추가
customers["age_group"]=(customers["age"] // 10) * 10
# 조인 (일단 inner로. 향후 left 필요하면 그때)
df_tr_cu = transactions.merge(customers, how="inner", on="customer_id")
df_tr_ar = transactions.merge(articles, how="inner", on="article_id")
df_full = df_tr_cu.merge(articles, how="inner", on="article_id")
# 연 월 일 요일 분기
df_full["t_dat"] = pd.to_datetime(df_full["t_dat"]) # 날짜 형식으로 변환
df_full["year"] = df_full["t_dat"].dt.year # 연도
df_full["month"] = df_full["t_dat"].dt.month # 월
df_full["day"] = df_full["t_dat"].dt.day # 일
df_full["weekday"] = df_full["t_dat"].dt.day_name() # 요일
df_full["quarter"] = df_full["t_dat"].dt.quarter # 분기
JavaScript
복사
1. 고객 세그먼트별 매출 특징
- 연령대 별 매출 구하기
age_group_sales = (df_full.groupby("age_group")["price"]
.sum()
.reset_index())
JavaScript
복사
- 회원 상태 별 매출 구하기
club_member_status_sales = (df_full.groupby("club_member_status")["price"]
.sum()
.reset_index()
.sort_values("price", ascending=False))
JavaScript
복사
- 고객별 평균적인 재구매 주기 구하기
# 재구매 주기
df_full['t_dat'] = pd.to_datetime(df_full['t_dat']) # 날짜 계산을 위해 날짜형으로 변경
df_full = df_full.sort_values(['customer_id', 't_dat']) # 고객 id와 날짜 기준으로 정렬
df_full['next_purchase_date'] = df_full.groupby('customer_id')['t_dat'].shift(-1) # 다음 구매일 만들기.
각 고객의 다음 구매일을 옆 칼럼에 붙이기 shift(-1)은 한 칸 아래 있는 값을 끌어올림
df_full['days_between'] = (df_full['next_purchase_date'] - df_full['t_dat']).dt.days # 구매 간격 계산 # dt.days 며칠인지 정수 변환
# 고객별 평균 재구매 주기
repurchase = (df_full.dropna(subset=['days_between']) # 마지막 구매는 next가 없으니 평균 계산에 필요없음. days_between이 Nan인 행 제거
.groupby('customer_id')['days_between'] # 고객별로 묶기
.mean() # 평균
.reset_index()) # 연산 후 인덱스 재설정
JavaScript
복사
(+) # 연령대별 재구매 주기 섹션 나누어서 분석 (1주, 2주 한달, 두달, 장기로 구분)
bins = [0, 7, 14, 30, 60, 400]
labels = ['Within a week', 'Within 2 weeks', 'Within a month', 'Within 2 months', 'Long term']
repurchase['cycle_group'] = pd.cut(repurchase['days_between'],
bins=bins,
labels=labels,
right=True)
# 재구매한 고객을 분석하는거니까 inner로
repurchase_age = repurchase.merge(customers[['customer_id', 'age_group']],on='customer_id',how='inner')
age_cycle = (repurchase_age.groupby(['age_group', 'cycle_group'])['customer_id']
.count()
.reset_index(name='cnt'))
age_cycle['ratio'] = age_cycle['cnt'] / age_cycle.groupby('age_group')['cnt'].transform('sum')
# 위 분석 결과를 피벗으로
pivot_age_cycle = age_cycle.pivot(index='age_group', columns='cycle_group', values='ratio')
JavaScript
복사
연령대별 재구매 주기 시각화
1달이내, 2달이내, 3달이내, 4달이내, 장기로 주기 변경해서 재분석
2. 상품군 별 트렌드는 무엇인가?
- 상품군별 매출 TOP 10 구하기 + TOP 10 에서 각 상품군별 인기색상 구하기
# 상품군별 매출 -> 고객정보가 없는 매출도 포함해서 분석 left
df_tr_ar_left = transactions.merge(articles, on="article_id", how="left")
# 상품군별 매출 TOP 10
product_group_sales = (df_tr_ar_left.groupby("product_group_name")["price"]
.sum()
.reset_index()
.sort_values("price", ascending=False))
top10_product_group = product_group_sales.head(10)
JavaScript
복사
# 상품군별 매출 TOP 10에서 각 인기색상
# 상품군별 매출 TOP 10을 top10_list 리스트로 만듦
top10_list = top10_product_group["product_group_name"].tolist()
# TOP 10 상품군만 추출
df_top10 = df_tr_ar_left[df_tr_ar_left["product_group_name"].isin(top10_list)] # 프로덕트그룹네임 컬럼에서 탑텐리스트에 포함되면 df_top10에 포함
# 색상별 매출 합
colour_sales = (df_top10.groupby(["product_group_name", "colour_group_name"])["price"]
.sum()
.reset_index())
# 상품군별 인기 색상 상위 3개
colour_sales_rank = (colour_sales.sort_values(["product_group_name", "price"], ascending=[True, False])
.groupby("product_group_name")
.head(3))
JavaScript
복사
- 상품군별 재구매율 파악하기
# 상품군별 재구매율
purchase_count = (df_full.groupby(['product_group_name', 'customer_id']) # 고객의 상품군별 구매 횟수
.size()
.reset_index(name='count'))
total_customers = purchase_count.groupby('product_group_name')['customer_id'].count() # 총 고객 수
repurchase_customers = purchase_count[purchase_count['count'] > 1].groupby('product_group_name')['customer_id'].count() # 2회 이상(재구매) 구매 고객 수
# 재구매율 계산 후 상위 10개
repurchase_rate = (repurchase_customers / total_customers).fillna(0)
repurchase_rate = (repurchase_rate.sort_values(ascending=False)
.reset_index(name = 'repurchase_rate')
.head(10))
JavaScript
복사
3. 연령대별 채널(온, 오프라인) 사용 현황 + 연령대별 매출 상위 10개 상품군 구하기
- 연령대별 채널 사용 현황
# 연령대별 채널 사용현황 (1:오프라인 2:온라인 변환)
df_full['channel'] = df_full['sales_channel_id'].map({1: 'Offline', 2: 'Online'})
age_group_channel = (df_full.groupby(["age_group", "channel"])
.size()
.reset_index(name="transaction_cnt"))
JavaScript
복사
(+) # 각 연령대에서 온라인/오프라인 비율
age_group_channel['sales_ratio'] = age_group_channel['transaction_cnt'] / age_group_channel.groupby('age_group')['transaction_cnt'].transform('sum')
JavaScript
복사
- 연령대별 매출 상위 10개 상품군 구하기
# 연령대 상품군 매출 집계
age_product_sales = (df_full.groupby(["age_group", "product_group_name"])["price"]
.sum()
.reset_index())
# 연령대별 매출 TOP 10 상품군
top10_age_product = (age_product_sales.sort_values(["age_group", "price"], ascending=[True, False])
.groupby("age_group")
.head(10))
JavaScript
복사
4. 개인 추가적인 문제정의 제시
인사이트 정리
연령대별 온/오프라인 사용현황
•
젊은층에서의 온라인 이용 비중이 더 높을줄 알았는데 생각보다 그렇지 않고 오프라인 매장 이용이 유지된다.
10대 58% 20대 70% 30대 75%
SPA 브랜드 특성상 입어보고 사려는 니즈가 유지되어 오프라인 비중도 생각보다 큼.
•
중장년층의 온라인 이용 비중이 생각보다 높다
40대 67% 50대 66% 60대 65%
•
고령층에서 온라인 이용 비중은 예상보다 더 높게 나타남
70대 61% 80대 73% 90대 87%
손주/자녀 도움, 건강, 체력 등 제한사항으로 자연스러운 온라인 구매
표본이 적어 유의해야함
•
오프라인 매장은 전 연령대에서 여전히 이용한다. 실제 구매는 대부분 온라인에서 이루어지고 있고, 40대 이상에서도 온라인 비중이 높다.
온라인 전략
•
사이즈 추천 프로그램 강화
오프라인에서 한 번 피팅하면 온라인에서 해당 사이즈 추천 자동화
•
연령대별 UI·UX 차별화된 추천 페이지 제공
→ 40대 이상 고객에게는 기본템/세트 중심의 단순한 추천 구조
오프라인 매장 전략
•
오프라인 : 체험,확인 채널, 온라인 : 구매 채널로 역할을 확실히 분리
ex) 오프라인에서 스캔 후 온라인 장바구니 담기 기능
•
오래 머무르는 매장, 온라인과 오프라인의 연결, 타사와의 협업
h&m과 고객 경험 향상을 위해 스포티파이와 파트너십을 맺고 매장 내 음악 및 멤버십 혜택 등 다양한 협업을 진행
매장 방문 시 고객이 스포티파이 플레이리스트를 스캔하면 관련 상품 추천 + 할인 쿠폰 제공
오프라인 이벤트 → 온라인 커뮤니티 연계
스포티파이 이벤트와 매장 이벤트를 연동 → 어플, SNS에서 매장 경험 후기 공유 + 보상
고객 참여 유도 → 오프라인 체험이 온라인 구매 나아가 브랜드 충성도로 연결
브랜드 몰입도 상승, 구매 전환율 증가
온라인 전략 정리
1.
40대 이상 고객은 복잡한 추천 구조보다 기본템,세트 중심의 간단한 맞춤형 추천 제공
2.
장바구니에 넣기만 하거나 조회하고 구매하지 않은 상품을 다시 보여주는 기능
ex) 최근 본 상품 + 유사 트렌드 추천, 최근 본 상품 + 가격 변동/재입고 알림
오프라인 전략 정리
1.
오프라인 매장의 강점인 피팅룸 경험 강화 ex) h&m 핵심품목 2~3가지 비치
2.
오래 머무르는 매장, 타사와의 협업
사례) 고객 경험 향상을 위해 스포티파이와 파트너십을 맺고 매장 내 재생하는 플레이리스트 제공 및 멤버십 혜택 등 다양한 협업을 진행
온+오프라인 (옴니채널) 전략 정리
1.
온라인 구매 → 오프라인 픽업 or 오프라인 피팅 → 온라인 구매 연계를 통해 편의성 확대
2.
오프라인에서 구매했던 스타일 or 사이즈 기반으로 온라인에서 추천 제공
연령대별 재구매 주기
•
10~30대(핵심 반복 구매층) 대상
1~2개월 내 반복 구매 비중이 가장 높음
제안
구매 후 30~45일 사이에 신상 추천 / 카테고리 연관 추천 알림 자동 발송
신상품, 트렌디 아이템 중심의 개인화 추천 강화
온라인 전용 프로모션 강화
→ 10~30대 전용 혜택으로 구매 유도
재방문 주기 단축 + 객단가 증가 + 온라인 전환율 상승
•
40~60대(안정적 소비층) 대상
2~3개월 단위로 규칙적 재구매 → 필요 기반 소비 성향
제안
기본템, 시즌성 카테고리 기반 리마인드 캠페인
→ ex) 겨울 시작 전 아우터, 여름 전 린넨/베이직 제품 추천
세트,패키지 기획
→ 기존에 구매했던 제품군과 연계해 묶음 할인 제공
구매 이력 기반 ‘필요 시점’ 추천
→ ex) 양말/속옷/베이직티의 교체 주기 2~3개월 기준 자동 추천
효과 기대
구매 주기를 체계적으로 단축시키며 충성도 상승
매출 TOP 10 상품군의 인기 색상
블랙은 모든 상품군에서 1위 컬러
매출 분석 결과 블랙이 가장 많이 팔렸다는 것은 단순히 사람들이 블랙을 많이 샀다라는 사실
→ “블랙을 선호하기 때문에 H&M 매출이 오른다”는 말까지 곧바로 인과로 연결하면 위험
애초에 h&m이 블랙 의류를 많이 출시하고, 매장 디스플레이나 가격 전략이 블랙에 유리하게 설계됐을 가능성도 있기 때문에 블랙이 잘 팔리는 것은 소비자 선호 + 회사 전략 둘 다의 결과일 수 있음
근거 : 실제 관찰된 데이터(블랙이 제일 잘팔림) + 한국인이 좋아하는 옷 색깔
한국갤럽조사연구소
의사결정을 돕는 방향
마케팅팀이 고객 세그먼트별 마케팅 전략을 어떻게 가져가야 하는지
H&M 상품팀이 상품군별 판매 전략을 어떻게 가져갈지
H&M의 온라인, 오프라인 채널 운영 전략을 어떻게 설정할지
의사결정도움
상품팀
•
성수기 카테고리 가격, 물량 전략
•
비수기 판매 촉진
•
재구매율 높은 상품군에 집중
마케팅팀
•
연령대별 핵심 채널에 집중
•
재구매 주기 기반 자동 알림 시스템 도입
•
블랙 컬러 선호도 기반 프로모션
경영진
•
신규 고객 유치 및 기존 고객 유지 전략
•
수요 예측 기반 상품 기획 체계화
•
재구매율 기반의 상품군별 재고, 공급 운영 효율화 전략









