티스토리 뷰

캐글에서 제공하는 타이타닉 생존자 데이터로 사이킷런 생존자 예측 모델을 학습하고 평가해봅시다.

타이타닉 생존자 데이터 세트의 피처는 다음과 같습니다.

 

 

 

Passengerid, survived(0 : 사망), pclass(1, 2, 3), sex, name, Age, sibsp(동반 형제자매 or 배우자 수), parch(동반 부모님 or 어린이 수), ticket(번호), fare, cabin(선실 번호), embarked(중간 정착 항구)

 

 

 

 

 

 

 

타이타닉 탑승자 데이터를 판다스 DataFrame 객체로 받아왔습니다.

 

 

 

 

 

 

 

 

데이터 세트의 칼럼 타입을 확인해보기 위해, df.info() 메서드를 호출합시다. RangeIndex가 891entries이므로, 총 891개의 로우가 있습니다. 칼럼의 수는 12개이며, 5개의 칼럼이 object 타입입니다. 판다스의 object 타입은 문자열 타입으로 보아도 무방합니다. 사이킷런 알고리즘은 문자열을 입력값으로 받지 않으므로, 숫자형으로 변환해야 합니다.

 

 

 

info() 메서드는 각 칼럼별로 non-null인 데이터의 개수를 알려줍니다. 결손값을 어떻게 대체해야 할 지 고민해야 하지만, 이번 실습에선 간단히 각 피처의 평균 또는 고정 값으로 대체하겠습니다. 탑승객의 이름, 아이디, 티켓 번호등은 생존 여부와 관련 없는 식별자이므로 드랍하는 것이 좋습니다.

 

 

 

 

 

 

 

 

Cabin(선실 번호) 칼럼의 값 분포를 살펴보니, 속성값이 잘 정리되지 않은 것처럼 보입니다. 각 선실 번호는 "알파벳-숫자"로 구성되는 듯 한데, 알파벳이 선실의 등급을 나타내는 것처럼 보이며, 알파벳이 같을 경우 뒤의 숫자는 큰 의미를 가지지 않는 것으로 보입니다. 그러므로 Cabin 피처는 각 속성의 첫 번째 알파벳만으로 대체합시다.

 

 

 

 

 

 

 

 

데이터의 모든 결손값을 대체하는 fillna() 메서드를 정의했습니다. 나이의 결손값은 평균값으로, Cabin과 Embarked는 카테고리형 피처이므로 평균값을 정의할 수 없어 'N'이라는 고정값으로 결손값을 대체했습니다. df.fillna() 메서드에서 inplace=True로 설정하는 것을 잊지맙시다. 필요없는 칼럼을 드랍하는 것은 df.drop() 메서드로 수행합니다. 칼럼을 드랍할 것이므로 axis=1로 설정합시다.

 

 

 

 

 

 

 

 

카테고리형 피처를 전처리하는 format_features() 메서드입니다. 일단 Cabin 피처는 맨 앞 알파벳 한 글자만 남기는 것으로 전처리 했습니다. 또한 모든 카테고리 피처는 LabelEncoder()를 이용하여 숫자형으로 변환했습니다. 모든 전처리를 수행하는 transform_features() 메서드를 정의했습니다.

 

 

 

 

 

 

 

 

LabelEncoder로 fit()을 진행한 뒤 classes_ 속성을 출력시켰기 때문에, 각 카테고리형 피처에서 어떤 값이 어떤 수로 인코딩 됐는지를 쉽게 확인할 수 있습니다.

 

 

 

 

 

 

 

 

이제 모델을 학습시키기 전에 먼저 데이터에서 인사이트를 얻을 수 있나 탐색해봅시다.

 

 

 

예측해야 하는 것은 탑승객의 생존/사망 여부이므로, 어떤 탑승객이 생존했을 가능성이 높았을 지 생각해봅시다. 보통 사고가 난다면 어린이나 노약자가 최우선적으로 구조될 것이고, 가난한 사람보다는 부자가 구조될 확률이 높을 것입니다. 성별 또한 중요한 피처가 될 수 있습니다. 먼저 성별이 생존 확률에 어떤 영향을 미쳤는지, 성별에 따른 생존자 수를 비교해봅시다. groupby로 가능한 작업이며, 이 참에 groupby를 연습해봅시다.

 

 

 

 

 

 

 

