2019. 6. 1. 19:09ㆍ관심있는 주제/뉴럴넷 질문
도움이 되셨다면, 광고 한번만 눌러주세요. 블로그 관리에 큰 힘이 됩니다 ^^
페북에서 유명하게 공유가 되고, 개인적으로도 관심이 있는 글이라 빠르게 읽고 쓰려고 한다. 코드는 medium을 참고하기 바란다! 코드는 밑에 URL
극단적인 경우는 무엇일까?
실제 데이터에는 불균형 데이터셋이 흔하다.
그 의미는 우리가 알고자 하는 대상은 상대적으로 적다는 의미이다.
그것들 중에서는 우리가 알고자 하는 대상이 전체 대상의 0.6% 와 같이 엄청나게 극단적이게 나올 수 있다.
이러한 것을 분류하는 것은 꽤 어려운 일이다.
최근에 아무리 딥러닝이 발전했다 해도, 작은 레이블에 대해서는 딥러닝 실행을 금지한다고 한다( 처음 안 사실...?)
이유라고 하면, 아무리 데이터가 늘어난다 할지라도, 우리가 알고 싶은 대상의 Label은 제한돼서 오히려 다른 많은 클래스에 대해서 일반화가 되어서, 잘 못할 것이라는 말 같다.
Why should we still bother to use Deep Learning?
그런데도 왜 우리는 다른 기계 학습 접근법을 사용하지 않을 것인가?
그 이유로는 주관적일 수도 있는데, 우리가 머신러닝으로 이러한 일을 할 때 많은 클래스에 대해서는 undersample을 해서 균형 잡힌 데이터셋을 만들려고 노력한다.
그렇다면 이렇게 0.6% 데이테에 균형을 맞추려면 다른 클래스에 대해서도 1%만 사용하게 되어서, 실제 데이터를 다 쓰지를 못하게 된다. (SVM , RandomForest 같은 것은 이러한 데이터셋에도 잘 된다.)
그러나 이런 것들에 정확도는 제한된다.
결국 이런 것은 우리가 사용하지 않은 99% 데이터셋에 대해서 유용한 정보를 쓰지 못하게 된다!
여기서는 Autoencoder로 1 layer를 이용하여서, 희귀 케이스를 잡는 것을 보여주겠다고 한다.
- 일단 이 네트워크는 3가지에 대해서 알면 되는데,
- encoder
- 데이터를 잘 압축하는 Network
- Latent Variable
- 그 데이터가 잘 압축된 Latent 변수
- decoder
- 이 Latent가 잘 압축이 됐는데, 이것을 다시 펼쳤을 때 다시 원래로 복원할 수 있게 하는 Network
- encoder
아주 대충대충 설명했는데, 이 정도만 알아도 될 것 같다.
이것을 어떻게 희귀 이벤트에 사용할 수 있을까?
- 일단 2가지로 나눈다(희귀 케이스와 일반 케이스)
- 일반 케이스를 현재 그냥 평온한 상태 즉 99% 데이터를 뜻한다.
- 일단 희귀 케이스에 대해서는 무시하고 일반 케이스만 이용해서 학습시킨다.
- 같은 케이스로만 AutoEncoder를 학습시켜서 MSE Loss를 떨어트려서 일반 케이스에 대해서 잘 학습시킨다.
- 여기에 희귀 케이스 살짝 넣어주면 분명히 크게 나올 것이다.
일단 표준화를 해준다.
그리고 학습을 시켜준다
MSE를 낮추려고 한다.
valid_x_predictions = autoencoder.predict(df_valid_x_rescaled)
mse = np.mean(np.power(df_valid_x_rescaled - valid_x_predictions, 2), axis=1)
error_df = pd.DataFrame({'Reconstruction_error': mse,
'True_class': df_valid['y']})
precision_rt, recall_rt, threshold_rt = precision_recall_curve(error_df.True_class, error_df.Reconstruction_error)
plt.plot(threshold_rt, precision_rt[1:], label="Precision",linewidth=5)
plt.plot(threshold_rt, recall_rt[1:], label="Recall",linewidth=5)
plt.title('Precision and recall for different threshold values')
plt.xlabel('Threshold')
plt.ylabel('Precision/Recall')
plt.legend()
plt.show()
테스트 데이터에서 분류 임계 값을 추정해서는 안됩니다. 지나치게 적합합니다.
( 중요 사항!!!!!!!!)
test_x_predictions = autoencoder.predict(df_test_x_rescaled)
mse = np.mean(np.power(df_test_x_rescaled - test_x_predictions, 2), axis=1)
error_df_test = pd.DataFrame({'Reconstruction_error': mse,
'True_class': df_test['y']})
error_df_test = error_df_test.reset_index()
threshold_fixed = 0.85
groups = error_df_test.groupby('True_class')
fig, ax = plt.subplots()
for name, group in groups:
ax.plot(group.index, group.Reconstruction_error, marker='o', ms=3.5, linestyle='',
label= "Break" if name == 1 else "Normal")
ax.hlines(threshold_fixed, ax.get_xlim()[0], ax.get_xlim()[1], colors="r", zorder=100, label='Threshold')
ax.legend()
plt.title("Reconstruction error for different classes")
plt.ylabel("Reconstruction error")
plt.xlabel("Data point index")
plt.show();
실제 이 알고리즘을 사용하면,
9개를 탐지하고 32개는 못 잡는다.
이상적으로 완벽하지는 않지만, 꽤 나쁘지는 않다고 하는데
으흠... 별로인 것 같은데...
이것의 발전 단계로 LSTM AutoEncoder로 시계열 데이터에 적용한 사례를 소개한다.
결론 :
저자는 만족스러운 결과라고 하는데,,,
으음 개인적으로는 동의하지 못한다.
> 최근에 알게 된 사실
>> 오히려 중간 Layer를 인풋보다 더 많이하는 구조로 하게 되면 훨씬 더 잘되는 것을 확인했다.
>> 왜 이것이 잘된지에 대해 생각을 해본다면, 결국 Super Overfitting을 통해서 Normal에 완전 적합을 시키는 것이다!
>> 흔히 이러한 구조를 Overcomplete Autoencoders 라고 한다!
https://thekishankumar.com/2018/12/23/autoencoder/
실제 이 모델을 사용하면 177명이라는 실제는 평범한 사람인데, 이 사람들을 희귀 케이스라고 치부하는 것이다.
즉 그렇게 되면, 억울한 사람들이 많이 발생시킬 수 있어서, 피해자가 생길 수도 있기 때문에 좋지 않다고 생각하고,
더 나은 방법으로 VAE도 있긴 할 텐데, LSTM도 신기하다.
https://github.com/cran2367/autoencoder_classifier/blob/master/autoencoder_classifier.ipynb
'관심있는 주제 > 뉴럴넷 질문' 카테고리의 다른 글
What is Label Smoothing? - 리뷰 (Overconfidence) (0) | 2020.01.04 |
---|---|
Designing Your Neural Networks 리뷰 (0) | 2019.09.26 |
[변수 생성]Structured Data에서 CNN을 활용한 새로운 변수 생성하기 (0) | 2019.05.27 |
hidden layer 수와 Node를 몇개나 해야 할 지에 대한 글 (0) | 2019.05.23 |
Neural Network를 학습하기 전에 Normalize를 왜 해줘야 할까? (1) | 2019.05.17 |