Today I learned
1. QAQC 문제풀이
링크 닫힘으로 열람 불가
2. [라이브세션] 파이썬 베이직반 4회차
1. 샘플링
1) 데이터 불균형
- 정상 범주의 관측치 수와 이상 범주의 관측치 수가 현저히 차이나는 데이터
- 정상 데이터가 많고 불량 데이터가 매우 적을 때 발생
- 불균형 데이터의 위험성
- 정확도 함정: 불균형 데이터로 학습딘 모델은 정상에 치우친 예측을 할 가능성이 높음
- 결함 탐지 실패: 불량을 충분히 학습하지 않으면 제품 결함을 놓칠 가능성이 있음
- 해결 방안
- 불량 데이터를 더 많이 수집, 샘플링 방법을 마련
- 불량 케이스를 의도적으로 생성
- 모델 검증 강화
2) 언더 샘플링과 오버 샘플링의 기법
- 데이터 불균형을 해결하기 위해 나온 개념

| 언더 샘플링 | 오버 샘플링 |
| - 다수 데이터를 소수 데이터에 맞게 수를 줄임 - 학습에 사용되는 전체 데이터 수를 감소시키기 때문에, 오히려 성능이 감소할 수 있음 |
소수 범주의 데이터를 다수 범주의 데이터에 맞게 늘림 |
| Random Sampling, Tomek Links | Resampling, SMOTE |
2-1) 언더샘플링 - Random Sampling
- 다수 범주에서 무작위로 샘플링
| 랜덤샘플링 파이썬 실습 | |
|
#클래스 불균형 예시
import numpy as np
import pandas as pd
from sklearn.utils import resample
# 예제 데이터셋 생성
data = {'feature1': np.random.randn(1000), # 랜덤 피처 데이터
'feature2': np.random.randn(1000),
'class': [0] * 900 + [1] * 100} # 클래스 불균형 (0: 900개, 1: 100개)
df = pd.DataFrame(data)
|
데이터를 만들어놓은거임 클래스 불균형을 의도적으로 배치 0이 900개, 1이 100개 |
|
# 클래스 분리
df_majority = df[df['class'] == 0] # 다수 클래스 (0)
df_minority = df[df['class'] == 1] # 소수 클래스 (1)
|
- df_majority: ['class'] 칼럼의 0만 모은 데이터, 900개 - df_minority: ['class'] 칼럼의 1만 모은 데이터, 100개 |
|
# 랜덤 언더샘플링
df_majority_downsampled = resample(df_majority,
replace=False, # 복제하지 않음
n_samples=len(df_minority), # 소수 클래스 크기와 동일
random_state=42) # 재현성을 위해
|
- resample(): sklearn의 샘플링 함수(데이터를 무작위로 뽑음) - replace = False: 복원 추출 금지 - n_samples = len(df_minority) : 다수 클래스(0)의 갯수를 소수 클래스(1)의 갯수로 줄이기 |
|
# 언더샘플링 데이터 병합
df_balanced = pd.concat([df_majority_downsampled, df_minority])
print("언더샘플링 전 데이터 분포:")
print(df['class'].value_counts())
print("\n언더샘플링 후 데이터 분포:")
print(df_balanced['class'].value_counts())
|
줄어든 다수 클래스 데이터 100개 + 원래의 소수 클래스 데이터 100개 합침 0과 1의 비율이 1:1로 균등한 200개의 데이터셋 완성 ![]() |
2-2) 언더샘플링 - Tomek Links
- 두 범주 사이를 탐지하고 정리를 통해 부정확한 분류경계선을 방지하는 방법
- 선택한 두 데이터에서 Xk까지의 거리보다 선택한 두 데이터 사이의 거리가 짧을 때 선택한 두 데이터간의 링크를 Tomek link라고 부름
2-3) 오버샘플링 - Resampling

- 소수 클래스 데이터를 단순 복제하여 데이터 양을 증가
- 소수 범주에 과적합이 발생 할 수 있음
- 데이터 다양성이 낮게 나타남
| 오버샘플링 파이썬 실습 | |
|
from sklearn.utils import resample
import pandas as pd
# 데이터 생성
data = {'feature': [1, 2, 3, 4, 5, 6], 'class': [0, 0, 0, 0, 0, 1]} # 클래스 0이 다수
df = pd.DataFrame(data)
|
데이터를 만듦 class 항목에 0이 5개, 1이 1개로 이상 데이터가 너무 적은 형태 |
|
# 소수 클래스 분리
df_majority = df[df['class'] == 0]
df_minority = df[df['class'] == 1]
|
- df_majority = [1,2,3,4,5] - df_minority = [6] 두 클래스로 나 |
|
f# 랜덤 오버샘플링
df_minority_oversampled = resample(df_minority,
replace=True, # 복제 허용
n_samples=len(df_majority), # 다수 클래스와 동일한 크기로
random_state=42) # 재현성
|
- resample : 무작위 샘플링 함수 - replace = True: 복원 추출을 허용함 - n_sample = len(df_majority): 소수의 클래스를 다수 클래스 만큼 갯수를 맞춤 즉 이렇게 됨 - df_majority = [1,2,3,4,5] - df_minority = [6,6,6,6,6] |
|
# 오버샘플링 데이터 병합
df_oversampled = pd.concat([df_majority, df_minority_oversampled])
print("오버샘플링 전 데이터 분포:")
print(df['class'].value_counts())
print("\n오버샘플링 후 데이터 분포:")
print(df_oversampled['class'].value_counts())
|
데이터를 병합하여 총 10개의 균형잡힌 데이터셋이 나옴![]() |
2-4) SMOTE(중요)
- SMOTE 방법은 소수 범주에서 가상의 데이터를 생성한느 방법
- 기존 소수 클래스 데이터를 기반으로 새로운 데이터를 선형 보간 하여 생성함
- K값을 정한 후 소수 범주에서 임의의 데이터를 선택, 선택된 데이터와 가장 가까운 K개의 데이터 중 하나를 무작위로 선정해 Synthetic 공식을 통해 가상의 데이터를 생성하는 방법

