[E&C] 06. 시계열 데이터 분석

21401 단어 EDACrawlingCrawling

작업 환경

  • python 3.8
directory 구조
ds_stdy
├── data 	# 데이터 폴더
├── driver 	# driver 폴더
└── source_code # 작업 위치

코드

목적

  • fbprophet을 사용 방법을 다룸
    • 시계열 데이터를 다루고 시각화

fbprophet

  • 페이스북에서 만든 시계열 모델 라이브러리
    • 통계적 지식 없이도 좋은 성능을 냄
  • 데이터 형식
    • ds : 2021-01-01 형식
    • y : 각 ds에 해당하는 값

시계열 데이터 분석

네이버 주식

데이터 읽어오기

url = 'https://finance.yahoo.com/quote/035420.KS/history?p=035420.KS&guccounter=1'

req = Request(url, headers={'User-Agent':'Chrome'})
page = urlopen(req).read()
soup = BeautifulSoup(page, 'html.parser')
table = soup.find('table')

df_raw = pd.read_html(str(table))[0]
df_raw
  • 마지막 값은 의미없는 값으로 전처리 과정에서 제거

데이터 전처리

df_raw = df_raw.iloc[:-1, :]
df_raw['Date'] = pd.to_datetime(df_raw['Date'], format='%b %d, %Y')
df_raw['Open'] = df_raw['Open'].astype(float)
df_raw['High'] = df_raw['High'].astype(float)
df_raw['Low'] = df_raw['Low'].astype(float)
df_raw['Close*'] = df_raw['Close*'].astype(float)
df_raw['Adj Close**'] = df_raw['Adj Close**'].astype(float)
df_raw['Volume'] = df_raw['Volume'].astype(float)
  • 분석에 맞춰 Date 값을 날짜형으로, 나머지 값은 float 형으로 형변환

Prophet 모델 적용

  • df_raw 데이터에서 Date 컬럼과 Close* 컬럼 사용
  • Prophet의 경우 컬럼명을 dsy로 맞춰 줘야 함
model = Prophet(yearly_seasonality=True)
model.fit(df_close_ts);
  • 연간 계절성을 고려해서 모델 적합
future = model.make_future_dataframe(periods=30)
  • 30일이 추가된 날짜 데이터 프레임 만들기

모델 예측

forecast = model.predict(future)
model.plot_components(forecast);
  • 시간이 지날수록 증가하는 추세
  • 장이 닫혀있는 주말을 제외하면 월요일과 목요일에 주가가 높은 편
  • 여름에 주가가 높은편
  • 10월엔 하락했다가 11월엔 증가할 것으로 예측 됨
plt.figure(figsize=(12, 6))
plt.plot(df_close_ts['ds'], df_close_ts['y'], label='real')
plt.plot(forecast['ds'], forecast['yhat'], label='forecast')
plt.grid(True)
plt.legend()
plt.show()
  • 실제 값과 비교했을 때 추세를 6월부터 10월까지의 추세를 잘 예측했음
  • 이후의 예측의 상한선과 하한선의 차이가 크지 않음

KIA 주식

데이터 수집

  • yfinance를 이용해 데이터 수집
    • 해당 주식의 종목 코드와 추출하고자하는 날짜를 넣어 데이터 수집
import yfinance as yf
from pandas_datareader import data 

yf.pdr_override()

start_date = "2010-03-01"
end_date = "2018-02-28"
KIA = data.get_data_yahoo("000270.KS", start_date, end_date)

Prophet 모델 적용

  • 모델의 정확도를 위해 일부분을 잘라내고 모델 적합
KIA_trunc = KIA[:"2017-11-30"]
KIA_trunc.tail()
  • 2017년 11월 30일까지만 모델 적합
df_kia = pd.DataFrame({
    'ds' : KIA_trunc.index, 
    'y' : KIA_trunc['Close']
})
df_kia.reset_index(inplace=True)
del df_kia["Date"]
  • 모델 적합용 데이터 준비 완료
model = Prophet(yearly_seasonality=True, weekly_seasonality=True, daily_seasonality=True)
model.fit(df_kia)

future = model.make_future_dataframe(periods=90)
forecast = model.predict(future)
model.plot(forecast);
  • 연간/월간/일간 계절성 고려하며 모델 적합
  • 예측된 그래프 그리려보기
  • 계속 낮아지는 쪽으로 예측
# 실제값과 비교
plt.figure(figsize=(12, 4))
plt.plot(KIA.index, KIA['Close'], label='real')
plt.plot(forecast['ds'], forecast['yhat'], label = 'forecast')
plt.grid(True)
plt.legend()
plt.show()
  • 실제값은 내려갔다가 올라가는 형태
  • 예측값은 계속 내려가는 형태

비트코인

데이터 수집

  • 셀레니움을 이용해 Load raw data의 버튼을 클릭해 데이터를 얻어옴
url = "https://bitcoincharts.com/charts/bitstampUSD#rg730ztgSzm1g10zm2g25zv"
driver = webdriver.Chrome("../driver/chromedriver")
driver.get(url)
  • url #rg{숫자} 부분에서 {숫자}를 변경하면 해당 일만큼의 데이터 추출 가능
    • 단 페이지에 나와있는 범위의 기간만 가능
xpath = '//*[@id="content_chart"]/div/div[2]/a'
variable = driver.find_element_by_xpath(xpath)
driver.execute_script("return arguments[0].scrollIntoView();", variable)
variable.click()

html = driver.page_source
soup = BeautifulSoup(html, "html.parser")
table = soup.find("table", "data")
  • Load raw data 버튼을 누르고
  • 해당 페이지에 있는 table을 가져오기

Prophet 모델 적용

df = pd.DataFrame({"ds": bitcoin["Timestamp"], "y": bitcoin["Close"]})
model = Prophet(yearly_seasonality=True, daily_seasonality=True)
model.fit(df);

future = model.make_future_dataframe(periods=30)
forecast = model.predict(future)
model.plot(forecast);
  • 향후 30일간의 데이터 예측
  • 11월은 증가하는 추세를 보임

좋은 웹페이지 즐겨찾기