본문 바로가기
STUDY

[멋쟁이사자처럼부트캠프_그로스마케팅] Day18-2 고객 세분화를 위한 통계 분석

by vol2 2025. 3. 7.

 

     

    1 고객 세분화를 위한 통계 분석

    고객 세분화(Customer Segmentation)는 고객의 특성과 행동 패턴을 분석하여 비슷한 그룹으로 나누는 과정이다. 이를 통해 맞춤형 마케팅 전략을 수립하고, 고객 만족도를 높이며, 기업의 수익을 극대화할 수 있다.

    고객 세분화를 수행하기 위해 다양한 통계 분석 기법이 활용되며, 대표적인 방법으로 기술 통계 분석, K-평균 군집 분석, RFM 분석, 계층적 군집 분석이 있다.

    1.1 기술 통계 분석

    기술 통계 분석은 데이터의 분포와 기본적인 특징을 파악하는 데 사용된다. 고객 데이터를 분석할 때 자주 사용되는 통계 지표는 다음과 같다.

    • 평균 (Mean): 고객 1인당 평균 구매 금액, 평균 방문 횟수 등을 분석하는 데 사용된다.
    • 중앙값 (Median): 데이터의 중앙값을 계산하여 이상치의 영향을 최소화할 수 있다.
    • 표준편차 (Standard Deviation): 고객 간 소비 패턴의 차이를 파악하는 데 도움을 준다.
    • 최댓값 및 최솟값 (Max & Min): 가장 높은 구매 금액과 가장 낮은 구매 금액을 확인할 수 있다.

    예제 코드

    import pandas as pd
    
    data = {
        "고객ID": range(1, 11),
        "총구매금액": [50000, 150000, 30000, 400000, 120000, 80000, 60000, 200000, 90000, 250000],
        "방문횟수": [5, 20, 3, 40, 12, 8, 6, 25, 10, 35]
    }
    
    df = pd.DataFrame(data)
    
    # 기술 통계 분석 수행
    summary_stats = df.describe()
    print(summary_stats)
    

    1.2 K-평균 군집 분석

    K-평균 군집 분석(K-Means Clustering)은 고객을 여러 개의 그룹으로 나누는 방법이다. 유사한 특성을 가진 고객끼리 묶어 그룹을 생성하며, 그룹의 개수(K)는 사전에 지정해야 한다.

    이 방법을 사용하면 고객을 고가 제품 선호 그룹, 할인 제품 선호 그룹 등으로 구분할 수 있다.

    예제 코드

    import matplotlib.pyplot as plt
    import pandas as pd
    !pip install koreanize-matplotlib
    import koreanize_matplotlib
    from sklearn.cluster import KMeans #sklearn.cluster 모듈, Kmeans 클래스 삽입
    
    data = {
        "고객ID": range(1, 11),
        "총구매금액": [50000, 150000, 30000, 400000, 120000, 80000, 60000, 200000, 90000, 250000],
        "방문횟수": [5, 20, 3, 40, 12, 8, 6, 25, 10, 35]
    }
    
    df = pd.DataFrame(data) #데이터프레임 생성
    X = df[["총구매금액", "방문횟수"]] #X 변수 설정
    
    # K-Means 클러스터링 수행
    kmeans = KMeans(n_clusters=3, random_state=42) # Kmeans 클러스터링 K= 3, random값 42(관례적)
    df["군집"] = kmeans.fit_predict(X) #X변수에 대해 Kmeans 학습, 군집
    
    # 시각화
    plt.scatter(X["총구매금액"], X["방문횟수"], c=df["군집"], cmap="viridis", alpha=0.7) # 산점도 x값 총구매금액, y값 방문횟수, 색 추가 군집
    plt.xlabel("총 구매 금액")
    plt.ylabel("방문 횟수")
    plt.title("K-Means 군집 분석 결과")
    plt.colorbar() # 색상바 추가
    plt.show()
    
    print(df['군집'])
    

    1.3 RFM 분석

    RFM 분석(Recency, Frequency, Monetary Analysis)은 고객을 최근성(Recency), 빈도(Frequency), 금액(Monetary) 기준으로 평가하여 고객의 가치를 측정하는 방법이다.

    • 최근성 (Recency): 고객이 마지막으로 구매한 날짜를 기준으로 측정된다.
    • 빈도 (Frequency): 일정 기간 동안 고객이 구매한 횟수를 측정한다.
    • 금액 (Monetary): 고객이 사용한 총 금액을 기준으로 평가한다.

    이 분석을 통해 VIP 고객, 일반 고객, 이탈 가능 고객을 구분할 수 있다.

    예제 코드

    import numpy as np
    
    data = {
        "고객ID": range(1, 11),
        "구매일": pd.date_range(start="2024-01-01", periods=10, freq="30D"),
        "총구매금액": [50000, 150000, 30000, 400000, 120000, 80000, 60000, 200000, 90000, 250000]
    }
    
    df = pd.DataFrame(data)
    
    # 현재 날짜 기준 최근성 계산
    df["Recency"] = (pd.to_datetime("today") - df["구매일"]).dt.days
    
    # 빈도와 금액 계산
    df["Frequency"] = np.random.randint(1, 20, len(df))
    df["Monetary"] = df["총구매금액"]
    
    # RFM 점수 부여
    df["R_Score"] = pd.qcut(df["Recency"], 5, labels=[5, 4, 3, 2, 1])
    df["F_Score"] = pd.qcut(df["Frequency"], 5, labels=[1, 2, 3, 4, 5])
    df["M_Score"] = pd.qcut(df["Monetary"], 5, labels=[1, 2, 3, 4, 5])
    
    df["RFM_Score"] = df["R_Score"].astype(int) + df["F_Score"].astype(int) + df["M_Score"].astype(int)
    
    print(df[["고객ID", "Recency", "Frequency", "Monetary", "RFM_Score"]])
    
    #출력값
       고객ID  Recency  Frequency  Monetary  RFM_Score
    0     1      423         17     50000          6
    1     2      393          9    150000          6
    2     3      363         18     30000          8
    3     4      333         19    400000         12
    4     5      303         14    120000          8
    5     6      273          2     80000          6
    6     7      243         15     60000          9
    7     8      213         16    200000         12
    8     9      183         13     90000         10
    9    10      153         14    250000         12
    

    1.4 계층적 군집 분석

    계층적 군집 분석(Hierarchical Clustering)은 고객을 계층 구조로 그룹화하여 유사도에 따라 점진적으로 병합하는 방법이다. 이 분석을 통해 고객을 세부적인 등급으로 나눌 수 있다.

    예제 코드

    from scipy.cluster.hierarchy import linkage, dendrogram
    
    data = {
        "고객ID": range(1, 11),
        "총구매금액": [50000, 150000, 30000, 400000, 120000, 80000, 60000, 200000, 90000, 250000],
        "방문횟수": [5, 20, 3, 40, 12, 8, 6, 25, 10, 35]
    }
    
    df = pd.DataFrame(data)
    X = df[["총구매금액", "방문횟수"]]
    
    # 계층적 군집 분석 수행
    linkage_matrix = linkage(X, method="ward")
    
    # 덴드로그램 시각화
    plt.figure(figsize=(10, 5))
    dendrogram(linkage_matrix)
    plt.title("계층적 군집 분석 (Dendrogram)")
    plt.xlabel("고객 인덱스")
    plt.ylabel("거리")
    plt.show()
    

    • "customer_segmentation.csv” 기본 통계 정보 출력, K-Means 클러스터링, 군집 시각화, RFM, 계층적 군집 분석

    2. 확률변수(Probability Variable)

    확률변수는 불확실한 사건의 결과를 수치화하는 변수를 의미한다. 예를 들어, 동전을 던졌을 때 앞면(1) 또는 뒷면(0)이 나오는 것은 불확실하지만, 이 사건을 확률적으로 모델링할 수 있다.


    2.1 확률변수의 유형

    확률변수는 크게 이산형(Discrete) 확률변수연속형(Continuous) 확률변수로 나뉜다.

    1. 이산 확률변수 (Discrete Random Variable)

    • 특정한 개별 값만 가질 수 있는 확률변수
    • 예) 동전 던지기(앞면=1, 뒷면=0), 주사위 눈금(1,2,3,4,5,6), 고객의 구매 횟수(정수값)

    대표적인 이산 확률분포:

    • 베르누이 분포 (Bernoulli Distribution) → 성공(1) 또는 실패(0) 중 하나의 값을 가지는 확률 모델
    • 이항 분포 (Binomial Distribution) → n번 시행 중 성공이 나오는 횟수 분포
    • 포아송 분포 (Poisson Distribution) → 일정 시간 내에 발생하는 이벤트 횟수 분포

    2. 연속 확률변수 (Continuous Random Variable)

    • 특정 구간 내의 모든 실수 값을 가질 수 있는 확률변수
    • 예) 고객의 방문 시간(2.5초, 3.7초 등), 평균 구매 금액(75,000원)

    대표적인 연속 확률분포:

    • 정규 분포 (Normal Distribution) → 자연에서 가장 많이 나타나는 분포, 평균을 중심으로 대칭적
    • 지수 분포 (Exponential Distribution) → 사건이 발생하는 시간 간격의 확률 모델
    • 감마 분포 (Gamma Distribution) → 여러 개의 지수 분포를 합친 형태

    확률변수의 적용 예시

    1. 베르누이 확률변수 (광고 클릭 여부)
      • 광고가 노출될 때, 클릭(1)할지 안 할지(0) 결정하는 확률변수
    2. 이항 확률변수 (A/B 테스트 결과)
      • 1000명의 고객에게 광고 A를 노출했을 때 몇 명이 클릭할 것인가?
    3. 지수 확률변수 (고객의 웹사이트 체류 시간)
      • 고객이 웹사이트에 방문 후 얼마나 오래 머무르는가?
    4. 베타 확률변수 (전환율 예측)
      • 두 가지 마케팅 전략 중 전환율이 높은 캠페인은 무엇인가?

     

    확률 분포 그래프

    import numpy as np
    import matplotlib.pyplot as plt
    import seaborn as sns
    from scipy.stats import bernoulli, binom, poisson, norm, expon, gamma, beta
    
    # 데이터 시드 설정
    np.random.seed(42)
    
    # 1. 베르누이 분포 (Bernoulli Distribution) - 광고 클릭 여부 (0 or 1)
    bernoulli_data = bernoulli.rvs(p=0.3, size=1000)
    
    plt.figure(figsize=(8, 5))
    sns.histplot(bernoulli_data, discrete=True, kde=False, bins=2)
    plt.xlabel("광고 클릭 여부 (0: 실패, 1: 성공)")
    plt.ylabel("빈도")
    plt.title("베르누이 분포 (Bernoulli Distribution)")
    plt.xticks([0, 1])
    plt.grid()
    plt.show()
    
    # 2. 이항 분포 (Binomial Distribution) - 10번 광고 노출 중 클릭 횟수
    binom_data = binom.rvs(n=10, p=0.3, size=1000)
    
    plt.figure(figsize=(8, 5))
    sns.histplot(binom_data, discrete=True, kde=False, bins=11)
    plt.xlabel("클릭 횟수")
    plt.ylabel("빈도")
    plt.title("이항 분포 (Binomial Distribution)")
    plt.grid()
    plt.show()
    
    # 3. 포아송 분포 (Poisson Distribution) - 1시간 동안 유입되는 고객 수
    poisson_data = poisson.rvs(mu=5, size=1000)
    
    plt.figure(figsize=(8, 5))
    sns.histplot(poisson_data, discrete=True, kde=False, bins=15)
    plt.xlabel("1시간 동안 유입된 고객 수")
    plt.ylabel("빈도")
    plt.title("포아송 분포 (Poisson Distribution)")
    plt.grid()
    plt.show()
    
    # 4. 정규 분포 (Normal Distribution) - 고객 평균 구매 금액
    norm_data = norm.rvs(loc=50000, scale=15000, size=1000)
    
    plt.figure(figsize=(8, 5))
    sns.histplot(norm_data, kde=True, bins=30)
    plt.xlabel("구매 금액 (원)")
    plt.ylabel("빈도")
    plt.title("정규 분포 (Normal Distribution)")
    plt.grid()
    plt.show()
    
    # 5. 지수 분포 (Exponential Distribution) - 고객의 체류 시간
    expon_data = expon.rvs(scale=5, size=1000)
    
    plt.figure(figsize=(8, 5))
    sns.histplot(expon_data, kde=True, bins=30)
    plt.xlabel("고객 체류 시간 (분)")
    plt.ylabel("빈도")
    plt.title("지수 분포 (Exponential Distribution)")
    plt.grid()
    plt.show()
    
    # 6. 감마 분포 (Gamma Distribution) - 고객 생애 구매 횟수
    gamma_data = gamma.rvs(a=2, scale=2, size=1000)
    
    plt.figure(figsize=(8, 5))
    sns.histplot(gamma_data, kde=True, bins=30)
    plt.xlabel("고객 생애 구매 횟수")
    plt.ylabel("빈도")
    plt.title("감마 분포 (Gamma Distribution)")
    plt.grid()
    plt.show()
    
    # 7. 베타 분포 (Beta Distribution) - 전환율 예측
    beta_data = beta.rvs(a=2, b=5, size=1000)
    
    plt.figure(figsize=(8, 5))
    sns.histplot(beta_data, kde=True, bins=30)
    plt.xlabel("전환율")
    plt.ylabel("빈도")
    plt.title("베타 분포 (Beta Distribution)")
    plt.grid()
    plt.show()
    

     


    *day 19에 한 day18 교안 내용