티스토리 뷰

반응형

비즈니스 kpi(성과지표)에 얼마나 영향을 미쳤는가

매출, 수익, 비용, 재고

100배가 빨라진 것은 얼마나 비즈니스 관점에 영향에 미쳤는가?

 

high variance = 각 예측값의 편차와 변동성이 높다.

bias = 목표 지점으로부터의 거리가 멀다. 

 

적절한 feature을 추가하는 것은 bias를 줄이는 것 -mse, mae가 얼마나 줄었느냐

행(데이터 건수)를 추가하는 것은 편차 줄이기(variance 줄이기)

 

흔히 bias만 이야기 하지만, variance도 굉장히 중요하다.

 

학습 : 에포크 = 10~50에서 시작

lr = 0.1~0.001에서 시작

 

funcional api는 다중 입력을 받아서 결과를 내겠다 할 때 사용하면 좋다.

 

다중 출력

만약 다중출력을 하려면 마지막에 loss function을 각각 지정을 해야 한다.

y도 2개, 예측결과도 2개를 줘야 한다.

target1 = 'Sales'
target2 = 'US'

data[target2] = np.where(data[target2] == 'Yes',1,0)

 

x_train = train.drop([target1, target2], axis=1)
y_train1 = train.loc[:, target1]
y_train2 = train.loc[:, target2]

x_val = val.drop([target1, target2], axis=1)
y_val1 = val.loc[:, target1]
y_val2 = val.loc[:, target2]

 

스케일링에 x_train만 fit 하는 이유는 train 데어터의 기준으로 바꿔줘야 하기 때문이다.

 

model.compile(optimizer= Adam(0.01),
            #   loss={'output1': 'mse', 'output2': 'binary_crossentropy'}) # 출력층 이름을 기반으로 딕셔너리로 지정
              loss= ['mse', 'binary_crossentropy']) # 출력층 순서대로 리스트로 지정

 

추천하지 않는 이유는, loss를 줄이는 모델이 2개가 들어가기 때문에, loss를 줄이는 게 편향될 수 있기 때문이다.

 

 

시계열 데이터

Sequential Data 중에서도 시간의 등 간격을 가지고 있는 것을 시계열 데이터라고 한다.

voice, stock data, sentence 가 대표적

시계열 데이터는 시간의 흐름에 따른 패턴을 분석한다.

 

모델링 - 통계적 시계열 모델링

x는 관심이 없고, y만 쳐다보면서 y값의 흐름만을 이용해서 추출하며 예측한다.

y의 패턴 : Trend(추세), Seasonality(계절성) 등을 예측

 

모델 구조 예 : yt = w1yt-1 + w2yt-2 + w3yt-3+w0

패턴이 충분히 도출된 모델의 잔차는 stationary 해야 한다.

 

모델링 - ML 기반 시계열 모델링

특정 시점 데이터들(1차원)과 예측 대상시점(yt+1)과의 관계로부터 패턴을 추출하여 예측한다.

  • 시간의 흐름을 x변수로 도출하는 것이 중요.
  • x1 피처가 전날 주가,x2 피처가 전전날 주가,x3 = 평균 변동액
  • 이런 걸로 피처 엔지니어링을 진행해서 똑같이 진행한다.
  • yt+1을 target으로 잡는다.

 

딥러닝 기반 시계열 모델링

시간흐름 구간(timestep) 데이터들(2차원)과 

예측 대상시점(yt+1)과의 관계로부터 패턴 추출

  • 행과 열을 모두 다 고려한 게 timestep.
  • 구간을 정해줘서 그 각각의 흐름으로 다음 날을 예측하는 방법이다.
  • 예를 들어서 7행*7컬럼을 timestep으로 yt+1을 구하는 것이다.
  • 그래서 분석 단위를 2차원으로 만드는 전처리가 필요하다. -> 데이터 셋이 3차원이어야 한다.
  • 스칼라 -> 벡터 -> 행렬 -> 텐서(3차원 이상)

 

중요한 건 어떤 간격(timestep)으로 하나의 흐름을 묶어줄 것인가이다. 그래서 중요한 하이퍼 파라미터가 된다.

 

시계열 데이터 모델링의 절차

1. y 시각화(눈으로 보면서 패턴을 찾는다),

  • 정상성을 검토(통계적 모델링의 전제 조건 = y가 정상 데이터여야 한다)
  • white noise와 비슷해야 한다.->시간에 대한 패턴이 존재하지 않는 noise
  • 잔차에 아무런 패턴이 없었으면 좋겠다는 것이다.

2. 모델 생성

3. Train_err(잔차) 분석

4. 검증(예측)

5. 검증(평가) 

 

기술적 평가 - 잔차 분석(ACF, PACF), 검정(정상성 검정, 정규성 검정)

ML metric - AIC, MAE,

 

잔차 분석

잔차(Residuals) = 실제 데이터 - 예측값

시계열 모델 y=f(x) +e

모델이 잘 만들어졌을 때, 잔차 e는 white noise에 가까워야 한다.

