TIL/딥러닝

12/19 월 시계열 예측 ,비즈니스 데이터 분석

monawa 2022. 12. 20.
728x90

107 시계열 RNN 실습

Time series forecasting | TensorFlow Core

 

시계열 예측  |  TensorFlow Core

KerasCV, 온디바이스 ML 등을 사용한 확산 모델을 다루는 WiML 심포지엄의 세션을 확인하세요. 주문형 시청 시계열 예측 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류

www.tensorflow.org

기존에는 데이터를 나눌 때 섞어서 나누었습니다.

그런데 시계열 데이터에서는 섞어서 나누지 않고 순서를 고려해서 나누게 됩니다. [시계열 데이터에서도 순서 중요]

자연어 텍스트를 시퀀스 인코딩 했던 것처럼 언어도 맥락이 있기 때문에 섞으면 원래 의미를 잃어버릴 수 있습니다. 시계열 데이터에서도 순서가 중요합니다.

예를 들어 지난 일년 간의 데이터를 통해 앞으로 일주일 간의 데이터를 예측한다고 했을 때도

윈도우를 밀어서 앞으로 예측할 일주일 데이터도 일주일치를 한번에 예측하게 하지 않고 그 전날까지의 데이터를 가지고 와서 다음날을 예측하게 합니다.

 

시계열 데이터로 예측해 볼 수 있는게 무엇이 있을까요?

 주가, 부동산 가격, 판매량, 재고량, 매출액, 신선식품 업체의 유통량, 농수산물가격, 동시접속자수, 서비스이용 고객수, 식물의 성장예측, 트래픽량 등 순서상관관계가 있는 데이터

그중에 주식데이터를 실습해볼 것입니다


회귀와 시계열의 차이점?

데이터의 순서 고려 여부로써 데이터를 예측하는데 있어서 과정 차이

bike-sharing-demand 를 실습했을 때 날짜, 시간 데이터가 있었습니다. 그런데 그 데이터로 시계열 방법을 사용하기 보다는 회귀 방법을 사용했습니다. 시계열을 사용해서 예측해 볼 수도 있기는 합니다.

 

왜 시계열 방법을 사용하지 않고 회귀 방법을 사용했었을까요?

시간대별로 binning 이 되어있기는 한데, 지금 주가 데이터도 일자별로 binning 이 되어있는 상태입니다.

bike-sharing-demand 데이터를 나누는 기준이 1~19일까지가 train, 나머지가 test 로 되어있었습니다.

여러 변수를 고려해서 수치데이터를 예측할 때 회귀 모델을 사용하기도 합니다.


실습진행순서

데이터 로드 => 데이터셋 나누기 => 정규화(Min-Max) => 윈도우 방식으로 x, y 값 만들기=> 순서를 고려해서 데이터셋 나누기 => 모델 만들고 예측하기

데이터 로드

!pip install finance-datareader 
이번에 api가 바뀌면서 기존에 했던건 안불러와 질수있다 
import FinanceDataReader as fdr

주가수집

df= fdr.DataReader("TQQQ","2020")
(주가 종목 = 한국껀 종목코드숫자, 미국주식은 종목단어, 시작연도)

문제 정답 답안 나누기

df_ohlcv = df.iloc[:,:-1]
마지막 전까지 선택 = 마지막껀 종가가 없으니까 

dfx = df_ohlcv.drop(columns = "Close")
종가를 뺴고

dfy = df_ohlcv["Close"]
테스트데이터엔 종가만 
dfx.shape , dfy.shape

 

시각화하기

dfx.plot()

 

정규화(Min-Max)

 

# MinMaxScaler
# 복원을 위해 x, y 따로 스케일링하기
# 스케일링 후 list 형태로 변환하기
from sklearn.preprocessing import MinMaxScaler

# 나중에 복원하기 편리하게 하기 위해 x, y 를 따로 스케일링 해주겠습니다.
mmsx = MinMaxScaler()
mmsy = MinMaxScaler()

# x
# y

x_mm = mmsx.fit_transform(dfx)
# fit_transform 을 할 때는 1차원 데이터는 받지 않습니다.
# y 값은 종가(Close) 컬럼의 값을 시리즈 형태로 가져왔기 때문에 2차원 형태로 변경할 필요가 있습니다.
y_mm = mmsx.fit_transform(dfy.to_frame())
x_mm.shape, y_mm

len(x_mm), len(y_mm)

이 값은 변수별로 스케일링을 해준 값으로 윈도우를 고려하지 않은 값입니다.

이전 시점의 데이터가 각 행에 들어있지 않고 해당 시점의 스냅샷만 있는 상태입니다. 그로므로 각시점을 고려하기 위해 윈도우를 고려해서 데이터를 만들 예정입니다.

지금까지 사용햇던 방법과는 조금 차이가 있습니다!

 

