[024] 함수와 시계열분석(prophet 기초) / EDA·웹 크롤링·파이썬 프로그래밍

이연희·2023년 9월 11일

Chapter
1. 함수
(1) 전역변수(global)
(2) 키워드 매개변수 (**kwargs)
(3) 내가 만든 함수 import하기
2. prophet 기초
3. 웹 유입량 데이터 분석

1. 함수

(1) 전역변수(global)

8월 강의에서 파이썬 함수 파트에서 전역변수에 대해서 배웠지만 복습하는 기분으로 한번 더 익히고 가자.

먼저 함수를 정의하는 방법은 다음과 같다.

def test_def(a,b):
	return a+b

def 명령어 뒤에 함수이름을 정의해주고, 입력 인자를 설정해주면(설정하지 않을 수도 있음), 다음에 들여쓴 실행문으로 출력 데이터를 작성하면 된다.

함수값으로는 다음과 같다.

test_def(1,2)

ouput: 3

실행문에 임의의 변수를 지정해서 출력물을 정할 수 있는데, 이때 변수를 지역변수라고 하고, 함수 밖에서 지정된 변수는 전역변수라고 한다.
만약, 이미 할당된 전역변수가 있음에도 함수로 같은 모양의 지역변수로 함수를 선언해도 지역변수는 전역변수에 영향을 끼칠 수 없다.

하지만, 만약 global 명령어를 이용한다면 지역변수는 전역변수에 영향을 끼쳐 전역변수까지 값이 다시 지정된다. 혹은, 실행문에서 전역변수를 사용할 수도 있게 되는 것이다.


.
.

(2) 키워드 매개변수(**kwargs)

임의의 함수를 하나 정의해보자. 사인 그래프를 그리는 함수이다.

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

