카테고리 없음

통계 복습1

lightnsolt 2026. 6. 13. 19:54

목차

  1. 로그변환
  2. [산포도 - 분산 / 표준편차]
  3. 정규분포
  4. [Z-Score]
  5. [왜도 / 첨도](#
  6. 데이터 시각화 - 히스토그램 / 박스플롯

로그변환

가정) 100명의 구매 데이터 중 1명이 10억을 지불했고 나머지는 1만원을 지불 했을 때.
그래프 모양 : 해당 데이터는 한쪽으로 치우친 왜도 형태

  • 그래프 형태가 왜도(치우쳐 있다) 일 때 log()를 사용하면 데이터값의 변동 폭이 줄어들어 정규분포에 가깝게 그래프를 다시 구성할 수 있다.

파이썬 로그 함수

from scipy import stats
import numpy as np

np.log1p("로그 적용할 데이터") 
# np.log()가 아닌 np.log1p()를 쓰는 이유 : 데이터가 0이 들어가면 무한대 값이 나와서 사전 방지

클로드가 알려준 실무 흐름

① .skew() 로 왜도 확인 → 1 이상이면 변환 고려
② 0 포함 가능 → np.log1p() / 0 없음 → np.log()
③ 변환 후 왜도 다시 확인 → 0에 가까우면 성공
④ 예측값은 반드시 np.expm1() 로 복원
⑤ 변환 전후 R² 비교 → 올랐으면 변환 채택

로그변환을 사용하면 좋을 상황

  • 양의 왜도 형태일 때 / 데이터가 왼쪽에 모여있을 때 꼬리는 오른쪽
  • 정규분포 가정을 충족해야 할 때 ex)제미나이가 말하기로 통계검정, 머신러닝 모델은 정규성 가정을 충족해야 한다고 말함
  • 데이터의 대소관계(순위) 유지하되 차이규모를 압축하고 싶을 때

로그변환을 사용하면 좋지 않을 상황

  • 음의 왜도일 때 ex)높은 별점 데이터 오른쪽으로 데이터가 밀집된 경우 로그변환 하면 분포의 불균형이 생긴다.
  • (-)음의 값이 있을 때 계산이 안된다.
  • vvip, 봇 감지 등 이탈값이 중요한 point가 되는 경우

산포도

1. 분산

  • 정의 : 평균에서 각 데이터가 얼마나 떨어져있는지를 제곱하여 평균낸 값.
  • 분산 수치만 가지고 이 데이터가 얼마나 변동성이 있는지는 대략적으로만 예측가능 => 그래서 표준편차를 사용

2. 표준편차 SD (Standard Deviation 수치/편차)

  • 정의 : 분산을 제곱근 한 데이터
  • 표준편차가 n 일때 해당 데이터는 평균 대비 n 만큼의 변동이 있어!

분산 / 표준편차 파이썬 함수

import numpy as np

data = df['Total_Revenue']
variance = np.var(data)  # 분산 계산
std_deviation = np.std(data)  # 표준편차(SD) 계산

#DF에서 바로 사용
df['Total_Revenue'].var()  # 해당 컬럼의 분산
df['Total_Revenue'].std()  # 해당 컬럼의 표준편차

3. CV (변동 계수) Coefficient of Variation

  • CV : 표준편차 / 평균 -> 평균(고정값) 대비 표준편차(흔들림의 정도)
  • 한 개의 데이터만 볼 때는 표준편차만 보면 된다. But 2개 이상의 데이터를 비교해 볼 때는 SD가 같더라도 평균이 다르기 때문에 공정하게 비교가 어렵다. 데이터의 상대적인 변동성
    • CV가 10% 이다 : 데이터는 평균 대비 10% 가량 변동이 있다.
    • CV가 70% 이다 : 데이터는 평균 대비 70% 가량 변동이 있다.

#정규분포

정의 : 마케팅에서 자주 볼 수 있는 데이터의 분포 / 종모양 / 평균 = 중앙값 = 최빈값 이 비슷한 구간에 있을 경우 나타나는 분포

  • 68-95-99.7규칙 : 각 수치별로 1시그마(SD) / 2시그마 / 3시그마가 포함하는 데이터의 범위를 나타낸다.
    • 1시그마 : 가장 일반적인 유저 유형을 대변한다. 정규분포의 68% 에 해당 평균 +,- 1SD
    • 2시그마 : 95.4% 유저를 포함하는 구간. 극단유저(5%)를 제외한 애부분의 유저 / 유의수준 5%의 기준이 된다.
  • 표준 정규분포 : 평균이 0 표준편차가 1인 분포를 말한다 / 데이터의 상대적인 비교를 하기위한 기준으로 사용된다.
  • 어떤 정규분포든 평균을 0, 표준편차를 1이 되도록 일치시키는 과정을 표준화(Standardization)라고 하며, 이때 변환된 점수가 바로 Z-스코어입니다

