본문 바로가기
Artificial Intelligence

[Kaggle] Logistic Regression으로 생존/사망자 예측하기

by blackjack_96 2022. 5. 22.

안녕하세요.

오늘은 Kaggle Site의 대표적인 문제인

생존/사망자 예측을 하는 머신 러닝 프로젝트를 해보겠습니다.

 

1. 필요한 Module과 Library를 import하기

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report, plot_confusion_matrix
from sklearn.metrics import precision_recall_curve, plot_precision_recall_curve, plot_roc_curve
from sklearn import metrics
%matplotlib inline

마지막 줄의 

%matplotlib inline이 무슨 의미일까요?

우리는 도중에 데이터의 대략적인 특성을 파악하기 위해 여러 시각화 도구를 이용할 예정입니다.

시각화를 할 때, Graphic Backend가 필요한데,

사용하고 있는 주피터 노트북에 내장된 그래픽 백엔드를 이용한다는 의미입니다.

 

2. 데이터 추출하기

train = pd.read_csv('../input/titanic/train.csv')
test = pd.read_csv('../input/titanic/test.csv')

훈련용 데이터와 Test용 데이터를 위와 같이 Pandas의 Dataframe형태로 추출합니다.

 

3. 데이터 살펴보기

데이터를 추출했으니, 어떻게 생긴 데이터인지 알아보겠습니다.

train.head()
test.head()

train.head()의 결과
test.head()의 결과

훈련데이터와 테스트 데이터를 추출한 후 어떻게 생겼는지 살펴보는 과정입니다.

우리가 하는 일은 다음과 같습니다.

여러 특성들(Passengetid, Pclass, Name,...)을 이용하여 

Survived여부(0 또는 1)를 예측하는 머신러닝 프로그램을 제작하는 것입니다.

 

 

위에서 보시다시피 test데이터에는 Survived 컬럼이 빠져 있습니다.

나머지 특성을 이용해서 test데이터의 Survived값들을 예측하라는 것이죠.

 

우린 지금 Survied를 예측하는 머신러닝 프로그램을 만드는 것입니다.

그러면 Survived열을 한 번 구체적으로 살펴볼까요?

 

train['Survived'].value_counts()

훈련 데이터 중 생존자는 342명, 그 외 549명은 사망자입니다.

시각화를 해서 표현해 봅시다.

각 카테고리 별 데이터의 개수를 표현해주는 seaborn 라이브러리의 countplot 메소드를 이용하겠습니다.

sns.countplot(data=train, x='Survived')

훈련데이터 중 생존자와 사망자 수를 그래프로 시각화하여 표현하였습니다.

 

갑자기 저는 이 점이 궁금해졌습니다.

타이타닉 생존자 중 나이가 적은사람과 나이가 많은 사람 중 어느 집단이 더 많이 살았을까?

boxplot을 이용하여 알아보겠습니다.

 

sns.boxplot(data=train, x="Survived", y="Age")

생존되신 분들의 경우는 나이 분포보다, 그렇지 않은 분들의 나이 분포가 약간 더 높이 나타나네요.

 

4. 데이터에서 특이값 처리하기

데이터를 머신러닝 알고리즘을 훈련하여 프로그램을 만드는데,

머신러닝 알고리즘이 아무리 훌륭해도, 주입시키는 데이터가 질이 낮다면 그 머신러닝 프로젝트는 쓸모가 없습니다.

데이터의 질을 높이기 위하여

비정상적인 값들을 잘 처리해주어야 하는데, 그 중 대표적인 것이 null값의 처리입니다.

 

train.isnull().sum(axis=0)

train.isnull()메소드는 train이라는 DataFrame객체 내부의 데이터가

null이면 True를, 아니면 False로 모두 교체해버립니다.

 

다음과 같이 말이죠.

 

우리가 원하는 것은

각 열마다 null인 데이터가 몇개인가 입니다.

그러면 다음과 같이 null값 개수를 열별로 구하면 됩니다.

 

