Databricks ML Associate 시험 노트개념 정리14 MIN
표준편차와 IQR로 이상치 걸러내기
평균 ± k×표준편차와 IQR 1.5배 울타리가 같은 데이터에서 서로 다른 답을 내는 이유를 숫자로 짚고, approxQuantile과 filter로 실제로 걸러내는 코드까지 정리합니다.
이상치(outlier)는 나머지 값들과 동떨어져 혼자 멀리 있는 관측값입니다. 앞 노트에서 상자그림이 집어 주던 그 점입니다. 이것을 어떻게 할지는 취향이 아니라 기준을 정하는 일이고, 시험은 기준 둘을 놓고 「이 분포에서는 어느 쪽인가」를 묻습니다. 두 기준이 같은 데이터에서 다른 답을 내는 상황이 그대로 문항이 됩니다.
기준 하나 — 평균에서 몇 걸음인가
z-점수(z-score)는 한 값이 평균에서 표준편차의 몇 배만큼 떨어져 있는지를 나타낸 수입니다.
이면 이상치로 봅니다. 는 보통 3, 조금 엄하게 잡으면 2입니다. 같은 말을 값의 단위로 옮기면 평균 ± k×표준편차 밖입니다.
Spark의 stddev는 표본 표준편차로 분모가 입니다. 손으로 검산할 때 모집단 공식( 으로 나누는 것)을 쓰면 답이 어긋나니 주의합니다.
이 기준이 깔고 있는 가정이 있습니다 — 분포가 대칭이고 종 모양일 것. 정규분포라면 밖에 있는 값이 약 0.3%뿐이라 「드문 값」이라는 말이 성립합니다. 그 가정이 깨지면 기준도 함께 무너집니다.
기준 둘 — 사분위수 울타리
IQR(사분위 범위, interquartile range)은 3사분위수에서 1사분위수를 뺀 값, 즉 가운데 50%가 차지하는 폭입니다.
이 울타리 밖이 이상치이고, 상자그림이 수염을 뻗다 멈추는 자리가 바로 여기입니다. 1.5라는 수는 관행이며 더 엄하게 잡을 때 3.0을 씁니다.
두 기준의 결정적 차이는 이상치 자신이 기준에 끼어드는가입니다. 평균과 표준편차는 극단값 하나에 통째로 끌려가지만, 사분위수는 순서만 보므로 극단값이 아무리 커도 자리가 거의 안 바뀝니다. 이런 성질을 로버스트하다(robust, 튼튼하다)고 합니다.
숫자로 갈라 보기
월 사용액 여덟 건이 있습니다(단위: 천 원).
2400 2600 2800 3000 3200 3400 3600 12000
먼저 z-점수 기준입니다. 합이 33,000이므로 평균은 , 표본 표준편차는 약 3,207입니다. 12,000의 z-점수는
이면 상한이 이라 12,000은 걸리지 않습니다.
이제 IQR 기준입니다. , 이므로 IQR은 800이고 상한은
12,000은 여기 걸립니다. 같은 데이터에서 한 기준은 놓치고 한 기준은 잡습니다.
이유가 셋째 줄에 있습니다. 12,000이 혼자 평균을 4,125까지 끌어올렸고 표준편차도 3,207까지 부풀렸습니다. 자기가 만든 넓은 울타리 안에 자기가 들어앉은 것입니다. 12,000을 빼면 남은 일곱의 평균이 3,000으로 내려앉는 것을 보면 얼마나 끌고 있었는지가 보입니다.
그래서 오른쪽 꼬리가 긴 치우친 분포(소득·구매액·체류 시간이 대개 그렇습니다)에서는 IQR 기준이 먼저입니다. 반대로 분포가 대칭이고 종 모양이면 두 기준이 비슷한 답을 내고, 이때는 계산이 간단한 z-점수를 써도 무방합니다.
Spark로 실제로 걸러내기
사분위수는 approxQuantile으로 구합니다. 인자가 셋이고 그대로 문항이 됩니다 — 컬럼, 확률 목록, 상대 오차입니다.
q1, q3 = df.approxQuantile("monthly_spend", [0.25, 0.75], 0.0)
iqr = q3 - q1
lower, upper = q1 - 1.5 * iqr, q3 + 1.5 * iqr
clean = df.filter((df.monthly_spend >= lower) & (df.monthly_spend <= upper))
상대 오차 0.0은 정확한 값을 구하지만 계산이 비쌉니다. 큰 테이블에서는 0.01 정도를 주어 근사로 빠르게 얻습니다. 그리고 이 메서드가 돌려주는 것은 컬럼 하나에 대한 목록이라 위처럼 풀어 받습니다.
z-점수 쪽은 집계 함수로 평균과 표준편차를 먼저 구해 씁니다.
from pyspark.sql import functions as F
stats = df.select(F.mean("monthly_spend").alias("m"),
F.stddev("monthly_spend").alias("s")).first()
clean = df.filter(F.abs((F.col("monthly_spend") - stats["m"]) / stats["s"]) <= 3)
Spark DataFrame은 값을 고쳐 쓰는 것이 아니라 조건에 맞는 행만 남긴 새 DataFrame을 만드는 것이라는 점을 기억합니다. filter와 where는 같은 메서드입니다.
지울 것인가 자를 것인가
행을 아예 빼는 것만이 답은 아닙니다.
- 제거(trimming)는 울타리 밖 행을 버립니다. 그 행의 다른 컬럼 값도 함께 사라지고, 이상치가 많으면 데이터가 눈에 띄게 줄어듭니다.
- 윈저라이징(winsorizing)은 값을 버리는 대신 울타리 값으로 잘라 붙입니다. 위 예에서 12,000은 4,600이 됩니다. 행 수가 유지되고 극단값의 영향만 줄어듭니다.
clean = df.withColumn(
"monthly_spend",
F.when(F.col("monthly_spend") > upper, upper)
.when(F.col("monthly_spend") < lower, lower)
.otherwise(F.col("monthly_spend")),
)
고르는 기준은 그 값이 오류인가 사실인가입니다. 센서 고장이나 입력 실수처럼 있을 수 없는 값이면 제거가 맞습니다. 실제로 그만큼 쓴 고객이라면 그 행에는 유효한 정보가 있으므로, 버리기보다 자르거나 로그 변환으로 눌러 주는 쪽이 낫습니다. 아무 근거 없이 제거하면 모델이 실제로 마주칠 값의 범위를 학습하지 못합니다.
울타리를 어느 데이터에서 계산하는가도 짚고 갑니다. 학습·검증을 나눈 뒤 학습 세트에서만 · 를 구하고, 그 값을 그대로 검증·추론 데이터에 적용합니다. 전체 데이터로 울타리를 잡으면 검증 세트의 정보가 전처리를 통해 학습 쪽으로 새어 들어와 성능이 실제보다 좋게 나옵니다. 윈저라이징도 마찬가지라, 자를 값은 학습 세트에서 정해 저장해 두고 추론 때 꺼내 씁니다.
한 가지 덧붙이면, 트리 계열 모델은 값을 크기 순서로만 쓰기 때문에 이상치에 훨씬 둔합니다. 선형 회귀나 거리 기반 모델이 이상치에 크게 흔들립니다. 「어느 모델을 쓸 것인가」가 「얼마나 신경 쓸 것인가」를 함께 정합니다.
연습 문제
값이
2400, 2600, 2800, 3000, 3200, 3400, 3600, 12000이고 , 입니다. IQR 1.5배 규칙의 상한은?
① 3400
② 4200
③ 4600
④ 5800③. IQR은 이고 상한은 입니다.같은 데이터의 평균이 4,125, 표본 표준편차가 약 3,207입니다. 12,000의 z-점수에 가장 가까운 값은?
① 1.24
② 2.46
③ 3.74
④ 5.02②. 입니다. 기준으로는 걸리지 않고 기준으로는 걸립니다.위 두 문제에서 두 기준의 판정이 갈립니다. 그 이유로 가장 알맞은 것은?
① IQR 규칙이 항상 더 많은 값을 잡도록 설계되어 있다
② 12,000이 평균과 표준편차를 함께 끌어올려 자기가 만든 울타리 안에 들어갔다
③ 표본 표준편차 대신 모집단 표준편차를 써야 한다
④ 데이터가 여덟 개뿐이라 z-점수를 쓸 수 없다②. 평균과 표준편차는 극단값에 끌려가지만 사분위수는 순서만 보므로 흔들리지 않습니다.이상치 처리에 대한 설명으로 옳은 것을 둘 고르시오.
① IQR 기준은 사분위수를 쓰므로 극단값에 로버스트하다
② 윈저라이징은 행 수를 유지한다
③ z-점수 기준은 치우친 분포에서 더 정확하다
④ 울타리 배수를 1.5에서 3.0으로 올리면 더 많은 값이 이상치가 된다
⑤ 트리 계열 모델은 선형 모델보다 이상치에 민감하다①과 ②. ③은 반대입니다 — 치우친 분포에서는 극단값이 표준편차를 부풀려 오히려 놓칩니다. ④는 울타리가 넓어지므로 잡히는 값이 줄어듭니다. ⑤도 반대로, 트리는 값의 순서만 쓰므로 이상치에 둔합니다.df.approxQuantile("spend", [0.25, 0.75], 0.0)에서 세 번째 인자가 뜻하는 것은?
① 표본 비율
② 허용하는 상대 오차. 0이면 정확하지만 비싸다
③ 이상치 배수
④ 반환할 값의 개수②. 큰 테이블에서는0.01같은 값을 주어 근사로 빠르게 구합니다.고객 월 사용액이 오른쪽 꼬리가 매우 긴 분포입니다. 이상치 기준으로 더 알맞은 것과 그 이유는?
① z-점수. 계산이 간단하다
② z-점수. 꼬리가 길수록 표준편차가 커져 잘 잡는다
③ IQR. 사분위수가 극단값에 흔들리지 않는다
④ IQR. 치우친 분포에서는 평균이 중앙값보다 항상 작다③. ②는 사실 관계가 반대로, 표준편차가 커지면 울타리가 넓어져 오히려 놓칩니다. ④의 「항상 작다」도 틀렸습니다 — 오른쪽 꼬리가 길면 평균이 중앙값보다 큽니다.울타리 상한이 4,600일 때 12,000을 윈저라이징한 뒤 여덟 값의 평균은? (나머지 일곱의 합은 21,000)
① 3000
② 3200
③ 3450
④ 4125②. 12,000이 4,600이 되므로 입니다. 참고로 그 행을 아예 제거하면 일곱 값의 평균이 입니다.센서 오작동으로 체온이 250도로 기록된 행을 발견했습니다. 알맞은 처리는?
① 울타리 값으로 잘라 붙인다
② 그대로 둔다 — 실제 관측이므로
③ 있을 수 없는 값이므로 제거하거나 결측으로 표시한다
④ 로그 변환으로 누른다③. 오류와 사실을 가르는 것이 먼저입니다. 물리적으로 불가능한 값은 자를 대상이 아니라 잘못된 기록입니다.
정리하면 기준은 분포가 정하고, 처리는 그 값이 오류인지 사실인지가 정합니다. 대칭이면 z-점수도 되지만 치우쳐 있으면 IQR이고, 오류면 지우고 사실이면 자르거나 눌러 씁니다.

