1. 데이터 전처리

 

데이터 분석을 할 때, 데이터 전처리 과정은 반드시 거쳐야 한다. 데이터 분석 과정 중 가장 많은 시간을 할애해야 하는 부분이 데이터 전처리다. 실제로 데이터 분석가는 업무 시간의 80% 정도를 데이터 수집과 전처리에 사용할 정도라고 하니 더 이상 데이터 전처리의 중요성에 관해서는 설명할 것도 없다. 데이터 전처리 방법으로는 결측값 처리, Feature Engineering, 이상값 처리 등이 있다. 여기서는 결측값 처리, Feature Engineering에 대해서만 다루도록 한다.

 

2. 결측값 처리

 

앞선 글에서와 같이 결측값이 있는 데이터를 그대로 모델링할 경우 예측과정에서 높은 정확도를 얻을 수 없다. 결측치를 처리하는 방법으로는 삭제와 대체가 있다. 삭제는 말 그대로 결측값이 존재하는 부분을 삭제하는 것이다. 그런데, 결측부분을 삭제할 경우 사용할 수 있는 데이터의 범위가 줄어든다는 단점이 있다. 다음으로는 대체가 있다. 결측값이 발생한 부분을 다른 존재하는 값을 평균이나 중간값으로 채울 수 있다. 시계열 데이터 같은 경우는 결측부분의 전후 값에 따라 결측치를 대체할 수도 있다. 여기서 결측값 처리는 평균값과 최빈값을 활용해 대체한다.

 

1) Age 처리

 

177개의 결측값이 있는 Age column을 처리하기 위해 승객의 이름을 활용한다. 정규표현식을 사용해서 승객의 이니셜을 따로 가져와서 새로운 column에 저장한 다음 이니셜 별로 평균을 구해서 결측치를 처리한다.

 

# Initial column 생성
train['Initial'] = 0
# 정규표현식으로 이름 column의 이니셜을 Initial에 넣음
for i in train:
    train['Initial'] = train.Name.str.extract('([A-Za-z]+)\.')

 

pd.crosstab(train.Initial,train.Sex).T.style.background_gradient(cmap='coolwarm')

 

이니셜을 들여다보면 Dr, Mile, Mme와 같이 성별 이니셜에 오타가 있는 것이 있다. 이를 replace를 통해 Mr나 Miss 등으로 바르게 변경한다.

 

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

 

정리된 이니셜 별로 평균 나이를 확인한다.

 

train.groupby('Initial')['Age'].mean()

 

이를 토대로 반올림한 값을 결측치로 대체한다.

train.loc[(train.Age.isnull())&(train.Initial=='Master'),'Age'] = 5
train.loc[(train.Age.isnull())&(train.Initial=='Miss'),'Age'] = 22
train.loc[(train.Age.isnull())&(train.Initial=='Mr'),'Age'] = 33
train.loc[(train.Age.isnull())&(train.Initial=='Mrs'),'Age'] = 36
train.loc[(train.Age.isnull())&(train.Initial=='Other'),'Age'] = 46

 

2) Embarked 처리

 

Embarked column에는 결측값이 2개뿐이다. 결측값 대체는 최빈값으로 수행한다.

f,ax = plt.subplots(1, 2, figsize = (20,10))
sns.countplot('Embarked', data = train, ax = ax[0])
ax[0].set_title('Passengers Boarded')
sns.countplot('Embarked', hue = 'Survived', data = train, ax = ax[1])
ax[1].set_title('Embarked vs Survived')
plt.subplots_adjust(wspace = 0.2,hspace = 0.5)
plt.show()

 

탑승 위치의 최빈값인 S를 결측치로 대체한다.

train['Embarked'].fillna('S',inplace=True)

 

Cabin column은 결측값이 대부분이기에 전처리를 하지 않고 이후 머신러닝 과정에서도 사용하지 않는다.

 

3. Feature Engineering

 

머신러닝 과정에서 train 데이터로 학습을 시키지만 매번 좋은 결과를 나타내지는 않는다. 그 말은 머신러닝의 성능은 어떤 데이터를 입력하느냐에 따라 달라진다는 것이다. 그러므로 충분한 데이터를 기반으로 어떠한 Feature를 사용해야할지 확인하는 과정이 필요한데, 그것이 Feature Enginnering이다. Feature Engineering이란 새로운 데이터의 추가 없이 날 것의 데이터를 유용하게 다루는 과정이다. 방법은 Scaling, Binning, One Hot Encoding, Transfrom, Dummy 등 다양한 방법이 있으며, 데이터 분석가의 객관적인 시각에 따라 활용하는 것이 중요하다.

 

