데이터분석/미니프로젝트 04. 시계열 분석

04-01-02. 웹 유입량 데이터 분석

책다니엘 2024. 4. 20. 06:51

1. 이번에는 numpy를 이용해 트렌드를 분석해보자. 먼저 아래의 필요한 라이브러리들을 import해준다.

 

** 한글 세팅을 해주는 모듈(set_matplotlib_hangul)을 미리 만들어두었다. 아래 링크에 그 과정이 있다.

https://bookdaniel.tistory.com/93

 

# Python 함수의 기초(docstring 만들기, **kwargs 사용, import하기)

1. 아래는 가장 기초적인 def(함수)의 정의이다. 이름(test_def)와 입력 인자(a, b)를 정해 주고, 출력(return)을 작성하는 모양이다. def test_def(a,b): return a+b print(test_def(2,3)) # 5 2. 함수 내의 어떤 변수를

bookdaniel.tistory.com

 

2. 웹 유입량 데이터는 강의에서 제공해 준 것을 그대로 사용했다. 아주 옛날 자료이다!

pinkwink_web = pd.read_csv(
    '../data/05_PinkWink_Web_Traffic.csv',
    encoding = 'utf-8',
    thousands=',', 
    names=['date', 'hit'],
    index_col=0,
)

pinkwink_web = pinkwink_web[pinkwink_web['hit'].notnull()]
pinkwink_web.head()

 

3. 위처럼 불러온 DataFrame을 바탕으로 전체 데이터를 한 번 표시해보았다.

 

4. 위의 데이터를 활용하기 위해 시계열을 정하고, 참값과 예측값 사이의 평균제곱근편차를 구해 보자. 이를 통해 오차가 가장 적은 함수를 찾아 본다.

# 데이터의 전체 길이만큼 데이터의 범위를 정한다
time = np.arange(0, len(pinkwink_web))
traffic = pinkwink_web['hit'].values

# fx는 0부터 time의 마지막까지(-1) 1000등분하는 함수
fx = np.linspace(0, time[-1], 1000)
# f는 함, y(참), x(예측값) 사이의 RMSE(평균제곱근편차)를 구한다
def error(f, x, y):
    return np.sqrt(np.mean((f(x)-y)**2))

 

** 함수는 아래와 같은 형식으로 만들어진다

f1p = np.polyfit(time, traffic, 1) # 1차함수
f1 = np.poly1d(f1p) # 

f2p = np.polyfit(time, traffic, 2) # 2차함수
f2 = np.poly1d(f2p)

f3p = np.polyfit(time, traffic, 3) # 3차함수
f3 = np.poly1d(f3p)

f15p = np.polyfit(time, traffic, 15) # 15차함수
f15 = np.poly1d(f15p)

 

1, 2, 3차함수까지는 에러의 큰 차이가 없으나, 15차함수부터는 오차가 확 줄어든다. 그러면 디자이너는 두 가지 선택을 할 수 있다.

  • 가장 표현이 쉬운 1차함수로 그리거나
  • 그림은 복잡하지만 오차가 가장 적은 15차함수로 그리거나

디자이너의 상황과 계획에 따라 적절한 방향성을 선택하면 된다.

 

5. 한 번 1, 2, 3, 15차함수를 전부 그려보자.

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(loc=2)

plt.show()

1, 2, 3차식은 거의 겹쳐 보인다. 실제 데이터는 15차함수와 가장 비슷하게 위치하고 있다.

6. 이번에는 prophet을 써보자. 먼저 numpy를 사용하기 좋도록 데이터를 재배치한다.

# ds를 날짜형 데이터로 변환해준다.

df = pd.DataFrame({'ds':pinkwink_web.index, 'y':pinkwink_web['hit']})
df.reset_index(inplace=True)
df['ds'] = pd.to_datetime(df['ds'], format='%y. %m. %d.')
del df['date']
df.head()

 

7. 위에서 재배치한 데이터를 prophet에 넣고 돌려 보자. 이후 60일에 해당되는 데이터를 예측해본다.

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

future = m.make_future_dataframe(periods=60)
future.tail()

forecast = m.predict(future)

forecast 안에는 엄청나게 많은 데이터들이 들어가게 된다.

 

8. forecast = m.predict(future)을 통해 얻어진 forecast의 수많은 컬럼들 중 yhat(종속변수의 예측값)만 가져와보자. 예측값은 상한과 하한의 범위를 포함하여 얻어진다.

 

9. 이제 위에서 구한 데이터를 plot로 표현해보자.

m.plot(forecast)

그럴듯한 데이터가 얻어졌다. 데이터의 주기성이 좋을 수록 더 예측 결과가 괜찮게 나온다.

 

10. plot_components()는 트렌드를 분석해준다.

m.plot_components(forecast)