본문 바로가기
AI/AI 부트캠프

[AI 부트캠프] DAY 60 - 머신러닝 프로젝트 4

by HOHHOH 2023. 10. 17.

[오늘의 일지]

머신러닝 프로젝트 - 이상치 조절, 왜도가 심한 데이터 처리, 전처리 결과

[상세 내용]

머신러닝 프로젝트

이상치 조절

- 지난 일지를 보면 알겠지만 어느 시점부터  아무리 하이퍼파라미터를 더 많은 학습을 할 수 있도록 수정도 해보고 알고리즘 모델을 바꿔서 사용해 봐도 특정 평가지표에 머물러 있는 상황이 이어졌습니다. 그래서 결국 초심으로 돌아가서 주어진 데이터의 분포부터 파악했습니다. 데이터를 보다 보니 몇 가지 특이한 점을 발견했습니다. 타깃 값을 포함한 피치 5가지가 이상치를 많이 가지고 있었으며 왜도도 심하게 0 값으로 쏠려 있는 것을 확인했습니다. 그래서 이상치가 모델학습에 주는 영향에 대해서 한번 찾아보았습니다.

  • 모델의 정확성에 부정적인 영향: 이상치는 모델이 일반적인 패턴을 학습하기 어렵게 만들 수 있습니다. 모델은 훈련 데이터에서 이상치를 노이즈로 간주하고 이상치의 영향을 받아 정확한 예측을 어렵게 합니다.
  • 모델의 일반화 능력에 부정적인 영향: 이상치가 모델의 훈련 데이터에 포함되어 있으면, 모델이 이상치에 과적합(overfitting)할 수 있습니다. 이는 모델이 훈련 데이터에는 잘 맞지만 새로운 데이터에 대한 일반화 능력이 떨어질 수 있음을 의미합니다.

그래서 이상치를 처리하는 방법에 대해서도 알아보았습니다.

  • 로그 변환: 데이터의 왜도를 감소시키는 한 가지 방법은 로그 변환을 적용하는 것입니다. 특히 양수 값이 있는 경우 로그 변환은 데이터를 정규 분포에 가깝게 만들 수 있습니다. 로그, 자연로그, 루트 등 다양한 변환을 시도해 보고 어떤 것이 가장 적합한지 확인할 수 있습니다.(여기서 0이 많이 존재한느 데이터는 전체적으로 1을 더해서 로그 변환을 해줘야 나중에 다시 돌릴 수 있습니다.)
  • 박스-콕스 변환: 박스-콕스 변환은 데이터의 왜도를 줄이기 위한 다른 방법입니다. 이는 여러 종류의 데이터 분포에 대해 적용할 수 있으며, 최적의 변환 매개변수를 찾기 위한 방법으로 사용할 수 있습니다.
  • 이상치 대체 또는 제거: 왜도가 심한 데이터에 이상치가 있는 경우, 이상치를 대체하거나 제거하는 것이 도움이 될 수 있습니다. (이상치 대체는 평균값이나 최빈값으로 대체하는 방법이 있습니다.)
  • 표준화 및 정규화: 데이터를 표준화(평균이 0, 표준편차가 1)하거나 정규화(0과 1 사이로 스케일링)하여 왜도를 줄일 수 있습니다.

저희가 가지고 있는 데이터의 특성상 이진으로 표준화하는 것은 불가능했고 로그 박스-코스 변환은 잘 모르는 방식이었기 때문에 로그변환과 이상치를 평균값으로 대체하는 과정을 진행했습니다. 예시로 가장 왜도가 심하고 이상치가 많았던 하나의 피처를 보여 드리겠습니다.

 

- 처음 상태

처음 데이터의 boxplot

 

- 이상치 최빈값 처리

이상치를 최빈값으로 처리한 boxplot

 

 - 이상치 평균값 처리

이상치를 평균값으로 대체한 boxplot

 

- 위 전처리 과정의 코드

# 이상치를 평균이나 최빈으로 대체하는 예시

column_list = ['DIST', 'BREADTH', 'BUILT', 'DEADWEIGHT', 'GT', 'LENGTH', 'U_WIND', 'V_WIND', 'AIR_TEMPERATURE', 'BN', 'DUBAI', 'BDI_ADJ', 'PORT_SIZE']

for column_name in tqdm(column_list):
    IQR = test[column_name].quantile(0.75) - test[column_name].quantile(0.25)
    outlier_line_h = test[column_name].quantile(0.75) + (1.5 * IQR)
    outlier_line_l = test[column_name].quantile(0.25) - (1.5 * IQR)  # 0.25에서 계산

    # 이상치 처리(mean을 median으로 바꾸면 최빈값)
    test[column_name] = test[column_name].apply(lambda x: test[column_name].mean() if x > outlier_line_h or x < outlier_line_l else x)

 

왜도가 심한 데이터 처리

- 이번 데이터의 특징상 왜도가 심한 데이터가 이상치도 많이 가지고 있었기 때문에 위에서 보여줬던 피처에 로그변환을 시도해 보았습니다. 결과적으로는 로그변환이 가장 좋은 그래프를 보여줬던 거 같습니다.

 

- 전체 데이터 로그 변환

전체 데이터를 로그 변환한 boxplot

 

# 로그변환 예시

columns_to_log = ['DIST', 'DEADWEIGHT', 'BDI_ADJ', 'BUILT']
for column_name in columns_to_log:
    X_train[column_name] = np.log(X_train[column_name] + 1)

 

전처리 결과

- 이상치가 존재하는 데이터를 위에 방법을 사용해서 모두 처리하고 동시에 같은 방법을 중첩적으로 사용하는데 경우의 수를 최대한 사용하였지만 성능지표의 결과는 크게 변하지 않았습니다. 결과적으로 이전 전처리 과정이 크게 문제 되지는 않았다는 것도 알게 되었습니다.

 

[마무리]

 오늘은 성능 지표를 개선하기 위해서 초심으로 돌아가 데이터에 대해서 살펴보고 다시 전처리를 해보는 과정을 진행해 보았습니다. 성능지표의 기준으로는 좋은 결과를 얻지는 못했지만 지금까지 배웠던 부분을 다시 복습했다고 생각하고 넘어갔습니다. 이제는 전처리든 여러 가지 알고리즘 모델을 사용해 보든 머신러닝으로는 배웠던 대부분을 수행했기 때문에 내일부터는 더 새로운 방법을 찾아봐야 될 거 같습니다.

반응형

댓글