지금은마라톤중

캐글 타이타닉 (5) 본문

Machine Learning/Kaggle

캐글 타이타닉 (5)

달리는중 2022. 10. 27. 13:26

Titanic 9. Feature engineering - Fill Null in Age

 

https://youtu.be/qVknmB5OElE

 

* Feature Engineering
: Feature Engineering은 머신러닝 알고리즘을 작동하기 위해 데이터에 대한 도메인 지식을 활용하여 특징(Feature)를 만들어내는 과정이다. 다른 정의를 살펴보면, 머신러닝 모델을 위한 데이터 테이블의 컬럼(특징)을 생성하거나 선택하는 작업을 의미한다. Feature Engineering은 모델 성능에 미치는 영향이 크기 때문에 머신러닝 응용에 있어서 굉장히 중요한 단계이며, 전문성과 시간과 비용이 많이 드는 작업이다.

- Feature가 중요한 이유 
머신러닝은 입력 데이터의 함수이며 선형 또는 비선형의 형태를 가질 수 있는데, 우리는 훈련 데이터를 사용해서 이 함수를 학습하지만, 매번 학습이 잘되어 결과가 나타나지 않는다. 내가 가지고 있는 데이터가 방대하다해도 그 데이터를 모두 결과를 도출하는데 쓰면 정확히 나타날 듯하지만 오히려 결과를 잘못되게 도출하는 경우가 많다. 이는 통계분석에서 선형 함수의 독립변수가 많다고 해서 종속변수의 기대값이 정확도가 무조건 올라가지 않는 이유라고도 할 수 있다.
즉, 머신 러닝의 성능은 어떤 데이터를 입력하는지가 굉장히 의존적이라는 것을 알 수 있다. 가장 이상적인 입력 데이터는 부족하지도 과하지도 않은 정확한 정보만 포함될 때이다. 그렇기에 가장 적절 한 방법은 먼저 충분한 데이터를 먼저 모으고 어떤 feature가 유용한지 아닌지 확인하는 과정을 거칩니다. feature가 유용한지 아닌지 확인하는 과정을 특징 선택(feature selection) 또는 특징 추출(feature extraction) 이라고 한다. 해당 과정은 기존 입력을 토대로 새로운 입력 데이터를 만들기 때문에 보통 learning 과정 전에 실행된다.

 

 Feature engineering은  실제 모델에 학습에 쓰는 것이기 때문에 훈련세트와 테스트 세트에 모두 적용하여야한다.

df_train['Age'].isnull().sum()

'Age'에 있는 177개의 널값이 존재한다.

이 널값을 채우기 위해 통계적 방법보다는 'Name'에 있는 호칭을 이용하여 채워준다.

indexing 두가지 방법
- df_train['Name']
- df_train.Name
둘다 같은 결과를 불러온다.

 

df_train['Initial']= df_train.Name.str.extract('([A-Za-z]+)\.')
df_test['Initial']= df_train.Name.str.extract('([A-Za-z]+)\.')

'Initial'이라는 새로운 Feature를 만들고 이름에서 대문자와 소문자 상관없이 ' . '이 나오는 곳까지 추출하는 방법이다.

그럼 다음과 같이 'Initial'이라는 새로운 Feature가 생기고 Mr, Mrs, Miss 등이 추출된 것을 확인할 수 있다.

 

이니셜과 성별로 크로스탭을 만들어 확인하니 너무 많은 이니셜이 존재해서 특징적인 이니셜 위주로 합쳐주었다.

pd.crosstab(df_train['Initial'], df_train['Sex']).T.style.background_gradient(cmap='summer_r')

 

 

df_train['Initial'].replace(['Mlle','Mme','Ms','Dr','Major','Lady','Countess','Jonkheer','Col','Rev','Capt','Sir','Don', 'Dona'],
                        ['Miss','Miss','Miss','Mr','Mr','Mrs','Mrs','Other','Other','Other','Mr','Mr','Mr', 'Mr'],inplace=True)

df_test['Initial'].replace(['Mlle','Mme','Ms','Dr','Major','Lady','Countess','Jonkheer','Col','Rev','Capt','Sir','Don', 'Dona'],
                        ['Miss','Miss','Miss','Mr','Mr','Mrs','Mrs','Other','Other','Other','Mr','Mr','Mr', 'Mr'],inplace=True)

 

 

df_train.groupby('Initial').mean()

 

이니셜별로 다른 특징들의 평균치를 확인하니 Master의 나이가 어린 것을 확인할 수 있었고, Miss, Mrs, Master가 생존을 많이 한 것을 확인하였다.

* merge 와 concat 설명
: 여러 데이터 플레임을 합쳐서 사용해야 할 때 쓰는 것이 바로 concat 과 merge이다.

-concat : 단순히 두 데이터 프레임을 합치는 것
-merge : 두 데이터 프레임을 공통된 항목을 기준으로 합치는 것
#concat으로 훈련세트와 테스트세트를 붙여준다.
df_all = pd.concat([df_train, df_test])

# 두개를 붙이면 원래 있던 index가 빠져나왔을 때 없애주는 법
df_all.reset_index(drop=True)

 

