Titanic: Machine Learning from Disaster
1. 대회 설명
-
설명: 타이타닉호에서 생존한 승객을 예측하는 모델을 만듭니다.
-
키워드: #분류 # classification
-
평가방법: 승객의 생존여부를 0, 1로 예측하여 제출하고, 정확도(accuracy)를 계산하여 순위를 결정
2. 데이터
Variable | Definition | Key |
---|---|---|
survival | 생존여부 | 0 = No, 1 = Yes |
pclass | 티켓 등급 | 1 = 1st, 2 = 2nd, 3 = 3rd |
sex | 성별 | |
Age | 나이 | |
sibsp | 타이타닉에 탑승한 형제/자매 수 | |
parch | 타이타닉에 탑승한 부모/자녀 수 | |
ticket | 티켓번호 | |
fare | 운임(티켓요금) | |
cabin | 객실 번호 | |
embarked | 탑승한 곳(항구) | C = Cherbourg, Q = Queenstown, S = Southampton |
3. 데이터 전처리
데이터 훑어보기
-
데이터 로딩 : csv 파일을 데이터프레임으로 읽기
train = pd.read_csv('./dataset/train.csv') test = pd.read_csv('./dataset/test.csv') submission = pd.read_csv('./dataset/gender_submission.csv')
-
학습 데이터 셋의 상위 5개 항목 출력
train.head()
[결과]
-
학습 데이터 셋의 각 필드 데이터 분포(평균, 최소값, 최대값 등)를 살펴보기
train.describe()
[결과]
수치형 데이터를 포함한 컬럼에 대해서만 요약 값을 출력합니다. 총 891개의 학습데이터 셋이 있고(Age값은 714개), 각 컬럼의 최소값, 최대값, 4분위수 등을 확인할 수 있습니다.
-
각 컬럼의 데이터 타입 확인하기
train.info()
[결과]
```
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
```
info() 메소드를 통해 각 컬럼의 데이터 타입(Dtype)과 개수를 확인할 수 있습니다. 일부 컬럼(Age, Cabin, Embarked)은 데이터가 누락된 항목이 포함되어 있는 것 같습니다.
-
'Cabin'필드에는 어떤 값이 있는지 확인하기
train['Cabin'].unique()
[결과]
```
array([nan, 'C85', 'C123', 'E46', 'G6', 'C103', 'D56', 'A6',
'C23 C25 C27', 'B78', 'D33', 'B30', 'C52', 'B28', 'C83', 'F33',
'F G73', 'E31', 'A5', 'D10 D12', 'D26', 'C110', 'B58 B60', 'E101',
'F E69', 'D47', 'B86', 'F2', 'C2', 'E33', 'B19', 'A7', 'C49', 'F4',
'A32', 'B4', 'B80', 'A31', 'D36', 'D15', 'C93', 'C78', 'D35',
'C87', 'B77', 'E67', 'B94', 'C125', 'C99', 'C118', 'D7', 'A19',
'B49', 'D', 'C22 C26', 'C106', 'C65', 'E36', 'C54',
'B57 B59 B63 B66', 'C7', 'E34', 'C32', 'B18', 'C124', 'C91', 'E40',
'T', 'C128', 'D37', 'B35', 'E50', 'C82', 'B96 B98', 'E10', 'E44',
'A34', 'C104', 'C111', 'C92', 'E38', 'D21', 'E12', 'E63', 'A14',
'B37', 'C30', 'D20', 'B79', 'E25', 'D46', 'B73', 'C95', 'B38',
'B39', 'B22', 'C86', 'C70', 'A16', 'C101', 'C68', 'A10', 'E68',
'B41', 'A20', 'D19', 'D50', 'D9', 'A23', 'B50', 'A26', 'D48',
'E58', 'C126', 'B71', 'B51 B53 B55', 'D49', 'B5', 'B20', 'F G63',
'C62 C64', 'E24', 'C90', 'C45', 'E8', 'B101', 'D45', 'C46', 'D30',
'E121', 'D11', 'E77', 'F38', 'B3', 'D6', 'B82 B84', 'D17', 'A36',
'B102', 'B69', 'E49', 'C47', 'D28', 'E17', 'A24', 'C50', 'B42',
'C148'], dtype=object)
```
-
생존한 사람, 사망한 사람의 수 확인하기
train['Survived'].value_counts()
[결과]
0 549 1 342 Name: Survived, dtype: int64
-
각 클래스('Pclass')별 탑승객 분포 확인하기
train['Pclass'].value_counts().sort_index()
[결과]
1 216 2 184 3 491 Name: Pclass, dtype: int64
- 성('Sex')별 탑승객 분표 확인하기
train['Sex'].value_counts().sort_index()
[결과]
female 314
male 577
Name: Sex, dtype: int64
8. 탑승 위치('Embarked') 별 탑승객 분표 확인하기
train['Embarked'].value_counts().sort_index()
[결과]
C 168
Q 77
S 644
Name: Embarked, dtype: int64
데이터 전처리
-
null값 체크
train.isnull().any()
[결과]
PassengerId False Survived False Pclass False Name False Sex False Age True SibSp False Parch False Ticket False Fare False Cabin True Embarked True dtype: bool
train.isnull().mean()
[결과]
PassengerId 0.000000 Survived 0.000000 Pclass 0.000000 Name 0.000000 Sex 0.000000 Age 0.198653 SibSp 0.000000 Parch 0.000000 Ticket 0.000000 Fare 0.000000 Cabin 0.771044 Embarked 0.002245
Age, Cabin,Embarked는 null값을 포함하고 있다는 것을 확인했습니다. 'Cabin' 컬럼의 경우 null값이 차지하는 비중이 커서 데이터 분석에 활용하기에 어려울 것 같습니다.
-
결측치 처리(1) : 'Embarked' 필드의 결측치는 값이 가장 많은 'S'로 할당하기
train['Embarked'] = train['Embarked'].fillna('S')
-
결측치 처리(2) : 'Age' 필드의 결측치는 값이 중간값으로 할당하기
train['Age'].fillna(train['Age'].median(), inplace=True)
-
'Name'필드에서 신분을 나타내는 단어를 뽑아서 'Title' 필드에 할당하기
(힌트1) : '.'을 기준으로 앞에 위치하는 문자열을 추출
(힌트2): train['Name'].str.extract(' ([A-Za-z]+).', expand = False)
train['Title'] = train['Name'].str.extract(' ([A-Za-z]+)\.', expand = False) train['Title'].unique().tolist()
-
'Title' 필드의 카테고리를 6개의 항목으로 변경하기
- 'Officer': 'Capt', 'Col', 'Major', 'Dr', 'Rev'
- 'Master' : 'Jonkheer', 'Master'
- 'Royalty' : 'Don', 'Sir', 'the Countess', 'Lady', 'Dona'
- 'Mrs' : 'Mme', 'Ms', 'Mrs'
- 'Miss': 'Mlle', 'Miss'
- 'Mr' : 'Mr'
train['Title'] = train['Title'].replace(['Capt', 'Col', 'Major', 'Dr', 'Rev'], 'Officer') train['Title'] = train['Title'].replace(['Jonkheer', 'Master'], 'Master') train['Title'] = train['Title'].replace(['Don', 'Sir', 'the Countess', 'Lady', 'Dona'], 'Royalty') train['Title'] = train['Title'].replace(['Mme', 'Ms', 'Mrs'], 'Mrs') train['Title'] = train['Title'].replace(['Mlle', 'Miss'], 'Miss') train['Title'].value_counts()
[결과]
Mr 757 Miss 262 Mrs 200 Master 62 Officer 23 Royalty 4 Countess 1 Name: Title, dtype: int64
- 변수 y를 선언해서 학습할 목표변수(=종속변수)인 'Survived'필드값을 담기
y = train['Survived']
-
나이('Age') 필드를 그룹핑하여 'AgeGroup'필드 생성하여 할당하기
- 0~18세: Baby
- 19~25세: Youth
- 26~35세: YoungAdult
- 36~60세: MiddleAged
- 61~100세: Senior
bins = [0, 18, 25, 35, 60, 100] group_names = ['Baby', 'Youth', 'YoungAdult', 'MiddleAged', 'Senior'] train['AgeGroup'] = pd.cut(train['Age'], bins, labels=group_names) train['AgeGroup'].value_counts()
[결과]
YoungAdult 196 MiddleAged 195 Youth 162 Baby 139 Senior 22 Name: AgeGroup, dtype: int64
-
'AgeGroup'이 'Baby'인 raw만 출력하기
train[train['AgeGroup'] == 'Baby']
[결과]
데이터 시각화
-
라이브러리 import
import seaborn as sns import matplotlib.pylab as plt
-
학습 데이터셋(train)의 데이터 분포확인하기
(힌트) 히스토그램 그리기, bins = 20
train.hist(figsize=(14,14), bins=20) plt.show()
-
성별('Sex')의 생존여부('Survived') 데이터 분포확인하기 : barplot
sns.barplot(x="Sex", y="Survived", data=train)
[결과]
-
탑승 클래스('Pclass')별 + 성별('Sex') 생존여부('Survived') 데이터 분포확인하기 : barplot
sns.barplot(x="Pclass", y="Survived", hue ='Sex', data=train)
[결과]
-
전체 변수의 correlation에 대해 히트맵 그리기
plt.subplots(figsize=(10, 10)) sns.heatmap(train.corr(), annot=True, linewidths=.2)
[결과]
5, 연령분포('AgeGroup')별 + 클래스('Pclass')별 생존여부('Survived') 데이터 분포확인하기: barplot
sns.barplot(x="AgeGroup", y="Survived", hue ='Pclass', data=train)
-
형제/자매수(''SibSp")별 + 클래스('Pclass') 별 생존여부("Survived")
sns.barplot(x="SibSp", y="Survived",hue ='Pclass', data=train)
데이터 삭제하기(delete)
-
'Name', 'Ticket', 'SibSp', 'Parch', 'Cabin' , 'AgeGroup'컬럼 삭제하기
train.drop(['Name', 'Ticket', 'SibSp', 'Parch', 'Cabin', 'AgeGroup'], axis=1, inplace=True)
텍스트 데이터 숫자 변환
from sklearn.preprocessing import LabelEncoder
label = LabelEncoder()
for col in ['Sex', 'Embarked', 'Title']:
train[col] = label.fit_transform(train[col])
학습용, 테스트용 데이터 셋 분리하기
from sklearn.model_selection import train_test_split
x_train, x_valid, y_train, y_valid = train_test_split(train, y, test_size=0.2, random_state = 5, stratify = y)
'Kaggle·데이터분석예제' 카테고리의 다른 글
[Kaggle][문제]강아지 품종 분류(dog-breed-identification) (0) | 2020.07.20 |
---|---|
[파시데]파이썬 기본 연습문제 (4) | 2020.07.20 |
[Kaggle][문제]타이타닉(titanic) (0) | 2020.07.20 |
[Kaggle][답]샌프란시스코 범죄 예측(sf-crime) (0) | 2020.07.20 |
[Kaggle][문제]샌프란시스코 범죄 예측(sf-crime) (0) | 2020.07.19 |