본문 바로가기
Hobby/Hobby_4 - Coding

[자격증] 빅분기 실기 - 3. 분석과정 정리 및 타이타닉 생존 확률 예제

by 와우멍 2021. 6. 15.

안녕하세요 와우멍입니다.

오늘은 다른 예제를 수행해보면서, 데이터 분석과정을 다시 한 번 복습해보겠습니다.


빅데이터 분석기사 실기 합격 전략

먼저 전략을 다시금 정리해보겠습니다.

- 단답형 문제 3점 * 10개 = 30점

- 작업형 1유형 10점 * 3개 = 30점

- 작업형 2유형 40점 * 1개 = 40점

 그런데 예시로 주어진걸 보면, 단답형과 작업형 1유형은 모두 답이 정해져있는 문제들이라 맞추는 것이 중요한 것 같습니다. 왠지 1유형은 단답형 비슷하게 통계량을 직접 계산하는 문제도 나올법 하네요. 예를 들어 boxplot에서 outlier 판별하는 범위(IQR)라던지..? 2유형은 제출한 모델을 주최측에서 평가하는 방식으로 진행될 것 같으니... 일단 모델 결과를 만들기만 하면 성능에 따라 차등점수를 받더라도 점수를 받긴 할 것 같다고 생각이 들고요..!

 그렇다면...!! 빅분기 필기 실기 범위에서 계산문제로 나올만한 통계량, 평가법 등을 쭈욱 정리해보는게 첫번째일 것 같구요! 2유형에서는 만점을 노리기보다 일단 결과 도출까지만 쭉 해볼 수 있게 파이프라인을 다져놓는 것이 두번째일 것 같습니다.

 1유형과 단답형의 공부 내용은 다음글에서 정리하기로 하고!

 감을 잃기전에 캐글의 타이타닉 예제를 통해 데이터 전처리부터 생존자 예측 모델수립과 검증까지 한 번 밟아보겠습니다.


 캐글 타이타닉 예제 풀이

 분석과정은 다음과 같이 파이프라인을 만들고 따르려 합니다. (+ 예제 해본 후 한줄 요약)

0. 데이터 다운로드

1. 데이터셋 확인

 - .head(n) / .info() 사용

2. 탐색적 데이터 분석

 - 시각화 안되니... 일단 보류, 그나마 전처리 후에 .corr()로 상관관계만 살짝 확인 후 사용하지 않을 column 삭제

