기초 프로그래밍 주차/기초 프로젝트

기초 프로젝트 코드 분석 #4

juneoh20 2025. 4. 3. 17:23

원래 TIL에 오늘 워낙 많이 적어놔서 스크롤 압박이 심할 것 같아서 여기다가 따로 정리해야 될 것 같았다

 

 

기초 프로젝트 코드 분석 #4

이 코드는 아동복(Baby/Children)을 구매한 고객들이 함께 구매한 다른 품목이 무엇인지 분석하고,
해당 품목의 구매 비율(%) 을 계산하여 표로 나타내는 코드다.

즉, 아동복을 구매하는 고객이 추가로 어떤 품목을 가장 많이 구매하는지를 알아보기 위한 분석이다.

 

 

1. 날짜 형식 변환

 

tran_df["t_dat"] = pd.to_datetime(tran_df["t_dat"])

 

2. 거래 데이터와 상품 정보 병합

 

tran_merged = tran_df.merge(
    art_df[['article_id', 'index_group_name']], 
    on='article_id', 
    how='left'
)

 

  • 거래 데이터(tran_df)와 상품 정보 데이터(art_df)를 article_id 기준으로 병합하여, 각 거래 내역에 상품의 카테고리 정보(index_group_name)를 추가
  • 이를 통해 어떤 품목이 구매되었는지 알 수 있다

 

3. 아동복(Baby/Children) 구매 고객 ID 추출

 

baby_buyers = tran_merged[
    tran_merged["index_group_name"] == "Baby/Children"
]["customer_id"].unique()

 

  • 거래 품목 중 아동의류를 구매한 고객들의 고유 ID를 추출하여, 별도의 배열로 저장
  • 이 과정으로 아동복 구매 고객 리스트 확보.

 

4. 아동복 구매 고객들의 모든 구매 내역 확보

 

baby_customer_purchases = tran_merged[
    tran_merged["customer_id"].isin(baby_buyers)
]

 

  • 위에서 확보한 아동복 구매 고객들이 구매한 전체 상품 목록을 얻음
  • 이를 통해 이 고객들이 아동복 외에 추가로 어떤 품목을 함께 샀는지 분석할 수 있다.

 

5. 고객별 구매 카테고리 묶기

 

customer_categories = baby_customer_purchases.groupby("customer_id")[
    "index_group_name"
].unique().reset_index()

 

  • 고객별로 구매한 모든 품목의 카테고리를 중복 없이 묶어서 각 고객별 구매 카테고리 목록을 정리
  • 즉, 각 고객이 구매한 품목의 종류(카테고리) 를 쉽게 볼 수 있다.

 

6. 아동복을 제외한 품목만 추출하고 카운트하기

 

from collections import Counter
co_purchase_counter = Counter()
for categories in customer_categories["index_group_name"]:
    others = [cat for cat in categories if cat != "Baby/Children"]
    co_purchase_counter.update(others)

 

  • Counter() 객체를 사용하여 아동복을 제외한 품목들의 빈도수를 계산
  • 즉, 아동복과 함께 어떤 품목이 몇 번이나 함께 구매되었는지 빈도수를 셉니다.

 

7. 결과를 DataFrame 형태로 변환

 

co_purchase_df = pd.DataFrame(
    co_purchase_counter.most_common(), 
    columns=["Category", "CoPurchaseCount"]
)

 

8. 각 품목의 구매 비율(%) 계산

 

total_co_purchases = co_purchase_df["CoPurchaseCount"].sum()
co_purchase_df["Percentage"] = (
    co_purchase_df["CoPurchaseCount"] / total_co_purchases * 100
)

 

  • 전체 교차구매 빈도수 합계(total_co_purchases)를 구하고,
  • 각 품목의 빈도수를 전체 빈도수 합계로 나누어 비율(%)을 계산.

 

9. 소수점 둘째자리까지 정리

 

co_purchase_df["Percentage"] = co_purchase_df["Percentage"].round(2)

 

10. 최종 코드

# 교차구매 고객 구매 품목 비율 계산

# 날짜 형식 변환
tran_df["t_dat"] = pd.to_datetime(tran_df["t_dat"])

# article_id에 index_group_name 붙이기
tran_merged = tran_df.merge(art_df[['article_id', 'index_group_name']], on='article_id', how='left')

# Baby/Children 구매한 고객 ID
baby_buyers = tran_merged[tran_merged["index_group_name"] == "Baby/Children"]["customer_id"].unique()

