[zerobase_데이터 취업스쿨_스터디노트] 23. 시계열데이터

김소희·2023년 12월 21일
0

study_note

목록 보기
23/50
post-thumbnail

댕댱댕....드디어 시계열데이터 입성....

[회고]

지난 1주일간 로마여행으로 ㅠㅠ (제로베이스 전부터 예약해둔 여행이라 취소 안 됨..)

때문에 너무나 밀려버린 진도..그리고 1,2회차 EDA 테스트 모두 제출을 못해서 망..해따..ㅎ

이렇게 꼬이는 걸 너무 싫어하기 때문에 처음부터 다시 시작하고 싶어서 재수강을 듣고 싶었으나

꾹 참고 다시 일어서보기로 한다..!

하루라도 빨리 취업하고 싶은 욕구가 강하기 때문에

밤을 새서라도 따라잡아 보겠다.

현재 진도는 SQL 인데

  • 시계열분석
  • NAVER API
  • 인구 분석

이렇게 3파트를 다 들어야만 SQL 로 넘어갈 수 있다.
오늘 이 세 파트를 다 끝내보고자 한다. (불끈..)


1.시계열분석(forecast)

[출처] 제로베이스

페이스북 팀이 fp-prophet 이라는 모듈을 만들었다고 하는데,

Seasonal Time Series 에 좋을 모듈이라고 한다.

이것을 다운받아주는 과정

windows
1. visual c++ build tools 다운로드
https://visualstudio.microsoft.com/ko/downloads/

  1. 가상환경에 pandas-datareader , fbprophet 다운로드
conda install pandas-datareader
conda install -c conda-forge fbprophet
  1. 설치확인
    주피터 노트북에 코드실행시 문제없으면 다운로드가 잘 된 것.
from pandas_datareader import data
from fbprophet import Prophet
  1. 만약 잘 안 된다면
    코랩에서 실행 (아무것도 설치하지 않아도 됨)

2. def 함수

파이썬의 기초인 함수이론에 대해서 살짝 다시 복습해 본다.

  • 가장 기초적인 모양의 def 정의
  • 이름(test_def) 과 입력 인자 (a, b)를 정해준다
  • 출력(return)을 작성
# 전역변수
a = 1

def edit_a(i):
    # 지역변수
    a = i
    return a
    
edit_a(3)

답: 3
a

답: 1

여기서 왜 edit_a(3) 을 하면 3인지 a가 왜 3이 아니고 1인지를 이해 해야 한다.
지역변수의 a 는 함수 안에서만 사용이 가능하기 때문에 함수 안에서의 a 는 3이될 수 있지만 (edit_a(3) 과 같음)
바깥에서의 a 는 전역변수의 1인 출력이 된다.

  • 만약 전역변수를 함수내에서 사용하고 싶다면 global 함수를 사용하면 된다.
# 전역변수(global)
a = 1

def edit_a(i):
    # 지역변수(local)
    global a
    a = i
    
edit_a(3)

답: 아무것도 실행되지 않음
a

답: 3
$$ y = asin(2\pi ft + t_0) + b $$ 

이렇게 쓰면 수식을 쓸 수 있음.

def plotSineWave(amp, freq, endTime, sampleTime, startTime, bias):
    """
    plot sine wave
    y = a sin(2 pi f t _ t_0) + b
    """
    
    time = np.arange(startTime, endTime, sampleTime)
    result = amp * np.sin(2 * np.pi * freq * time + startTime) + bias
    
    plt.figure(figsize=(12, 6))
    plt.plot(time, result)
    plt.grid(True)
    plt.xlabel('time')
    plt.ylabel('sin')
    plt.title(str(amp) + "*sin(2*pi" + str(freq) + " *t+" + str(startTime) + ")+" + str(bias)) 
    plt.show()   
  • 인자 : 전달인자. 함수에서 받는 값중 실제로 값을 가지고 오는 input의 값

  • 매개변수 : 함수정의에서 함수안에서 사용되는 매개'변수'임.

이렇게 쓰고 매개변수(parameter) 를 지정해주지 않으면 함수 실행시 에러가 난다.

# 수정진행

def plotSineWave(**kwargs):
    """
    plot sine wave
    y = a sin(2 pi f t _ t_0) + b
    """
    endTime = kwargs.get("endTime", 1)
    sampleTime = kwargs.get("sampleTime", 0.01)
    amp = kwargs.get("amp", 1)
    freq = kwargs.get("freq", 1)
    startTime =  kwargs.get("startTime", 0)
    bias = kwargs.get("bias", 0)
    figsize = kwargs.get("figsize", (12, 6))
    
    
    time = np.arange(startTime, endTime, sampleTime)
    result = amp * np.sin(2 * np.pi * freq * time + startTime) + bias
    
    plt.figure(figsize=(12, 6))
    plt.plot(time, result)
    plt.grid(True)
    plt.xlabel('time')
    plt.ylabel('sin')
    plt.title(str(amp) + "*sin(2*pi" + str(freq) + " *t+" + str(startTime) + ")+" + str(bias)) 
    plt.show()   

그러나 미리 변수의 기본값을 설정해주면 매개변수를 따로 설정해 주지 않아도 기본값으로 실행이 된다.
(독스트링으로 매개변수를 미리 확인 가능)

plotSineWave(amp=2, freq=0.5, endTime=10) # 원하는 값으로 출력


3. 내가 만든 함수를 import 해보자

%%writefile ./drawSinWave.py