train.isnull().sum(axis=0)

위의 axis=0은 생략해도 됩니다. default로 axis=0 즉, 열별로 sum을 구해서 시리즈 값을 반환하기 때문이죠.

Age열에는 null값이 177개, Cabin열에는 null값이 687개, Embarked에는 null값이 2개가 있네요.

저는 위처럼 그냥 출력하는 것보다.

데이터 프레임을 던져주면

해당 데이터 프레임의 각 column별로 null값이 들어있는 비율을 리턴해주는 함수를 정의할 생각입니다.

 

def missing_percent(train):
  nan_percent = 100*(train.isnull().sum() / len(train))
  nan_percent = nan_percent[nan_percent > 0].sort_values()
  return nan_percent
missing_percent(train)

각 컬럼에 포함된 null값들의 비율을 위와 같이 출력하였습니다.

 

이 null값들을 어떻게 처리해 줄까요?

총 세 가지 방법이 있습니다.

 

- 각 열의 중간값으로 대체하기

- 해당 Row 버려버리기

- 해당 Column을 사용하지 않기

 

Cabin 열은 아예 삭제를 해 버리고,

Embarked열은 null값이 설정되어 있는 Row만 버리고,

Age는 null값을 평균값으로 대체하는 방법을 사용하겠습니다.

 

train = train.dropna(axis=0, subset=['Embarked'])
train.drop("Cabin", axis = 1, inplace = True)
train['Age'].fillna(train['Age'].mean(), inplace = True)

null값이 완전히 제거되었는지 위에서 만든 함수로 테스트를 해 봅시다.

 

missing_percent(train)

했더니 null값이 없다고 출력됩니다.

 

그리고 모델의 복잡성을 제거하기 위해 다음과 같이 column들을 제거해 줍시다.

train.drop(['PassengerId', 'Name', 'Ticket', 'Fare',"Embarked"], axis=1, inplace = True)

그리고 Sex열의 값이 Object(텍스트 오브젝트)입니다.

이러한 객체값은 머신러닝 알고리즘으로 다룰 수 없기에

전부 숫자로 바꾸어 줍시다.

 

train.loc[train['Sex']=='male','Sex'] = 1
train.loc[train['Sex']=='female','Sex'] = 0

5. 데이터 가공 완료. 훈련 준비

데이터의 가공이 완료되었습니다.

이제 예측 데이터와 훈련 레이블로 나누어 보겠습니다.

 

X = train.drop("Survived", axis=1, inplace = False)
Y = train['Survived']

그리고 이렇게 나눈 데이터를

훈련용 데이터와 시험용 데이터로 나누어 보도록 하죠

 

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.1, random_state = 101)

그리고 훈련 데이터를 기준으로

모든 데이터들을 Standardization 시키도록 하겠습니다.

 

scaler = StandardScaler()
scaler.fit(X_train)

scaled_X_train = scaler.transform(X_train)
scaled_X_test = scaler.transform(X_test)

 

6. 훈련 데이터로 훈련하기

자, 이제 데이터의 모든 준비가 끝났습니다.

이제 Logistic Regressor객체를 만들고 훈련을 시켜보도록 하겠습니다.

 

Lr_model = LogisticRegression()
Lr_model.fit(scaled_X_train, Y_train)

y_pred = Lr_model.predict(scaled_X_test)

훈련을 완료하고 테스트용 데이터를 예측한 값까지 반환 완료하였습니다.

그러면 얼마나 정확하게 예측하였는지 알아볼까요?

 

print(accuracy_score(y_pred, Y_test))

0.8426966292134831라는 정확도가 산출되었습니다.

 

훈련용 데이터도 같은 방법으로 예측해서 점수를 내 보시면 아시겠지만, 

Underfitting이 되어 훈련점수와 테스트점수가 둘 다 낮습니다.

오늘은 여기까지 하고,

다음 포스팅을 통해 이 Underfitting을 해결해 보도록 하겠습니다.

 

감사합니다.