박가방

1. 모델링 간단 요약(선형 회귀) 본문

데이터 마이닝/딥러닝

1. 모델링 간단 요약(선형 회귀)

박가방 2023. 3. 22. 10:34

서울 시 따릉이 데이터 → **시계열 데이터 **

  • DateTime : year-month-day hh:mi:ss
  • Count : 시간대별 수요량
  • Temperature : 온도(섭씨)
  • Humidity : 습도(%)
  • WindSpeed : 풍속(m/s)
  • Rainfall - mm
  • Snowfall - cm
  • Seasons - Winter, Spring, Summer, Autumn
  • Holiday - Holiday / No holiday
  • FuncDay - Yes / No

1. 환경 설정

 1.1 라이브러리

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.model_selection import train_test_split
from sklearn.metrics import *
from sklearn.preprocessing import MinMaxScaler

from keras.models import Sequential
from keras.layers import Dense
from keras.backend import clear_session
from keras.optimizers import Adam

 

 1.2 학습곡선 함수

# 학습곡선 함수
def dl_history_plot(history):
    plt.figure(figsize=(10,6))
    plt.plot(history['loss'], label='train_err', marker = '.')
    plt.plot(history['val_loss'], label='val_err', marker = '.')

    plt.ylabel('Loss')
    plt.xlabel('Epoch')
    plt.legend()
    plt.grid()
    plt.show()

 

 1.3 파일 불러오기

path = 'https://raw.githubusercontent.com---------교육용-----.csv'
data = pd.read_csv(path)

 

 1.4 DateTime열을 판다스형으로 변환 & 불필요한 열 제거

data['DateTime'] = pd.to_datetime(data['DateTime'])
data.drop(['Visibility','Solar'], axis = 1, inplace = True)

 

 1.5 14일치의 수요량 확인

temp = data[:24*14]
plt.figure(figsize = (20,8))
plt.plot('DateTime', 'Count', data = temp)
plt.grid()
plt.show()

 

2. 전처리

 ① 결측치 조회

data.isna().sum()

 

 ② (예외) 의도적으로 y 만들어서 예측 - 실제 예측할 수 있는 미래 데이터가 없으므로 따로 y를 만들자.

# 2칸을 앞당겼기 때문에 하위 2행의 y값에 NaN이 표시
data['y'] = data['Count'].shift(-2)
data.tail()

# 하위 2행 제외하여 재 할당
data = data.iloc[:-2]

 

 ③ 데이터 정리

target = 'y'
x = data.drop(target, axis = 1)
y = data.loc[:, target]

# 날짜 데이터 제거
x.drop('DateTime', axis = 1, inplace = True)
x.head()

 

 ④ 가변수화

cat_cols = ['Seasons','Holiday','FuncDay']
x = pd.get_dummies(x, columns = cat_cols, drop_first = True)

 

  데이터 분할

   -> 시계열 데이터이므로 시간의 흐름에 맞게 분할 해야함

  * 뒤에서 30일 : validaiton
  * 나머지 : train
  * 30일 : 시간단위 데이터이므로 24 * 30
* train_test_split : shuffle(뒤섞기) 옵션을 False로 하면 저장된 순서대로 자름.
i = 30 * 24
x_train, x_val, y_train, y_val = train_test_split(x, y, test_size = i, shuffle = False)

 - 이에 대한 그래프

plt.figure(figsize = (20,8))
plt.plot(y_val)
plt.grid()
plt.show()

y_val에 대한 그래프로, X축은 인덱스 번호(8038~8757), Y축은 열 'Y'의 값

 -> 이를보면 test_size와 shuffle의 관계를 알 수 있다. y_train은 당연히 0부터 8037까지

즉, 여기서 아래 식과 train_split~ 식은 같다

# 30일 기준으로 분할
i = 30 * 24

x_train, x_val = x[:-i], x[-i:]
y_train, y_val = y[:-i], y[-i:]

 

 ⑥ 스케일링 : DL에서 필수

scaler = MinMaxScaler()
x_train = scaler.fit_transform(x_train)
x_val = scaler.transform(x_val)

 

3.  모델링

 ① features 입력

# 모든 X 변수의 개수
# num of columns, 피쳐의 개수를 뽑아서 담아라. 18개
#  1차원은 데이터만 있지 방향은 없습니다. -> (3, )  (개수, )

nfeatures = x_train.shape[1]
nfeatures

-> 여기서, x_train의 모든 변수(열) 개수를 가져왔는데,

   만약 다중공선성을 위반하거나 & 영향도가 미미하여 제외시킬 변수가 있다면 여기서 바꾸는게 아니라,

    x_train을 다시 그에 맞게 전처리 후 모델링을 시작해줘야한다. 

 

 ② 구조 설계

  Node 4 - 2 - 1 - y^  : 일반적인 레이어 패턴

  - Node 수 감소

    4 -> 2 : 예측 값의 오차를 최소화, 중요한 정보로 묶는 것

  - Node 수 증가

    3 -> 5 : 입력된 3개의 정보로 더 많은 5개의 정보로 확장 

# 메모리 정리 - 꼭 써줘야하는 건 아니지만, 써주면 좋다.
clear_session()