df_all의 나이 평균치를 확인하고 널값이면서 호칭별로 loc으로 indexing 해서 평균 나이를 사용하여 채워준다.

df_train.loc[(df_train['Age'].isnull()) & (df_train['Initial']=='Mr'), 'Age' ]= 33
df_train.loc[(df_train['Age'].isnull()) & (df_train['Initial']=='Mrs'), 'Age' ]= 37
df_train.loc[(df_train['Age'].isnull()) & (df_train['Initial']=='Master'), 'Age' ]= 5
df_train.loc[(df_train['Age'].isnull()) & (df_train['Initial']=='Miss'), 'Age' ]= 22
df_train.loc[(df_train['Age'].isnull()) & (df_train['Initial']=='Other'), 'Age' ]= 45

df_test.loc[(df_test['Age'].isnull()) & (df_test['Initial']=='Mr'), 'Age' ]= 33
df_test.loc[(df_test['Age'].isnull()) & (df_test['Initial']=='Mrs'), 'Age' ]= 37
df_test.loc[(df_test['Age'].isnull()) & (df_test['Initial']=='Master'), 'Age' ]= 5
df_test.loc[(df_test['Age'].isnull()) & (df_test['Initial']=='Miss'), 'Age' ]= 22
df_test.loc[(df_test['Age'].isnull()) & (df_test['Initial']=='Other'), 'Age' ]= 45

그 후 다시 널값의 합을 확인하니 0으로 이제 나이에는 널값이 없는 것을 확인했다.


Titanic 10. Feature engineering - Fill Null in Embarked and categorize Age

 

https://youtu.be/Q9Mry5rJIP8

 

#fillna 널값을 채워주는 함수
df_train['Embarked'].fillna('S',inplace=True)

fillna 함수를 사용하면 간단하게 널값을 채워줄 수 있다.

 


이번에는 나이를 범위로 나누어 새로운 Feature을 만들 것이다.

* 범위 안에서 너무 차이가 나는 값들이 하나로 묶이면 정보에 손실이 일어날 수 있다.

 

df_train.loc[df_train['Age']< 10, 'Age_cat'] = 0
df_train.loc[(10 <= df_train['Age']) & (df_train['Age'] < 20), 'Age_cat'] = 1
df_train.loc[(20 <= df_train['Age']) & (df_train['Age'] < 30), 'Age_cat'] = 2
df_train.loc[(30 <= df_train['Age']) & (df_train['Age'] < 40), 'Age_cat'] = 3
df_train.loc[(40 <= df_train['Age']) & (df_train['Age'] < 50), 'Age_cat'] = 4
df_train.loc[(50 <= df_train['Age']) & (df_train['Age'] < 60), 'Age_cat'] = 5
df_train.loc[(60 <= df_train['Age']) & (df_train['Age'] < 70), 'Age_cat'] = 6
df_train.loc[(70 <= df_train['Age'])] = 7

df_test.loc[df_test['Age']< 10, 'Age_cat'] = 0
df_test.loc[(10 <= df_test['Age']) & (df_test['Age'] < 20), 'Age_cat'] = 1
df_test.loc[(20 <= df_test['Age']) & (df_test['Age'] < 30), 'Age_cat'] = 2
df_test.loc[(30 <= df_test['Age']) & (df_test['Age'] < 40), 'Age_cat'] = 3
df_test.loc[(40 <= df_test['Age']) & (df_test['Age'] < 50), 'Age_cat'] = 4
df_test.loc[(50 <= df_test['Age']) & (df_test['Age'] < 60), 'Age_cat'] = 5
df_test.loc[(60 <= df_test['Age']) & (df_test['Age'] < 70), 'Age_cat'] = 6
df_test.loc[(70 <= df_test['Age'])] = 7

앞서 해본 방법과 동일하게 loc을 이용해서 하는 방법이 있다.

이 방법은 너무 어렵고 복잡하다. 그래서 apply 매서드를 사용하여 쉽게 하는 방법도 있다.

#단순 반복 형태는 함수를 활용하면 좋다
def category_age(x):
    if x < 10:
        return 0
    elif x < 20 :
        return 1
    elif x < 30:
        return 2
    elif x < 40:
        return 3
    elif x < 50:
        return 4
    elif x < 60:
        return 5
    elif x < 70:
        return 6
    else :
        return 7
df_train['Age_cat_2'] = df_train['Age'].apply(category_age)

# all은 전체가 True 여야 True이고 , any는 하나만 True 여도 True이다. 전체가 같은 것을 확인할 때는 all 사용
(df_train['Age_cat'] == df_train['Age_cat_2']).all()

 

Reference

- http://www.incodom.kr/기계학습/feature_engineering

- https://velog.io/@gayeon/데이터-분석-초보자를-위한-concat-merge 

'Machine Learning > Kaggle' 카테고리의 다른 글

캐글 타이타닉 ( 6 )  (1) 2022.11.23
캐글 타이타닉 ( 4 )  (2) 2022.10.09
캐글 타이타닉 ( 3 )  (0) 2022.10.09
캐글 타이타닉 ( 2 )  (1) 2022.10.03
캐글 타이타닉 ( 1 )  (1) 2022.10.03
Comments