# 이 고객들이 구매한 모든 상품
baby_customer_purchases = tran_merged[tran_merged["customer_id"].isin(baby_buyers)]

# 고객별 구매한 카테고리 묶기
customer_categories = baby_customer_purchases.groupby("customer_id")["index_group_name"].unique().reset_index()

# "Baby/Children" 외 카테고리만 추출
from collections import Counter

co_purchase_counter = Counter()
for categories in customer_categories["index_group_name"]:
    others = [cat for cat in categories if cat != "Baby/Children"]
    co_purchase_counter.update(others)

# DataFrame 생성 (빈도수)
co_purchase_df = pd.DataFrame(co_purchase_counter.most_common(), columns=["Category", "CoPurchaseCount"])

# 퍼센티지 계산
total_co_purchases = co_purchase_df["CoPurchaseCount"].sum()
co_purchase_df["Percentage"] = (co_purchase_df["CoPurchaseCount"] / total_co_purchases) * 100

# 소수점 둘째자리까지 정리
co_purchase_df["Percentage"] = co_purchase_df["Percentage"].round(2)

# 결과 출력
print("✅ Co-Purchase Categories with 'Baby/Children' (Percentage)")
display(co_purchase_df)

 


시각화 코드

1. 데이터를 비율 기준으로 정렬

co_purchase_df_sorted = co_purchase_df.sort_values(by="Percentage", ascending=False)

 

  • 파이차트를 그릴 때, 비율이 높은 카테고리부터 시계 방향으로 표시하기 위해 내림차순으로 데이터를 정렬합니다.
  • 즉, 가장 많이 함께 구매된 품목이 파이차트에서 가장 크게 나타납니다.

 

 

2. 색상 팔레트 지정

colors = ["#595959", "#7F7F7F", "#AEAEAE", "#D1D1D1"]
if len(co_purchase_df_sorted) > len(colors):
    colors = sns.color_palette("pastel", len(co_purchase_df_sorted))

 

  • 파이차트의 각 조각을 명확히 구별하기 위해 색상을 지정합니다.
  • 미리 정해진 4가지 색상을 사용하고, 만약 표시할 데이터가 4개보다 많으면 seaborn의 "pastel" 팔레트를 자동으로 활용하여 색상을 추가 지정합니다.

3. 파이차트 그리기 (plt.pie)

plt.figure(figsize=(8, 8))  # 그래프 크기 지정

plt.pie(
    co_purchase_df_sorted["Percentage"],  # 각 조각의 크기(비율) 지정
    labels=co_purchase_df_sorted["Category"],  # 각 조각의 이름
    autopct='%.1f%%',                       # 자동으로 비율을 %로 표시 (소수점 첫째 자리까지)
    startangle=140,                         # 첫 번째 조각의 시작 각도를 140도로 지정
    colors=colors,                          # 위에서 지정한 색상 사용
    textprops={'fontsize': 12, 'fontweight': 'bold'} # 글자 크기와 굵기 설정
)

 

 

4. 제목과 레이아웃 설정

plt.title("Percentage of Categories Co-purchased with 'Baby/Children'",
          fontsize=15)

plt.axis('equal')  # 원형 유지
plt.tight_layout()
plt.show()

 

5. 전체 코드 및 결과

# 교차구매 고객 구매 품목 비율 시각화

import matplotlib.pyplot as plt
import seaborn as sns

# 데이터 정렬
co_purchase_df_sorted = co_purchase_df.sort_values(by="Percentage", ascending=False)

# 색상 팔레트 지정
colors = ["#595959", "#7F7F7F", "#AEAEAE", "#D1D1D1"]
# 만약 데이터가 4개보다 많다면 추가 색상 지정 필요
if len(co_purchase_df_sorted) > len(colors):
    colors = sns.color_palette("pastel", len(co_purchase_df_sorted))

# 파이차트 그리기
plt.figure(figsize=(8, 8))
plt.pie(
    co_purchase_df_sorted["Percentage"],
    labels=co_purchase_df_sorted["Category"],
    autopct='%.1f%%',
    startangle=140,
    colors=colors,
    textprops={'fontsize': 12, 'fontweight': 'bold'}
)

# 제목 설정
plt.title("Percentage of Categories Co-purchased with 'Baby/Children'",
          fontsize=15)

plt.axis('equal')  # 원형 유지
plt.tight_layout()
plt.show()