brunch

You can make anything
by writing

C.S.Lewis

by 유윤식 Apr 23. 2019

Python: m.l with Keras #8

부동산 예측의 대표예제, 'BOSTON_HOUSING'

분류의 문제에서 AI는 눈부신(?) 성과를 보였다.


당신의 얼굴을 보고 누구인지 판단하기까지

1초 안으로 90% 이상의 정확도로 정답을 도출한다.


하지만!

회귀라면 좀 다르다.


정확한 답(Range on real number)을 찾는 것은

무한한 우주에서 정확한 별의 위치, 크기, 모양을 찾는 것과 같다.

과장이다.

그러나 사실과도 가깝다.


우리는 산수를 배우면서,

어림잡다. 라는 용어를 접했다.

지금이 하려는 회귀도 어느정도 이와 같다.


근거가 어느정도 있겠지만,

결국 회귀를 통한 머신러닝은 어림잡기와 비슷하다.


그럼!

어서 답을 찾아보자.


보스톤 집값 예측 예제에서는 규제 관련 모델링은 제외하고 진행한다.

그래서 추가하지 않았다.

이 예제의 키는 K-Fold 방식의 학습을 통한 성능 변화 관찰이다!



from keras.datasets import boston_housing

(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()


train_data.shape


mean = train_data.mean(axis=0)

train_data -= mean

std = train_data.std(axis=0)

train_data /= std


test_data -= mean

test_data /= std


from keras import models, layers


def based_model():

  model = models.Sequential()

  model.add(layers.Dense(16, activation='relu', input_shape=(train_data.shape[1],)))

  model.add(layers.Dense(16, activation='relu'))

  model.add(layers.Dense(1))  

  model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])  

  return model


import numpy as np


k = 4

num_val_samples = len(train_data) // k

num_epochs = 100

all_scores = []

for i in range(k):

    print('처리중인 폴드 #', i)


    val_data = train_data[i * num_val_samples: (i + 1) * num_val_samples]

    val_targets = train_targets[i * num_val_samples: (i + 1) * num_val_samples]


    partial_train_data = np.concatenate(

        [train_data[:i * num_val_samples],

         train_data[(i + 1) * num_val_samples:]],

        axis=0)    

    partial_train_targets = np.concatenate(

        [train_targets[:i * num_val_samples],

         train_targets[(i + 1) * num_val_samples:]],

        axis=0)


    model = based_model()


    model.fit(partial_train_data, partial_train_targets,

              epochs=num_epochs, batch_size=1, verbose=0)


    val_mse, val_mae = model.evaluate(val_data, val_targets, verbose=0)

    all_scores.append(val_mae)


from keras import backend as K

K.clear_session()


k = 4

num_epochs = 500

all_mae_histories = []

for i in range(k):

    print('처리중인 폴드 #', i)

    # 검증 데이터 준비: k번째 분할

    val_data = train_data[i * num_val_samples: (i + 1) * num_val_samples]

    val_targets = train_targets[i * num_val_samples: (i + 1) * num_val_samples]


    # 훈련 데이터 준비: 다른 분할 전체

    partial_train_data = np.concatenate(

        [train_data[:i * num_val_samples],

         train_data[(i + 1) * num_val_samples:]],

        axis=0)

    partial_train_targets = np.concatenate(

        [train_targets[:i * num_val_samples],

         train_targets[(i + 1) * num_val_samples:]],

        axis=0)


    # 케라스 모델 구성(컴파일 포함)

    model = based_model()

    # 모델 훈련(verbose=0 이므로 훈련 과정이 출력되지 않습니다)

    history = model.fit(partial_train_data, partial_train_targets,

                        validation_data=(val_data, val_targets),

                        epochs=num_epochs, batch_size=1, verbose=0)

    #mae_history = history.history['mean_absolute_error']

    all_mae_histories.append(history)


len(all_mae_histories[0].history['mean_absolute_error'])


for i in all_mae_histories:

  print(i.history['val_mean_absolute_error'])


average_mae_history = [

    np.mean([x.history['val_mean_absolute_error'][i] for x in all_mae_histories]) for i in range(num_epochs)]



def smooth_curve(points, factor=0.9):

  smoothed_points = []

  for point in points:

    if smoothed_points:

      previous = smoothed_points[-1]

      smoothed_points.append(previous * factor + point * (1 - factor))

    else:

      smoothed_points.append(point)

  return smoothed_points


smooth_mae_history = smooth_curve(average_mae_history[10:])


import matplotlib.pyplot as plt


plt.plot(range(1, len(smooth_mae_history) + 1), smooth_mae_history)

plt.xlabel('Epochs')

plt.ylabel('Validation MAE')

plt.show()


# history.history.keys()


예제 코드라서 크게 변형은 없지만,

위에 노란색 코드를 조금 변형했다.


아무튼 지금까지 진행하면서 가장 강조되었던 부분은!

바로 과적합! Over-fitting 을 어떻게 줄일 수 있느냐인데

이건 꽤~나 어렵고,

우선은 좀 더 과적합이 일어나는 Case에 대한 관찰이 필요하다고 판단한다.


결과를 보면,


mean_absolute_error
val_mean_absolute_error



대략 80 ~ 90 사이에서 최적화가 이루어 지고,

그 이후엔 과적합을 관찰 할 수 있다.


무슨 이유에서 과적합이 발생하는가? 에 대해서는

1. 데이터가 충분하지 않거나, 더러워서

2. 모델이 너무 깊어서(or 너무 얕아서)

3. 튜닝 유무

4. 학습방식을 이해하지 못해서(?)


다음에는 이 모델의 성능을 어떻게 향상 시킬 수 있는지,

연구를 좀 해보고

다시 이어간다.


끝.

작가의 이전글 Python: m.l with Keras #7
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari