내일배움캠프/TIL

[최종프로젝트정리] 군집결과, 가설검정

dydatablog 2025. 4. 10. 21:15

군집 시행 결과

군집결과1

-> 평균 좋아요 수, 총 판매 상품 수가 너무 한쪽으로 치우쳐 있거나 극단적으로 떨어져 있어 명확하게 구분이 되지 않음.

각 컬럼에서 0값을 제거한 후 상위 1%를 제외한 데이터 분포를 확인


평균 좋아요 수와 총 판매 상품 수는 오른쪽으로 긴 꼬리를 가지며 이상치의 영향을 크게 받는 것으로 보임. 따라서 로그 변환을 적용하여 군집 분석을 진행(NumPy의 log1p 함수, StandardScaler를 사용)

→ K-means는 거리기반으로 군집을 수행하기 때문에 반드시 해석 과정에서 변환 전 원본 값을 함께 확인하기!!(튜터님 피드백)

 

정품 인증 통과율이 0인 판매자들은 신뢰의 정도를 측정할 수 없고, 기업의 추구 방향성과 맞지 않기 때문에 별도의 클러스터로 분류하기로 결정.

 

군집결과2
클러스터별 이름 부여

 


가설설정

검정 방법 선택 과정

  • 정규성을 만족하지 못하는 경우 (2개 집단 비교) ⇒ mann-whitney 검정

mannwhitneyu — SciPy v1.15.2 Manual

  • 정규성을 만족하지 못하는 경우 (3개 집단 비교) ⇒ kruskal 검정

kruskal — SciPy v1.15.2 Manual

통계 주차에서 사용했던 t-test나 anova-test는 집단들 간의 평균을 이용하여 검정

⇒ mann-whiteny와 kruskal은 중앙값을 이용하여 집단들 간 비교 검정

 


가설1 : 판매자의 배지 레벨이 높을 수록 평균 수익이 높을 것이다. ⇒ 기각

  • 가설 설정 과정: 판매 개수와 인증 통과율이 현재의 뱃지 분류와 불일치 → 회사 수익과 관련이 있다.
  • 가설: 판매자의 뱃지 레벨이 높을수록 회사에게 가져다 주는 수익이 많을 것이다.
    • 종속변수: 뱃지 레벨 (범주형 변수)
    • 독립변수: 수익 (연속형 변수)
    • ⇒ 독립변수가 정규분보를 만족하지 않아 Kruskal 사용
  • 검정 결과 : H-통계량 : 201.0458 / p-value: 0.0000
  • 가설 기각, 판매자의 뱃지 레벨이 수익에 영향을 미치지 않는다.

사후 검정

# 색상이 다르게 나와서 matplotlib으로 변경
import matplotlib.pyplot as plt

# x축 순서 정의
order = ['Common', 'Trusted', 'Expert']
badge_profit_ordered = badge_profit.set_index('seller_badge').loc[order].reset_index()

# 색상 매핑
badge_colors = {
    'Common': '#FBE1CC',
    'Trusted': '#F4A261',
    'Expert': '#FF5A28'
}
colors = [badge_colors[badge] for badge in badge_profit_ordered['seller_badge']]

# 시각화
plt.figure(figsize=(6, 4))
plt.bar(
    badge_profit_ordered['seller_badge'],
    badge_profit_ordered['company_profit'],
    color=colors
)

plt.title('Seller Badge ~ Company Profit')
plt.xlabel('Seller Badge')
plt.ylabel('Company Profit Average')
plt.tight_layout()
plt.show()

가설2 : 정품 인증 통과율이 높은 그룹이 판매한 상품의 이윤이 많을 것이다 ⇒ 기각

kruskal 검정

Google Colab

  • stats.kruskal
    • H0: 모든 그룹의 중위수 차이는 0이다.
    • H1: 적어도 한 그룹의 중앙값이 다른 그룹과 다르다.

import scikit_posthocs as sp

Kruskal-Wallis 테스트

F, p = stats.kruskal(anova_0['회사수익'], anova_2['회사수익'], anova_4['회사수익'])

print(f'Kruskal-Wallis H-statistic: {F:.4f}') print(f'P-Value: {p:.4f}')

Kruskal-Wallis 검정에서 유의미한 차이가 있을 경우, Dunn's Test를 수행

if p < 0.05: print("\nKruskal-Wallis 결과 유의미함! → Dunn's Test 수행")

