이전 포스트

 

 

 

2023.01.09 - [분류 전체보기] - 타이타닉 생존자 예측 분석 (2-3) EDA(상관관계 및 기타) - v.1.0.1

 

타이타닉 생존자 예측 분석 (2-3) EDA(상관관계 및 기타) - v.1.0.1

이전 포스트 타이타닉 생존자 예측 분석 (2-2) EDA(연령대별) - v.1.0.1 이전 포스트 타이타닉 생존자 예측 분석 (2-1) EDA(성별) - v.1.0.1 - 개요 우선 데이터 사이언티스트 (이하 DS)의 꿈을 가장 크게 꾸

drewvvv.tistory.com

 

 

 

 

 

 
 

1. 결측치 처리

 

우선 타이타닉 데이터셋에서 결측치를 확인해보았다.

  • 나이의 경우 전체 891개 (트레인 데이터셋) 에서 177개의 결측치를 보였다.
  • 따라 다양한 결측치 처리 법 중 대체를 통해 나이의 결측치를  채우도록 하겠다.
  • 우선 정렬을 해가며 데이터를 확인해보았을 때,

 

  • 나이 순으로 정렬했을 때 이름에 Master, Miss가 들어가는 경우 16세 이하임을 확인할 수 있다.
  • 따라 이름에 Master나 Miss가 들어가는 경우 ca_Age를 0또는 1로 대부분 대체할 생각이다. (Miss가 들어가는데 나이가 많은 경우도 있기 때문)
