준비
- Python 3 개발 환경
본 글에서는 Jupyter Notebook 을 사용하여 실습을 진행합니다.
Kaggle
먼저 Kaggle 에 접속해서 새 계정을 생성합니다.
풀어볼 문제 Titanic - Machine Learning from Disaster 에 접속하여 참가합니다.
Data 섹션에서 필요한 데이터셋을 모두 다운로드합니다.
- gender_submission.csv
- test.csv
- train.csv
실습을 위한 디렉토리에 데이터셋을 구성합니다.
데이터셋 분석
필요한 모듈들을 가져옵니다. (설치 과정은 생략)
import pandas as pd
import numpy as np
필요한 데이터셋을 불러와서 확인합니다.
train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')
print(train.shape)
print(test.shape)
train.head()
test.head()
데이터셋 정보 확인
print(train.info())
print(test.info())
유실된 데이터 확인
print(train.isnull().sum())
print(test.isnull().sum())
데이터셋 설명 (참고용)
- Survived : 0이면 사망, 1이면 생존
- Pclass : 선실 등급
- SibSp : 배우자 형제 동행 수
- Parch : 부모 or 아이 동행 수
- Fare : 선실당 요금
- Cabin : 짐칸
- Embarked : 선착장
시각화
필요한 모듈들을 가져옵니다.
import matplotlib.pyplot as plt
import seaborn as sns
원 그래프를 그리는 함수를 작성합니다.
def pie_chart(feature):
feature_ratio = train[feature].value_counts(sort=False)
feature_size = feature_ratio.size
feature_index = feature_ratio.index
survived = train[train['Survived'] == 1][feature].value_counts()
dead = train[train['Survived'] == 0][feature].value_counts()
plt.plot(aspect='auto')
plt.pie(feature_ratio, labels=feature_index, autopct='%1.1f%%')
plt.title(feature + '\'s ratio in total')
plt.show()
for i, index in enumerate(feature_index):
plt.subplot(1, feature_size + 1, i + 1, aspect='equal')
plt.pie([survived[index], dead[index]], labels=['Survivied', 'Dead'], autopct='%1.1f%%')
plt.title(str(index) + '\'s ratio')
plt.show()
Sex 칼럼 시각화
pie_chart('Sex')
막대 그래프를 그리는 함수를 작성합니다.
def bar_chart(feature):
survived = train[train['Survived'] == 1][feature].value_counts()
dead = train[train['Survived'] == 0][feature].value_counts()
df = pd.DataFrame([survived, dead])
df.index = ['Survived', 'Dead']
df.plot(kind='bar', stacked=True, figsize=(10, 5))
Pclass 칼럼 시각화
bar_chart('Pclass')
데이터 전처리
두 데이터셋을 병합하고 Name 칼럼에서 Mr., Mrs. 등의 문자열을 추출하여 Title 칼럼에 넣습니다.
train_and_test = [train, test]
for dataset in train_and_test:
dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+)\.')
Title 과 Sex 별 승객 수 출력
pd.crosstab(train['Title'], train['Sex'])
Title 카테고리 분류
for dataset in train_and_test:
dataset['Title'] = dataset['Title'].replace(
['Capt', 'Col', 'Countess', Don','Dona', 'Dr', 'Jonkheer', 'Lady','Major', 'Rev', 'Sir'],
'Other',
)
dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss')
dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs')
dataset['Title'] = dataset['Title'].replace('Ms', 'Miss')
train[['Title', 'Survived']].groupby(['Title'], as_index=False).mean()
string 형으로 변환
for dataset in train_and_test:
dataset['Title'] = dataset['Title'].astype(str)
dataset['Sex'] = dataset['Sex'].astype(str)
NaN 을 포함한 Embarked 데이터 갯수를 확인하고 Nan 값을 모두 'S' 로 대체합니다.
print(train.Embarked.value_counts(dropna=False))
for dataset in train_and_test:
dataset['Embarked'] = dataset['Embarked'].fillna('S').astype(str)
Age 의 NaN 값은 승객들 나이의 평균 값으로 대체하고 연령대별 생존율을 출력합니다.
for dataset in train_and_test:
dataset['Age'].fillna(dataset['Age'].mean(), inplace=True)
dataset['Age'] = dataset['Age'].astype(int)
train['AgeBand'] = pd.cut(train['Age'], 5)
print(train[['AgeBand', 'Survived']].groupby(['AgeBand'], as_index=False).mean())
Fare 의 Nan 값은 평균 값인 13.675 로 대체합니다.
for dataset in train_and_test:
dataset['Fare'] = dataset['Fare'].fillna(13.675)
Binning 기법
여러 종류의 데이터에 대해 범위를 지정하거나 카테고리를 통해 이전보다 작은 수의 그룹으로 만드는 방법.
for dataset in train_and_test:
dataset['Embarked'] = dataset['Embarked'].fillna(dataset['Age'].mean())
for dataset in train_and_test:
dataset.loc[dataset['Age'] <= 16, 'Age'] = 0
dataset.loc[(dataset['Age'] > 16) & (dataset['Age'] <= 32), 'Age'] = 1
dataset.loc[(dataset['Age'] > 32) & (dataset['Age'] <= 48), 'Age'] = 2
dataset.loc[(dataset['Age'] > 48) & (dataset['Age'] <= 64), 'Age'] = 3
dataset.loc[dataset['Age'] > 64, 'Age'] = 4
dataset['Age'] = dataset['Age'].map(
{
0: 'Child',
1: 'Young',
2: 'Middle',
3: 'Prime',
4: 'Old'
}
).astype(str)
for dataset in train_and_test:
dataset.loc[dataset['Fare'] <= 7.854, 'Fare'] = 0
dataset.loc[(dataset['Fare'] > 7.854) & (dataset['Fare'] <= 10.5), 'Fare'] = 1
dataset.loc[(dataset['Fare'] > 10.5) & (dataset['Fare'] <= 21.679), 'Fare'] = 2
dataset.loc[(dataset['Fare'] > 21.679) & (dataset['Fare'] <= 39.688), 'Fare'] = 3
dataset.loc[dataset['Fare'] > 39.688, 'Fare'] = 4
dataset['Fare'] = dataset['Fare'].astype(int)
for dataset in train_and_test:
dataset['Family'] = dataset["Parch"] + dataset["SibSp"]
dataset['Family'] = dataset['Family'].astype(int)
사용하지 않을 데이터는 제거합니다.
features_drop = ['Name', 'Ticket', 'Cabin', 'SibSp', 'Parch']
train = train.drop(features_drop, axis=1)
test = test.drop(features_drop, axis=1)
train = train.drop(['PassengerId', 'AgeBand'], axis=1)
원-핫 인코딩 (One-Hot Encoding)
컴퓨터의 데이터 처리를 위해 0과 1로 데이터를 구별하는 인코딩입니다.
본 글에서 사용할 scikit-learn 라이브러리의 머신러닝 알고리즘은 문자열을 입력 값으로 허용하지 않기 때문에 숫자형으로 인코딩하는 전처리 작업이 필요합니다.
train = pd.get_dummies(train)
test = pd.get_dummies(test)
train_label = train['Survived']
train_data = train.drop('Survived', axis=1)
test_data = test.drop("PassengerId", axis=1).copy()
학습
필요한 모듈들을 가져옵니다.
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.utils import shuffle
데이터 셔플
train_data, train_label = shuffle(train_data, train_label, random_state = 5)
모델 학습 적용
def train_and_test(model):
model.fit(train_data, train_label)
prediction = model.predict(test_data)
accuracy = round(model.score(train_data, train_label) * 100, 2)
print("Accuracy: ", accuracy, "%")
return prediction
예측
알고리즘별 예측 결과를 확인합니다.
# Logistic Regression
log_pred = train_and_test(LogisticRegression())
# SVM
svm_pred = train_and_test(SVC())
# KNN
knn_pred = train_and_test(KNeighborsClassifier(n_neighbors = 4))
# Random Forest
rf_pred = train_and_test(RandomForestClassifier(n_estimators = 100))
# Navie Bayes
nb_pred = train_and_test(GaussianNB())
제출을 위해 정확도가 제일 높은 알고리즘의 예측 값을 csv 파일로 저장합니다.
submission = pd.DataFrame(
{
"PassengerId": test["PassengerId"],
"Survived": rf_pred
}
)
submission.to_csv('submission_rf.csv', index=False)
제출
submission_rf.csv
파일이 생성되면 페이지에서 Submit Predictions 을 클릭하고 업로드 후 제출합니다.
제출 결과
비록 점수는 낮지만 성공적으로 완료한 것 같습니다.
읽어주셔서 감사합니다.
😍 댓글