일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Brightics studio
- 브라이틱스 분석
- 데이터 분석 플랫폼
- 파이썬 SQL 연동
- pymysql
- Random Forest
- Brightics EDA
- 파이썬 내장 그래프
- 검증 평가 지표
- paper review
- 브라이틱스 스태킹
- Brightics 서포터즈
- 범주형 변수 처리
- 비전공자를 위한 데이터 분석
- 머신러닝
- 삼성 SDS
- Activation Function
- Brigthics Studio
- Deep Learning for Computer Vision
- 브라이틱스 AI
- Brightics AI
- 딥러닝
- 브라이틱스 서포터즈
- 브라이틱스 프로젝트
- 데이터 분석
- Python
- 분석 툴
- 서포터즈 촬영
- 삼성 SDS 서포터즈
- michigan university deep learning for computer vision
- Today
- Total
하마가 분석하마
[machine learning class] 6. feature engineering 본문
feature engineering은 좋은 머신러닝 모델을 만드는데 있어서 가장 중요한 부분 중 하나이다. 크고 복잡한 모델을 잘 가공된 피쳐와 단순한 모델로 대체하는 것이 가능한 경우가 대다수이다.
- 새로운 피쳐 만들기
- 기존의 피쳐에 적용하는 다양한 평준화 및 변환 기법
등의 여러 피쳐 가공법들이 있다. 피쳐 가공은 사용하는 데이터에 따라 차이가 있기 때문에, 최선의 피쳐 가공 방식은 문제의 영역에 대해 어느 정도 이해하는 것이 필요하다.
저번에 범주형 변수의 처리에 대해서 알아보았다. 이번에는 수치형 변수와 수치형 변수, 범주형 변수의 조합을 위한 피쳐 가공에 초점을 맞춰본다.
[날짜 / 시간 변수에 대한 피쳐 생성]
날짜 / 시간 (datetime) 타입의 변수가 있는 pandas 데이터프레임이 있다면 다음과 같은 피쳐를 생성할 수 있다.
df.loc[:, 'year'] = df['datetime_column'].dt.year
df.loc[:, 'weekofyear'] = df['datetime_column'].dt.weekofyear
df.loc[:, 'month'] = df['datetime_column'].dt.month
df.loc[:, 'dayofweek'] = df['datetime_column'].dt.dayofweek
df.loc[:, 'weekend'] = (df.datetime_column.dt.weekday>=5).astype(int)
df.loc[:, 'hour'] = df['datetime_column'].dt.hour
이는 pandas가 지원하는 많은 날짜 / 시간 피쳐 중 일부이다. 날짜/시간 피쳐는 업소의 매출을 예측하는 것과 같이 시계열 데이터로 머신러닝 모델을 학습할 때 아주 중요하다.
이번에는 고객 id 변수와 날짜 변수, 범주형 변수와 수치형 변수 모두가 주어졌다고 가정해보자. 날짜 변수로부터 연도, 분기, 월과 같은 피쳐를 쉽게 추출할 수 있다. 그리고 다음과 같은 여러 집계 (aggregated) 피쳐를 생성할 수 있다.
def generate_features(df):
# date 열로부터 여러 피쳐를 생성한다.
# 날짜 변수 = date
df.loc[:, 'year'] = df['date'].dt.year
df.loc[:, 'weekofyear'] = df['date'].dt.weekofyear
df.loc[:, 'month'] = df['date'].dt.month
df.loc[:, 'dayofweek'] = df['date'].dt.dayofweek
df.loc[:, 'weekend'] = (df['date'].dt.weekday >=5).astype(int)
# 집계 사전을 생성한다.
aggs = {}
# 월별/주별 집계로는 월의 유일 값의 개수와 평균 값을 사용한다.
aggs['month'] = ['nunique', 'mean']
aggs['weekofyear'] = ['nunique', 'mean']
# num1 열은 합, 최대 값, 최소 값, 평균 값으로 집계한다.
aggs['num1'] = ['sum','max','min','mean']
# 고객 id 는 총 개수를 집계한다.
aggs['id'] = ['size']
# 고객 id 의 유일 값의 개수를 집계한다.
aggs['id'] = ['nunique']
# id 를 기준으로 집계한다.
agg_df = df.groupby('id').agg(aggs)
agg_df = agg_df.reset_index()
return agg_df
위 코드에서 범주형 변수는 사용하지 않았으나 원한다면 동일한 방식으로 범주형 변수로부터 집계 피쳐를 생성할 수 있다.
generate_features() 함수를 실행한 예시를 보자.
이처럼 새로 생성된 데이터프레임을 '고객 id' 변수를 기준으로 원래 데이터프레임과 합칠 수 있다. 분석을 통해 예측하려는 목적이 있다면 (타겟 변수가 존재한다면) 그 목적에 맞춰서 피쳐를 생성할 수 있다.
[수치형 변수에 대한 통계 피쳐 생성]
수치형 변수를 특정 범주형 변수 기준으로 그룹을 지어 집계 변수를 생성할 때 다음과 같은 여러 통계 피쳐를 생성할 수 있다.
- 평균값
- 최대값
- 최소값
- unique한 값의 개수(고유값의 개수)
- 왜곡도
- 첨도
- 백분위
- 최소/최대값의 차이
- Kstat
이와 같은 여러 통계 피쳐들은 numpy 함수를 이용하여 쉽게 구할 수 있다. 아래 함수에서 x는 값의 목록을 의미한다.
import numpy as np
feature_dict = {}
# 평균 값
feature_dict['mean'] = np.mean(x)
# 최대 값
feature_dict['max'] = np.max(x)
# 최소 값
feature_dict['min'] = np.min(x)
# 표준편차 값
feature_dict['std'] = np.std(x)
# 분산 값
feature_dict['var'] = np.var(x)
# 최대-최소 값 차이
feature_dict['ptp'] = np.ptp(x)
# 백분율 피쳐
feature_dict['percentile_10'] = np.percentile(x, 10)
feature_dict['percentile_60'] = np.percentile(x, 60)
feature_dict['percentile_90'] = np.percentile(x, 90)
# 퀀타일 피쳐
feature_dict['quantile_5'] = np.quantile(x, 0.05)
feature_dict['quantile_95'] = np.quantile(x, 0.95)
feature_dict['quantile_99'] = np.quantile(x, 0.99)
[tsfresh를 사용한 피쳐 변환]
시계열 데이터는 많은 피쳐로 변환할 수 있다. 이 때 tsfresh 라는 파이썬 라이브러리가 유용하다. 아래 코드에서 x는 값의 목록을 의미한다.
from tsfresh.feature_extraction import feature_calculators as fc
# tsfresh 를 사용한 피쳐 생성
feature_dict['abs_energy'] = fc.abs_energy(x)
feature_dict['count_above_mean'] = fc.count_above_mean(x)
feature_dict['count_below_mean'] = fc.count_below_mean(x)
feature_dict['mean_abs_change'] = fc.mean_abs_change(x)
feature_dict['mean_change'] = fc.mean_change(x)
이 외에도 tsfresh는 시계열 데이터에 사용가능한 수백 가지의 피쳐를 제공한다.
abs_energy | 제곱 된 값에 대한 합계인 시계열의 절대 에너지를 반환 |
count_above_mean | x의 평균보다 큰 x 값의 개수를 반환 |
count_below_mean | x의 평균보다 작은 x 값의 개수를 반환 |
mean_abs_change | 다음 시계열 값 간의 절대 차이에 대한 평균을 반환 |
mean_change | 후속 시계열 값 간의 차이에 대한 평균을 반환 |
또 다른 많은 피쳐를 생성하는 간단한 방법은 다항 (polynomial) 피쳐를 생성하는 것이다. 예로 a와 b로부터 생성된 2차 다항 피쳐는 a, b, aa, bb가 된다.
만약 3차 다항 피쳐를 생성한다면 두 개의 변수로부터 총 9개의 피쳐를 생성하게 된다. 변수의 개수가 늘어나면 생성되는 다항 피쳐의 개수도 증가한다. 사이즈가 큰 데이터의 경우 다항 피쳐를 생성하는데 많은 시간이 걸린다는 점도 염두해 두어야 한다.
[양자화 (binning)]
또 다른 피쳐 가공법으로는 수치형 변수를 범주형 변수로 변환하는 양자화 (binning)가 있다. pandas의 cut 함수를 사용하여 데이터를 원하는 개수의 범위로 나눌 수 있다.
양자화는 수치형 변수를 범주형 변수처럼 다룰 수 있게 만든다. 양자화 한 후 기존 변수와 양자화된 피쳐를 함께 모델링에 사용할 수 있다.
[로그 변환]
수치형 변수를 변환하는데 자주 사용되는 방법으로 로그 변환이 있다. 분산을 줄이기 위해 로그 변환을 취한다.
경우에 따라 로그 대신 지수 변환을 취할 때도 있다. RMSLE와 같은 로그 기반의 검증 메트릭을 사용하는 경우, 타겟 변수를 로그 변환하여 모델을 학습한 후, 예측 시에 지수 변환을 하여 원래 척도로 돌려놓는 방법을 사용한다. 이렇게 하면 메트릭에 최적화된 학습을 하는데 도움이 된다.
대부분 피쳐 가공은 정해진 공식이 없이 직관에 많이 의존한다. 특종 업종에 종사하는 경우, 업종에 특화된 피쳐를 생성할 수 있다.
[수치형 변수의 결측값 처리]
범주형 변수와 수치형 변수를 함께 사용하는 경우 결측값이 나타날 수 있다. 이전에 설명했듯이 범주형 변수의 경우 결측값을 하나의 범주로 간주하면 간단하다. 결측값을 하나의 범주인 'NONE'으로 두는 이 방법은 대부분 효과가 있다.
수치형 변수에서 결측값을 처리하는 한 가지 방법은 결측값을 특정한 값으로 대치하는 것이다. 예를 들어, 해당 변수에 0이 존재하지 않다면, 모든 결측값을 0으로 대치할 수 있다. 이보다 나은 방법은 0 대신 해당 변수의 평균값이나 중위값, 또는 가장 빈번하게 나타나는 값으로 대치하는 것이다.
수치형 변수의 결측값을 대치하는 또 다른 방법은 knn을 사용하는 것이다. 이 방법은 결측값이 있는 샘플과 유클리드 거리와 같은 거리 메트릭을 사용하여 가장 가까운 이웃 샘플을 찾는다. 그리고 발견된 이웃 샘플들의 평균으로 결측값을 대치한다.
import numpy as np
from sklearn import impute
# 1 에서 15 사이의 값을 가지는 10 개의 행, 6 개의 열로 구성된 랜덤 데이터 생성
X = np.random.randint(1, 15, (10, 6))
# 데이터 타입을 실수형으로 변경한다.
X = X.astype(float)
# 랜덤하게 10 개의 값을 NaN 으로 변경한다.
X.ravel()[np.random.choice(X.size, 10, replace=False)] = np.nan
# kNN 을 사용하여 결측 값을 대치한다.
knn_imputer = impute.KNNImputer(n_neighbors=2)
knn_imputer.fit_transform(X)
결측값을 대치하기위해 회귀 모델을 사용할 수도 있다. 결측값이 있는 변수를 타겟 변수로 사용하고 남은 변수들을 피쳐로 사용하여 회귀 모델을 학습한 후 결측값을 예측 값으로 대치하는 것이다. 여기서 결측값이 없는 샘플은 학습 데이터로 결측값이 있는 샘플은 시험 데이터로 사용한다. 이는 앞서 다룬 방법보다 더 안정적인 방식이다.
트리 기반 모델을 사용하는 경우, 자체적으로 결측값을 처리하므로 별도로 결측값을 대치할 필요가 없다. 또한 트리 기반 모델은 수치형 변수를 표준화할 필요도 없다. 반면에 SVM 이나 로지스틱 회귀와 같은 모델을 사용할 때에는 반드시 수치형 변수를 표준화해야 한다.
피쳐를 가공하고 생성할 때 데이터를 자세히 살펴보고 어떤 피쳐를 생성할지 고민해야 한다.
또한 결측치를 대체할 때 다양한 방면으로 데이터를 확인해 본 뒤 결측치를 예측하거나 대체해야 한다. 이전 장에서도 소개했듯이 필자도 작은 프로젝트를 할 때 결측치를 예측했었다. 실제 프로젝트에서 데이터의 손실을 별로 좋아하지 않기에 여러 방법을 잘 녹여내어서 결측치를 대체하는 것이 중요하다 생각한다.
https://tsfresh.readthedocs.io/en/latest/text/list_of_features.html
Overview on extracted features — tsfresh 0.18.0 documentation
Docs » Overview on extracted features Edit on GitHub © Copyright 2016-2021, Maximilian Christ et al./ Blue Yonder GmbH Revision b3395c12. Built with Sphinx using a theme provided by Read the Docs.
tsfresh.readthedocs.io
https://github.com/rch1025/Machine-learning-class
rch1025/Machine-learning-class
Several concepts and several tips that are important for data analysis can be learned. I studied based on 'Machine Learning Master Class'. - rch1025/Machine-learning-class
github.com
'Machine learning class' 카테고리의 다른 글
[machine learning class] 8. 하이퍼파라미터 (0) | 2021.03.23 |
---|---|
[machine learning class] 7. feature choice (0) | 2021.03.10 |
[machine learning class] 5. 범주형 변수 처리-3 (2) | 2021.03.03 |
[machine learning class] 5. 범주형 변수 처리-2 (0) | 2021.03.01 |
[machine learning class] 5. 범주형 변수 처리-1 (0) | 2021.02.26 |