1
2
3
train['designation'= train['Name'].str.extract(' (\w*)\.')
train['lastName'= train['Name'].str.extract('\.+ \(?([\w]*)')
train[['Name''designation''lastName']]
cs

 

 

  • 정규식을 활용해서 존칭과 성을 분류해보았다. 

  • 존칭에서 위의 패턴을 사용하지 않는 사람들은 전체 중 24명이었다.
  • 대부분의 경우 위의 경우를 other로 하나로 취급해서 처리했지만, 우선 존칭을 그대로 활용해볼 생각이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
orders = train['designation'].value_counts().index.tolist()
 
fig = plt.figure(figsize=(16,7))
 
area01 = fig.add_subplot(1,2,1)
area02 = fig.add_subplot(1,2,2)
 
ax1 = sns.countplot(data=train, x = "designation", hue="Survived", order=orders, ax = area01)
ax1.set_title('존칭별 인원(명)')
ax2 = sns.barplot(data = train, x = "designation", y = "Survived", hue="Sex", order=orders, errwidth = 0, ax = area02)
ax2.set_title('존칭별/성별 생존률')
 
plt.show()
cs
 
 
  • 존칭별 인원 카운트에선 큰 범주 4개를 제외하곤 갯수가 많이 없음을 확인하였고,
  • 존칭별/성별 생존율을 살펴보면 Dr를 제외하곤 각 막대가 없는 것을 볼 수 있는데, 당연히 성별에 따라 존칭을 사용하기 때문이다. 또한, 여성용 존칭과 남성용 존칭에 따라 생존을 볼 수 있다. 

 

존칭에 따른 성별표

  • 존칭과 성별로 groupby를하고 나이와 생존에 대해 describe()를 조회하여 존칭별/성별 나이의 기술통계값을 확인할 수 있었다. 
  • 위의 size()함수와는 다르게 Age에서는 count가 줄어든 것을 볼 수 있는데 이는 describe() 함수가 결측치를 제거하고 통계를 내기 때문이다. 

 

1
2
3
4
5
6
7
8
from sklearn.preprocessing import LabelEncoder
 
encoder = LabelEncoder()
encoder.fit(train['designation'])
labels = encoder.transform(train['designation'])
 
train['ca_designation'= labels
 
cs
  • LabelEncoder로 존칭을 숫자로 변환하였다. 
  • 이후 corr()함수를 사용하여 상관관계를 확인했을 때 

  • 특정 조건에서 나이와 존칭의 상관계수가 0.75까지 올라가는 경우가 존재한다.

 

 

2. 나이 예측

 

1
2
3
4
5
gTrain = train.groupby(['designation''Sex''Pclass''SibSp''Parch'])
gAge = gTrain.describe()['Age']
gAge['mDiff'= gAge['mean'- gAge['50%']
print(f"max value : \n{gAge[['mean','50%', 'mDiff']].max()}")
gAge[['mean','50%''mDiff']]
cs

 

  • 존칭, 성별, Pclass, SibSp, ParCh에 따라 분류한 후, 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
for item in train.iterrows():
    temp = item[1]
    guessAge = gAge.loc[temp['designation'],
                        temp['Sex'],
                        temp['Pclass'],
                        temp['SibSp'],
                        temp['Parch']]
 
    if (math.isnan(guessAge['mean'])):
        guessAge = gAge.loc[temp['designation'],
                            temp['Sex']].mean()
        
    train.loc[item[0], 'guessAgeMean'= round(guessAge['mean'], 2)
    train.loc[item[0], 'guessAgeMedian'= round(guessAge['50%'], 2)
cs

 

  • 각 row 데이터에 따른 평균 나이와 중앙값을 구하였다. 
  • 결측치가 없음을 확인하고

  • 실제 나이와 예측한 나이가 편차가 크지 않은 것으로 보인다.

 

  • 기술통계에서도 실제 나이와 추론한 나이가 비슷하고 오히려 편차는 낮게 나타났다. 

 

1
2
3
4
for index, item in enumerate(train['Age']):
    if(math.isnan(item)):
        train.loc[index, 'Age'= train.loc[index, 'guessAgeMean']
    
cs
  • 따라 추론한 평균값으로 171개의 NaN값을 대체한다. 
  • (현재는 Pclass까지 포함했지만 제외할 예정)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
for index, item in enumerate(train['ca_Age']):
    if(item == 99):
        age = train.loc[index, 'Age']
        if age < 10:
            result = 0
        elif age >= 10 and age < 20:
            result = 1
        elif age >= 20 and age < 30:
            result = 2
        elif age >= 30 and age < 40:
            result = 3
        elif age >= 40 and age < 50:
            result = 4
        elif age >= 50 and age < 60:
            result = 5
        elif age >= 60 and age < 70:
            result = 6
        elif age >= 70 and age <= 80:
            result = 7
        elif age > 80 and age < 90:
            result = 8
            
        train.loc[index, 'ca_Age'= result
    
cs
  • 이후 ca_Age 컬럼에서 99로 분류하였던 NaN값을 각 평균값으로 다시 대체한다.
1
2
3
train['Embarked'].fillna("S", inplace=True)
train['ca_Embarked'].fillna("2", inplace=True)
train = train.drop('Cabin', axis=1)
cs
  • Embarked의 경우 대부분이 S이므로 S로 대체하고 ca_Embared 값은 S의 숫자값인 2로 대체한다.
  • Cabin 컬럼은 결측치가 대부분이어서 이번 전처리에선 제거 처리하였다.

  • 결측치가 제거됐음을 확인하고 

 

1
train.to_csv('../input/noNaTrain.csv', index=False)
cs
  • noNa 데이터로 내보낸다. 

 

 

 

 

 

 

다음 포스트

 

2023.01.12 - [분류 전체보기] - 타이타닉 생존자 예측 분석 (3-2) 데이터 정리 - v.1.0.1

 

타이타닉 생존자 예측 분석 (3-2) 데이터 정리 - v.1.0.1

이전 포스트 2023.01.09 - [Kaggle/타이타닉] - 타이타닉 생존자 예측 분석 (3-1) 전처리 (나이예측) - v.1.0.1 타이타닉 생존자 예측 분석 (3-1) 전처리 (나이예측) - v.1.0.1 이전 포스트 2023.01.09 - [분류 전체

drewvvv.tistory.com

 
 
 
 

+ Recent posts