e가 white noise에 가까지 않다면 f(x)는 아직 y의 패턴을 제대로 반영하지 않은 것이다.

 

잔차 분석

  • 시각화 : ACF, PACF

검정

  • 정상성 검정(ADF Test, KPSS Test)
  • 정규성 검정(Shapiro-wilk Test)
  • 자기상관 검정(Ljung-Box Test)
  • 등분산성 거정(G-Q Test)

 

딥러닝 기반 시계열 모델링(RNN)

일 단위 주가 데이터

다음날 주가를 예측하는데 영향을 주는 요인은?

전날 주가

이동평균

기준금리

신제품발표

외국인 거래량

세력

 

행과 열을 만들 때 어떻게 데이터를 만들어야 하는가?

현실적인 이야기 : 데이터를 어떻게, 어떤 값으로 만들 것인가?

신제품 발표는 어떻게 수치화?

반응을 어떻게 수치화 할 것인가?

세력은?

 

4월말 미프 -> 문제 정의부터 문제가 정말 해결되었는가를 전부 배운다.

 

RNN(Recurrent Neural Networks)

input 1을 순차적으로 넣어서, 01이라는 output을 내놓는다.

그 다음에는 input 2를 넣어서, 02이라는 output을 내놓는다.

 

오래된 값들은 영향이 줄어들고, 최근 값들은 영향력이 늘어간다.

 

최근4일간의 데이터를 기반으로 다음날 주가 예측

1일 데이터로 h0를 만들어낸다. 그리고 A를 2일차로 전달

2일 데이터로 h1을 만들어낸다.h1을 만들어낼 때는 h0가 영향을 준다.

3일 데이터로 h2를 만들어낸다. h2를 만들어낼 때는 h0,h1가 영향을 준다. 이때 h0는 적게 영향을 받는다.

4일 데이터로 h3를 만들어낸다. h3를 만들어낼 떄는 h0,h1,h2가 영향을 준다. 이때 h0,h1은 적게 영향을 받는다.

 

순차적으로 적용하면서 중간 결과물을 만들어내는데, h0,h1,h2,h3 가 각각 스칼라 값이다.

한마디로 노드 하나에서 나오는 값이 1차원 데이터(h0,h1,h2,h3)가 된다. timestep 만큼의 데이터.

 

과거의 정보를 현재에 반영해 학습하도록 설계되었다.

 

input을 xt로 넣는다면, ht-1도 영향을 줘서, tanh를 활성화 함수로 쓴다.

그러면 ht와 ot(output vector)가 나온다.

 

이때 xt와 ht-1의 가중치가 얼마나 조절되는지가 rnn이다.

 

3차원 데이터셋 만들기

2차원 데이터셋 x를 timesteps 단위로 잘라서 사용한다.

한 칸씩 밀면서, sliding window로 만든다.

# 시계열 데이터 전처리 2차원 --> 3차원으로 변환
def temporalize(x, y, timesteps):
    nfeature = x.shape[1]
    output_x = []
    output_y = []
    for i in range(len(x) - timesteps + 1):
        t = []
        for j in range(timesteps):
            t.append(x[[(i + j)], :])
        output_x.append(t)
        output_y.append(y[i + timesteps - 1])
    return np.array(output_x).reshape(-1,timesteps, nfeature), np.array(output_y)

 

y를 만드려면 다음 주 기온을 -1 shift 해야 한다.

data['y'] = data['AvgTemp'].shift(-1)
data.dropna(axis = 0, inplace = True)
data.head()

 

시계열 모델링을 할 떄 주의사항

사전 확인 오류를 범하지 않아야 한다.

 

다음 날 주가를 예측하고 싶은데, 다음 날 거래량을 가지고 예측하면 안된다.

데이터 누수가 일어난다.

 

scaler = MinMaxScaler()
x = scaler.fit_transform(x)

데이터가 많아서 통으로 스케일링

 

3차원 구조 만들기

x2, y2 = temporalize(x, y, 4)
x2.shape, y2.shape
>((261, 4, 1), (261,))

4행 1열 데이터가 261개 있다.

 

4행 1열 데이터 자체가 단위데이터가 된다.

 

input_shape는 예측 단위 data의 shape이다.

 

따라서 이제 해당 rnn이 은닉층에 들어가려면 , input_shape=(4,1)이 들어가야 한다.

 

timesteps = x_train.shape[1]
nfeatures = x_train.shape[2]

clear_session()

model = Sequential()
model.add(SimpleRNN(8,input_shape=(timesteps,nfeatures),return_sequences=False) )
model.add(Dense(1))

model.summary()

 

SimpleRNN이 히든 레이어가 된다.

activation function은 default로 지정되어 있다.(tanh)

 

시계열 모델링을 한 후에는 시간에 대해 실제 데이터랑 예측 데이터를 그려볼 필요가 있다.

 

스케일링

x 스케일링은 필수

y값이 크다면 최적화를 위해 스케일링이 필요하지만, 모델 평가 시에는 원래 값으로 복원한다.

 

쪼개도 test 데이터에 영향을 주지 않는다면 스케일링을 전체로 할 수도 있다.