윈도우 방식으로 x, y 값 만들기

window_size = 10 
len(y_mm) - window_size

윈도우 사이즈를 지정

 

10일치를 뺴주게됨

그이유는 10일치 데이터로 예측을 할것이기 떄문에

 

x_mm[0:10], y_mm[10]

윈도우를 하나씩 이동하면서 데이터를 만들어 줄 예정입니다.

이전데이터를 이용해서 예측데이터를 만듬

⇒ ex 위 코드처럼0번부터 9번(10일치 종가로) 10번 데아터 예측한다

# window_size 만큼만 슬라이싱
# 10일치 데이터로 다음날 주가를 예측
# 다음 날 종가(i+windows_size)는 포함되지 않도록 X값을 만들고
# 다음 날 종가를 y로 만듦
x_data = []
y_data = []
for start in range(len(y_mm) - window_size):
    print("start:", start, "stop:", start+window_size, end=",")

0~10번으로 11번예측


회귀는 변수만 고려하나

시계열데이터는 이전 시점 데이터들까지 함께 고려하는것이 차이점이다


 

# window_size 만큼만 슬라이싱
# 10일치 데이터로 다음날 주가를 예측
# 다음 날 종가(i+windows_size)는 포함되지 않도록 X값을 만들고
# 다음 날 종가를 y로 만듦
from tqdm import trange
x_data = []
y_data = []
for start in trange(len(y_mm) - window_size):
    # 진행사항
    stop = start+window_size
    # print("start:", start, "stop:", stop, end=",")
    x_data.append(x_mm[start:stop])
    y_data.append(y_mm[stop])

len(x_data), len(y_data)

np.array(x_data).shape, np.array(y_data).shape

결과가 737 x 10

1~9일 사이의 학습데이터로 타겟값 10일로 학습을 합니다. X : 1~9일 y : 10일

왜 X 값에 10일까지 넣어주지 않을까요?

과거로 미래를 예측해야 하기떄문에

정형데이터에서 정답을 문제에 포함시키지 않는 것과 동일합니다.

 

 

train, test 나누기

# 8:2 로 나누기
split_size = int(len(x_data) * 0.8)
split_size
X_train = np.array(x_data[:split_size])
y_train = np.array(y_data[:split_size])
X_test =np.array(x_data[split_size:])
y_test = np.array(y_data[split_size:])

X_train.shape, y_train.shape,X_test.shape,y_test.shape

 

모델생성

data_size = dfx.shape[1]
data_size

4

# 모델 생성
from tensorflow.keras.layers import Bidirectional
model = Sequential()
# return_sequences=True 해당 층 아래 RNN 층을 추가할 것인지 여부에 따라 설정합니다.
model.add(LSTM(units=10, activation="tanh", return_sequences=True, 
               input_shape=X_train[0].shape))
model.add(Bidirectional(LSTM(units=10, activation="tanh")))
model.add(Dropout(0.05))
model.add(Dense(units=1))
model.summary()

모델 컴파인

model.compile(optimizer="adam", 
              loss="mse", 
              metrics=["mae", "mse"])

학습

history = model.fit(X_train, y_train, epochs=100, batch_size=30)
history

예측결과 시각화

pd.DataFrame(history.history).plot()

y_pred = model.predict(X_test)
y_pred[:5]

 

rmse = ((y_test - y_pred) ** 2).mean() ** 0.5
rmse

0.029055607240511507

pd.DataFrame({"test": y_test.flatten(), 
              "predict": y_pred.flatten()}).plot()

원래값으로 복원하여 비교

y_predict_inverse = mmsy.inverse_transform(y_pred)
y_predict = y_predict_inverse.flatten()
y_predict[:5]

위에 MinMaxScaler을 이용해서 축소시킨 데이터를 .inverse_transform을 통하여 다시 원래대로 풀어준다

y_predict.shape

# 예측 원본 정답
# 윈도우 방식으로 데이터셋을 만들어 줄 때 10번째 데이터부터 사용했기 때문입니다.
# 0~9 인덱스 데이터는 학습세트로 사용했습니다.
y_test_origin = dfy[10:][split_size:]
y_test_origin[:5]
# y_test_origin - y_predict

 

원본(origin)과 비교

# y_test_inverse
# 복원하는 방법도 있지만 정답값은 원래 데이터프레임에서 추출한 값을 사용하면 날짜 정보가 있기 때문에
# 데이터프레임에서 추출했던 값을 사용하겠습니다.
mmsy.inverse_transform(y_test).flatten()[:5]
# rmse 
((y_test_origin - y_predict) ** 2).mean() ** 0.5
y_test_df = y_test_origin.to_frame(name="test")
y_test_df["predict"] = y_predict
y_test_df.head()

 

y_test_df.plot(figsize=(12, 4))

 

 