3. Feature Engineering

 - 결측값 (NaN) 처리/ 문자형 변수 변환(LabelEncoder/ .get_dummies()/ 이상치(outlier) 처리/ 정규화(Min-Max)

4. 모델 수립 및 학습

5. 모델 예측 및 평가

 

그럼 시작해보겠습니다.


0. 데이터 다운로드

캐글 페이지에서 sign up 후 데이터를 다운로드 (train.csv/ test.csv 로 구성)

https://www.kaggle.com/c/titanic/

 

Titanic - Machine Learning from Disaster

Start here! Predict survival on the Titanic and get familiar with ML basics

www.kaggle.com


1.  데이터셋 확인하기

 데스크탑 환경에서는 엑셀로 csv 파일을 열어서 보는 것이 편합니다.

 빅분기 시험 환경에서 데이터 탭을 보는 것으로 대체해야겠습니다.

아니면 좀 더 간지나게, pandas의 head( ) 함수를 이용해서 보는 방법도 있겠네요. 

 - df.head(n)는 상위 n개 행까지의 데이터를, df.tail(n)은 하위 n개 행의 데이터를 보여주는 함수입니다. (n의 기본값은 5)

각 column의 정의와 특징을 정리하면 위와 같습니다.

목표는 Survived를 예측이고, 단순 식별자로 보이는 Passengerid/ Name/ Ticket/ Cabin은 사용하지 않겠습니다. 뒤에서 명목형 변수를 숫자형 변수로 변경해줘야 하는 column들은 성별Embarked입니다.

df.info( ) 함수를 이용하면 데이터 세부내용을 볼 수 있는데, 전체 891 행 중에 age랑 Embarked에 결측값이 있다는 것을 확인할 수 있습니다. Age는 어떻게 처리할지.... age와 상관관계 있는 변수찾아서 대체하는 방법이 떠오르는데, 한번 진행해보겠습니다.


2. 탐색적 데이터 분석 (EDA)

 여기는 사실 matplotlib의 다양한 시각화 툴을 이용해서 통찰력을 얻어야 하는데.... 시험장에서는 시각화가 안된다고 하니.. 고민이 많이 되네요.. 여기서는 1단계에서 했던 label보고 버릴거 버리는 정도라고 생각해보겠습니다.


3. Feature Engineering

 3-1. 결측값 처리

 빅분기 예제에서의 '환불금액'은 없으니까 0으로 대체할 수 있었는데, 이 데이터에서의 age와 embarked에 있는 결측값은 무엇으로 처리를 해야 할까요?

  df.isna().sum() 을 통해 결측값이 어떤 column에 얼마나 분포하는지 다시한 번 확인할 수 있습니다.

 편하게 df.dropna()로 다 날려버릴수도 있지만... 그러면 안될 것 같습니다.

 이럴 때 생각나는 것은 age와 상관관계가 있는 값과의 모델을 통해 값을 대치시킬 수도 있을 것 같지만.. 일단 주관적으로 봤을 때 그런 관계가 있어보이는 변수는 없어보이네요. 그럼 무난하게 mean/median 등의 값으로 날려버리는 방법이 있겠습니다.

 고민은 뒤로 미루고 평균값으로 대치하는 방법은 다음과 같습니다. 

 df.fillna({'변수명':df['변수명'].mean()}, inplace=True) 

*결측치 처리 나중에 다시 볼 것

https://eda-ai-lab.tistory.com/14?category=683835 

 

결측치 처리 (Missing Value)

NOTE: 대부분의 내용은  https://blog.naver.com/tjdudwo93/220976082118을 기반으로 Titanic 데이터에 실습을 적용하는 것으로 진행됩니다. 군밤고굼님의 설명에 따르면 결측치를 살펴보는 과정은 아래와 같

eda-ai-lab.tistory.com

 

 3-2. 문자형 변수 변형

One-Hot Encoding 순서가 없을 때(고유명사 등) 사용하고 고유값의 개수가 많지 않을 때 효율적인 반면,

Label Encoding 순서의 의미가 있을 때(순서 있는 직급 등) 사용하고 고유값의 개수가 많을 때 효율적입니다.

 그러니 여기서 male/female로 되어있는 성별 탭은 LabelEncoding를 사용해도 괜찮을 것 같습니다. preprocessing 모듈을 사용할수도 있지만, 그냥 map 함수를 통해 직접 수치를 매칭시키는게 편하네요.

(종류가 많아지면 불편할 수도 있겠지만, 그럴 경우에는 의미없는 dependency를 만들 수도 있으니 OneHotEncoding처리를 해야겠지요!)

 Embarked(탑승항구)는 항구 간 상관관계를 가질 일이 없는 고유명사니 One-Hot Encoding를 사용합니다.

이것도 sklearn.preprocessing에 모듈이 있긴 하지만, pandas의 df.get_dummies()를 이용하는 편이 훨씬 간단하고 직관적으로 문자형 변수를 숫자로 바꿀 수 있다.

 아래 결과를 보면, Embarked에 있던 C/Q/S가 각각 0/1로 표기되는 3개의 column으로 나눠진 것을 확인할 수 있습니다.

*LabelEncoder와 OneHotEncoding의 사용여부에 대해서는 sklearn의 docs에서도 내용을 확인할 수 있습니다.

 -> LabelEndoding는 경우의수에 따라 0부터 n까지 숫자를 부여하는 거라서, 이들간의 상관관계가 있는 것으로 영향을 미칠 수도 있다. 따라서 공식 doc에서도 y값에만 적용해야 하고, x에는 사용하면 안된다고 되어 있다.("This transformer should be used to encode target values, i.e. y, and not the input X." from https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html) 그러니 x값에 있는 문자형 변수를 처리하기 위해서는 one-hot-encoding을 해야만 한다.

 

 3-3. Outlier 처리

 일단 outlier는 Boxplot값을 이용하여 판별 후 상한/하한값으로 대체하는 것으로 결정했습니다.

 

3-4. Column별 Normalization(Scaler) 적용하기

 - 각 변수별 미치는 영향력이 달라질 수 있으니, outlier를 쳐낸 다음에 최솟값이 0 최대값이 1이 되도록 normalization을 해줬습니다.

 

*3-5 파생변수 생성은 옵션. 


4. 모델 개발 및 학습

- 분류모델이 나오면 Logit와 SVM, 딱 두개로만 하겠습니다.

우선 train data 내에서 모델을 만들고 평가를 해보기 위해, train set과 test set을 분리했습니다.

각 모델은 일단 파라미터 튜닝까지는 안건들고 기본 값으로만 수행했습니다.

1
2
from sklearn.model_selection import train_test_split
train_x, test_x, train_y, test_y = train_test_split(train_set_re.drop('Survived', axis=1), train_set_re['Survived'])
cs

4-1. Logistic Regression

1
2
3
4
5
6
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(train_x, train_y)
print(model.score(train_x, train_y))
 
predict = model.predict_proba(test_x)
cs

>> 0.80089 의 score가 출력되었습니다.

4-2. SVM

1
2
3
4
5
6
from sklearn.svm import SVC
model = SVC(probability=True)
model.fit(train_x, train_y)
print(model.score(train_x, train_y))
 
predict = model.predict_proba(test_x)
cs

>> 0.81886 의 score가 출력되었습니다.

역시 대충할 때는 SVM이 잘먹힙니다..!


5. 모델 예측 및 평가

1
2
from sklearn.metrics import roc_auc_score
roc_auc_score(test_y, predict[:,1])
cs

빅분기 예제에서 roc-auc score를 사용한다 했으니, sklearn에 있는 모듈로 평가해보았습니다.

LogisticRegression은 0.87018

SVM은 0.86529

의 결과가 나왔습니다.

튜닝을 하면 더 잘나올 것 같긴 하지만, 이정도면 대충 점수는 주겠지요..? 허헛

 

추가. Feature Engineering 수행 여부에 따른 성능 변화

**중간에 추가한 Feature engineering의 수행 여부에 따라서는 아래와 같이 성능이 달라집니다.

두 모델 모두 outlier 처리와 scaler 적용하는게 더 좋은 결과를 나타닙니다. 

LogistsicRegression은 뭘까요. 결과가 애매하네요 ㅋㅋㅋㅋㅋ 

SVM은 Min-Max scale에 민감한 결과를 보이는 것 같구요!

왠만하면 저는 두개 다 하는 과정으로 진행하겠습니다.

Outlier 찾아서 날리는 과정(3-3) X
Min-Max scale(3-4) X
Train set score Test set score (roc-auc)
LogisticRegression 0.81886 0.81913
SVM 0.68413 0.72612
Outlier 찾아서 날리는 과정(3-3) O
Min-Max scale(3-4) X
Train set score Test set score (roc-auc)
LogisticRegression 0.78143 0.89054
SVM 0.67664 0.76288
Outlier 찾아서 날리는 과정(3-3) X
Min-Max scale(3-4) O
Test set score Test set score (roc-auc)
LogisticRegression 0.79191 0.89840
SVM 0.80389 0.87205

 

https://www.dacon.io/competitions/open/235539/talkboard/400968?page=undefined&dtype=undefined&ptype=undefined 

 

[재난] 타이타닉 : 누가 살아남았을까?

출처 : DACON - Data Science Competition

dacon.io

'타이타닉 캐글' 이라고 검색하면 수많은 예제들이 나옵니다. 

근데 지금 목표는 슈퍼 좋은 모델 만드는 것이 아니기 때문에 저는 요정도에서 마무리하겠습니다.

더 욕심있으신 분들은 위 영상도 한 번 보셔요 (전 길어서 안봤습니다)


* 사용할 함수 입력변수랑 의미를 잘 모를 때는 help 함수를 사용하자.

이렇게 하면 시험환경에서도 사용할 모듈의 입출력값이 무엇인지, 어떤 값이 들어가야하는지에 대한 documentation을 확인할 수 있습니다..! 

(왼쪽은 주피터에서 출력한 화면, 오른쪽은 빅분기 시험화면에서 출력한 화면입니다.)

 

내일은 분류 문제가 아닌 선형회귀 문제를 한번 찾아서 해보겠습니다.

고럼 화이팅입니당 :-)

댓글