유의수준 5%의 기준이 된 2시그마

  • 2시그마는 유저의 95%를 반영한다.
  • 나머지 5%는 예측 불가능한 영역에 해당된다.
  • 그래서 유의 수준의 기준이 2시그마 외부인 5%로 책정되었다.

유의수준이 어떤 계산을 거치길래 5% 영역에 해당하지?

  • 가정 : 평균 구매액 50만원 표준편차 10만원인 정규분포 데이터가있어
    질문 : 2시그마에 해당하는 구매 금액은 => 평균 + (sd * 1.96) = 69.6만원[윈저라이징]
  • df['amount'].quantile(0.95)
from scipy.stats import norm

# 평균 50만 원, 표준편차 10만 원일 때 상위 2.5% 경계선 계산
cutoff_value = norm.ppf(0.975, loc=500000, scale=100000)
print(cutoff_value)  # 출력: 695996원 (약 69.6만 원)

정규분포 데이터 유의수준 5%의 수치 커트라인 알아보는 코드

#Z-score

  • 정의 : 특정 데이터가 평균이라는 기준점으로부터 SD를 몇 번 딛고 나아갔는가? 를 나타내는 상대적 위치 점수
  • 필요성 : 서로 다른 기준을 가진 데이터를 비교할 때 사용
    • 1번 데이터 : 2% CTR의 캠페인이 4%가 나왔을 때
    • 2번 데이터 : 10$ CTR의 캠페인이 14%로 나왔을 때

1,2 캠페인 중 어떤게 더 효과가 좋았는지 성과 비교하기 표준화 과정이 필요함 >> 이것이 z-score 산출

  • 공식 => Z-score : (내가 얻은 데이터 - 평균) / 표준편차
    • 1,2 데이터에 적용
      case1) (4-2) / 0.5 = +4.0
      case2) (14-10) / 4 = + 1.0
      해석 : 1번 캠페인은 시그마 범위로 봤을 때 +4는 3을 넘어선 범위에 해당 우연이 아니라 특정 요인이 작용한 것 / 2번 캠페인은 +1로 1구간 안에 포함됨 우연히 일어날 평범한 수준의 성과

가상의 정규분포데이터 생성하는 함수

import numpy as np

# 평균(loc)=0, 표준편차(scale)=1 인 표준정규분포 데이터 1,000개 생성
virtual_data = np.random.normal(loc=0, scale=1, size=1000)
# 또는 간단하게 np.random.randn(1000) 도 동일한 역할을 합니다.

Z-score 구하는 함수 (표준정규분포로 변환 함수)

from scipy.stats import zscore

# 데이터프레임의 특정 컬럼을 표준정규분포 점수(Z-score)로 변환
df['z_score'] = zscore(df['Total_Revenue'])

#아래 계산식을 줄인 것(공식 -> (값-평균)/sd
df['z_score'] = (df['Total_Revenue'] - df['Total_Revenue'].mean()) / df['Total_Revenue'].std()

Z-score 점수 보는법

  • 정규분포로 변환한 점수를 계산하기 때문에 시그마 법칙 구간과 동일하게 보면 된다.
    • 0.0 ~ 1.0 : 평균 주변
    • 1.0 ~ 2.0 : 전체의 95% 담당
    • 2.0 ~ 3.0 : 99.7% 영역
    • 3.0 이상 : 이상치에 해당
  • z-score가 1.98일 경우 : 이 데이터는 95% 범위 내의 데이터이구나! vvip 타겟으로 분류해 볼까?
  • z-score가 3.50일 경우 : 이 데이터는 이상치구나 제외시키거나 데이터 처리 해야겠다.

