10.1 분류 문제 정의¶
준비 코드¶
새 노트북에서 시작하는 경우, 9.2절의 자료 불러오기와 계절 위치 특징 코드를 먼저 실행한다.
import numpy as np
import pandas as pd
df = pd.read_csv("seoul_weather_2021_2025.csv", parse_dates=["date"])
day = df["date"].dt.day_of_year
df["doy_sin"] = np.sin(2 * np.pi * day / 365.25)
df["doy_cos"] = np.cos(2 * np.pi * day / 365.25)
강수일 레이블¶
분류 문제에서는 레이블을 정해진 범주로 정의한다. 이 장에서는 다음 날 일강수량이 1.0 mm 이상이면 1(강수), 미만이면 0(무강수)으로 정의한다. 0.1 mm 수준의 미량 강수는 우산이 필요하지 않은 경우가 많으므로, 이 책에서는 기준을 1.0 mm로 정했다. 기준값을 변경하면 레이블 분포와 모델 성능이 함께 변화한다.
특징에는 9장의 특징 외에 일교차(temp_range, 최고기온 − 최저기온)를 추가했다. 맑은 날은 낮에 기온이 많이 상승하고 밤에 많이 하강하므로 일교차가 크고, 흐리거나 비가 오는 날은 일교차가 작은 경향이 있다.
df["target_rain"] = (df["precip_mm"].shift(-1) >= 1.0).astype(int)
df["temp_range"] = df["temp_max"] - df["temp_min"]
data = df.iloc[:-1] # 마지막 날은 다음 날 자료가 없으므로 제외
feats = ["precip_mm", "humidity", "temp_range", "sunshine_h",
"wind_max", "doy_sin", "doy_cos"]
train = data[data["date"] < "2025-01-01"]
test = data[data["date"] >= "2025-01-01"]
print(train["target_rain"].value_counts())
print(round(test["target_rain"].mean(), 3))
실행 결과
학습 데이터 1,461일 중 다음 날 강수일은 445일(30.5%), 무강수일은 1,016일이다. 평가 데이터(2025년)의 강수일 비율은 29.7%다.
astype(int)와 마지막 행
마지막 날의 shift(-1) 결과는 결측이고, 결측과 1.0을 비교하면 거짓이 되어 레이블이 0으로 저장된다. 이 값은 실제 관측이 아니므로 df.iloc[:-1]로 마지막 행을 제외했다.
클래스 불균형¶
두 범주의 비율이 크게 다른 자료를 클래스 불균형(class imbalance) 자료라고 한다. 이 자료는 무강수가 약 70%, 강수가 약 30%다. 이 경우 모든 날을 "비 안 옴"으로 예측하는 모델도 약 70%의 정확도를 산출한다. 10.3절에서 이 단순 예측을 기준선으로 사용한다.
확인 문제¶
- 강수 기준을 0.1 mm와 10 mm로 변경해 학습 데이터의 강수일 비율을 각각 산출하시오.
temp_range가 강수 예측에 유용한 특징인지 확인하기 위해,train.groupby("target_rain")["temp_range"].mean()을 실행하고 결과를 해석하시오.