[프로젝트 #2-5] EDA 2차 마무리와 가설검정(통계) 시작!

오늘은 EDA 2차로 진행하고, 끝날 무렵에 통계 검정 부분 작성해보았다. 오늘도 튜터님의 가이드세션을 참고해서 진행했다.
 

개인 진행사항

우선 이렇게 t-test 4가지 를 진행하였다.

  1. 슈퍼호스트 여부에 평균금액의 차이가 있나?
  2. 즉시예약 가능여부에 평균금액의 차이가 있나?
  3. 단기숙소와 장기숙소에 평균금액에 차이가 있는가?
  4. 신원확인 여부에 따른 평균금액의 차이가 있나?
💡 검정 결과 유의미한 결과를 도출했다.
⭐유의미한 차이가 없다 = 1, 3번 | ⭐유의미한 차이가 있다 = 2, 4번
재밌는데? 슈퍼호스트 여부이 따른 금액차이는 유의미하게 있을줄 알았으나 아닌 결과가 나왔다.
아직은 가격에 영향을 주는 요인을 찾는 과정이 더 필요해 보인다. 추가적으로 무엇이 더 있을지 고민이 필요하다!!
reveiw 컬럼을 다시 불러와서 관계성을 찾아봐야 할까 싶다.

 
▼ (참고)통계 도우미 함수 코드 모음

더보기
# 정규성 검정 함수
def check_normality_simple(data, name="데이터"):
    """
    데이터의 정규성을 검정하는 함수
    
    Parameters
    ----------
    data : array-like
        정규성을 검정할 데이터 (NaN은 자동 제거)
    name : str, default="데이터"
        출력 시 표시될 데이터 이름
    
    Returns
    -------
    bool
        정규분포 가정 충족 여부
    """
    # NaN 제거
    if pd.isna(data).any():
        print(f"⚠️ 경고: {name}에 NaN 값이 {pd.isna(data).sum()}개 포함됨")
        data = data.dropna()
        print(f"   → NaN 제거 후 n={len(data)}")
    
    n = len(data)
    
    print(f"\n[{name} 정규성 검정] n={n}")
    print("-"*40)
    
    # 왜도와 첨도
    skew = stats.skew(data)
    kurt = stats.kurtosis(data, fisher=True)
    print(f"왜도(Skewness): {skew:.3f}")
    print(f"첨도(Kurtosis): {kurt:.3f}")
    
    # 표본 크기에 따른 판단
    if n < 30:
        # 작은 표본: Shapiro-Wilk 필수
        stat, p = shapiro(data)
        print(f"Shapiro-Wilk p-value: {p:.4f}")
        is_normal = p > 0.05
        reason = f"Shapiro p={'>' if is_normal else '≤'}0.05"
    elif n < 100:
        # 중간 표본: 왜도/첨도 먼저, 불충족 시 Shapiro-Wilk
        if abs(skew) < 1 and abs(kurt) < 2:
            is_normal = True
            reason = "|왜도|<1, |첨도|<2"
        else:
            print(f"   → 왜도/첨도 기준 미충족, Shapiro-Wilk 추가 검정")
            stat, p = shapiro(data)
            print(f"추가 Shapiro-Wilk p-value: {p:.4f}")
            is_normal = p > 0.05
            reason = f"Shapiro p={'>' if is_normal else '≤'}0.05"
    else:
        is_normal = abs(skew) < 2
        reason = f"|왜도|{'<' if is_normal else '≥'}2 (중심극한정리)"
    
    print(f"결과: {'✅ 정규분포 가정 충족' if is_normal else '❌ 정규분포 가정 위반'} ({reason})")
    return is_normal


# Cramér's V 계산 : 효과 크기
def cramers_v(chi2_stat, n, r, c):
    """Cramér's V 효과 크기 계산"""
    return np.sqrt(chi2_stat / (n * min(r-1, c-1)))


def interpret_cramers_v(v):
    """Cramér's V 값 해석"""
    if v < 0.1:
        return "매우 약한 관계"
    elif v < 0.3:
        return "약한 관계"
    elif v < 0.5:
        return "중간 관계"
    else:
        return "강한 관계"


# 에타제곱 계산
def calculate_eta_squared(f_statistic, df_between, df_within):
    """에타제곱 (효과 크기) 계산"""
    eta_squared = (f_statistic * df_between) / (f_statistic * df_between + df_within)
    
    if eta_squared < 0.01:
        interpretation = "매우 작은 효과"
    elif eta_squared < 0.06:
        interpretation = "작은 효과"
    elif eta_squared < 0.14:
        interpretation = "중간 효과"
    else:
        interpretation = "큰 효과"
    
    return eta_squared, interpretation

 
 

팀 진행 및 결정사항

- 28일 전후로 단기/장기 구분하기
minimum_nights 컬럼에서 일수 가져오고, 전후로 장기/단기 적용하기

df['stay_type'] = np.where(df['minimum_nights'] <= 27, 'Short-term', 'Long-term')

🔍 minimum_nights 값이 28 미만이면 'Short-term' 으로, 28 이상이면 'Long_term' 에 값 저장하고 'stay_type' 새로운 파생컬럼을 만들어서 장기/단기 숙소 구분. ==> 통계 검정으로 확인
 
- 팀장님의 아이디어로 가격 책정 가이드표 비슷한거를 만들어서 조건에 맞는 가격 제안 추진! (짱) input 입력까지 !!
 
 
 

오늘의 회고

오늘 EDA 2차 마무리 단계에서 추가적은 아이디어가 떠오르질 않다보니 스스로 답답한 감정이 들었다. 하지만 팀장님의 머리에는 모터가 달렸을까..? 의견도 다양하고 확실해서(고집X) 의견들이 자연스럽게 모이다가 디벨롭 되는 것을 본 것 같다. 나는 너무 단순하게만 생각해서 다각도로 생각하는 자세를 길러야 겠다는 생각(?)이 들었다.
 
통계 검정을 진행하다보니 가격에 영향을 미치는 요인을 조금 더 찾아보고 싶은데, 전처리 진행 전부터 제외시킨 컬럼들이 많아서 아쉬움이 남았다. 다음에는 조금 더 신중에서 컬럼들을 선정할 것이다. 이번에는 아쉬우니깐, 주말 시간을 이용해서 reveiw 관련 컬럼을 불러와 이런 저런 시도를 해봐야겠다. 거기서 추가적으로 유의미한 결론을 발견할 수 있기를 바라본다.
 
 
 

내일 할 거

  • 통계 부분 더 뽑아보기.
  • review 컬럼 살려서 통계에 연계해보기.