군집 시행 결과
-> 평균 좋아요 수, 총 판매 상품 수가 너무 한쪽으로 치우쳐 있거나 극단적으로 떨어져 있어 명확하게 구분이 되지 않음.
각 컬럼에서 0값을 제거한 후 상위 1%를 제외한 데이터 분포를 확인
평균 좋아요 수와 총 판매 상품 수는 오른쪽으로 긴 꼬리를 가지며 이상치의 영향을 크게 받는 것으로 보임. 따라서 로그 변환을 적용하여 군집 분석을 진행(NumPy의 log1p 함수, StandardScaler를 사용)
→ K-means는 거리기반으로 군집을 수행하기 때문에 반드시 해석 과정에서 변환 전 원본 값을 함께 확인하기!!(튜터님 피드백)
정품 인증 통과율이 0인 판매자들은 신뢰의 정도를 측정할 수 없고, 기업의 추구 방향성과 맞지 않기 때문에 별도의 클러스터로 분류하기로 결정.
가설설정
검정 방법 선택 과정
- 정규성을 만족하지 못하는 경우 (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 검정
- 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('가설을 기각합니다.')
'내일배움캠프 > TIL' 카테고리의 다른 글
[최종프로젝트] 최종발표 피드백 / 회고 (0) | 2025.04.11 |
---|---|
[최종프로젝트]중간발표 피드백 (0) | 2025.04.11 |
[TIL]250319_최종 프로젝트_군집을 위한 파생변수, 튜터링 노트 요약 (0) | 2025.03.19 |
[프로젝트 회고] 실전 프로젝트(Tableau)_게임 유저 및 이탈 요인 분석 대시보드 (0) | 2025.03.14 |
[TIL]250311_데이터 전처리product_type : Men Accessories (0) | 2025.03.11 |