TIL/머신러닝

11/10 머신러닝 주택가격 피처엔지니어링

monawa 2022. 11. 10.
728x90

변수 스케일링 

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

 

 

728x90

댓글