비즈니스 데이터 분석과 군집화(비지도학습) : 

=> JD 에서 종종 봐 왔던 비즈니스 KPI 에 대해 알아보고 해당 데이터를 통해 추천시스템까지 구현해볼 예정입니다.

오거닉은 무슨 의미일까요?

오가닉 트래픽(Organic Traffic)이란 광고나 소셜미디어, 리퍼럴 사이트와 같은 채널을 통해 사이트로 유도되는 트래픽을 제외하고 검색 엔진을 통해 곧바로 유입되거나 동일한 도메인 안에서 유입되는 트래픽을 말한다.

  1. 온라인 강의에서 처음부터 평생 수강권을 주지 않고 30일 수강권을 주고 절반 이상 수강하면 평생 수강할 수 있게 해주고 그 다음에 다른 강의를 수강할 수 있는 쿠폰을 준다?!
  2. 2022년 12월 19일 오후 3:192022년 12월 19일 오후 3:192022년 12월 19일 오후 3:19**
  3. 회사나 제품마다 측정하는 메트릭이 다 다릅니다. 절반 이상 수강했다면 다른 강의를 수강할 확률이 높아진다? 이런 것들을 데이터 분석을 통해 얻을 수 있겠죠.

AARRR(해적지표)란

  • 시장 진입 단계에 맞는 특정 지표를 기준으로 우리 서비스 상태를 가늠할 수 있는 효율적 기준
  • 수많은 데이터 중 현 시점에서 가장 핵심적인 지표에 집중할 수 있게 하며, 분석할 리소스가 충분하지 않은 스타트 기업 등에게 매력적인 프레임워크이다.

출처 : https://market.dighty.com/contents/?bmode=view&idx=7689119&t=board&src=image&kw=000495

AARRR 단계별 핵심 지표

 Acquisition : 어떻게 우리 서비스를 접하고 있는가??

  • 사용자를 획득하는 단계로 서비스 안정화를 거친 후 시장 진입을 위해 공격적인 마케팅을 할 때 집중하는 지표
  • 여러 채널을 통해 얼마나 많은 사용자가 유입되고 있는지, 신규 사용자는 얼마나 획득했는지 등을 파악
  • 적은 비용 → 높은 볼륨

Activation : 사용자가 처음 서비스를 이용할 때 긍정적인 경험을 제공하는가??

  • 서비스를 이용하기도 전에 이탈하는 비율은 얼마나 되는지
  • 서비스를 이용한 이후 engagement는 어떻게 되는지
  • Bounce Rate(반송률) : 첫 페이지에서 서비스를 종료한 비율 ,부정적 사용자 경험

Retention : 이후의 서비스 재사용률은 어떻게 되는가??

  • 사업 초기 단계에서 가장 중요한 지표 중 하나
  • 서비스의 만족도를 가장 잘 대변하는 지표
  • 서비스 만족도가 높다면 꾸준한 사용으로 높은 재사용률을 기록할 것
  • 재방문율이 낮으면 해당 서비스는 오랫동안 존속하기 힘듦 .

Referral : 사용자가 자발적 바이럴, 공유를 일으키고 있는가??

  • 서비스가 안정화되고 성장하는 단계에서 중요한 데이터
  • 서비스가 어디에 얼마나 공유되고 있으며, 그 채널로 인해 얼만큼의 사용자를 다시 확보하는지등을 파악하는 지표

Revenue : 최종 목적(매출)으로 연결되고 있는가??

  • 분명한 수익모델
  • 서비스를 이용하는 사용자의 Conversion Rate를 향상시키는 것이 목표

코호트 분석 (Cohort Analysis)이란?

시간의 흐름을 기준으로 고객 세분화를 하는 방법으로서

현 상황을 보다 정확하게 이해하여 이를 의사결정에 활용하기 위해 특정 기간에 특정 특성/경험을 공유하는 사용자 집단(코호트)' 간의 행동 패턴을 비교, 분석합니다

 

분석 전 데이터 세트의 데이터를 관련 그룹으로 나누는 행동 분석이다.

이러한 그룹 또는 집단은 일반적으로 정의된 시간범위 내에서 공통된 특성이나 경험을 공유

 

회사는 고객이 겪는 수명주기 전반에 걸쳐 패턴을 볼수있습니다
(이러한 패턴을 보고 특정 ㅈ집단에 맞게 서비스 조정 가능)

 

시간 집단

  • 특정 기간동안 제품이나 서비스에 가입한 고객
  • 고객이 회사의 제품이나 서비스를 사용하기 시작한 시점을 기준으로 고객의 행동을 분석한다.

