본문 바로가기
멋쟁이사자처럼 AIS7/오늘코드

[1114] Feature Engineering(2)

by YeonGun M 2022. 11. 14.

0701 실습

지난 수업 복습

기술통계

  • 이상치, 결측치, 표준편차 확인
  • 전체 피처에 대해 특이점 확인
  • 수치 범위의 개수가 적다면 범주형 데이터에 가까우며 nunique 값으로 추가적 확인이 필요하다

히스토그램

  • 수치 데이터의 분포 확인 -> 학습과 예측에 도움이 될만한 피처엔지니어링 기법 확인
  • 정규분포 형태인지, 왜도(치우침)나 첨도(뾰족함)이 심한지 등
  • 막대의 간격을 통해 범주형 데이터 확인

이상치

  • 이상치를 평균이나 중앙값 등으로 대체하면 데이터에 왜곡이 될 수 있으니 주의
  • 현실세계에서 풀어야할 문제 중에는 이상치를 탐지하는 문제도 있음

희소값

  • 희소값을 학습하게될 경우 연산 시간이 오래 걸리며 과대적합 우려가 있음
  • data binning, 결측치 처리 등

스케일링과 트랜스포메이션

변수 스케일링

  • 회귀 계열 모델에서 중요한 역할
  • 트리계열 모델에는 상대적 분포값이 바뀌는게 아니므로 큰 역할을 하지 않음

정규분포와 트랜스포메이션

  • 로그 변환 후 스케일링

  • 왜 정규분포를 해야하는가?
    1) 피처의 범위가 다르면 피처간 비교가 어려우며 경사하강법(Gradient Descent)이나 KNN, Clustering 등의 거리 기반 알고리즘에서는 머신러닝이 제대로 작동하지 않는다
    2) pca 전에 전처리 할 속성의 영향을 같은 선상에서 비교할 수 있다
    3) 너무 한쪽에 몰려있거나 치우쳐져 있을 때보다 고르게 분포되어 있다면 데이터의 특성을 더 고르게 학습할 수 있다

  • 로그 변환을 위한 전처리
    -> 최솟값의 절댓값 + 1을 더함 ex. 최소값이 -1000이라면 1001을 더함
    -> 이후 원래값으로 복원 ex. 지수함수(np.exp(x)) 적용 후 1001을 뺌

이산화

  • cut, qcut

  • 연속된 수치 데이터를 구간화하여 머신러닝 알고리즘에 힌트를 줄 수도 있다.
    -> EDA를 통화 구간화 기준 정립, 잘못나누면 모델 성능 저하 가능

  • ex. 트리 모델의 일반화에 기여

  • RFM(Rececny, Frequency, Monetary) 기법에서도 종종 사용되며 비즈니스 분석에서 다룰 예정

인코딩

Q. LabelEncoder와 OrdinalEncoder의 차이가 뭘까?
A. Ordinal Encoding은 Label Encoding과 달리 변수에 순서를 고려한다는 점에서 큰 차이를 갖는다. Label Encoding이 알파벳 순서 혹은 데이터셋에 등장하는 순서대로 매핑하는 것과 달리 Oridnal Encoding은 Label 변수의 순서 정보를 사용자가 지정해서 담을 수 있다. 추가로 LabelEncoder 입력이 1차원 y 값, OrdinalEncoder 입력이 2차원 X값이다.

Q. X, y값이 뭘까?
A.

  • X는 feature, 독립변수, 2차원 array 형태, 학습할 피처, 예) 시험의 문제
  • y는 label, 종속변수, target, 정답, 1차원 벡터, 예) 시험의 정답
  • X는 보통 2차원으로 대문자로 표기하고 y는 소문자로 표기하는 것이 관례

원핫인코딩에서 Found unknown categories [nan] in column 0 during transform 오류를 어떻게 고칠까?
A. ohe = OneHotEncoder(handle_unknown='ignore')

cf. 최신버전에서의 infrequent_if_exist?
A. test 에 train 에 들어있지 않은 값이 등장한다면 "기타" 등으로 만들겠다는 의미입니다.
sklearn.preprocessing.OneHotEncoder
빈도가 적은 값에 대해 기타로 처리하는 min_frequency

꼭 원핫인코딩 했을 때는 train, test 피처의 수가 같은지 확인해 주세요!
print(train_ohe.shape, test_ohe.shape)

다항식 전개

Q. uniform 의 의미가 뭘까?
A. 히스토그램을 그렸을 때 데이터의 많고 적음도 특징이 될 수 있는데, 이러한 특징이 잘 구분되지 않는다면 power transform와 같이 제곱해주는 등의 방법을 통해 특징을 더 두드러지게 보이게 할 수 있다.

특성선택

분산 기반 필터링
범주형 변수가 특정 값에 치중되어 있다면 학습에 장애가 될 수 있다. ex.90%이상 특정 값 치중