2. 인코딩
- 머신러닝은 숫자만 이해함 - 문자 데이터를 숫자로 바꿔야 함
- 인코딩 종류
| 구분 | Label Encoding | One-Hot Encoding |
| 뭐임 | 카테고리를 숫자 하나로 변환 | 각 카테고리를 컬럼으로 나누고 0/1 표시 |
| 예시 | red = 0, blue = 1, green = 2 | red = [1,0,0], blue = [0,1,0], green = [0,0,1] |
| 사용 데이터 | 순서가 있는 데이터(서열형) | 순서 없는 데이터(명목형) |
| 예시 | 의류 사이즈 S<M<L | 색상, 지역, 브랜드 |
| 주의사항 | 숫자 크기 때문에 '순서 오해'위험 | 컬럼 개수가 늘어남 |
| 인코딩 파이썬 실습 | |
|
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
# 예시 데이터
df = pd.DataFrame({
"color": ["red", "blue", "green", "blue", "red"],
"size": ["S", "M", "L", "M", "L"],
"price": [100, 150, 200, 130, 170]
})
X = df[["color", "size"]]
y = df["price"]
|
예시 데이터 생성 |
|
# 1) Train/Test 분리 먼저!
X_train, X_test = train_test_split(X, test_size=0.2, random_state=42)
|
Train/Test 데이터 분리 |
|
# 2) Label Encoding (size는 S<M<L 순서가 있음)
le = LabelEncoder()
X_train["size"] = le.fit_transform(X_train["size"]) # Train으로 fit
X_test["size"] = le.transform(X_test["size"]) # Test는 transform만
print("인코딩 완료")
print(X_train)
|
![]() 의류 사이즈 별로 S = 2, M = 1, L = 0로 인코딩 (LabelEncoder는 기본적으로 사전순으로 변환) |
|
# 3) One-Hot Encoding (color는 순서 없음)
ohe = OneHotEncoder(handle_unknown="ignore", sparse_output=False)
X_train_color = ohe.fit_transform(X_train[["color"]])
X_test_color = ohe.transform(X_test[["color"]])
print("인코딩 완료")
print(X_train_color)
|
![]() red = [1,0,0] blue = [0,1,0] green = [0,0,1] |
- Train, Test 분할 후 인코딩을 진행하는 이유
- 분할 전에 인코딩/스케일링을 하게 되면 테스트 데이터의 정보가 학습 기준에 섞임
- 모델이 테스트 분포를 '미리 확인한 상태'가 되어 성능이 뻥튀기
- 인코딩도 마찬가지.
- 분할 미진행 시 테스트 데이터 정보를 미리 훔쳐본 것과 같음
3. 스케일링
- 각 변수별로 수 차이가 클 때 머신러닝 모델이 특정 변수만 중요하다고 착각 할 수 있다.
- 키 170, 몸무게 70, 연봉 45,000,000 이런 데이터가 있으면 연봉 변수를 더 크게 보지 않을까?
- 따라서 스케일링으로 데이터를 변환시켜주는 작업이 필요함
| 구분 | StandardScaler | MinMaxScaler |
| 하는 일 | 평균 0, 표준편차 1로 변환 | 데이터 0~1 범위로 변환 |
| 사용 | 데이터가 정규 분포와 유사할 때, 또는 이상치의 영향이 상대적으로 덜 중요할 때. | Min-Max Scaling은 데이터 분포가 정규분포와 다르거나 왜도가 있어도 적용 가능하며, 데이터의 상대적 구조와 비율을 손대지 않으면서 0~1 범위로 선형 변환하는 비모수적 정규화 방법 |
| 특징 | 이상치(Outlier)의 영향을 받지만, 전체적인 데이터 분포의 모양을 유지하며 넓은 범위로 스케일링 될 수 있음. | 이상치(Outlier)의 영향을 크게 받아 이상치가 Min 또는 Max 값일 경우 대부분의 데이터가 좁은 범위에 몰릴 수 있음. |
| 스케일링 파이썬 실습 | |
|
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# 예시 데이터 생성
data = {
"price": [100, 150, 200, 130, 170, 210, 190, 160, 180, 140] # 수치형 피처
}
df = pd.DataFrame(data)
# Train/Test 분리
X_train, X_test = train_test_split(df, test_size=0.3, random_state=42)
# StandardScaler 사용
scaler = StandardScaler()
# Train 데이터로 fit하고 transform
X_train_scaled = scaler.fit_transform(X_train[["price"]])
# Test 데이터는 transform만 적용
X_test_scaled = scaler.transform(X_test[["price"]])
print("===== 원본 데이터 (Train) =====")
print(X_train.head())
print("\n===== 표준화 데이터 (Train 결과) =====")
print(X_train_scaled[:5])
print("\n===== 표준화 시 사용된 평균, 표준편차 =====")
print("평균(mean):", scaler.mean_)
print("표준편차(std):", scaler.scale_)
|
![]() |
'빅데이터 QAQC_3기 > 빅데이터 QAQC_3기 TIL' 카테고리의 다른 글
| TIL_251105 (0) | 2025.11.05 |
|---|---|
| TIL_251103 (0) | 2025.11.03 |
| TIL_251029 (1) | 2025.10.29 |
| TIL_251028 (0) | 2025.10.28 |
| TIL_251027 (0) | 2025.10.27 |




