- 희소값에 대해 원핫인코딩을 하게되면 오버피팅이 발생할 수도 있고
너무 희소한 행렬이 생성되기 때문에 계산에 많은 자원이 필요합니다.- 희소한 값을 사용하고자 한다면
1) 아예 희소값을 결측치 처리하면 원핫인코딩 하지 않습니다.
2) 희소한 값을 "기타" 등으로 묶어줄 수도 있습니다.
정보 균일도를 기반으로 되어 있기 때문에 트리기반 모델은 피처 스케일링이 필요 ❌
트리기반 모델은 데이터의 절대적인 크기보다 상대적인 크기에 영향을 받기 때문에 스케일링을 해도 상대적인 크기 관계는 같다(= 스케일링에 영향을 크게 받지 않는다).
💡 feature scaling: feature의 범위를 조정해서 정규화
feature의 분산과 표준편차를 조정해서 정규분포 형채를 띄게 하는 것이 목표.
💡 feature의 범위가 다르면, feature끼리 비교하기 어려워 일부 머신러닝 모델에서는 제대로 작동하지 않는다.
💡 feature scaling이 잘 되어 있으면:
1) 서로 다른 변수끼리 비교하는 것이 편리
2) feature scaling 없이 작동하는 알고리즘에서 더 빨리 작동
3) 머신러닝 성능이 상승
4) 이상치에 대한 강점이 있음.
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import RobustScaler
1) StandardScaler (Z-score scaling)
2) MinMaxScaler
3) RobustScaler
fit()
& transform()
fit과 transform을 하는 2가지 방법:
1) fit() & transform()
train[["SalePrice_ss"]] = ss.fit(train[["SalePrice"]]).transform(train[["SalePrice"]])
train[["SalePrice", "SalePrice_ss"]].head(2)
2) fit_transform(): 같은 컬럼을 fit하고 transform 할 때 사용하는 방법
# 주의: 피처에 fit_transform은 train에만 사용!!!
# test에도 fit을 하게 되면 trian, test의 기준이 달라지니 test에는 transform만 한다.
train[["SalePrice_ss"]] = ss.fit_transform(train[["SalePrice"]])
feature scaling은 편향된 분포나 이상치에 취약하기 때문에 transformation을 적용한 후 feature scaling을 하게 되면 표준정규분포가 된다.
🤔 왜 정규분포로 고르게 분포된 값이 예측에 유리할까?
중간값을 잘 예측하는 모델이 일반적으로 예측 성능이 높은 모델이기 때문에 1,4분위 보다 2,3분위가 상대적으로 더 중요하다.
🤔 만약 label이 편향되어 있다면?
label을 transform해서 예측하고 반대로 계산해서 출력하면 된다.
e.g.) log transformation된 상태로 학습하고 예측한 다음, 예측한 값에 np.exp() 적용하여 출력
log transformation만 적용해도 정규분포 형태가 되는데 여기에 standarad scaler를 적용하면 표준 편차가 1이고 0을 중심으로 하는 표준정규분포를 갖도록 조정됨.
❗️ log transformation 시 주의사항:
- log함수는 x가 0에 수렴할 때, y가 마이너스 무한대로 발산하기 때문에
x>0
을 만족해야 한다. (numpy에서는 음수를 NaN값으로 반환)- 그렇기 때문에 주어진 값에 +1 하는 방식으로 log transformation 해주는 것이 안전
numpy.log1p
는 사용자가 직접 1을 더하는 것보다 성능이 뛰어나기 때문에 log1p 사용을 권장
수치형 feature를 일정 기준으로 나누어 그룹화하는 것
e.g.) 25세 대신, 20대, 30대, 40대와 같이 10살을 단위로 나눠 분석
1) Equal width binning; 절대평가 pd.cut()
2) Equal frequency binning; 상대평가 pd.qcut()
pd.qcut()
은 상대평가와 유사한 개념이기 때문에 pd.qcut()
으로 데이터를 분할하게 되면 비슷한 비율로 나눠줌🤔 이산화가 왜 필요할까?
직관적이기 때문에 데이터 분석과 머신러닝 모델에 유리하다.
최근 부스팅3대장(Xgboost, LightGBM, CatBoost) 알고리즘 중에는 범주형 데이터를 알아서 처리해 주는 알고리즘도 있지만 사이킷런에서는 범주형 데이터를 피처로 사용하기 위해서는 별도의 변환작업이 필요하다.
부스팅은 약한 예측 모델을 여러개 연결시켜 강한 예측 모델을 만드는 앙상블 기법
1) Ordinal-Encoding
: Categorical Feature를 Numerical Feature 중 Ordinal Feature로 변환
2) Label-Encoding
💡 Ordinal / Label Encoding은 비슷한 개념이며, 숫자가 맵핑이 되기 때문에 이에 따른 순서나 연산이 가능하다는 특성이 있다. 이를 원치 않는 경우는 원핫인코딩을 사용.
3) One-Hot-Encoding
: Categorical Feature응 다른 bool변수로 대체하여 특정 레이블이 참인지 여부를 나타냄.
👀 Pandas로 인코딩하기
1) ordinal-encoding
# MSZoning - .cat.codes => Ordinal Encoding, 결과가 벡터, 1차원 형태
# 순서가 있는 명목형 데이터에 사용. e.g.) 기간의 1분기, 2분기, 3분기, 4분기
train["MSZoning"].astype("category").cat.codes
2) one-hot-encoding
pd.get_dummies(train["MSZoning"])
👀 Scikit-learn으로 인코딩하기
❗️ 사이킷런을 사용했을 때 train을 기준으로 fit을 하기 때문에 test는 transform만 하면 됨.
3) ordinal-encoding
from sklearn.preprocessing import OrdinalEncoder
oe = OrdinalEncoder()
MSZoning_oe = oe.fit_transform(train[["MSZoning"]])
4) one-hot-encoding
# train에는 있지만 test에만 있는 값은 ohe 되지 않는다.
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder()
MSZoning_enc = ohe.fit_transform(train[["MSZoning"]]).toarray()
pd.DataFrame(MSZoning_enc, columns=ohe.get_feature_names_out())
❗️
판다스로 인코딩했을 때 문제점은 테스트 데이터에 대한 인코딩에서 발생. 사이킷런의 원핫인코딩은 train 데이터로만 학습해서 진행하기에 test에만 존재하는 데이터를 인코딩하지 않는다. 그러나 판다스는 이 기능이 없어서 test셋과 train셋의 고유값을 비교해줘야 하는데, 현실에서 test 데이터는 미래의 데이터라 모르기 때문에 권장하지 않는다.
차수: degree
# np.reshape은 array의 shape값을 지정해서 shape을 변환해 준다.
from sklearn.preprocessing import PolynomialFeatures
X = np.arange(6).reshape(3, 2)
print(X)
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)
pd.DataFrame(X_poly, columns=poly.get_feature_names_out())
Output:
Q: IQR을 어디서 사용했을까요?
A: 박스플롯
Q: 스케일링 방법 중에서 표준화(Z-score), Min-Max, Robust 중 이상치에 가장 덜 민감한 스케일링 방법은 무엇일까요?
A: Robust scaling
Q: transform 기능 설명 부탁드리겠습니다.
A: fit은 해당 columns을 기준으로 받고 맞춰주는 역할을 합니다.
fit된 기준으로 해당 컬럼이나 다른 컬럼들의 값을 바꿔주기 원할 때 transform을 사용합니다.
Q: 기술 통계로 봤을 때 StandardScaling (Z-score scaling) 의 특징?
A: 평균 == 0, 표준편차 == 1로 만든다.
Q: 기술 통계로 봤을 때 Min-Max의 특징?
A: 최솟값 == 0, 최댓값 == 1로 만든다.
Q: 기술 통계로 봤을 때 Robust Scaling의 특징?
A: 중간값(중앙값, 50%, 2사분위수)가 0이다.
또, 이상치에 영향을 덜 받는다.
Q: 표준 정규분포 형태로 변환이 된 것은 어떤 것일까요?
A: SalePrice_log1p_ss 가장 표준정규분포에 가깝다. SalePrice_log1p 도 정규분포에 가까운 모습이다.
Q: uniform 이란?
A: histogram을 그렸을 때 어딘가는 많고 적은 데이터가 있다면 그것도 특징이 될 수 있는데, 특징이 잘 구분되지 않는다면 power transform 등을 통해 값을 제곱 해주면 특징이 좀 더 잘 구분되어 보이기도 한다.
Q: Robust Scaling에서 IQR로 나눠준다는 건 상위 75%의 값-하위25%의 값으로 나누는 것을 의미하나요?
A: 맞다.
Q: 절대적인 값보다 상대적인 값에 영향을 받는다는 것이 무슨 말인지 잘 모르겠습니다.
A: 예를 들어 1~10 인 값이 있고 어떤 값은 1 ~1000 인 값이 있다면 여기에서 절대적인 크기보다 그 값의 상대적인 값을 보게 됩니다. 1~10인 값의 중간값은 5, 1~1000인 값의 중간값은 500 이런식으로 상대적인 값을 보게 됩니다.
- 절대평가: 간격으로 나누기
- 상대평가: 개수로 나누기 e.g.) 학점
Q: 표준정규분표와 그냥 정규분포 두 개 중에는 모델에서 사용할 때 성능차이가 많이 나나요?
A: 트리계열 모델을 사용한다면 일반 정규분포를 사용해도 무관합니다. 그런데 스케일값이 영향을 미치는 모델에서는 표준정규분포로 만들어 주면 더 나은 성능을 낼 수도 있습니다. 표준정규분포로 만들 때 값이 왜곡될 수도 있기 때문에 주의가 필요합니다. 꼭 이런 변환작업을 많이 해준다고 해서 모델의 성능이 좋아진다고 보장할 수 없습니다. 상황에 맞는 변환방법을 사용하는 것을 추천합니다.
Q: 보통 스케일링을 먼저 하는 것보다는, 먼저 log를 적용한 후 스케일링으로 바꿔주는게 순서가 맞나요?
A: 데이터에 따라 다르겠지만 만약 로그를 적용해줘야겠다고 한다면 로그 적용 후 스케일링해주는 것이 분포가 정규분포에 가깝기 때문에 일단 log를 적용해줍니다.
Q: Ordinal Encoding과 Label Encoding은 같은건가요?
A: Ordinal Encoding과 Label Encoding의 방식에는 차이가 없다. 다만 Ordinal은 피처 및 다차원을 변환할 때 사용하고, Label은 타겟 및 일차원을 변환할 때 사용하는 차이가 있다.