결측치 처리
customer.dropna(inplace= True)
customer 테이블에 패션뉴스 구독 주기 컬럼 하나가 널값이길래 제거
articles.fillna('',inplace=True)
디테일 설명은 null값이라고 해서 제거하면 안된다고 생각해서 그냥 빈 값으로 채워줬다.
이상치 처리
튜터님과 논의한 결과, 나이와 금액은 이상치 처리 대상이 아니라고 하셔서 이상치 처리는 안하는 것으로 결론 났다.
회원 상태 별 구매율 다시
# 회원 상태별 고객 수
customer_counts = customer['club_member_status'].value_counts()
# 회원 상태별 구매 건수
purchase_counts = merge_data.groupby('club_member_status')['customer_id'].nunique()
# 구매율 계산
purchase_rate = (purchase_counts / customer_counts).reset_index()
purchase_rate.columns = ['club_member_status', 'purchase_rate']
# 시각화
sns.barplot(x='club_member_status', y='purchase_rate', data=purchase_rate)
plt.title('buy')
plt.show()
전에 했던 코드는 머지 데이터에 중복 id 처리를 안했다. nunique()로 다시!
구매 한 탈퇴 회원 vs 구매 안한 탈퇴 회원 수
LEFT CLUB 회원
left_club_data = customer[customer['club_member_status']=='LEFT CLUB']
# 'LEFT CLUB' 상태인 고객 구매 데이터만 필터링
left_club_data_p = merge_data[merge_data['club_member_status'] == 'LEFT CLUB']
# 'LEFT CLUB' 상태인 고객 중 구매한 고객 ID
purchased_ids = left_club_data_p['customer_id'].unique()
# 'LEFT CLUB' 상태인 고객 중 구매하지 않은 고객
non_purchased_member = customer[(customer['club_member_status'] == 'LEFT CLUB') & (~customer['customer_id'].isin(purchased_ids))]
# LEFT CLUB 멤버 중 구매 한 고객
purchased_member = customer[(customer['club_member_status'] == 'LEFT CLUB') & (customer['customer_id'].isin(purchased_ids))]
# 'LEFT CLUB' 상태에서 구매한 고객 수와 구매하지 않은 고객 수를 바로 리스트로 설정
purchase_status = ['Purchased', 'Not Purchased']
counts = [len(purchased_member), len(non_purchased_member)]
# 바 그래프 그리기
sns.barplot(x=purchase_status, y=counts)
plt.show()
전체 탈퇴 회원 뉴스 구독 여부
sns.countplot(x='FN',data = left_club_data)
plt.show()
구매 이력 있는 탈퇴 회원 뉴스 구독 여부
sns.countplot(x='FN',data = purchased_member)
plt.show()
여전히 구독 여부가 너무 미미함
구매 이력 없는 탈퇴 회원 뉴스 구독 여부
sns.countplot(x='FN',data = non_purchased_member)
plt.show()
결론은 구독 여부가 구매 결정에 도움이 되진 않는다.
탈퇴 회원은 몇 번이나 구매 했을까?
#탈퇴 회원은 몇 번정도 구매했는지
#구매 횟수
p_count = left_club_data_p.groupby('customer_id').size()
#구매 횟수별 고객 수
m_count = p_count.value_counts().sort_index()
# 그래프 그리기
sns.barplot(x=m_count.index, y=m_count.values)
plt.ylabel('member_count')
plt.show()
12번까지 산 사람이 있네...
탈퇴 회원들은 뭐 샀을까?
#탈퇴 회원들이 구매한 product_type_name
total = left_club_data_p.groupby('product_type_name')['customer_id'].count().reset_index().sort_values(by='customer_id', ascending=False)
sns.barplot(x='product_type_name', y='customer_id', data=total)
plt.xticks(rotation = 90)
plt.show()
1년에 5번 이상 구매한 사람들은 뭘 샀길래 탈퇴했을까?
#5번 이상 구매한 사람들이 산 제품들
more_5_id =p_count[p_count.values>=5].index
more_5_data = left_club_data_p[left_club_data_p['customer_id'].isin(more_5_id)]
more_5 = more_5_data.groupby('product_type_name')['customer_id'].count().reset_index().sort_values(by='customer_id', ascending=False)
sns.barplot(x='product_type_name', y='customer_id', data=more_5)
plt.xticks(rotation = 90)
plt.show()
1번만 사고 탈퇴한 사람들은 뭘 샀을까?
#한 번 사고 탈퇴한 회원들 제품 현황
one_id = p_count[p_count.values==1].index
one_data = left_club_data_p[left_club_data_p['customer_id'].isin(one_id)]
purchase_counts_by_group = one_data.groupby('product_type_name')['customer_id'].count().reset_index().sort_values(by='customer_id', ascending=False)
sns.barplot(x='product_type_name', y='customer_id', data=purchase_counts_by_group)
plt.xticks(rotation = 90)
plt.show()
12번 산 사람의 행적을 찾아서
# 12번 산 탈퇴 회원의 행적
id_12 =p_count[p_count.values==12].index
id_12_data = left_club_data_p[left_club_data_p['customer_id'].isin(id_12)]
id_12_data[['t_dat', 'product_type_name']].sort_values('t_dat')
마지막으로 산 제품은 뭐가 있을까?
#마지막 구매 제품
# 각 고객의 마지막 구매 날짜를 찾고
last_purchase = left_club_data_p.groupby('customer_id')['t_dat'].max().reset_index()
# 마지막 구매 날짜를 원본 데이터와 병합 (customer_id와 t_dat 기준으로)
last_purchase_products = last_purchase.merge(left_club_data_p, on=['customer_id', 't_dat'], how='inner')
# 결과 확인
last_product_type = last_purchase_products[['customer_id', 't_dat', 'product_type_name']]
sns.countplot(x='product_type_name',data=last_product_type,order=last_product_type['product_type_name'].value_counts().index)
plt.title('last_purchase')
plt.xticks(rotation = 90)
plt.show()
탈퇴 회원이 구매 후 가장 많이 탈퇴 한 제품은?
#마지막 구매/전체 구매 비율
# 탈퇴 회원들의 마지막 구매 제품 개수 계산
last_product_counts = last_purchase_products['product_type_name'].value_counts().reset_index()
last_product_counts.columns = ['product_type_name', 'last_purchase_count']
# 탈퇴 회원들이 전체적으로 구매한 제품 개수 계산
total_product_counts = left_club_data_p['product_type_name'].value_counts().reset_index()
total_product_counts.columns = ['product_type_name', 'total_purchase_count']
# 두 데이터 병합 + 마지막 구매율 계산
purchase_comparison = last_product_counts.merge(total_product_counts, on='product_type_name', how='inner')
purchase_comparison['last_purchase_rate'] = purchase_comparison['last_purchase_count'] / purchase_comparison['total_purchase_count']
# 마지막 구매율이 높은 순으로 정렬
purchase_comparison = purchase_comparison.sort_values(by='last_purchase_rate', ascending=False)
# 상위 10개 제품 바 그래프로 시각화
top_10 = purchase_comparison.head(10)
sns.barplot(x='product_type_name', y='last_purchase_rate', data=top_10)
plt.title('Last Purchase Rate by Product Type (LEFT CLUB Members)')
plt.xticks(rotation = 90)
plt.show()
블레이저는 사고 바로 탈퇴했네 다들
그걸 비율로 하면?
#마지막 구매 비율 누적 그래프
purchase_comparison['non_last_purchase_rate'] = 1 - purchase_comparison['last_purchase_rate'] # 나머지 비율 계산
purchase_comparison = purchase_comparison.sort_values(by='last_purchase_rate', ascending=False)
# 누적 막대 그래프 그리기 (비율로)
purchase_comparison.set_index('product_type_name', inplace=True)
purchase_comparison[['last_purchase_rate', 'non_last_purchase_rate']].plot(kind='bar', stacked=True, figsize=(12, 6), color=['red', 'skyblue'])
plt.title('Last Purchase Rate vs. Non-Last Purchase Rate by Product Type')
plt.xlabel('Product Type')
plt.ylabel('Purchase Rate')
plt.xticks(rotation=90)
plt.legend(['Last Purchase Rate', 'Non-Last Purchase Rate'])
plt.tight_layout()
plt.show()
근데 팀원들이 다들 이해 안간다고 한참 물어봄...
망한 그래프가 아닐까 그럼?ㅜㅜ
우선 오늘은 여기까지
'데이터분석 6기 > 본캠프' 카테고리의 다른 글
[TIL] 2025-03-26 기초 프로젝트 5 (0) | 2025.03.26 |
---|---|
[TIL] 2025-03-25 기초 프로젝트 4 (0) | 2025.03.25 |
[TIL] 2025-03-21 - 기초 프로젝트 2 (2) | 2025.03.21 |
[TIL] 2025.03.20 - 기초 프로젝트 (1) | 2025.03.21 |
[TIL] 2025.03.18 (0) | 2025.03.18 |