def plotSinWave(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()

예시로 그래프를 그려보았다.

plotSinWave(2, 1, 10, 0.01, 0.5, 0)

함수 정의할 때, 많은 인자가 있어서 좀더 세심한 그래프를 그릴 수 있었지만, 차례대로 어떤 인자인지 기억하기가 힘들어서 docstring을 살펴봐야하는 불편함이 있었다.

이때 사용할 수 있는 것이 인자로 키워드 매개변수를 사용하는 것이다. 인자에 **을 붙여넣는 것인데, 실행문을 통해서 인자마다 defualt 값을 지정할 수 있다.

def plotSinWave2(**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()

이런식으로 정의한다면 인자에 값을 딱히 지정하지 않았을 때에도 기본으로 설정된 값으로 함수값을 출력할 수 있다.

plotSinWave2()

물론 인자를 설정해서 함수를 출력할 수도 있다.

plotSinWave2(amp=2, freq=0.5, endTime=10)


.
.

(3) 내가 만든 함수 import하기

내가 직접만든 함수를 import해서 편리하게 사용하는 방법에 대해 알아보자. 파이썬 파일을 만들어 그 안에 함수를 정의한 다음, 실행문구를 넣어서 import하는 것이다.

%%writefile .\drawSinWave.py
# 파일 만들기

import numpy as np
import matplotlib.pyplot as plt

def plotSinWave2(**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()
    
    
if __name__ == "__main__":
    print("Hello world~!!")
    print("This is test graph!!")
    plotSinWave2(amp=1, endTime=2)

%%writefile 명령어도 파일 저장위치와 파일명을 작성하면 코드 한 번으로 간단하게 파이썬 파일을 만들 수가 있다! 그런데 주의할 점을 코드를 맨 첫째줄에 입력해야 한다. (실수로 주석 다음에 입력했더니 에러가 발생했었다.)

이제 파일을 불러와서 함수를 입력해보자.

import drawSinWave as ds

ds.plotSinWave2()

ds.plotSinWave2(freq=5)

.
.
.
.

2. prophet 기초

먼저 시계열 분석이란 시간의 흐름으로 기록된 데이터를 통해 미래의 데이터 값을 예측하는 기법이다.
파이썬으로는 prophet패키지를 통해 예측할 수 있다.
참고로 이전에는 fbprophet이름으로 사용됐었는데, 지금은 prophet이라는 이름으로 개명돼서 사용된다.
fbprophet으로 설치를 안내하는 블로그들이 아직도 많은데, 이름만 prophet으로 바꿔서 설치하면 간단하게 설치가 된다.

페이스북 github에 들어가면 더 자세하게 바뀐 사정을 확인할 수 있다.

prophet패키지 설치를 끝내고 간단하게 몇 가지 그래프들로 라이브러리를 사용해보자.

2년 동안의 주기성을 갖는 그래프를 사인함수를 통해 그려주었다.

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("2023-01-01", periods=365*2, freq="D")
df= pd.DataFrame({"ds":ds, "y":result})

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

이제 prophet으로 30일 동안의 예측 그래프를 그려준다.

from prophet import Prophet

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

#앞으로 30일 동안의 기간 예측
future = m.make_future_dataframe(periods=30) 
forecast = m.predict(future)  

m.plot(forecast)

까만색 dot이 실측값을 나타내며 그 연장되어 그려진 포물선이 예측값이 된다.

이번에는 주기성의 변동을 많이 나타냈을 경우이다.

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

ds = pd.date_range("2023-01-01", periods=365*2, 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);

예측 경로뿐만 아니라, 심지어는 그래프의 변동되는 정도까지도 예측이 된다는 것을 볼 수 있다.

그렇다면 이제 실측 데이터를 통해 시계열 분석을 해보자.
.
.
.
.

3. 웹 유입량 데이터 분석

다음은 한 블로그(ps. 저희 교수님이십니다.)의 2016/07 - 2017/06 1년 이용자 유입량 자료이다.

우선 trend분석을 시각화 해본다.
1년동안의 유입량을 확인했기 때문에 x축을 1년으로 잡고, 경향성을 확인할 함수의 x값으로도 그 기간동안 100개를 주었다.

time = np.arange(0, len(pinwink_web))
traffic = pinwink_web["hit"].values
fx = np.linspace(0, time[-1], 1000)

이제 1차,2차,3차, 15차 경향선을 그려줄 계수와 polynomial class를 찾아준다.

fp1 = np.polyfit(time, traffic, 1)
f1 = np.poly1d(fp1)

f2p = np.polyfit(time, traffic, 2)
f2 = np.poly1d(f2p)

f3p = np.polyfit(time, traffic, 3)
f3 = np.poly1d(f3p)

f15p = np.polyfit(time, traffic, 15)
f15 = np.poly1d(f15p)

이제 trend를 확인할 그래프를 그려본다.

plt.figure(figsize=(12,4))
plt.scatter(time, traffic, s=10)
plt.plot(fx, f1(fx), lw=4, label="f1")
plt.plot(fx, f2(fx), lw=4, label="f2")
plt.plot(fx, f3(fx), lw=4, label="f3")
plt.plot(fx, f15(fx), lw=4, label="f15")

plt.grid(True, linestyle="-", color="0.75")
plt.legend()
plt.show()

이제 시계열 분석을 해보자. 그 전에 사용할 데이터프레임을 만들어 주었다.

df= pd.DataFrame({"ds":pinwink_web.index, "y":pinwink_web["hit"]})
df.reset_index(inplace=True)
df["ds"] = pd.to_datetime(df["ds"], format="%y. %m. %d.")

del df["date"]
df

이제 60일간의 예측 데이터를 만들어 그래프를 그려본다.

future = m.make_future_dataframe(periods=60)

# 예측 결과는 상한/하한의 범위를 포함해서 얻어진다
forecast = m.predict(future)

m.plot(forecast);

다음과 같이 주제에 맞는 다양한 그래프를 그릴 수도 있다.

profile
안녕하세요, 데이터 공부를 하고 있습니다.

0개의 댓글