# Dunn's Test (scikit-posthocs 라이브러리 사용)
data = [anova_0['회사수익'], anova_2['회사수익'], anova_4['회사수익']]
dunn_result = sp.posthoc_dunn(data, p_adjust='bonferroni')

# Dunn's Test 결과 출력
print(dunn_result)

else: print("\nKruskal-Wallis 결과 유의하지 않으므로, Dunn's Test 생략")

import scikit_posthocs as sp

 

Kruskal-Wallis H-statistic: 187.3463 P-Value: 0.0000

⇒ 0.05보다 작으므로 귀무가설 기각.

⇒ 따라서 적어도 한 그룹의 중앙값이 다른 그룹과 다르다. = 모든 그룹의 중위수는 같은 것이 아니다.

  • Dunn's Test (사후검정) : 전체적인 분포가 같다/다르다
    • H0: 두 집단의 분포는 같다.
    • H1: 두 집단의 분포는 같지 않다.

그룹 1-2 P-value : 2.308949e-14 = 약 0 ⇒ 두 집단의 분포는 같지 않다

그룹 1-3 P-value : 3.050762e-10 = 약 0 ⇒ 두 집단의 분포는 같지 않다

그룹 2-3 P-value : 2.091523e-41 = 약 0 ⇒ 두 집단의 분포는 같지 않다

⇒ 모든 집단의 분포가 같지 않다.

 

 

사후 검정

 

통과율이 0인 군집4보다 통과율이 가장 높은 군집 0의 수익 분포가 더 낮음

따라서, 통과율이 높은 군집 마케팅 필요.


가설3 : 예비 우수 판매자들은 관심 필요 판매자보다 상품의 평균 가격이 더 높을 것이다  ⇒ 채택

  • 가설 설정 과정: 예비 우수 판매자들의 좋아요 수가 더 많지만 판매된 상품 수가 관심 필요 판매자보다 적음 → 비싼 제품을 팔기 때문일 것이다
  • 가설: 예비 우수 판매자들은 관심 필요 판매자보다 상품의 평균 가격이 더 높을 것이다.
    • 집단 A: 예비 우수 판매자 (클러스터 3)
    • 집단 B: 관심 필요 판매자 (클러스터 0)
    • 종속변수: 상품의 평균 가격 (연속형)
    • 독립변수: 예비 우수 판매자, 관심 필요 판매자 (범주형, 그룹 2개, 독립표본)
    • ⇒ 정규성 검정을 통해 2 sample T-test 와 Mann-Whitney 중 선택해야함

정규성 검정 : 가설 검정 전 선행되어야함 ⇒ 가설 검정 방법 선택 가능

# 집단 나누기
group_a = merge_df[merge_df['군집'] == 3]['판매가']
group_b = merge_df[merge_df['군집'] == 0]['판매가']

# 정규성 검정
from scipy import stats

stat, p = stats.shapiro(group_a)
print(f'stat: {stat:.4f}')
print(f'stat: {p:.4f}')

if p > 0.05:
    print('group_a는 정규성을 만족합니다.')
else:
    print('group_a는 정규성을 만족하지 않습니다.')

stat, p = stats.shapiro(group_b)
print(f'stat: {stat:.4f}')
print(f'stat: {p:.4f}')

if p > 0.05:
    print('group_b는 정규성을 만족합니다.')
else:
    print('group_b는 정규성을 만족하지 않습니다.')

정규성 검정결과

  • group_a와 group_b 모두 정규성을 만족하지 않으므로 Mann-whitney 사용
    • 하나라도 정규성을 만족지 않으면 비모수검정 사용

Mann-whitney 검정 결과

from scipy.stats import mannwhitneyu

# 집단 나누기
group_a = merge_df[merge_df['군집'] == 3]['판매가']
group_b = merge_df[merge_df['군집'] == 0]['판매가']

# Mann-Whitney U 검정
u_stat, p_value = mannwhitneyu(group_a, group_b, alternative = 'greater')

# 결과 출력
print('\n독립표본 mannwhitneyu 검정 결과')
print(f'u-통계량: {u_stat:.3f}')
print(f'p-value: {p_value:.4f}')

# 해석
if p_value < 0.05:
    print('가설을 채택합니다. 예비 우수 판매자가 평균 가격이 더 높을 가능성이 높습니다.')
else: 
    print('가설을 기각합니다.')

Mann-whitney검정결과