import numpy as np
import matplotlib.pyplot as plt


def plotSinWave(**kwargs):
    """
    plot sine wave
    y = a sin(2 pi f t _ t_0) + b
    """
    endTime = kwargs.get("endTime", 1)
    sampleTime = kwargs.get("sampleTime", 0.01)
    amp = kwargs.get("amp", 1)
    freq = kwargs.get("freq", 1)
    startTime =  kwargs.get("startTime", 0)
    bias = kwargs.get("bias", 0)
    figsize = kwargs.get("figsize", (12, 6))
    
    
    time = np.arange(startTime, endTime, sampleTime)
    result = amp * np.sin(2 * np.pi * freq * time + startTime) + bias
    
    plt.figure(figsize=(12, 6))
    plt.plot(time, result)
    plt.grid(True)
    plt.xlabel('time')
    plt.ylabel('sin')
    plt.title(str(amp) + "*sin(2*pi" + str(freq) + " *t+" + str(startTime) + ")+" + str(bias)) 
    plt.show()  
    
     

실행시켜주면 drawSinWave.py 라고하는 파일이 하나 생성이 된다. 아래에 코드를 담고 있는!

이 파일을 cmd 창으로 실행시켜주면 아무것도 실행이 되지 않는다.

왜냐하면 이 코드상에는 코드를 실행해 주는 코드가 없기 때문!

if __name__ == "__main__":
    print("hello world")
    print("this is test graph!!")
    plotSineWave(amp=1, endTime=2)

이 부분을 추가해 준 다음, 실행해 보자.

문제 없이 그래프가 잘 뜬다.

  • 내가 만든 코드를 import 하는 과정
    문제없이 잘 실행이 된다.
import drawSineWave as ds

ds.plotSinWave()

그래프 한글 설정 해보기

%%writefile ./set_matplotlib_hangul.py

import platform
import matplotlib.pyplot as plt 
from matplotlib import font_manager, rc

path = "c:/Windows/Fonts/malgun.ttf"

if platform.system() == "Darwin":
    print("Hangul OK in your MAC!")
    rc("font", family = "Arial Unicode MS")
elif platform.system() == "Windows":
    font_name = font_manager.FontProperties(fname=path).get_name()
    print("Hangul OK in your Windows!")
    rc("font", family= font_name)
else:
    print("Unknown system...sorry!")
    
plt.rcParams["axes.unicode_minus"] = False

이 코드를 import 해봅니다.

import set_matplotlib_hangul as sm

plt.title("한글")

한글을 잘 대응하네요!

4. Fbprophet 기초

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
time = np.linspace(0,1, 365*2)
result = np.sin(2*np.pi*12*time)

ds = pd.date_range("2018-01-01", periods=365*2, freq="D") # freq="D" : 일단위로
df = pd.DataFrame({"ds": ds, "y": result})
df.head()

데이터 프레임을 하나 만들었습니다.
다음 df의 y컬럼으로 plot 을 하나 그려보겠습니다.

df['y'].plot(figsize=(10,6));

(!)중요한 정보가 있습니다.
fbprophet의 이름이 prophet으로 바뀌었습니다!
conda install -c conda-forge prophet
위 명령어로 설치해 주시고, import하실 때에도 from prophet import Prophet으로 블러와 주세요.

from prophet import Prophet

m = Prophet(yearly_seasonality=True, daily_seasonality=True) # 연간, 일간 계절성을 고려
m.fit(df); # 학습

지금 연간,일간 계절성을 고려하여서 예측하는 모델을 만드는 과정입니다!

future = m.make_future_dataframe(periods=30) # 30일 예측
forecast = m.predict(future)
m.plot(forecast);

점이 박혀있지 않은 부분이 모델이 예측한 결과입니다.

time = np.linspace(0,1, 365*2)
result = np.sin(2*np.pi*12*time) + time

ds = pd.date_range("2018-01-01", periods=365*2, freq="D") # freq="D" : 일단위로
df = pd.DataFrame({"ds": ds, "y": result})

df['y'].plot(figsize=(10,6))

여기서 시간축 (bias) 값 까지 변수로 고려해 준다면,

이것을 예측할 겁니다.

m = Prophet(yearly_seasonality=True, daily_seasonality=True)
m.fit(df)

future = m.make_future_dataframe(periods=30)
forecast = m.predict(future)

학습을 시켜준 다음,

m.plot(forecast);

예측한 값을 시각화 하면!

이번에도 잘 예측한 모습을 볼 수 있네요!

마지막으로 한 번 더 해볼게요

time = np.linspace(0,1, 365*2)
result = np.sin(2*np.pi*12*time) + time + np.random.randn(365*2)/10

ds = pd.date_range("2018-01-01", periods=365*2, freq="D") # freq="D" : 일단위로
df = pd.DataFrame({"ds": ds, "y": result})

df['y'].plot(figsize=(10,6))

랜덤한 값을 결과값에 더 추가해 주었더니,

이것을 예측해 볼게요!

m = Prophet(yearly_seasonality=True, daily_seasonality=True)
m.fit(df)

future = m.make_future_dataframe(periods=30)
forecast = m.predict(future)
#학습
m.plot(forecast);   
#결과

불규칙한 결과물이어도 꽤 잘 예측해 내는 모습을 볼 수 있습니다..!
간단한 모델이어서 그런가
신기하긴 하네요 ㅎㅎ!

profile
AI 개발자로 가는 길 두렵지 않아요

0개의 댓글