먼저, 그저 성별로 그룹바이를 진행한 후 count 연산을 적용했습니다. 이는 우리가 원하는 그룹화가 아닙니다. 그저 성별에 따라 각 칼럼에 결손값이 아닌 데이터가 몇 개 인지를 보여줍니다.

 

 

 

 

 

 

 

 

성별로 먼저 그룹바이를 하고, 그 뒤에 생존여부로 한 번 더 그룹바이를 진행함으로써 우리가 원하는 필터링이 만족되었습니다. 요약 결과 탑승객은 남자가 여자보다 많았지만, 성별에 따른 생존 비율은 여성이 남성보다 훨씬 높은 것을 확인할 수 있습니다. 이러한 정보를 한 눈에 파악할 수 있도록 그래프로 시각화 해봅시다.

 

 

 

 

 

 

 

 

seaborn 패키지로 간단히 시각화 할 수 있습니다. 해당 패키지는 matplotlib에 기반하고 있지만 좀 더 세련된 비주얼과 쉬운 API, 판다스와의 편리한 연동성 등으로 시각화에 애용됩니다. x축으로 성별, y축으로 생존 여부를 지정하고 barplot() 메서드로 막대 그래프를 시각화했습니다.

 

 

 

 

 

 

 

 

 

성별 뿐만 아니라, 부의 상징을 대변하는 객실 등급 피처로 한 번 더 필터링하여 시각화를 진행해봅시다. hue 인자에 Pclass 피처를 설정하여 쉽게 가능합니다. 남여 모두 객실 등급이 높을수록 생존률이 높습니다.

 

 

 

 

 

 

 

 

 

나이에 따른 생존률도 시각화해봅시다. 일단 Age 칼럼은 숫자형 칼럼이므로, 수의 범위에 따라 카테고리형 피처로 해석해봅시다. 카테고리형 피처를 새로 만들기 위해 apply lambda 기법을 사용했습니다. 새로 만든 Age_cat 칼럼을 이용하여 성별과 나이에 따른 생존률을 시각화해봅시다. barplot() 메서드의 order 인자에 리스트를 지정하면, 해당 리스트에 있는 원소 순으로 그래핑을 해줍니다. 

 

 

 

 

 

 

 

 

 

여성 카테고리가 숫자형 0으로 전처리 된 것을 참고하면, 나이에 불문하고 여성이 남성보다 생존율이 월등히 높음을 확인할 수 있습니다. 또한 여성 노인의 생존율이 매우 높고, 남녀 불문 어린이(Child)는 생존율이 낮습니다. 지금까지의 분석으로 Sex, Pclass, Age가 생존에 중요한 피처임을 파악했습니다.

 

 

 

 

 

 

 

 

 

전처리를 수행한 DataFrame에서 레이블인 Survived 칼럼을 제외하여 피처 데이터를 만들고, Survived 칼럼만 떼어내어 레이블 데이터로 지정합시다. train_test_split() 메서드를 이용하여 학습/테스트 데이터로 분리합시다.

 

 

 

 

 

 

 

 

하이퍼 파라미터 최적화와 교차 검증을 한 번에 수행하는 GridSearchCV로 의사 결정 나무 모델의 하이퍼 파라미터를 튜닝합니다.

 

 

 

 

 

 

 

 

 

아직 배우지 않았지만, 로지스틱 회귀 모델로도 학습을 진행해봤습니다. 로지스틱 회귀 모델은 회귀라는 단어가 들어가지만, 실상은 매우 강력한 분류 모델입니다. 모델의 solver로 liblinear를 지정했으며, 비교적 작은 양의 데이터 세트를 가지는 이진 분류 태스크에선 liblinear가 좋다고 알려져 있습니다.

 

 

 

 

 

 

 

 

 

cross_val_score() 메서드에 대해 한 가지 주의해야 할 점은, 해당 메서드는 인자로 전달된 estimator를 복사한 뒤에 그 객체를 대상으로 교차 검증을 수행하기 때문에 실제 estimator는 학습(fit)되지 않는다는 점입니다. 만약 위의 코드에서 주석 처리를 한 코드를 실행시킨다면, dt_clf가 아직 fit 되지 않았다는 에러 메시지가 표시됩니다.

 

 

 

 

«   2025/08   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31