3차원 데이터셋으로 나누는데, 2차원 구조만 스케일링이 가능해서 먼저 스케일링 한다.

 

데이터가 많다고 생각하는 일반적인 기준

train test split에서도 비율이 중요한 게 아니라, train 데이터의 건수가 중요하다.

x축은 train의 사이즈, y축은 acc라고 하면 데이터만 늘려가면서 학습.

그러면 어느 지점에서 수평선을 이루는 지점이 있다. (elbow method)

 

그게 바로 적절한 train 데이터의 지점이다.

 

SimpleRNN에서 만약 out의 레이어가 8이면, rnn을 통과한 결과는 어떻게 될까?

timestemp은 4이면서, 레이어가 8개인, 4,8이 된다.

return_sequences=False면 4,1 에서 마지막 h3만 넘어간다.

그런데 True면 (4,1) 전체가 다음으로 넘어간다.

 

False는 제일 마지막것만 넘긴다.

True는 전체를 다 넘긴다.

 

그럼 False로 넘기는 건 시계열 데이터일까 아닐까?

시계열 데이터는 시간의 흐름이 있어야 하므로, 아니다.

False로 넘기는 건 특정 시점의 데이터만 넘어간다.

 

그래서, RNN을 히든 레이어로 구성하려면 반드시 return_sequences를 True로 해줘야 한다.

model = Sequential()
model.add(SimpleRNN(8,input_shape=(timesteps,nfeatures),return_sequences=True) )
model.add(SimpleRNN(4,return_sequences=False) )
model.add(Dense(1))

 

만약 h3만 쓰는 게 아니라 전체 값을 쓰고 싶다면, Flatten으로 펼친 후 Dense Layer로 연결할 수도 있다.

 

model.add(SimpleRNN(5,return_sequences=False) )

1*5가 다음 dense로 넘어간다.

model.add(SimpleRNN(5,return_sequences=True) )

4*5(2차원 데이터)가 다음 dense로 넘어간다.

 

만약 True로 해서 다 넘기면, flatten() 하면 1*32가 된다.

그렇게 Dense로 받으면 input이 32인 Dense layer가 된다.

 

실제는 LSTM을 더 많이 쓴다.

 

하이퍼볼릭 탄젠트 함수

기울기 소실 문제에서 조금 더 자유롭다.

 

tanh(x) =1-e^(-x) / 1+e^(-x)

rnn 계열은 그래서 전부 

그럼에도 불구하고 rnn은 장기 기억을 하지 못한다. 영향력이 줄어들기 때문.

그래서 나온 게 LSTM 구조.

 

LSTM

RNN, LSTM(일반적), GRU

한국인이 만든 GRU -> LSTM보다 조금 더 개선

rnn을 lstm으로만 바꿔주면 된다.

clear_session()

model = Sequential()
model.add(LSTM(16,input_shape=(timesteps,nfeatures),return_sequences = True) )
model.add(LSTM(8,return_sequences = True ))
model.add(Flatten())
model.add(Dense(8,activation='relu'))
model.add(Dense(1))

model.summary()

 

time step 간에 두 종류의 상태 값 업데이트 관리

Hidden State 업데이트

Cell State 업데이트 : 긴 시퀀스 동안 정보를 보존하기 위한 상태 값이 추가된다.

장기기억을 위한 상태 값(Cell State) 값이 있다.

 

Forget Gate, Input Gate

 

파레토 법칙

전체 매출의 80%가 20%의 상품에서 나온다.

 

장기 기억을 잘 유지하기 위한 전략 = 유지하고 싶은 기억만 기억한다.

여기서는 값이 중요한 값만 기억한다.

1. Cell State 업데이트 방법

불필요한 과거를 잊고(Forget Gate)

현재 정보 중 중요한 것은 기억한다(Input Gate)

그렇게 Input Gate와 Forget Gate를 결합해서 장기 기억 메모리에 넣는다.

 

2. Hidden State 업데이트 방법

업데이트된 Cell State와 input, 이전 셀의 hidden state로

새 hidden state 값을 생성해서 넘긴다.

 

lstm으로 훈련하면 loss가 유지되다가 갑자기 어느 순간 loss가 내려간다.

epoch를 늘려줘야 할 필요성이 있다.

 

lstm의 문제점

최적화 해야 하는 파라미터가 앖아서, training cost가 높다는 단점이 있다.

그래서 2014년에 한국 박사님이 GRU를 만들었다.

 

성능이 비슷한데 학습 속도가 조금 더 빠르다.

 

 

따릉이 대여 데이터에서,

출근 시간은 좁고, 퇴근 시간은 넓다.

y가 너무 크면 오래 걸리므로 스케일링

단, 이후에는 y를 복원해야 한다.

# y는 1차원이므로 수동으로.
y_max, y_min = y.max(), y.min()
y_s = (y - y_min) / (y_max - y_min)
x_train, x_val, y_train, y_val = train_test_split(x2, y2, test_size= 24*14, shuffle = False)

24시간 14일치를 test size로 쓴다.

 

 

반응형