내일배움캠프/TIL

[TIL]241227기초프로젝트_데이터 전처리

dydatablog 2024. 12. 27. 23:29
728x90

기초프로젝트(24.12.26-25.01.03)

사용 데이터 : 스타벅스 마케팅 데이터

 

오늘 토의 내용: 주제 선정에 맞는 목적과 구체적인 방법, 어떤 데이터를 사용하여 어떤 값을 찾을 것인지.

목적 : 스타벅스의 프로모션 성과 확인 및 강화

방법 :

- 전체 유저를 대상으로 각 프로모션(10개)의 영향력 측정:

  1. 참여율 offer complete/ offer view

(※received -> completed -> viewed 순서인 경우도 있어서 view를 하고 completed한 값이 반드시 참여율이라고는 할 수 없을수도..? complete / received로 측정? )

  2. 거래 금액

- 고객 세그먼트별 프로모션의 성과 확인:

  1. 고객 세그먼트 : RFM을 기준으로 4분위(25%,50%,75%)로 분류

  2. 세그먼트별 특징 분석 : 연령대, 성별, 가입날짜, 수입 등...

 

데이터에서 알게된 것

-  event에서 offer complete가 발생하기 직전에 같은 time값으로 항상 transaction이 발생했기 때문에 이 transaction은 쿠폰을 사용해서 구매한 값일 것으로 추측.  -> 프로모션을 통해 얻은 수익을 구할 수 있음.

 

전처리 하면서 알게된 것:

- RFM분석에서 구매를 한번도 하지 않은 고객값은 빼고 계산한다.

ex) 17000명의 유저 중 30일 동안 한번이라도 구매를 한 사람이 16578명이면 평균등의 기초통계를 구할 때 데이터 값은 16578로 카운트한다.


데이터 전처리

JSON타입을 파싱해서 컬럼값으로

transcript 테이블에 value컬럼이 JSON타입의 형태로 되어있기 때문에 데이터 값을 따로 컬럼값으로 만들어주기

 

[참고 사이트]

https://velog.io/@jellda/Python-json-%ED%83%80%EC%9E%85-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%84%ED%95%B4%ED%95%B4-%EC%83%88%EB%A1%9C%EC%9A%B4-%EC%BB%AC%EB%9F%BC%EC%9C%BC%EB%A1%9C-%EC%A0%80%EC%9E%A5%ED%95%98%EA%B8%B0

 

 

[Python] json 타입 데이터 파싱해 새로운 컬럼으로 저장하기

데이터셋 확인 value 컬럼을 보면 아래와 같이 묶여있는 것을 확인 할 수 있다. 이걸 풀어서 offer id 라는 새로운 컬럼을 생성해 그 안에 offer id 에 해당하는 값을 넣어줄 것이다. event = offer received ->

velog.io

 

import ast
df_value = df_trans['value'].apply(ast.literal_eval)
pd.json_normalize(df_value)

 

RFM분석

Recency 구하기 : 얼마나 최근에 구매했는가
# transaction이 발생한 person별 time값의 최대값(가장 최근 구매한 시간)
trn_recency = trn[trn['event']=='transaction'].groupby('person').max()

# time값의 4분위별 포인트 출력
Q1 = np.percentile(trn_recency['time'], 25)
Q2 = np.percentile(trn_recency['time'], 50)
Q3 = np.percentile(trn_recency['time'], 75)

def assign_points(amount):
    if amount >= Q3:
        return 4
    elif amount >= Q2:
        return 3
    elif amount >= Q1:
        return 2
    else:
        return 1

# 포인트 컬럼 생성
trn_recency['rpoint'] = trn_recency['time'].apply(assign_points)
trn_recency

 

Frequency 구하기 : 얼마나 자주 구매했는가
# 고객별 transaction이 발생한 빈도수
trn_frequency = trn[trn['event']=='transaction'].groupby('person').count()

# frequency의 amount값(count)의 4분위별 포인트 출력
Q1 = np.percentile(trn_frequency['amount'], 25)
Q2 = np.percentile(trn_frequency['amount'], 50)
Q3 = np.percentile(trn_frequency['amount'], 75)

def assign_points(amount):
    if amount >= Q3:
        return 4
    elif amount >= Q2:
        return 3
    elif amount >= Q1:
        return 2
    else:
        return 1

# 포인트 컬럼 생성
trn_frequency['fpoint'] = trn_frequency['amount'].apply(assign_points)
trn_frequency.drop(columns='point')

 

Monetary 구하기 : 얼마나 많은 금액을 지출했는가
#유저별 amount합계값
trn_monetary = trn[trn['event'] == 'transaction'].groupby('person').sum()

# monetary의 amount값(sum)의 4분위별 포인트 출력
Q1 = np.percentile(trn_monetary['amount'], 25)
Q2 = np.percentile(trn_monetary['amount'], 50)
Q3 = np.percentile(trn_monetary['amount'], 75)

def assign_points(amount):
    if amount >= Q3:
        return 4
    elif amount >= Q2:
        return 3
    elif amount >= Q1:
        return 2
    else:
        return 1

# 포인트 컬럼 생성
trn_monetary['mpoint'] = trn_monetary['amount'].apply(assign_points)
trn_monetary.drop(columns='point')

 

고객 세그멘트

# rfm의 각point들을 가져와서 새로운 데이터 프레임 생성
df1 = trn_recency['rpoint']
df2 = trn_frequency['fpoint']
df3 = trn_monetary['mpoint']

merged_df = pd.merge(df1, df2, on='person', how='outer')
merged_df = pd.merge(merged_df, df3, on='person', how='outer')
merged_df['total_point'] = merged_df['rpoint'] + merged_df['fpoint'] + merged_df['mpoint']
merged_df

#포인트 합계별 세그멘테이션
Q1 = np.percentile(merged_df['total_point'], 25)
Q2 = np.percentile(merged_df['total_point'], 50)
Q3 = np.percentile(merged_df['total_point'], 75)

def seg(amount):
    if amount >= Q3:
        return 'gold level'
    elif amount >= Q2:
        return 'green level'
    elif amount >= Q1:
        return 'welcome level'
    else:
        return 'low'

# 컬럼 생성
merged_df['user_seg'] = merged_df['total_point'].apply(seg)
merged_df

 

#유저 세그멘트별 유저 수
merged_df.groupby('user_seg').count()

 

 

 

728x90