왜도(Skewness)

  • 정의 : 데이터 분포의 치우침 정도를 나타냄
    • 양의 왜도 : 오른쪽으로 꼬리가 긴 분포 (평균 > 중앙값)
      • 아주 가끔 발생하는 vvip의 구매 데이터 / 헤비 유저의 긴 체류시간
    • 음의 왜도 : 왼쪽으로 꼬리가 긴 분포 (평균 < 중앙값)
      • 5점만점 대부분인 상품에 달린 1점 후기 / 정기 구독 서비스의 만기 유지율
  • 왜도 발생시 중앙값을 함께 표시하여 참고할 수 있게 한다.
  • 왜도 수치
    절댓값 기준 (00.5 거의 대칭/ 0.51.0 적당히 치우침/ 1.0 초과 심하게 치우침)
    1. 0에 가까움 : 정규분포 모양
    2. 양수 => 오른쪽으로 꼬리가 길게 늘어진 양의 왜도
    3. 음수 => 왼쪽으로 꼬리가 길게 늘어진 음의 왜도

왜도 파이선 코드

from scipy.stats import skew
import numpy as np

# 가상의 결제 데이터나 넘파이 배열이 있을 때
payment_array = df['Total_Revenue'].to_numpy()

# 왜도 계산
array_skew = skew(payment_array)
print(f"SciPy로 계산한 왜도: {array_skew:.4f}")

첨도(Kurtosis)

  • 정의 : 데이터 분포의 뾰족한 정도 + 꼬리의 두터움을 측정하는 지표
  • 정규분포의 수학적 첨도는 3!
  • 3을 기준으로 3보다 크면 고첨도 작으면 저첨도
  • 파이썬 .kurt() 함수의 정규분포 값은 0
  • 첨도가 0과 가깝다 => 가설검정(t-test, ANOVA)하기에 좋은 데이터
  • 고첨도 (파이썬 값 기준 > 0)
    1. 뾰족하고 꼬리가 두터움
    2. 대다수 유저가 평균 주변에 분포 + 예상치 못한 이탈값이 존재하고 있음 -> 평균유저 + vvip 잭팟 공존
  • 저첨도 (파이썬 값 기준 < 0)
    1. 덜 뾰족하고 뭉툭하며 옆으로 넓게 퍼진 평평한 형태
    2. 고객의 취향이나 패턴이 한 곳으로 통일되지 않고 다양하다 -> 고객 세분화 필요
  • 첨도 수치
    -1.0 ~ 1.0 : 정규분포에 근사
    2.0 초과 : 심한 고첨도 -> 로그변환(극단값이 존재할 수 있기 때문) + z-score기반 타겟 분리(상위 5% 타겟 분리)
    -1.0 미만 : 심한 저첨도 -> 고객 세분화 전략 수립

첨도 파이선 함수

from scipy.stats import kurtosis
import numpy as np

# 넘파이 배열 형태로 데이터 준비
revenue_array = df['Total_Revenue'].to_numpy()

# SciPy로 초과 첨도 계산 (Pandas 결과와 동일하게 기본값이 초과 첨도임)
array_kurt = kurtosis(revenue_array)
print(f"SciPy로 계산한 초과 첨도: {array_kurt:.4f}")
-----
import pandas as pd

# 예제 데이터 로드 (Market_data.csv 형태 가정)
df = pd.read_csv('Market_data.csv')

# ① 전체 수치형 컬럼의 첨도 일괄 확인하기
print(df.kurt(numeric_only=True))
# 참고: df.kurtosis() 라고 풀네임을 입력해도 완전히 똑같이 작동합니다.

# ② 특정 성과 지표(예: 누적 총매출)의 첨도만 콕 집어 확인하기
total_revenue_kurt = df['Total_Revenue'].kurt()
print(f"총 매출 데이터의 초과 첨도: {total_revenue_kurt:.4f}")

데이터 분포 시각화

히스토그램

  • 정의 : 연속형 수치 데이터를 일정하게 나눈 구간(Bin)별로 유저수나 빈도수(Frequency)를 측정하여 막대 그래프 형태로 나타낸 분포 시각화 도구
    • Bin(구간) : 데이터를 최솟값부터 최댓값까지 균등하게 쪼갠 구간
    • Frequency(막대의 높이) : 각 구간에 속하는 데이터의 갯수
  • 막대 그래프는 범주형 데이터 / 히스토그램은 연속된 수치형 데이터
  • 활용방법 : 정규성진단 / 왜도, 첨도 확인 / 다봉형 분포 감지 - 세그먼트 나눠줄 필요
  • 장점 : 전체적인 곡선의 모양(왜도, 첨도)확인 용이
  • 단점 : 여러 집단 동시 비교 어려움

히스토그램 파이썬 함수

import seaborn as sns
import matplotlib.pyplot as plt

