전처리는 데이터 분석에 알맞게 정돈하는 작업이다.
대표적인 전처리 과정은 1. 결측치 처리 2. 이상치 처리 3. 자료형 변환 4. 필요없는 변수 제거 5. 필요한 변수 추가 정도가 있다.
1. 결측치 확인
#결측치 확인
train.isnull().sum()
test.isnull().sum()
isnull() 함수는 null이면 True, null이 아니면 False를 반환하는 함수다.
isnull().sum()으로 결측치의 총 개수를 확인할 수 있다.
train에서는 Age(나이)에서 177, Cabin(객실)에서 687개, Embarked(승선장)에서 2개의 결측치를 확인할 수 있었다.
test에서는 Age에서 86개, Cabin에서 327개, Fare에서 1개의 결측치가 발생했다.
이 결측치들을 어떻게 처리할까 고민해보자.
1-1. Cabin 칼럼
먼저, train과 test 데이터는 각각 891, 418개의 행을 갖고있는데 Cabin칼럼은 80%에 가까운 행이 결측치를 갖고있다.
Cabin 칼럼으로 특별한 인사이트를 얻기도 힘드므로 Cabin 칼럼은 삭제하기로 한다.
-------------> Cabin 칼럼은 삭제
1-2. Embarked 칼럼
Embarked 승선장의 경우, 결측값을 특정값으로 대체하기가 어려운 편이다.]
891개 중 2개는 정보손실도 크지 않으므로 해당 행을 삭제해도 된다.
하지만 정보손실이 너무도 싫다면 891개 중 644개로 최빈값인 'S'를 부여해도 된다.
일단 해당 행이 어떤 정보를 담고 있는지 확인해보자.
#Embarked 칼럼에서 결측값을 갖는 행 찾기
train.loc[train['Embarked'].isnull() == True, :]
데이터를 살리고 Embarked에 특정값으로 대체하는 것도 괜찮을 것 같다.
단순하게 최빈값인 'S'를 부여해도 될까 생각해보았는데 Pclass와 Fare에 따라 승선장에 차이가 있지 않을까 싶어서 확인해보았다.
#Pclass별 승선장 차이 확인
train[train['Pclass'] == 1]['Embarked'].value_counts()
train[train['Pclass'] == 2]['Embarked'].value_counts()
train[train['Pclass'] == 3]['Embarked'].value_counts()
단순히 S라고 결론을 내리기는 어려울 수도 있겠다.
그래서 이번엔 요금을 비교해보았다.
#승선장별 Fare의 산포도
plt.scatter(train['Fare'], train['Embarked'].astype(str), c = 'blue', alpha = 0.5)
Queenstown의 요금은 확실히 저렴했지만 C와 S의 승선장별 요금 차이는 크게 눈에 띄지 않았다.
오히려 저 이상치만 눈에 띄었다...
#등급별, 승선장별 요금의 산점도
sns.relplot(x="Pclass", y="Fare", hue="Embarked", data = train)
역시 저 이상치는 1등석이었다. 그건 차치하고 1등석이면서 승선장별 요금 역시 분포가 상당히 고르게 보였다.
일단 이상치를 제거하고 다시 분포를 확인하고 싶어서 저 이상치를 제거하기로 했다.
계산을 해보니 Q3 + IQR 값보다 저 값이 아슬아슬하게 작아서 굳이 삭제하지 않아도 될 것으로 보였다.
결국 'Embarked' 칼럼의 결측치는 최빈값인 'S'로 대체하는 것이 합리적이라는 생각이 들어 S로 대체했다.
#Embarked 결측값 대체
train['Embarked'] = train['Embarked'].fillna('S')
train['Embarked'].isnull().sum()
1-3. Age 칼럼
Age 칼럼의 결측치는 891행 중 177개로 삭제할 경우 정보손실이 매우 컸다.
이 경우 평균치로 대체해주는 편이 좋다.
일반적으로는 전체 평균으로 대체해주는 편이 좋은데 괜히 또 욕심이 나서 요금과 나이의 분포도를 살펴보고 싶었다.
Pclass별 나이대의 평균에 차이가 있는지 정확히 확인하기 위해서는 사실 분산분석을 해야 좋은데 그렇게까지 하기 귀찮아서 안했다..
#Pclass별 나이 평균 확인
print('1등석의 평균나이:', train[train['Pclass'] == 1]['Age'].mean())
print('2등석의 평균나이:', train[train['Pclass'] == 2]['Age'].mean())
print('3등석의 평균나이:', train[train['Pclass'] == 3]['Age'].mean())
정확한 결과는 아니지만 Pclass별 나이대의 차이가 분명해보여서 Age 칼럼은 Pclass별 나이의 평균으로 대체해주기로 결정했다.
1-4. Fare 칼럼
Fare칼럼도 Age 칼럼과 마찬가지로 등급별 요금 차이가 분명해서 결측치를 등급별 평균으로 대체했다.
#등급별 요금 평균 확인
#Test데이터에서 결측이 발생한 행 확인
print('Test 데이터에서 결측이 발생한 행')
print(' ')
print(test.loc[test['Fare'].isnull() == True, :])
print(' ')
print(' ')
print('Train')
print('1등석의 평균요금:', train[train['Pclass'] == 1]['Fare'].mean())
print('2등석의 평균요금:', train[train['Pclass'] == 2]['Fare'].mean())
print('3등석의 평균요금:', train[train['Pclass'] == 3]['Fare'].mean())
print(' ')
print(' ')
print('Test')
print('1등석의 평균요금:', test[test['Pclass'] == 1]['Fare'].mean())
print('2등석의 평균요금:', test[test['Pclass'] == 2]['Fare'].mean())
print('3등석의 평균요금:', test[test['Pclass'] == 3]['Fare'].mean())
#Fare요금 평균으로 대체
test.loc[test['Pclass'] == 3, ['Fare']] = test[test['Pclass'] == 3]['Fare'].fillna(12.46)
2. 필요없는 칼럼 삭제
Cabin, PassengerId, Ticket 칼럼은 필요가 없으므로 삭제하기로 했다.
Name 칼럼도 사실 필요가 없는데 활용하는 법을 공유한 코드를 다시 참고해서 한번 코딩을 진행해보고 판단하려고 한다.
#Train, Test데이터에서 Cabin, PassengId, Ticket 칼럼 삭제
train = train.drop(['PassengerId', 'Ticket', 'Cabin'], axis = 1)
test = test.drop(['PassengerId', 'Ticket', 'Cabin'], axis = 1)
2-1. 결측치와 칼럼 삭제 확인
#결측치와 칼럼 삭제 확인
print(train.isnull().sum())
print(test.isnull().sum())
3. 더미변수화
Sex, Embarked, Pclass 변수는 범주형 변수이고, Embarked와 Pclass는 3개의 범주로 구성되었다.
이를 처리하기 위해서는 더미변수로 바꿔주는 것이 편하다.
#Sex, Embarked, Pclass 더미변수화
train_dummy = pd.get_dummies(train, columns = ['Sex', 'Embarked', 'Pclass'], drop_first = True)
test_dummy = pd.get_dummies(test, columns = ['Sex', 'Embarked', 'Pclass'], drop_first = True)
train 데이터는 총 9개의 특성과 Survived라는 target을 갖는 데이터로 전처리가 마무리되었다.
다음에는 전처리된 데이터로 성능평가를 진행해보자.
'연습장' 카테고리의 다른 글
[Kaggle] 캐글 상위권 코드 보고 공부하는 타이타닉 예제 심화 EDA 2 (이름 특성에서 인사이트 얻기, 승선장, 가족구성원 수, 요금 특성 분석) (0) | 2020.11.11 |
---|---|
[Kaggle] 캐글 상위권 코드 보고 공부하는 타이타닉 예제 심화 EDA 1 (성별, 등급, 나이 특성 확인) (0) | 2020.11.11 |
[Kaggle] 타이타닉 예제에서 막대그래프로 범주 살펴보기 (0) | 2020.11.07 |
[Kaggle] 파이썬에서 함수 정의해서 파이차트 만들기 (Titanic 예제 활용) (0) | 2020.11.07 |
[예제] Python 조건문 심화 예제 4 (세 정수 중 가장 큰 정수 출력) (0) | 2020.08.24 |