1) Age Binning

연속형 변수인 Age를 범주형 변수로 변환시킨다. 15세 이하, 30세 이하, 50세 이하, 65세 이하, 그 이상으로 5가지 범주로 구분한다.

train['age_bin'] = 0
train.loc[train['Age'] <= 15, 'age_bin'] = 0
train.loc[(train['Age'] > 15) & (train['Age'] <= 30),'age_bin'] = 1
train.loc[(train['Age'] > 30) & (train['Age'] <= 50),'age_bin'] = 2
train.loc[(train['Age'] > 50) & (train['Age'] <= 65),'age_bin'] = 3
train.loc[train['Age'] > 65,'age_bin'] = 4
sns.factorplot('age_bin', 'Survived', data = train, col = 'Pclass')
plt.show()

 

나이를 범주형 변수로 변환시키고 난 후 생존율을 확인한 결과, 젊을수록 생존율이 높게 나타남을 확인할 수 있다.

 

2) Fare Binning

탑승 요금도 Age와 동일한 방식으로 4개의 구간으로 범주화한다.

train['fare_range'] = pd.qcut(train['Fare'],4)
train.groupby(['fare_range'])['Survived'].mean().to_frame().style.background_gradient(cmap='coolwarm')

train['fare_bin'] = 0
train.loc[train['Fare'] <= 7.91, 'fare_bin'] = 0
train.loc[(train['Fare'] > 7.91) & (train['Fare'] <= 14.454),'fare_bin'] = 1
train.loc[(train['Fare'] > 14.454) & (train['Fare'] <= 31),'fare_bin'] = 2
train.loc[(train['Fare'] > 31) & (train['Fare'] <= 512.329),'fare_bin'] = 3

 

3) 동승객 Engineering

 

Parch와 Sibsp를 더한 값으로 같이 탑승한 전체 가족 수에 대한 column을 생성한다. 그 후 혼자 탑승한 승객은 Alone으로 표시해서 동승객의 여부에 관해 생존율을 비교한다.

 

train['family'] = 0
train['family'] = train['Parch'] + train['SibSp']
train['Alone'] = 0
train.loc[train.family==0,'Alone'] = 1

f,ax = plt.subplots(1, 2, figsize = (15,5))
sns.factorplot('family','Survived', data = train,ax = ax[0])
ax[0].set_title('family vs Survived')
sns.factorplot('Alone','Survived', data = train, ax = ax[1])
ax[1].set_title('Alone vs Survived')
plt.close(2)
plt.close(3)
plt.show()

 

혼자 탑승한 승객은 Alone에 1로 표시했다. 그래프를 확인한 결과, 함께 탑승한 가족이 3명일 경우 가장 높은 생존율이 나타났으며, 혼자 탑승한 승객의 생존율은 낮음을 확인할 수 있다.

 

4) mapping

범주형 변수인 성별, 탑승 위치, 이니셜을 mapping한다.

train['Sex'].replace(['male', 'female'],[0, 1],inplace = True)
train['Embarked'].replace(['S', 'C', 'Q'],[0, 1, 2],inplace = True)
train['Initial'].replace(['Mr', 'Mrs', 'Miss', 'Master', 'Other'],[0, 1, 2, 3, 4],inplace = True)

 

 

4. 무의미한 데이터 삭제

 

머신러닝 과정에서 사용하지 않을 데이터인 Name, Age, Fare, Cabin, fare_range, PassengerId column을 삭제하고 전처리를 한 변수들의 상관관계를 확인한다.

train.drop(['Name','Age','Ticket','Fare','Cabin','fare_range','PassengerId'], axis = 1, inplace = True)
sns.heatmap(train.corr(), annot = True, cmap = 'YlGnBu', linewidths = 0.1, annot_kws = {'size':20})
fig = plt.gcf()
fig.set_size_inches(15,12)
plt.xticks(fontsize = 8)
plt.yticks(fontsize = 8)
plt.show()

 

이제 어느 정도 데이터 정리가 완료되었다. 이후 머신러닝 모델을 사용하여 test 데이터에 담긴 탑승객의 생존율을 예측한다.

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기