2020. 4. 14. 21:45ㆍArtificial Intelligence
이번 포스팅은 Kaggle에서 제공하는 타이타닉 데이터셋을 가지고 어떤 사람이 타이타닉 침몰 상황에서 살아남을 수 있을지를 예측하는 머신 러닝 모델을 만드는 과정에 대해 살펴보려고 합니다.
Kaggle Titanic Tutorial 에서 해당 데이터셋과 여러 가지 가이드라인들을 제공받을 수 있으며, 동일한 데이터셋으로 다른 사람들이 어떤 모델을 가지고 어느 정도의 정확도를 나타내었는지도 확인해 볼 수 있습니다.
이번 모델은 MNIST때 사용하였던 RandomForest Classifier를 사용하였으며, 여러 가지 Map함수와, 데이터 전처리를 통해 학습에 용이한 Feature들을 추출하여 학습시켰습니다.
먼저 데이터 분석 및 전처리를 위한 여러 라이브러리들을 Import하고, 데이터셋을 다운받아줍니다. 데이터셋은 위의 shape에서 알 수 있는 것처럼 사이즈가 그리 크지 않기 때문에 Kaggle에서 로컬 디렉토리로 다운받은 후 거기서 Import 해주었습니다.
정확한 모델을 훈련시키기 위해서는 모델에 넣어줄 데이터를 전처리하는 과정이 굉장히 중요합니다. 데이터를 전처리하기 위해서는 데이터셋에 어떤 형태(type)의 데이터들이 들어있으며, 중간중간 데이터가 없는(Sparse)경우에는 어떻게 처리할지도 고려해주어야 합니다. (아예 제외할 것인지, 평균값으로 채워넣을 것인지, 최빈값으로 채워넣을 것인지 등등).
다운받은 데이터는 다음과 같은 형태를 띄고 있습니다.
PassengerId: 승객의 아이디. 임의로 부여되는 값이므로 생존율과는 크게 차이가 없어 보입니다. 조금더 구체적인 정보(특정 조건이 아이디를 결정하는 경우)가 주어지지 않는다면 해당 컬럼은 Drop하는 것이 효율적일 것이라고 판단됩니다.
Survived: 생존여부
Name: 승객 이름
Sex: 성별
Age: 나이
SibSp: 동승한 배우자, 형제, 가족인원수
Parch: 동승한 부모님 수
Ticket: 티켓 번호 . 이 티켓번호도 PassengerId와 마찬가지로 특정 조건이 주어지지 않는다면 큰 의미를 갖지는 못하는 것처럼 보입니다.
Fare: 운임 요금
Cabin: 객실 구역을 의미하는것 처럼 보입니다.
Embarked: 어디서 탑승했는지 등에 대한 정보
train.info() 메서드를 통해 데이터가 충분히 갖추어져 있는지, 어떤 타입의 데이터인지를 확인해 줍니다.
전체 891개의 데이터중에서 Cabin의 정보는 무려 687개나 NULL(값이 들어있지 않은 상태)임을 알 수 있습니다. 따라서 이 부분은 학습해야하는 파라미터의 대상에서 제외하였습니다.
Age의 경우 177개가 비어있지만, Age와 생존률과의 상관관계를 분석해 본 후에 중요하다고 판단되면, 평균값등으로 채워넣는 방식을 택하고, 그리 중요하지 않아보이는 경우에는 마찬가지로 파라미터의 대상에서 제외하도록 하겠습니다.
Embarked의 경우 2개만 NULL값이므로 데이터의 분포를 한번 살펴본 뒤에, 평균값이나 최빈값으로 채워넣으면 학습에 큰 지장이 없을 것으로 보입니다.
성별의 경우 여성이 남성보다 압도적으로 생존율이 높은 것을 확인할 수 있습니다. 적어도 이 데이터셋에서는 성별이 생존율을 결정하는 데 있어서 상당히 유의미한 요소로 보입니다.
나이의 경우 선형적인 분포를 보이고 있지는 않지만, 30세 이후부터는 나이가 많을 수록 생존률이 낮아진다는 점, 그리고 아주 나이가 어린 경우에는 생존률이 꽤 높은 반면 10대의 생존률은 낮다는 점을 확인할 수 있습니다.
이 경우에, 동승한 가족의 수, 부모의 수와 연관지어서 분석해 볼 수도 있을 것입니다.
좋은 객실에 탑승한 승객일수록 생존확률이 높다는 점을 확인할 수 있습니다. 마찬가지로 PClass 정보도 생존율에 영향을 미치고 있는 것을 확인할 수 있습니다.
본격적으로 데이터를 머신 러닝 모델 학습에 적합한 형태로 가공해 보도록 하겠습니다. 우선 Cabin의 경우 NULL인 데이터가 그렇지 않은 데이터보다 많으므로 해당 Column을 Drop하였습니다.
Age의 경우에는 앞서 살펴본 것처럼 생존률에 유의미한 영향을 미치는 것으로 판단하여 Drop하지 않고, NULL인 경우에는 나이의 평균 분포 내에 있는 값을 임의로 선택에서 채워넣어 주었습니다.
Embarked의 경우에는 최빈값으로 NULL인 값(2개)를 채워넣었습니다.
데이터 분석 중 발견한 한 가지 흥미로운 사실은 Name 자체의 경우 생존율과 그다시 높은 상관관계를 보이지 않는 것 같지만, Name의 일부분인 칭호(Mr, Mrs...)등을 통해 승객들을 그룹화할 수 있으며, 이를 유의미한 상관관계를 갖는 데이터셋으로 분류할 수 있다는 것입니다. 따라서 이름에서 일부분을 추출하여 칭호별로 분류하였습니다.
성별의 경우 학습에 용이하게끔 남자는 0, 여자는 1로 Mapping하여 넣어 주었고, Embarked도 마찬가지로 0, 1, 2로 카테고리화 하여 해당 정수로 값을 채워넣었습니다.
나이는 0세부터 70세 이상까지 촘촘하게 분포되어 있어서 이를 특정 나이대로 분류하여 앞선 데이터셋들처럼 나누어주기로 했습니다. 나이가 증가함에 따라 생존률이 증가하거나 감소하는 선형 관계를 나타내고 있는 것도 아니며, 카테고리로 나누어서 해당 그룹의 생존률을 비교할때 더 유의미한 상관관계를 보이는 것을 확인하였기 때문입니다.
요금도 마찬가지로 그룹화하여 분류해주었습니다.
머신 러닝 모델에서 성능 향상을 위해 여러 Feature들을 곱해서 새로운 Feature를 만들어내는 경우가 있습니다. 이 데이터셋의 경우 나이와 클래스를 곱한 값을 추가해 주었습니다.
Classification 문제이므로 (생존했는가, 아닌가를 예측) RandomForest Classifier를 사용하였으며 (성능을 비교해 보았을때 다른 Classifier보다 높은 성능을 보임), 트레이닝 셋에서는 91.13%, Cross Validation 셋에서는 81.6%의 정확도를 보이는 것으로 확인되었습니다.
'Artificial Intelligence' 카테고리의 다른 글
[SVM] SVM으로 MNIST 분류하기 (0) | 2020.04.18 |
---|---|
[SPAM FILTER] 간단한 스팸 분류기 (1) | 2020.04.15 |
[MNIST] Random Forest를 이용한 간단한 모델 만들기 (0) | 2020.04.12 |
Principal Component Analysis(PCA) (1) | 2020.04.02 |
KNN Algorithm with Data-Driven k Value (0) | 2020.04.01 |