[zero-base/] DS Part 4. EDA - 31일차 스터디 노트

손윤재·2024년 1월 15일

제로베이스 DS 22기

목록 보기
32/55
post-thumbnail

실습 프로젝트 5️⃣

【시계열 데이터 분석】 웹 유입량 데이터 분석

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from prophet import Prophet

    %matplotlib inline

🔰 데이터 읽어오기

  • 데이터를 읽어온 후 NaN 값을 제거한다.
    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[pinkwink_web["hit"].notnull()]
  • 전체 데이터를 시각화
	pinkwink_web["hit"].plot(figsize=(12, 4), grid=True);


🔰 경향 분석 by Numpy

  • 먼저 numpy를 이용해 trend를 따로 파악해 본다.
    prophet 모듈이 어떤 방식으로 예측을 하는지 알 수 없으므로 numpy를 이용해 직접 경향성을 파악해 본다.

  • 다항식 회귀(Polynomial Regression) 모델을 사용한다.
    다항식 회귀는 다항식 함수를 사용하여 데이터를 근사하는 회귀 모델이다.
    일반적으로 다항식은 다음과 같은 형태를 가진다.
    y=anxn+an1xn1++a2x2+a1x+a0y = a_n x^n + a_{n-1} x^{n-1} + \ldots + a_2 x^2 + a_1 x + a_0

❕ x, y값 생성

trend 분석을 위한 x, y축 값을 생성한다.

  • x값은 0부터 pinkwink_web 데이터 길이까지 365개의 값이다.
	time = np.arange(0, len(pinkwink_web))
  • y축은 PinkWink 블로그의 일일 유입량이다.
	traffic = pinkwink_web["hit"].values

❕ 회귀함수 생성

trend 파악을 위한 다항식 회귀 함수를 생성한다.

  • np.polyfit() : 먼저 데이터에 적합한 다항식의 계수를 구한다.

  • np.poly1d() : 계수를 적용한 다항식을 생성한다.

  • 다항식은 1차, 2차, 3차, 15차 함수까지 4개를 생성한다.

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

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

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

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

❕ 경향성과 데이터 비교

numpy로 만든 4종류의 trend 함수들과 실제 데이터를 그래프로 확인해 본다.

    plt.figure(figsize=(14, 6))
    plt.scatter(time, traffic, s=10)

    plt.plot(fx, f1(fx), lw=3, label='f1')
    plt.plot(fx, f2(fx), lw=3, label='f2')
    plt.plot(fx, f3(fx), lw=3, label='f3')
    plt.plot(fx, f15(fx), lw=4, label='f15')

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

        👉 실제 데이터에 가장 잘 맞는 경향성은 f15로 보인다.


🔰 오차 검증: RMSE

  • 경향성 모델이 얼마나 정확한지 확인해줄 지표로 RMSE(rmse average, 제곱근오차평균)을 사용한다.

  • numpy로 계산한 경향성과 실제 데이터의 오차가 얼마인지 확인해줄 error 함수를 생성한다.

    def error(f, x, y):
        return np.sqrt(np.mean((f(x) - y) ** 2))

    print(error(f1, time, traffic))
    print(error(f2, time, traffic))
    print(error(f3, time, traffic))
    print(error(f15, time, traffic))
    --> 430.85973081109626
    --> 430.6284101894695
    --> 429.5328046676293
    --> 330.47773079342267

        👉 error() 함수로 검증한 값도 f15의 오차값이 가장 작았다.


🔰 경향 분석 by Prophet

  • Prophet을 이용해 경향성을 분석하고 미래 데이터를 얻어본다.

❕ 데이터 생성

Prophet에 학습시킬 데이터프레임 형식으로 웹 유입량 데이터를 변형시켜 준다.

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

❕ 미래값 예측

Prophet으로 모델을 생성하고 학습시킨 후 미래 예측값을 얻어온다.

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

    future = model.make_future_dataframe(periods=60)
    forecast = model.predict(future)
    forecast[["ds", "yhat", "yhat_lower", "yhat_upper"]].tail()

❕ 예측값 시각화

	model.plot(forecast);

❕ 경향 분석

Prophet.plot_components() : 미래 예측 데이터를 포함해 경향을 분석해준다.

	model.plot_components(forecast);

❗ 오차 검증

    np.sqrt(np.mean((forecast["trend"]-df["y"])**2))
    //--> 536.0321309635455

        👉 Prophet이 분석한 경향은 실제 데이터 분포와 상당한 오차가 존재하는 편이다.


🔰 종합 분석

실제 데이터와 Numpy로 계산한 trend, Prophet으로 예측한 trend를 모두 함께 비교한다.

    plt.figure(figsize=(14, 6))

    plt.scatter(time, traffic, s=10)
    plt.plot(fx, f1(fx), lw=4, label='Numpy Trend')
    ptrend = forecast.loc[:364, "trend"].values
    plt.plot(time, ptrend, lw=4, label='Prophet Trend')

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

        👉 Prophet이 분석한 경향보다 Numpy로 계산한 경향이
            실제 데이터 추세와 더 잘 맞아 보인다.

profile
ISTP(정신승리), To Be Data Scientist

0개의 댓글