카테고리 없음

데이터 분석 트랙 97일차 25.06.26. [TIL]

jjaio8986 2025. 6. 26. 22:25

[최종 프로젝트 진행 상황]

  • 상품추천 시스템 구현 완료
  • 대시보드 구상 시작

- 협업 필터링을 통한 상품 추천 시스템 구현 완료

# 1. 데이터 전처리 "고객-상품 매트릭스 생성"
# 설명 : 고객(household_key)과 상품(PRODUCT_ID)의 구매 수량 데이터를 집계하여 기초 상호작용 테이블을 생성
df_matrix = df_cleaned[['household_key', 'PRODUCT_ID', 'QUANTITY']].copy()
df_matrix['QUANTITY'] = df_matrix['QUANTITY'].astype(int)
df_matrix = df_matrix.groupby(['household_key', 'PRODUCT_ID'])['QUANTITY'].sum().reset_index()
# 2. 고객-중분류 기반 협업 필터링(유사한 상품군 추천)
# 2.1. 고객*중분류 매트릭스 생성
# 설명 : 고객-상품 메트릭스에서 중분류 단위로 상품 유사도를 계산하여 행렬로 표시!
# 원본
df_sub = df_cleaned[['household_key', 'SUB_COMMODITY_DESC', 'QUANTITY']].copy()
df_sub = df_sub.groupby(['household_key', 'SUB_COMMODITY_DESC'])['QUANTITY'].sum().reset_index()

user_sub_matrix = df_sub.pivot_table(index='household_key',
                                     columns='SUB_COMMODITY_DESC',
                                     values='QUANTITY',
                                     fill_value=0)
# 중분류 단위 구매 수량 집계 및 피벗 테이블 생성
df_sub = df_cleaned[['household_key', 'COMMODITY_DESC', 'QUANTITY']].copy()
df_sub = df_sub.groupby(['household_key', 'COMMODITY_DESC'])['QUANTITY'].sum().reset_index()

user_sub_matrix = df_sub.pivot_table(index='household_key',
                                     columns='COMMODITY_DESC',
                                     values='QUANTITY',
                                     fill_value=0)

# 2.2. 중분류 간 유사도 계산 [현재 중분류 단위로 적용]
# 설명 : cosine similarity를 이용한 소분류 간 유사도 행렬 생성
from sklearn.metrics.pairwise import cosine_similarity

sub_sim_matrix = cosine_similarity(user_sub_matrix.T)
sub_sim_df = pd.DataFrame(sub_sim_matrix,
                          index=user_sub_matrix.columns,
                          columns=user_sub_matrix.columns)
# 3. 추천 함수 구현
# 3.1. 사용자의 구매 이력을 기반으로 유사 소분류 추천
def recommend_subcategories(user_id, user_sub_matrix, sub_sim_df, top_n=5):
    user_vector = user_sub_matrix.loc[user_id]
    user_prefs = user_vector[user_vector > 0]
    scores = pd.Series(dtype='float64')

    for sub in user_prefs.index:
        similar_subs = sub_sim_df[sub] * user_prefs[sub]
        scores = scores.add(similar_subs, fill_value=0)

    scores = scores.drop(user_prefs.index, errors='ignore')
    return scores.sort_values(ascending=False).head(top_n)
# 4. 성능 개선 : 유효 상품군으로 필터링
valid_departments = [
    'GROCERY', 'PASTRY', 'MEAT-PCKGD', 'SEAFOOD-PCKGD', 'PRODUCE',
                'NUTRITION', 'DELI', 'MEAT', 'SEAFOOD', 'SALAD BAR',
                'GRO BAKERY', 'FROZEN GROCERY', 'SPIRITS', 'DAIRY DELI',
                'CHEF SHOPPE', 'PORK', 'POSTAL CENTER', 'PHOTO', 'VIDEO'
]  # 주요 DEPARTMENT 리스트
# 원본
"""valid_sub_desc = product[product['DEPARTMENT'].isin(valid_departments)]['SUB_COMMODITY_DESC'].unique()
filtered_df = df_cleaned[df_cleaned['SUB_COMMODITY_DESC'].isin(valid_sub_desc)]"""
# 중분류 단위로 적용
valid_sub_desc = product[product['DEPARTMENT'].isin(valid_departments)]['COMMODITY_DESC'].unique()
filtered_df = df_cleaned[df_cleaned['COMMODITY_DESC'].isin(valid_sub_desc)]