# Sequential 타입 모델 선언
# Sequential의 뜻은 순차적, 연속적이라는 뜻
# 이것은 MLP(MultiLayer Perceptron) 레이어가 순차적으로 쌓여가는 것을 의미.

# Dense
# Perceptron 설게를 위해 -> 문제를 어떻게 학습할래?라는 알고리즘 설계.
# Sequential 타입 모델 선언(입력은 리스트로!)
model1 = Sequential([Dense(8, input_shape = (nfeatures,), activation = 'relu'),
                    Dense(4, activation = 'relu'),
                    Dense(1)]) #  dense(1)은 자기가 알아서 연결시켜 줌.

# input_shape에 들어갈 데이터는 -> 1차원 데이터(nfeatures, )

# 모델요약
model1.summary()

 

 ③ 컴파일 

  고급언어 -> 기계언어

  - Optimizer : 'Adam' - 가중치를 조절(Learning_rate : 보폭 크기, 증가, 감소)하면서 오차를 최소화 시켜라.

  - Loss : 'MSE' - 회귀  , 'Binary_crossentrophy' - 분류 

# 컴파일
model1.compile(optimizer=Adam(learning_rate=0.01), loss='mse')

 

 ④ 학습

  - fit(xtrain,ytrain, epochs = 10 : 10번 반복 학습, validation_split = 0.2  : xtrain의 20 %를 검증용으로 만들어 오차 평가)

 - medv = w_1 * istat + w_0

 - 몇번 가중치(w)를 조절해서 모델('medv')을 찾아갈 것이냐( ep=5 -> 5번, ep=30 -> 30번),

 - 가중치를 파라미터라고도 부름

 

  - 이 코드만 다시돌리면 이전에 학습된 위치에서 시작하므로, 모델링 첫 단계부터 다시 실행시켜줘야 함.

 -  epochs를 같은 값으로 다시 실행해도 다른 그래프가 생성됨 -> 가중치 초기 값이 랜덤으로 지정되기 때문

#학습
#첫번째 history는 단순히 변수명
#두번째 history는 loss, val_loss에 대한 정보를 저장하는용도

history = model1.fit(x_train, y_train, epochs = 50, validation_split=0.2).history

 

 ⑤ 학습 곡선

   - 한 번의 epoch는 인공 신경망에서 전체 데이터 셋에 대해 forward pass/backward pass 과정을 거친 것을 말함.

     즉, 전체 데이터 셋에 대해 한 번 학습을 완료한 상태.

   - train_err와 달리 val_err는 값이 들쑥날쑥이므로 과적합.

dl_history_plot(history)

 

4. 검증

 ① 모델의 예측값과 실제값에 대해 MSE, MAE를 확인

pred1 = model1.predict(x_val)

# 스케일링된 데이터 원래대로 돌려놓기
# pred1 = pred1 * (y_train_max - y_train_min) + y_train_min

print(f'RMSE : {mean_squared_error(y_val, pred1, squared=False)}')
print(f'MAE  : {mean_absolute_error(y_val, pred1)}')

 

 ② 그래프로 예측값과 실제값 비교

#예측값과 실제값 비교 그래프
plt.figure(figsize = (20,8))
plt.plot(y_val.values, label = 'actual') # y_val.values ==> 넘파이 어레이가 되면서 인덱스가 0부터 시작
plt.plot(pred1, label = 'pred1')
plt.grid()
plt.legend()
plt.show()

 

 

5. 파라미터 튜닝

- 위와 동일한 모델을, Layer 갯수를 증가시키고, epochs를 늘려보았다.

 

5.1 Layer 변경

  5.1.1 기존

# 메모리 정리
clear_session()

# Sequential 타입 모델 선언
model1 = Sequential([Dense(8, input_shape = (nfeatures,), activation = 'relu'),
                    Dense(4, activation = 'relu'),
                    Dense(1)])

# 모델요약
model1.summary()

  5.1.2 변경

# 메모리 정리
clear_session()

# Sequential 타입 모델 선언
model2 = Sequential([Dense(10, input_shape = (nfeatures,), activation = 'relu'),
                    Dense(10, activation = 'relu'),
                    Dense(5, activation = 'relu'),
                    Dense(1)])

# 모델요약
model2.summary()

5.2 epochs 변경 - (일단은, learning rate 동일)

  5.2.1 기존

#학습
history = model1.fit(x_train, y_train, epochs = 50, validation_split=0.2).history

  5.2.2 변경

# 컴파일 후 학습
model2.compile(optimizer=Adam(learning_rate=0.01), loss='mse')

history = model2.fit(x_train, y_train, epochs = 200, validation_split=0.2).his

- learning rate가 동일했음에도 값의 변화가 크지 않음.

 

기존                                                                                              변경

 

5.3 결과

- 미세하게 더 좋아짐

'데이터 마이닝 > 딥러닝' 카테고리의 다른 글

3.1 softmax  (0) 2023.03.22
2. 모델링 간단 요약 - (이진 분류)  (0) 2023.03.22
1.1 활성화 함수 Sigmoid, Relu  (0) 2023.03.22
Relu  (0) 2023.03.22
AIVLE 복습 1.  (0) 2023.03.06