변수 스케일링
Feature의 범위를 조정하여 정규화하는 것을 의미합니다
Feature의 분산과 표준편차를 조정하여 정규분포 형태를 띄게 하는 것이 목표입니다
변수 스케일링이 중요한이유
- Feature의 범위가 다르면,Feature끼리 비교하기 어려우며 일부 머신러닝 모델에서는 제대로 작동하지 않습니다.
- FeatureScaling이 잘 되어있다면 서로 다른 변수가 있더라도 비교하기 편리합니다
- 비교가 편리하기에 FeatureScaling 없이 작동하는 알고리즘에서 더 빨리 작동합니다
(트리기반 모델은 피처 스케일링이 필요 X - 데이터의 절대적 크기보단 상대적인 크기에 영향 받기에 ) - 또한 머신러닝 성능이 상승합니다
- 일부 FeatureScaling은 이상치에 대해 강점이 있습니다 (RobustScaler)
이름 | 표준화 Normalization- Standardization (Z-scorescaling) |
Min-Maxscaling | Robustscaling |
정의 | 평균을 제거하고데이터를 단위 분산에 맞게 조정합니다. |
Feature를 지정된범위로 확장하여 기능을 변환합니다. 기본값은[0,1]입니다. |
중앙값을제거하고 분위수범위(기본값은IQR)에 따라 데이터크기를조정합니다. |
장점 | 표준편차가 1이고 0을 중심으로하는 표준정규 분포를 갖도록 조정됩니다 |
편향된 변수에 대한 변환후 변수의 분산을 더 잘 보존합니다. 이상치 제거에 효과적입니다 |
|
단점 | 변수가 왜곡되거나 이상치가 있으면 좁은 범위의 관측치를 압축하여 예측력을 손상시킵니다 | 변수가 왜곡되거나 이상치가 있으면 좁은범위의관측치를 압축하여 예측력을 손상시킵니다. |
|
수식 | z=(X-X.mean)/std | X_scaled=(X-X.min)/(X.max-X.min) | X_scaled=(X-X.median)/IQR |
요약 | ‘평균’을 빼주고 ‘표준편차’로 나눔 | 변수 범위를 0과 1사이로 압축해주는 개념 | 중간값을 빼주고 IQR값으로 나눔 |
특징 | 평균 0, 표준편차 1의 특징을 가지고 있음 | 0~1 사이의 값으로 만듬 | 이상치에 영향을 덜 받는다 |
IQR:InterquartileRange로,상위75%와하위25%사이의범위를의미합니다.
{mean : 산술평균, std : 표준편차 ,max : 최대값, min : 최소값,median : 중간값}
세방법은 모두 sklearn의 전처리모듈에서 메서드로 지원되고 잇습니다
(수식을 몰라도 사용가능 - 하지만 개념이해를 위해 수식을 알면 좋다!)
이떄
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler
이렇게 불러올수도 있지만
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import RobustScaler
로 불러오는걸 권장합니다
한번더 리마인드 요약 정리
StandardScaler
- 평균 0, 표준편차 1의 특징을 가지고 있음
- 평균을 이용하여 계산해주기 때문에 이상치에 영향을 받는다.
(평균: 이상치의 값에 크게 영향을 받기 때문)
MinMaxScaler
- 변수 범위를 0과 1사이로 압축해주는 개념
- 이상치를 포함하고 있으면 범위설정에 영향이 가기 때문에 이상치에 의해 영향을 많이 받는다.
RobustScaler
- 중앙값과 사분위 수를 이용한 스케일링 기법
- StandardScaler와 다르게 중앙값(median)을 이용하기 때문에 StandardScaler, MinMaxScaler에 비해서 이상치의 영향을 덜 받는다.
(사분위수를 기준으로 IQR값을 이용하기 떄문에 매우 큰값이나 매우 작은 값을 갖는 경우 완화)
fit & transform
fit은 해당 columns을 기준으로 받고 맞춰주는 역할을 합니다.
- fit() : Compute the mean and std to be used for later scaling. matrix형태의 값을 받습니다
(반환값도 matrix)
fit 은 train 에만 사용
(fit 은 test 에 사용하지 않는다. 왜냐하면 기준은 train이다.
전처리할 때 train을 기준으로 전처리해주듯이 Scaling의 기준도 마찬가지입니다!
test 에는 train을 기준으로 학습한 것을 바탕으로 transform 만 합니다.)
- trainform() : Call func on self producing a DataFrame with the same axis shape as self.
transform 은 train, test 에 사용한다.
스케일링에서 fit 은 계산하기 위한 평균, 중앙값, 표준편차가 필요하다면 해당 데이터를 기준으로 기술통계값을 구하고 그 값을 기준으로 transform 에서 계산을 적용해서 값을 변환해준다
fit된 기준으로 해당 컬럼이나 다른 컬럼들의 값을 바꿔주기 원할 때 transform을 사용합니다.
fit().transform() = fit_transform()\
ss = StandardScaler()
train['SalePrice_ss'] = ss.fit(train[['SalePrice']]).transform(train[['SalePrice']])
train['SalePrice_ss'] = ss.fit_transform(train[['SalePrice']])
# fit_transform : fit과 transfrom을 한 번에해준다.
Transformation
Robust Scaling을 제외한 Feature Scaling은 일반적으로 편향된 분포나 이상치에 취약하며, Feature Scaling을 해줘도 표준정규분표형태를 띄지 않음.
Log Transformation을 적용하는 이유
- log 함수가 x값에 대해 상대적으로 작은 스케일에서는 키우고,
- 큰 스케일에서는 줄여주는 효과가 있기 때문
- 편향된 Feature의 경우 log가 적용된 값은 원래 값에 비해서 더 고르게 분포되며, 이는 y예측값에 유용하다.
(고르게 분포된 값이 예측에 유리한 이유)
고르게 분포된 값이 예측에 유리한 이유
- 구간을 4개의 간격으로 나누었을 때 1,4분위보다 2,3분위가 상대적으로 더 중요하다
> 예측하려는 값이 비교적 매우 작거나 매우 큰 값보단 중간값에 가까운 값일 확률이 높기 때문 - 표준정규분포를 띄게 된 값을 2,3분위에 값이 집중되어 있어 일반적인 예측 성능이 올라간다.
- 정규분포로 고르게 분포된 값이 예측에 더 유리한 값이다.
주의할 점
- 로그의 진수 조건에 따라 x>0을 만족해야 함
- 주어진 값에 1을 더해서 log transformation을 해 주는 것이 안전
=> numpy.log1p : 주어진 값에 1을 더해서 log 변환하는 과정을 메서드 - 직접 1을 더하고 빼는 것보다 “numpy.log1p ”, “numpy.exp1m” 사용을 권장
변환 작업시 주의점
- 표준정규분포로 만들 때 값이 왜곡될 수도 있음
- 변환작업을 많이 해준다고 해서 모델의 성능이 좋아진다고 보장할 수 없음 => 상황에 맞는 변환방법을 사용하는 것을 추천
이산화
Numerical Feature를 일정 기준으로 나누어 그룹화하는 것
이산화는 직관적(사고방식과 부합)
데이터분석과 머신러닝 모델에 유리(그룹화는 학습 시에 힌트를 제공)
Equal width binning | Equal frequency binning | |
정의 | 동일한 너비의 범위로 그룹화 (간단히 요약) 동일한 길이로 나누기 |
동일한 데이터 개수로 그룹화 (간단히 요약) 동일한 개수로 나누기 |
특징 | 가능한 값의 범위를 동일한 너비의 N개의 bins로 나눔 |
변수의 가능한 값 범위를 N개의 bins로 나눔 각 bins은 동일한 양의 관측값을 전달 |
장점 | 알고리즘 성능 향상에 도움 | |
단점 | 편향된 분포에 민감 | 임의의 binning은 대상과의 관계를 방해할 수 있음 |
예시 | 절대평가 히스토그램 고객을 구매 금액 구간에 따라 나눌 때 |
상대평가 고객을 고객의 수를 기준으로 등급을 나눌 때 |
pandas | pandas.cut (값을 기반으로 이산화) 사용자가 이산화를 할 수치를 직접 입력하게 됩니다. |
pandas.qcut (샘플의 변위치를 기반으로 이산화) 계산한 특정 분위수를 기반으로 해서 이산화를 수행 |
train["SalePrice_cut"] = pd.cut(train["SalePrice"], bins=4, labels=[1, 2, 3, 4])
train["SalePrice_qcut"]= pd.qcut(train["SalePrice"], q=4, labels=[1, 2, 3, 4])
머신러닝에서 데이터를 분할해서 연속된 수치데이터를 이산화 해주는 이유
-> 머신러닝알고리즘에 힌트를 줄 수도 있고, 너무 세분화된 조건으로 오버피팅(과대적합)되지 않도록 도와준다.
인코딩
Categorical Feature를 Numerical Feature로 변환하는 과정
장점
- 데이터 시각화에 유리 (ex) lineplot / scatterplot 등
- 머신러닝 모델에 따라 Categorical Feature를 처리할 수 없는 경우가 있음
(ex) 선형회귀 모델, 딥러닝 모델 등 - 범주형 데이터를 알아서 처리해 주는 알고리즘도 있음
(ex) Xgboost, LightGBM, catBoost
Ordinal-Encoding | One-Hot-Encoding | |
정의 | Categorical Feature의 고유값들을 임의의 숫자로 바꿈 | Categorical Feature를 다른 bool 변수로 대체하여 해당 관찰에 대해 특정 레이블이 참인지 여부를 나타냄 |
특징 | 임의의 숫자를 지정 가능 (지정하지 않으면 0부터 1씩 증가하는 정수로 지정) 순서가 있는 명목형 데이터에 사용 (ex 분기) 1차원 형태로 반환 |
순서가 없는 명목형 데이터에 사용 (ex 좋아하는 음료) matrix, 2차원 형태로 반환 |
장점 | 간단하고, 직관적이다 | 해당 Feature의 모든 정보를 유지한다는 점이다. |
단점 | 데이터에 추가적인 가치를 더해주지 않는다는 점이다. 표현 방식이 바뀌었을 뿐, 데이터의 정보 자체는 동일 그 값이 크고 작은게 의미가 있을 때는 상관 없지만, 순서가 없는 데이터에 적용하게 되면 잘못된 해석을 할 수 있음 |
해당 Feature의 고유값이 많은 경우 Feature를 지나치게 많이 사용한다는 점이다. |
Pandas | cat.codes | get_dummies |
사이킷런 예제
from sklearn.preprocessing import OrdinalEncoder
enc = OrdinalEncoder()
X = [['male', 'from US', 'uses Safari'],
['female', 'from Europe', 'uses Firefox']]
enc.fit(X)
print(enc.transform([['female', 'from US', 'uses Safari']]))
print(enc.categories_)
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder()
X = [['male', 'from US', 'uses Safari'],
['female', 'from Europe', 'uses Firefox']]
enc.fit(X)
enc_out = enc.transform([['female', 'from US', 'uses Safari'],
['male', 'from Europe', 'uses Safari']]).toarray()
print(enc_out)
print(enc.get_feature_names_out())
라벨인코딩(Label Encoding)
참고 : [ML] How to encode categorical variables
https://techblog-history-younghunjo1.tistory.com/99
라벨과 오디널 인코딩은 거의 비슷해보이지만 라벨 인코더는 기본적으로 딱히 순서에 의미가 없는 데이터에 사용되게 됩니다.(예: 지역코드)
차이점 : 오디널 인코딩은 이름처럼 기본적으로 각 카테고리에 고유한 숫자값을 지정해주는 것은 같지만 순서에 의미가 있는 데이터 처럼 각 숫자에 의미가 필요할 경우 사용하게 됩니다. (예: 우수: 3 중간: 2 나쁨: 1)
- 과거에는 라벨인코딩을 꼭 써야했지만, 최근에는 오디널 인코딩으로 대체되는 영역이 늘어나면서 코딩이 단순해지고 있다. 다만 딥러닝이나 몇몇 분야에서는 라벨 인코딩을 필수적으로 요구된다.
사이킷런 예제
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])
print(list(le.classes_))
print(["tokyo", "tokyo", "paris"])
print(le.transform(["tokyo", "tokyo", "paris"]))
list(le.inverse_transform([2, 2, 1]))
파생 변수 생성(Feature Generation)
이미 존재하는 변수로부터 여러가지 방법을 이용해 새로운 변수를 만들어내는 것
만드는 이유
- 적절히 파생된 변수는 데이터의 특성을 잘 설명해준다.
- Feature간의 숨겨진 연관관계 드러낼 수 있음
주의점
- Feature가 늘어날수록 모델 학습 시간이 길어진다.
- 파생변수 생성으로 인해 데이터 해석이 편리해지고 성능이 올라갈 수 있으나 역효과가 생길 수도 있음.
파생변수를 생성할 때, 다른 분석가도 이해할 수 있게 직관적으로 생성하거나 보고서에도 Feature관련 내용을 잘 작성해야 한다.
pandas로 train, test를 각각 인코딩 했다면 피처의 수, 종류가 다를 수 있다.
학습 및 예측을 할 때에는 동일한 피처, 개수를 입력해 주어야 한다.
uniform
균등하게 분포하는 것을 의미한다.
히스토그램을 그렸을 때 어딘가는 많고 적고인 데이터가 있다면 그것도 특징이 될 수 있는데
특징이 잘 구분되지 않는다면 power transform 등을 통해 값을 제곱을 해주거나 하면 특징이 좀 더 구분되어 보이기도 한다.
degree == 차수
다항식 전개에 기반한 파생 변수 생성(Polynomial Expansion)
- 주어진 다항식의 차수 값에 기반하여 파생변수를 생성
- 다항식 전개에 기반한 변수보다 원래 변수를 보는 게 더 직관적이고 이해하기 쉽기 때문이다.
단 데이터를 분석할 시 다항식 전개에 기반한 파생 변수생성은 유용하지 않을 수 있다. - 다항식 전개에 기반해서 파생변수를 만들게 되면 머신러닝 모델이 여러 Feature에 기반하게 되어 안정성이 높아진다.단 적은 Feature 수를 기반으로 머신러닝을 할 시 과적합이 일어날 가능성이 크다.
따라서 안정성을 높이기 위해 다항식 전개에 기반한 파생변수를 생성하는 것이 유용하다. - SOTA == State Of The Art(현재 최고 수준의 결과)
참고문헌 :
멋쟁이 사자처럼 AI School 7기 수업내용
https://techblog-history-younghunjo1.tistory.com/99
'TIL > 머신러닝' 카테고리의 다른 글
11.15 머신러닝 주택가격, 벤츠 (0) | 2022.11.16 |
---|---|
11.14일 주택가격 피처엔지니어링 0702 (0) | 2022.11.16 |
11.09 머신러닝 회귀 스케일링 피처 엔지니어링 (1) | 2022.11.10 |
11.08 머신러닝 bike log 회귀 (0) | 2022.11.09 |
공부한거 정리해보기 (0) | 2022.11.03 |
댓글