Titanic data training

2022. 3. 19. 12:07AI/Big data

    목차
반응형

https://colab.research.google.com/에 train.csv와 test.csv를 upload

data load

train = pd.read_csv('train.csv')
test = pd.read_csv('test.csv')

독립변수와 종속변수 구분

종속변수 = 목적 변수

train_x = train.drop(['survived'], axis=1)
train_y = train['survived']

test data는 독립변수만 있음

test_x = test.copy()

feature extraction

학습 가능한 feature로 만듦
학습은 GBDT 사용

  • GBDT를 사용하려면, one-hot encoding 필요 (label encoding)
from sklearn.preprocessing import LabelEncoder

불필요한 passenger id를 제거

train_x = train_x.drop(['PassengerId'], axis=1)
test_x = test_x.drop(['PassengerId'], axis=1)

불필요한 Name, Ticket, Cabin 제거

train_x = train_x.drop(['Name', 'Ticket', 'Cabin'], axis=1)
test_x = test_x.drop(['Name', 'Ticket', 'Cabin'], axis=1)

label encoding

  • sex와 Embarked에 대해 label encoding
  • 결측 데이터 확인
train_x['Sex'].isna()
  0      False
  1      False
  2      False
  3      False
  4      False
         ...  
  886    False
  887    False
  888    False
  889    False
  890    False
  Name: Sex, Length: 891, dtype: bool
train_x['Sex'].isna().sum()
    0

결측 데이터는 없음

이제 'Sex'에 대해서 'male', 'female'을 0과 1로 label encoding 수행

le = LabelEncoder()
le.fit(train_x['Sex'].fillna('NA'))

train_x['Sex'] = le.transform(train_x['Sex'].fillna('NA'))
test_x['Sex'] = le.transform(test_x['Sex'].fillna('NA'))

label encoding 변환 결과

train_x['Sex']
0      1
1      0
2      0
3      0
4      1
      ..
886    1
887    0
888    0
889    1
890    1
Name: Sex, Length: 891, dtype: int64

'Embarked'에 대해서도 label encoding 수행

le = LabelEncoder()
le.fit(train_x['Embarked'].fillna('NA'))

train_x['Embarked'] = le.transform(train_x['Embarked'].fillna('NA'))
test_x['Embarked'] = le.transform(test_x['Embarked'].fillna('NA'))
0      3
1      0
2      3
3      3
4      3
      ..
886    3
887    3
888    3
889    0
890    2
Name: Embarked, Length: 891, dtype: int64

모델 구축

정형 data의 경우 GBDT 모델이 효과적임
GBDT 중 하나인 xgboost

모델 생성 및 학습

from xgboost import XGBClassifier

model = XGBClassifier(n_estimators=20, random_state=71, use_label_encoder=False)
model.fit(train_x, train_y)
    XGBClassifier(n_estimators=20, random_state=71, use_label_encoder=False)

예측