상관관계 기반 필터링
수치형 변수와 종속 변수 간의 상관관계가 너무 낮을 경우 학습에 도움이 되지 않을 수 있다.
Untitled

JD

Q. SQL 로 관리하는 데이터와 파일로 관리하는 데이터는 어떻게 구분해서 관리할까?
A. sql 에 저장하는 데이터는 실시간으로 사용해야 하는 데이터이고, 파일로 관리하는 데이터는 로그성 데이터다.아카이빙할 데이터는 대부분 파일로 저장합니다. 실시간으로 보여주어야 하는 현재 status 값만 DB에 저장해서 사용하기도 합니다. status값을 업데이트 해서 SQL로 관리하고 아카이빙할 데이터는 파일로 저장합니다.
ex. 유튜브는 맞춤형 광고를 위해 영상 시청시 개인 정보를 대략적으로 수집함

Q.실시간으로 관리할 데이터는 어떤 것이 있을까?
A. 로그인, 장바구니, 결제, 회원가입 정보, 각종 status값(게임의 캐릭터 위치, 캐릭터 정보, 게임머니, 캐릭터가 가지고 있는 장비 인벤토리 정보 등) 등

채용공고와 기사 연결하기

  • 오늘의집
  • DAU : Daily Active User 하루에 몇 명이 접속하는지(혹은 로그인 하는지)
  • AARRR, Funnel : 분석을 통해 얼마나 많은 사람이 와서 물건을 살펴보고 거기서 회원가입 구매전환 친구 추천 혹은 재구매로 이어지는지?
  • Churn : 얼마나 사람들이 어느 페이지에서 이탈하는지? 퍼널, AARRR 과 함께 볼 수 있는 지표입니다.
  • AB Testing : 1~2년이 넘는 시간 동안 수백 가지의 노력이 꾸준히 모여서 매달 마주하는 문제를 개선한 것이 결과적으로는 성장의 모멘텀을 만들었다고 생각합니다.

0702 실습파일

pd.concat([train, test])

간혹 경진대회를 보면 train과 test셋을 concat해서 전처리를 하는 경우가 있다. 전처리를 한 번에 할 수 있는 편리한 방법이지만 현실세계에서는 불가능한 방법이다. test셋을 알 수 있는 현실은 없기 때문이다. 간혹 몇몇 경진대회에서는 이와 같은 전처리를 금지하는 경우가 있으니 주의하자.

왜도와 첨도

SalePrice의 왜도와 첨도

print("왜도(Skewness):", train["SalePrice"].skew())
print("첨도(Kurtosis):", train["SalePrice"].kurtosis())
  • 왜도(Skewness): 1.8828757597682129
  • 첨도(Kurtosis): 6.536281860064529

SalePrice_log1p의 왜도와 첨도
왜도(Skewness): 0.12134661989685333
첨도(Kurtosis): 0.809519155707878
Untitled

Q. 이중축을 이용해서 그릴 수는 없을까?
A. 이중축은 y값의 스케일이 다를 때 지원하는데 판다스에서는 x값에 대해서는 이중축을 지원하지 않는다.
Untitled

수치형 변수 상관관계의 pairplot

  • SalePrice와 상관계수가 0.5 이상인 데이터를 관측해보자.
    high_corr_col = corr.loc[(abs(corr['SalePrice']) > 0.5), 'SalePrice'].index
    sns.pairplot(train[high_corr_col], corner=True)
    Untitled

파생변수 만들기

df['TotalSF'] = df['TotalBsmtSF'] + df['1stFlrSF'] + df['2ndFlrSF']

결측치

결측치 확인

  • 메서드 체이닝은 도움말 보기가 잘 안될 수 있으니, 도움말을 보기 위해서는 변수 지정을 해주자.
  • 결측치가 너무 많은 피처의 경우 없애주는 것이 학습에 도움이 될 수 있다.
    isna_sum = df.isnull().sum()
    isna_mean = df.isnull().mean()
    pd.concat([isna_sum, isna_mean], axis=1).nlargest(10, 1)

결측치 채우기

  • 범주형 변수는 None, 수치형 변수는 0으로 채울 수 있다.
  • 최빈값으로도 채울 수 있다.
fill_mode = ['MSZoning', 'KitchenQual', 'Exterior1st', 'Exterior2nd', 'SaleType', 'Functional']
# 최빈값 채우기 - 반복문
for col in fill_mode:
    df[col] = df[col].fillna(df[col].mode()[0])
# 최빈값 채우기 - 딕셔너리
mode_dict = df[fill_mode].mode().iloc[0].to_dict()
df[fill_mode] = df[fill_mode].fillna(mode_dict)
# 최빈값 채우기 - 시리즈
df[fill_mode] = df[fill_mode].fillna(df[fill_mode].mode().loc[0])

데이터 타입 바꾸기

  • nunique 값이 너무 작은 수치형 데이터는 범주형 데이터로 변환하여 원핫인코딩이 가능하게 해준다.

댓글