Data Analysis Study

시험 점수 예측 딥러닝 모델

Solbi Lee 2025. 7. 19. 20:01

1. 코드의 목적과 분석 

딥러닝 기초 학습을 위한 예제 

공부시간과 수면 시간이 시험 점수에 어떤 영향을 주는 지 파악하여 예측하는 신경망 모델을 구축 

역할 : 

- 신경망 구조를 통해 입력된 데이터를 학습하여 출력값 (시험 점수)을 예측 

- 실제 데이터에 정규화를 수행하고, 예측된 결과를 역변환 하여 실제 점수로 표시함 

 

2. 필수 라이브러리 설명 

* numpy 

: 배열 생성 및 수치 계산을 위한 라이브러리 

* TensoFlow / Keras 

: 딥러닝 모델 구성 및 학습을 위한 대표적 라이브러리 

( equential, Dense, Input 등을 통해 신경망 구조를 만듦 )

* Scikit-learn (sklearn.preprocessing)

: 데이터 정규화 및 스테일링 (MinMaxScaler)

3. 주요 기능 분석 

1. 데이터 정규화 : MinMaxScaler를 활용해 입력 및 출력 데이터를 0과 1 사이 값으로 변환하여 신경망 학습에 최적화

2. 모델 구축 : Sequential 모델로 입력층, 은닉층, 출력층 구성

3. 모델 컴파일 : 최적화 알고리즘(Adam)과 손실 함수(MSE)를 지정하여 모델이 학습할 방향 제시

4. 모델 학습 : 주어진 데이터를 기반으로 모델을 반복적으로 학습

5. 모델 예측 : 새로운 데이터를 입력받아 학습된 모델이 시험 점수 예측

4. 코드 해석 

# layer.py (완료)

# 1. 필요한 라이브러리 임포트
from tensorflow.keras.models import Sequential #층을 순서대로 쌓는 케라스 모델 클래스
from tensorflow.keras.layers import Input, Dense #input : 입력층 정의, Dense : 완전 연결층
from sklearn.preprocessing import MinMaxScaler # 데이터를 0~1 구간으로 선형 이동, 확대/축소하는 전처리 도구
import numpy as np # 수치 연산용 배열 (array) 및 연산 함수 제공

# 2. 데이터 준비
# 입력 : 공부시간과 수면시간, 출력 : 시험점수
X = np.array([[1, 5], [2, 4], [3, 3], [4, 2], [5, 1]])
y = np.array([50, 60, 70, 80, 90]).reshape(-1, 1) # 2차원 배열로 변환 (5,) -> (5,1)

# 3. 입력/출력 데이터 정규화 : 학습 속도 및 안정성 향상
# 서로 다른 스케일의 피처(공부시간, 수면시간, 점수)를 동일 기준으로 맞춤
X_scaler = MinMaxScaler()
y_scaler = MinMaxScaler()
# 학습 데이터를 보고 min, max 계산 -> 각 값에 (value-min) / (max-min) 적용
X_scaled = X_scaler.fit_transform(X)
y_scaled = y_scaler.fit_transform(y)

# 4. 모델 구성

# 각 층들을 순서적으로 연결하는 빈 시퀀셜 모델 생성
model = Sequential()

# 4-1. 모델에 입력층을 추가 : 입력 데이터 형태는 특성 2개
model.add(
    Input(
        shape = (2,)
    )
)

# 4-2. 모델에 은닉층을 추가
model.add(
    Dense(
        10, # 데이터 수(뉴런)
        input_dim=2, # 2차원 (Input(shape=(2,))와 중복이므로 Input만 남기고 지워도 됨)
        activation='relu' # 활성화 함수 : 0이하는 0 출력, 0초과입력은 입력값 그대로 출력, 비선형성 도입, 학습속도 빠름
    )
)

# 4-3. 모델에 출력층을 추가
model.add(
    Dense(1) # 데이터 수
)

# Q. 똑같이 Dense()로만 추가하는데, 왜 하나는 은닉층이고 하나는 출력층인지 어떻게 알 수 있을까?
# Dense 층의 역할은 추가되는 순서와 모델 설계자의 목적에 따라 결정됨.


# 5. 모델 컴파일
model.compile(
    optimizer = 'adam', # 최적화 함수 : 학습률을 자동 조정하는 확률적 경사하강법 변형
    loss = 'mse' # 손실 함수 : 회귀용 손실 함수, (실제값 - 예측값)^2의 평균 
)

# 6. 모델 학습
model.fit(
    X_scaled, # 정규화한 입력데이터
    y_scaled, # 정규화한 출력데이터
    epochs=100, # 학습 반복 횟수
    verbose=0 # 학습 상태에 대한 출력 설정 0:출력 없음, 1:진행바형태 출력, 2: epoch별 출력
)

# 7. 예측 결과 (스케일 복원 포함)
y_pred_scaled = model.predict(
    X_scaler.transform(np.array([[3, 2]])) # 공부 3시간, 수면 2시간 새 입력 (0~1로 변환)
)
y_pred = y_scaler.inverse_transform(y_pred_scaled) # 점수 예측값 (inverse로 원래 점수 범위로 복원)

print("예측 시험 점수:", y_pred[0][0])

 

Epoch 1/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 4s 2ms/step - accuracy: 0.8781 - loss: 0.4302
Epoch 2/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 3s 2ms/step - accuracy: 0.9651 - loss: 0.1215
Epoch 3/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 3s 2ms/step - accuracy: 0.9762 - loss: 0.0809
Epoch 4/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 3s 2ms/step - accuracy: 0.9837 - loss: 0.0541
Epoch 5/5
1875/1875 ━━━━━━━━━━━━━━━━━━━━ 3s 2ms/step - accuracy: 0.9882 - loss: 0.0423
313/313 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9724 - loss: 0.0860
테스트 정확도 : 0.9766
313/313 ━━━━━━━━━━━━━━━━━━━━ 0s 791us/step

# 용어 복습 
- Epoch(에폭):전체 데이터를 한 번 학습한 것 (지금은 5번 반복 학습함)
- Accuracy(정확도) : 전체 예측 중 몇 개 맞췄는 지 비율
- Loss(손실) : 예측한 값과 실제 값의 차이, 숫자가 낮을 수록 좋음!, 모델이 잘 학습했다는 의미 
- 테스트 정확도 (Test Accuracy) :  학습이 끝난 모델이 실제 "새로운 데이터"를 얼마나 잘 맞췄는지 평가

 

  • Epoch별 accuracy/loss
    • 이 코드(회귀)엔 accuracy 지표가 없으므로,
    • MNIST 분류 같은 별도 예제에서 출력된 로그로 보입니다.
  • 훈련 정확도 증가, 손실 감소
    • accuracy 0.8781→0.9882, loss 0.4302→0.0423
    • 모델이 데이터 특징을 잘 학습함
  • 테스트 평가
    • accuracy 0.9724, 별도 테스트 정확도 : 0.9766
    • 과적합 과소적합 없이 잘 일반화됨
    • 만약 과적합이면 학습 정확도는 높고, 테스트 정확도는 낮게 나타남. 지금은 별 차이가 없기 때문에 없다고 볼 수 있음.

 

주의: 회귀 모델엔 accuracy 대신 MAE, R² 등의 지표를 사용함.

 

+ ) 추가로 학습

1. 지표 적합성 

- 회귀 : loss='mse' 외에 metrics = ['mae'] 추가 

2. Train/Test 분리 

- 검증용 데이터 확보 해보기 

3. 하이퍼 파리미터 튜닝 

- 은닉층 크기, 레이어 수, 학습률 실험