import tensorflow as tf # 딥러닝 모델 생성을 위한 탠서플로우 라이브러리 호출
from tensorflow.keras import layers, models # 신경망 레이어와 모델 구성 도구 호출
from sklearn.model_selection import train_test_split # 데이터를 학습/테스트 및 나누기 위해 사용
from sklearn.preprocessing import StandardScaler # 입력 데이터를 정규화하기 위해 사용하는 라이브러리
from sklearn.datasets import fetch_california_housing # 회귀 분석 실습용 캘리포니아 주택 가격 데이터 가져옴
3. 사용할 캘리포니아 집 데이터 불러오기
3-1. 데이터 불러오기
data = fetch_california_housing() # 캘리포니아 데이터 가져오기 (메모리)
X = data.data # 입력 변수 가져옴
y = data.target # 예측해야 할 값
print(X)
3-2. 데이터를 학습용과 테스트용으로 나누기
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size = 0.2, random_state= 42 # 데이터 80%는 학습용으로 사용, 20%는 테스트 데이터로 분리해서 모델 성능 평가에 사용하기 위한 데이터셋 설정
)
# 데이터 정규화(스케일링)
scaler = StandardScaler() # 평균 0. 표준편차 1로 변환하기 위한 스케일러 객체 생성
X_train = scaler.fit_transform(X_train) # 학습 데이터를 기준으로 스케일을 맞추고 반환
X_test = scaler.transform(X_test) # 테스트 데이터도 같은 기준으로 변환
print(X_train)
4. 회귀 모델 생성
model = models.Sequential([ # sequential 구조로 신경망 모델을 생성
layers.Dense(64, activation='relu', input_shape=(8, )), # 첫 번째 은닉층을 만들고, 64개의 뉴런으로 입력은 8개의 특성이고, relu 활성화 함수 사용
layers.Dense(32, activation='relu'), # 두 번째 은닉층을 만들고, 32개의 뉴런으로 학습
layers.Dense(1) # 출력층은 집값처럼 연속값을 예측하기 때문에 뉴런 1개로 구성하고 활성화 함수는 사용하지 않음
])
5. 모델 설정(컴파일)
model.compile(
optimizer='adam', # Adam 옵티마이저로 가중치를 효율적으로 업데이터
loss='mse', # 회귀해서 평균제곱오차(MSE)를 손실 함수로 사용
metrics=['mae'] # 예측 오차를 직관적으로 확인하기 위해 MAAE를 추가
)
6. 모델 학습
history = model.fit(
X_train, y_train, # 학습에 사용할 입력과 출력 Label 값 넣음
epochs = 15, # 데이터를 15번 반복해서 학습하도록 설정
batch_size = 32, # 32개의 샘플씩 모델에게 제공해서 가중치를 업데이트
validation_split = 0.2 # 학습 데이터 중에서 20%는 검증 데이터로 사용해서 과적함 여부 확인
)
7. 모델 평가
loss, mae = model.evaluate(X_test, y_test) # 학습하지 않은 20% 테스트 데이터로 모델의 성능을 평가
print("Test MAE :", mae) # MAE를 출력해서 실제값과 예측값과의 평균 오차를 확인
8. 예측 수행
pred = model.predict(X_test[:5]) # 테스트 데이터 중 앞 5개를 예측
print("실제값:", y_test[:5]) # 실제 집값을 출력
print("예측값:", pred.reshape(-1)) # 모델이 예측한 집값을 출력
9. 학습 시각화(loss, mae 그래프 생성)
9-1 손실값(loss)
import matplotlib.pyplot as plt
plt.figure(figsize=(10,5)) # 가로 10, 세로 5
# 학습/검증 손실 그래프 생성
plt.subplot(1, 2, 1) # 1행 2열 중 첫 번째 그래프 사용
plt.plot(history.history['loss'], label='Train Loss') # 학습에 대한 손실값을 그래프로 표현
plt.plot(history.history['val_loss'], label='Validation Loss') # 검증에 대한 손실값을 그래프로 표현
plt.title("Loss Curve (MSE)")
plt.xlabel("Epoch") # X축은 Epoch(학습 반복 횟수)
plt.ylabel("Loss (MSE)") # Y축은 손실값(MSE)
plt.legend() # 범례 표시
9-2 mae
실제값과 예측값과의 평균 오차 확인 그래프
# 실제값 vs 예측값 비교 그래프(시각화)
# MAE : 실제값과 예측값과의 평균 오차를 의미
plt.subplot(1, 2, 2)
plt.plot(history.history['mae'], label='Train MAE') # 학습에 대한 MAE값을 그래프로 표현
plt.plot(history.history['val_mae'], label='Validation MAE') # 검증에 대한 MAE값을 그래프로 표현
plt.title("MAE Curve")
plt.xlabel("Epoch") # X축은 Epoch(학습 반복 횟수) 제목 설정
plt.ylabel("MAE") # Y축은 MAE(제목 설정)
plt.legend() # 범례 표시
plt.tight_layout() # 간격을 자동으로 보기 좋기 맞춰줌
plt.show()
9-3 실제값 vs 예측값 비교 시각화
plt.rcParams['font.family'] = 'Malgun Gothic' # 한글 폰트 지정
plt.rcParams['axes.unicode_minus'] = False # 마이너스 부호 깨짐 방지
plt.figure(figsize=(5, 5))
plt.scatter(y_test, model.predict(X_test), alpha= 0.5)
# 실제 집값(y_test)을 x축에 두고, 예측 집값을 y축에 두어 산점도로 그리기
# alpha=0.5 점의 투명도를 50%로 설정(겹치는 부분을 보기 쉽게 하기 위해)
plt.plot([0, 5], [0, 5], color='red', linestyle='--') # 예측 = 실제인 경우에 직선(대각선)을 그리기
# 모델이 정확하다면 모든 점이 이 직선 근방에 위치해야 함
plt.title("Actual vs Predicted")
plt.xlabel("Actual Value (실제 집 값)")
plt.ylabel("Predicted Value (예측 집 값)")
plt.grid(True) # 격자 추가
plt.show()