#kde=True: 막대 위에 데이터의 밀도를 부드러운 곡선(Kernel Density Estimation)으로 나타내어 데이터가 종 모양을 잘 따르는지 한눈에 보게 돕습니다.

# 6월 11일 수업에서 다룬 캠페인 매출 데이터 시각화 예시
plt.figure(figsize=(8, 5))
sns.histplot(data=df, x="revenue", kde=True, bins=30, color="skyblue")
plt.title("Campaign Revenue Distribution")
plt.xlabel("Revenue")
plt.ylabel("Frequency")
plt.show()
------

import numpy as np
from scipy.stats import norm

# 1. density=True 옵션으로 y축을 '비율'로 설정해 히스토그램 그리기
sns.histplot(data=df, x="Total_Revenue", density=True, alpha=0.6, color="gray")

# 2. 이론상 정규분포 곡선(PDF) 계산 후 빨간 선으로 얹기
mu, std = df["Total_Revenue"].mean(), df["Total_Revenue"].std()
x = np.linspace(df["Total_Revenue"].min(), df["Total_Revenue"].max(), 100)
p = norm.pdf(x, mu, std)

plt.plot(x, p, 'r--', linewidth=2) # 완벽한 이론적 종 모양 곡선이 그려집니다.
plt.show()

박스 플롯

  • 정의 :
    수집된 수치형 데이터를 크기순으로 정렬
    -> 4등분(사분위수) 진행
    -> 중심의 50% 부근 데이터를 상자모양으로 감싸고
    -> 양 끝에 수염을 달아
    -> 전체 분포와 이상치 후보를 한눈에 보여주는 시각화 도구
  • 6가지 핵심 지표
    1. Q1(25% 지점) : 상자의 아래쪽 모서리 - 데이터의 하위 25% 해당
    2. Q2(50% 지점) : 상자의 중간을 가로지르는 선 - 평균(이상치에 영향 받음)이 아닌 중앙값(이상치에 영향을 받지 않음)
    3. Q3(75% 지점) : 상자의 위쪽 모서리 - 데이터의 75%에 해당
    4. IQR(사분위간 범위 Interquartile Range) : 상자의 총 세로 길이 [Q3 - Q1] - 전체 데이터의 핵심인 50%가 모여있는 구간
    5. 최솟값 & 최댓값 (수염의 양 끝) : 전체 데이터의 1등 꼴등이 아닌 아래 계산식을 반영
      • 하한선 : Q1 - (1.5 * IQR)
      • 상한선 : Q3 + (1.5 * IQR)
        왜 1.5를 곱해? 위 계산식을 적용하면 2.7시그마 범위안에 들어감. 이상치는 0.7%에 해당하게 됨
    6. 이상치 : 수염을 벗어난 데이터
  • 박스플롯 활용법
    1. 여러 집단을 나란히 세워놓고 한눈에 성과를 비교할 때 가장 강력
    2. IQR이 크다면 데이터가 변동성이 클 수 있다는 예측 가능
    3. 이상치 확인시 추후 대응 가능
  • 단점
    • 데이터의 실제 디테일한 모양은 확인할 수 없음/ 정규분포인지 왜도인지

박스 플롯 파이썬 코드

import seaborn as sns
import matplotlib.pyplot as plt

# 결제 금액 데이터의 이상치 분포 확인
plt.figure(figsize=(5, 6))
sns.boxplot(data=df, y="Total_Revenue", color="lightcoral")
plt.title("Total Revenue Boxplot")
plt.show()
-----

# 캠페인 그룹별 매출액 분포 비교 시각화
plt.figure(figsize=(10, 5))
sns.boxplot(data=df, x="group", y="revenue", hue="group", palette="pastel")
plt.title("Revenue Comparison by Campaign Group")
plt.xlabel("Campaign Group")
plt.ylabel("Revenue")
plt.show()

데이터 분포 시각화 정리

비교 항목 히스토그램 (Histogram) 박스 플롯 (Box Plot)
핵심 목적 데이터의 전체적인 형태(관상) 및 정규성 점검 여러 집단 간의 성과 비교 및 이상치 필터링
최적의 상황 단일 변수(예: 전체 매출)의 왜도/첨도 진단 시 집단 간 변동(예: 채널별, 캠페인별 매출 비교) 대조 시
추천 액션 꼬리가 길면 로그 변환 힌트 획득 삐져나온 점을 보고 윈저라이징/VVIP 분리 판단

용어 정리

ARPU

  • 정의 : Average Revenue Per User 고객당 평균 매출?