목표
- 타이타닉 데이터를 학습해서 생존자/사망자를 예측해보자
- 머신러닝의 전체 과정을 진행해보자.
머신러닝 과정
- 문제정의
- 데이터 수집
- 데이터 전처리
- 탐색적 데이터 분석
- 모델 선택 및 학습
- 모델 평가
1. 문제 정의
- 생존자/사망자를 예측
- Kaggle 경진대회에서 높은 순위를 차지
- 머신러닝 과정 전체를 체험 해보는 예제
2. 데이터 수집
- Kaggle 사이트로부터 train, test 다운로드
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns # 시각화 라이브러리
Question1
- 타이타닉 train데이터와 test데이터를 변수 train,test에 저장하세요.(단 인덱스는 PassengerId를 사용 할 것.)
train = pd.read_csv('data/train.csv',index_col='PassengerId')
test = pd.read_csv('data/test.csv',index_col='PassengerId')
print(train.shape)
print(test.shape)
3.데이터 전처리 및 데이터 탐색
결측치 확인
train.info()
test.info()
Age 채우기
- 단순 기술통계치로 채우지 않고 다른 컬럼과의 상관관계를 이용해 결측치를 채워보자.
- Age와 다른 컬럼간의 상관관계를 알아보자.
train.corr()
- Pclass가 가장 높은 상관관계를 갖는다.
- 생존에 관련이 많을 것 같은 성별을 함께 그룹핑에 활용해보자.
pt1 = train.pivot_table(values='Age',
index=['Pclass','Sex'],
aggfunc = 'mean')
pt1
pt1.loc[1,'female']
pt1.loc[3,'male']
def fill_age(row):
# 만약 나이가 결측치라면 피봇데이블에서 값을 가져오고
if np.isnan(row['Age']):
return pt1.loc[row['Pclass'],row['Sex']]
# 만약 나이가 결측치가 아니라면 원래 나이 값을 사용하자.
else:
return row['Age']
train['Age'] = train.apply(fill_age, axis=1).astype('int64')
train.info()
train.head(8)
test['Age'] = test.apply(fill_age, axis=1).astype('int64')
test.info()
Embarked 채우기
train['Embarked'].value_counts()
test['Embarked'].value_counts()
train['Embarked'] = train['Embarked'].fillna('S')
train.info()
Fare 채우기
train.corr()
pt2 = train.pivot_table(values='Fare',
index=['Pclass','Sex'],
aggfunc = 'mean')
pt2
test[test['Fare'].isnull()]
test['Fare'] = test['Fare'].fillna(12.661633)
test.info()
Cabin 채우기
train['Cabin'].unique()
train['Deck'] = train['Cabin'].fillna('M')
test['Deck'] = test['Cabin'].fillna('M')
train['Deck'] = train['Deck'].str[0]
test['Deck'] = test['Deck'].str[0]
train.drop('Cabin', inplace=True, axis=1)
test.drop('Cabin', inplace=True, axis=1)
train.info()
test.info()
데이터 탐색
- train데이터를 이용해 탐색을 한다.
- test를 탐색하는 것은 모델 일반화에 도움이 되지 않음.
범주형 데이터
Deck 시각화
train_deck = train[['Deck','Survived','Name']].groupby(['Deck','Survived']).count()
train_deck
sns.countplot(data=train, x='Deck', hue='Survived')
- M에서 상대적으로 사람이 많이 죽었다.
- 생존여부 판단에 활용해도 괜찮겠다.
Pclass 시각화
sns.countplot(data=train, x='Pclass', hue='Survived')
- 3등급의 사람들이 많이 죽었다.
Deck과 Pclass 시각화
sns.countplot(data=train, x='Deck', hue='Pclass')
Question2
- Sex, Embarked 시각화 해보자.
sns.countplot(data=train, x='Sex', hue='Survived')
sns.countplot(data=train, x='Embarked', hue='Survived')
수치형 데이터
Age 시각화
plt.figure(figsize=(15,5))
sns.violinplot(data=train,
x='Sex',
y='Age',
hue='Survived',
split=True)
- 20~40대 사이가 많이 사망했고
- 어린아이 중에서는 남자아이가 여자아이에 비해 많이 살았다.
Fare 시각화
train['Fare'].describe()
plt.figure(figsize=(15,5))
sns.violinplot(data=train,
x='Sex',
y='Fare',
hue='Survived',
split=True)
- 요금이 싼사람은 상대적으로 많이 죽었다.
Parch,SibSp - 부모자식, 형제배우자
- 특성공학 : Parch와 SibSp를 더해서 가족의 숫자라는 새로운 컬럼 생성
- train에 진행한 작업은 test에도 해줘야한다.
train['Family_Size'] = train['Parch'] + train['SibSp'] + 1
test['Family_Size'] = test['Parch'] + test['SibSp'] + 1
sns.countplot(data=train, x='Family_Size', hue='Survived')
- 1명일때는 죽은 비율이 높고, 2~4일때는 산 비율이 높고, 5명이상이면 죽은 비율이 높다.
- binning(사소한 관찰오류의 영향을 줄여 줄 수 있다.)
Question3
- 가족사이즈가 1이면 Alone, 2~4면 Small, 5이상이면 Large
- train, test 전부 적용
bins = [0,1,4,11]
labels = ['Alone','Small','Large']
train['Family_Group'] = pd.cut(train['Family_Size'], bins=bins, labels=labels)
test['Family_Group'] = pd.cut(test['Family_Size'], bins=bins, labels=labels)
sns.countplot(data=train, x='Family_Group', hue='Survived')
Text 데이터 다루기
Name 시각화
- 중간 호칭만 추출하자.
train['Name']
def split_title(row):
return row.split(',')[1].split('.')[0].strip()
train['Title'] = train['Name'].apply(split_title)
test['Title'] = test['Name'].apply(split_title)
plt.figure(figsize=(15,5))
sns.countplot(data=train, x='Title', hue='Survived')
plt.figure(figsize=(15,5))
plt.ylim(0,20)
sns.countplot(data=train, x='Title', hue='Survived')
- Master : 결혼하지 않은 남성. 주로 청소년 이하
- Rev : 목사님 (6명 모두 죽음)
- Mr,Mrs,Miss,Master,Rev,Other(나머지)
train['Title'].unique()
title = ['Mr', 'Mrs', 'Miss', 'Master', 'Rev', 'Don', 'Dr', 'Mme', 'Ms',
'Major', 'Lady', 'Sir', 'Mlle', 'Col', 'Capt', 'the Countess',
'Jonkheer']
len(title)
covert_title = ['Mr', 'Mrs', 'Miss', 'Master', 'Rev'] + ['Other'] * 12
covert_title
title_dict = dict(zip(title,covert_title))
train['Title'] = train['Title'].map(title_dict)
test['Title'].unique()
title_dict['Dona'] = 'Other'
title_dict
test['Title'] = test['Title'].map(title_dict)
티켓
- 버리자
train.drop('Ticket',axis=1,inplace=True)
test.drop('Ticket',axis=1,inplace=True)
train.drop('Name',axis=1,inplace=True)
test.drop('Name',axis=1,inplace=True)
train.info()
특성선택
- 범주형 데이터 인코딩
- 전체 데이터를 이용해서 학습
- 추후 상관계수, Decision tree 중요도를 활용해서 특성 고르기
y_train = train['Survived']
X_train = train.drop('Survived',axis=1)
X_test = test
X_train.columns
cat_feature = ['Sex','Embarked','Deck','Family_Group','Title']
for cat_name in cat_feature:
dummy = pd.get_dummies(train[cat_name], prefix=cat_name)
X_train = pd.concat([X_train,dummy], axis=1)
X_train.drop(cat_name,axis=1,inplace=True)
for cat_name in cat_feature:
dummy = pd.get_dummies(test[cat_name], prefix=cat_name)
X_test = pd.concat([X_test,dummy], axis=1)
X_test.drop(cat_name,axis=1,inplace=True)
X_train.shape
X_test.shape
set(X_train.columns) - set(X_test.columns)
X_test['Deck_T'] = 0
X_train.shape
X_test.shape
4. 모델 선택 및 학습
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
Tree 모델
tree_model = DecisionTreeClassifier(max_depth=5)
result = cross_val_score(tree_model,
X_train,
y_train,
cv = 5)
result
result.mean()
KNN 모델
knn_model = KNeighborsClassifier(n_neighbors=3)
result = cross_val_score(knn_model,
X_train,
y_train,
cv=5)
result
result.mean()
KNN Scaler 적용
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
transform_X_train = scaler.transform(X_train)
transform_X_train
transform_X_test = scaler.transform(X_test)
transform_X_test
result = cross_val_score(knn_model,
transform_X_train,
y_train,
cv=5)
result
result.mean()
5. 모델평가
result = pd.read_csv('data/gender_submission.csv')
result
tree_model.fit(X_train,y_train)
pre = tree_model.predict(X_test)
pre
result['Survived'] = pre
result.to_csv('HHD_submission_01.csv', index=False)
'Programming > Machine Learning' 카테고리의 다른 글
보스턴주택 값 예측 (0) | 2020.02.17 |
---|---|
Linear Model - Regression (0) | 2020.02.17 |
버섯데이터 분류 (0) | 2020.02.17 |
iris 품종분류 (0) | 2020.02.17 |
BMI 학습하기 (0) | 2020.02.16 |