pred = model.predict_proba(test_x)
    array([[0.86473066, 0.13526936],
     [0.513669  , 0.48633102],
     [0.82747805, 0.17252192],
     [0.82747805, 0.17252192],
     [0.51461303, 0.48538697],

각 사람들의 비생존, 생존의 확률을 보여줌
첫 번째 사람의 경우 생존 확률은 13% 정도임

생존 확률만 보고 싶다면,

pred = model.predict_proba(test_x)[:, 1]
    array([0.13526936, 0.48633102, 0.17252192, 0.17252192, 0.48538697,
           0.17252192, 0.6266853 , 0.25083348, 0.6266853 , 0.17252192,
           0.13526936, 0.2509813 , 0.90446395, 0.17252192, 0.90446395,
           ...

생존 확률이 0.5 이상인 경우는 1로, 아닌 경우는 0으로 치환

pred_label = np.where(pred > 0.5, 1, 0)

제출 파일 생성

submission = pd.DataFrame({'PassengerId': test['PassengerId'], 'Survived': pred_label})
  PassengerId    Survived
  0    892    0
  1    893    0
  2    894    0
  3    895    0
  4    896    0
  ...    ...    ...
  413    1305    0
  414    1306    1
  415    1307    0
  416    1308    0
  417    1309    0
  418 rows × 2 columns
submission.to_csv('submission.csv', index=False)

모델 평가

validation: 평가용 데이터로 예측 성능을 평가

cross-validation (교차 검증)

block 별 검증

전체 data set을 n 등분하여
n 개중 하나를 validation data로 사용

각 fold 별로,

  • 이를 0부터 n - 1까지 이동하면서 validation으로 선택
  • 각 fold의 validation data의 예측 점수를 합하여 평가

logloss

  • 이진 분류의 평가시 logloss를 사용
  • 분류 문제의 대표적인 평가지표
  • cross entropy라고 부름
  • log 손실이 낮을 수록 좋은 지표

logloss 계산

  • label (1, 0) 과 예측 확률을 가지고 loss를 계산
  • 양성의 예측 확률만 계산
    • 양성에 대해 높은 양성 예측 -> 높은 예측 확률
    • 음성에 대해 낮은 양성 예측 -> 높은 예측 확률
  • 이들 loss를 평균
    • 수식에 -1을 앞에 곱함
      • 이는 실제값 예측 확률에 log를 취함 (음수가 나오니) 부호를 반전
from sklearn.metrics import log_loss, accuracy_score
from sklearn.model_selection import KFold


scores_accuracy = []
scores_logloss = []

kf = KFold(n_splits=4, shuffle=True, random_state=71)
for tr_idx, va_idx in kf.split(train_x):
    tr_x, va_x = train_x.iloc[tr_idx], train_x.iloc[va_idx]
    tr_y, va_y = train_y.iloc[tr_idx], train_y.iloc[va_idx]

    model = XGBClassifier(n_estimators=20, random_state=71, use_label_encoder=False)
    model.fit(tr_x, tr_y)

    va_pred = model.predict_proba(va_x)[:, 1]

    logloss = log_loss(va_y, va_pred)
    accuracy = accuracy_score(va_y, va_pred > 0.5)

    scores_logloss.append(logloss)
    scores_accuracy.append(accuracy)

logloss = np.mean(scores_logloss)
accuracy = np.mean(scores_accuracy)
print(f'logloss: {logloss:.4f}, accuracy: {accuracy:.4f}')
  • tr_x, va_x = train_x.iloc[tr_idx], train_x.iloc[va_idx]
    • train과 valid로 사용할 index들을 iloc에 넣어 이에대한 row들을 train_x와 valid_x로 분리
  • tr_y, va_y = train_y.iloc[tr_idx], train_y.iloc[va_idx]
    • 마찬가지로 종속변수 y 역시 train과 valid로 분리
  • model = XGBClassifier(n_estimators=20, random_state=71, use_label_encoder=False)
    • 모델을 만든 후,
  • model.fit(tr_x, tr_y)
    • train data로 학습
  • va_pred = model.predict_proba(va_x)[:, 1]
    • valid data에 대해 예측 수행
  • logloss = log_loss(va_y, va_pred)
    • 예측한 결과와 실제 결과의 loss를 logloss로 계산
  • accuracy = accuracy_score(va_y, va_pred > 0.5)
    • 이번에는 accuracy_score로 계산
  • logloss 값과 accuracy를 저장하고,
  • logloss = np.mean(scores_logloss)
  • accuracy = np.mean(scores_accuracy)
    • 산술평균을 계산

logloss: 0.4270, accuracy: 0.8148

logloss

모델 성능 평가 지표
확률에 log를 취하여 이를 panalty로 사용
100%의 확률로 예측 시 -log(1.0) = 0 (0의 panalty)
-log(0.8) = 0.2231, -log(0.6) = 0.5108... 낮은 확률일수록 기하급수적으로 높은 panalty를 적용

0.4270의 loss는 대략 70%의 예측 확률을 의미함을 알 수 있다.

accuracy

  • accuracy
    • 교차 검증 정확도
    • 예측이 정확한 비율

accuracy = (TP + TN) / (TP + TN + FP + FN)
accuracy = 정확히 예측한 수 / 전체 예측 수

  • FP: False-Positive (잘못된 positive, 양성으로 잘 못 예측)
  • FN: False-Negative (잘못된 negative, 음성으로 잘 못 예측)

logloss 구현

```python
def logloss(y, pred):
tot = 0

for label, p in zip(y, pred):
    tot += -np.log(max(p[label - 1], 1e-15))

return tot / y.shape[0]

``

반응형

'AI > Big data' 카테고리의 다른 글

영화 추천 - 높은 평균 평점 기준  (0) 2022.03.21
hyperparameter tuning  (0) 2022.03.19
Titanic data analysis  (0) 2022.03.19
Pandas DataFrame  (0) 2022.03.18
Pandas Series  (0) 2022.03.18