행동 집단

  • 과거에 제품을 구매했거나 서비스에 가입한 고객
  • 가입한 제품 또는 서비스 유형에 따라 고객을 그룹화
  • 다양한 코호트 요구사항을 이해하면 비즈니스에서 특정 세그먼트에 대해 맞춤형 서비스 or 제품을 설계하는 데 도움이 된다

규모 집단

  • 회사 제품이나 서비스를 구매하는 다양한 규모의 고객
  • 획득 후 특정 기간의 지출 금액 또는 고객이 주어진 기간 동안 주문 금액의 대부분을 지출한 제품 유형을 기반으로 한다.

잔존율 분석

  • 고객이 이탈하는 방법과 이유를 이해하기 위해 사용자 메트릭을 분석화는 과정
  • 유지분석은 유지및 신규 사용자 확보율을 개선하여 수익성 있는 고객 기반을 유지방법 확보할수있다]
  • 일관된 유지 분석으로 파악 가능한 항목들
    • 고객 이탈 이유
    • 고객 이탈 가능성이 높은 때
    • 이탈이 수익에 미치는 영향
    • 유지 전략 개선법

 


RFM - 잔존율 분석(Retention rate analysis)

  • 가치있는 고객을 추출해내어 이를 기준으로 분류할 수 있는 분석 방법
  • 구매 가능성이 높은 고객을 선정하기 위한 분석 방법
  • Recency
  • 거래의 최근성
  • 고객이 얼마나 최근에 구입했는가
  • Frequency
  • 거래 빈도
  • 고객이 얼마나 빈번하게 구입하는가
  • Monetary
  • 거래 규모
  • 고객이 구입했던 총 금액은 어느 정도인가

1201 online retail data 실습 순서

EDA(리텐션) => RFM(segmentation)을 판다스로 구하고 => 군집화로 고객 세분화(segmentation)

=> 유사도를 통한 추천시스템

# 판매 상위 데이터에 Description 추가하기
# join을 사용해도 되지만, index값이 같은 값을 알아서 연결해줍니다
stock_sale["Desc"] = stock_desc
stock_sale

Description 항목을 groupby 에 사용하지 않은 이유?

Description 항목을 groupby 에 사용하면 StockCode 가 같은데도 다른 Description 이라면 함께 집계되지 않습니다. StockCode 기준으로 집계하기 위해 집계 후에 Description 을 구해주었습니다.

 

 


오답노트

rnn특징

다양한 길이의 입력 시퀀스를 처리할 수 있는 인공 신경망이다.

결과값을 출력층 방향으로도 보내면서, 다시 은닉층 노드의 다음 계산의 입력으로 보내는 특징이 있다.

텍스트 분류나 기계 번역과 같은 다양한 자연어 처리에 대표적으로 사용되는 인공 신경망이다.

 

rnn종류

SimpleRNN, LSTM,GRU


SimpleRNN용어정리

타임스텝(timesteps) : 시점의 수로 입력 시퀀스의 길이(input_length)라고도 표현

은닉상태(hidden state): 은닉층의 메모리 셀에서 나온 값이 출력층 방향 또는 다음 시점의 자신(다음 메모리 셀)에게 보내는 상태

셀(cell): RNN의 은닉층에서 활성화 함수를 통해 결과를 내보내는 역할을 하는 노드

셀 상태(cell state): input, forget, output 세 개의 게이트(gate)들을 이용하여 정보의 반영 여부를 결정 → lstm

 

SimpleRNN의 한계점으로 옳은 보기를 선택해주세요.

기울기 소실 또는 폭발 문제(Vanishing-Exploding Gradient Problem)


LSTM이란

RNN의 기울기 소실문제를 해결하기 위한 LSTM을 변형시킨 알고리즘이다.

LSTM GRUs
RNN의 기울기 소실문제를 해결하기 위한 LSTM을 변형시킨 알고리즘 LSTM을 변형시킨 알고리즘으로, Gradient Vanishing의 문제를 해결
초기의 가중치가 지속적으로 업데이트 과거의 정보를 어떻게 반영할 것인지에 따라 가중치가 결정
게이트가 3개 게이트가 2개
  pdate Gate는 과거의 상태를 반영하는 Gate
Reset Gate는 현 시점 정보와 과거 시점 정보의 반영 여부를 결정하는 Gate
메모리가 덮어씌워 질 가능성이 있으며 연산속도가 느리다 <- 단점 해결을 위해  2개의 게이트로 정보반영의 결정
메모리와 결과값 컨트롤 불가하다

 

 

GRUs (Gated Recurrent Units)에서 출력에 전달할 정보를 결정하는 두 개의 벡터는 무엇일까요?

① reset gate, ② update gate

Update Gate는 과거의 상태를 반영하는 Gate이며, Reset Gate는 현 시점 정보와 과거 시점 정보의 반영 여부를 결정

 

 


참고자료 :

멋쟁이 사자처럼 AI School 7기 수업내용

728x90

댓글