머신러닝(파이썬) - 데이터 처리 및 시각화 (2)

LSH·2023년 7월 21일
0

교육 정보

  • 교육 명: 경기미래기술학교 AI 교육
  • 교육 기간: 2023.05.08 ~ 2023.10.31
  • 오늘의 커리큘럼:
    머신러닝
    (7/17 ~ 7/28)
  • 강사: 이현주, 이애리 강사님
  • 강의 계획:
    1. 머신러닝

데이터 처리 및 시각화 기법

주식 데이터

import FinanceDataReader as fdr
# 삼성전자(005930) 전체 (1996-11-05 ~ 현재)
ss = fdr.DataReader('005930')


  • 데이터 가져오기(pandas_datareader)
from pandas_datareader import data as pdr
ss_pdr = pdr.DataReader('005930', 'naver','1999-04-09')
ss_pdr.dtypes
#
# 결과
Open      object
High      object
Low       object
Close     object
Volume    object
dtype: object

데이터 타입 변경 (object → float)

ss_pdr= ss_pdr.astype('float')
ss_pdr

  • 변화값 계산 (pct_change())
    ss_pdr에 ss 데이터의 change 컬럼을 추가하기
    (오늘종가-어제종가)/오늘종가

    pandas.DataFrame.pct_change(): 변화값 계산 함수

ss_pdr['Change'] = ss_pdr['Close'].pct_change()
ss_pdr

→ FinanceDataReader로 가져온 데이터의 change 값과 동일함을 확인


  • 변화값 계산 (직접 계산, shift() 사용)
    ss_pdr에 ss 데이터의 change 컬럼을 직접 계산하여 추가하기
    (오늘종가-어제종가)/오늘종가

    pandas.DataFrame.shift(): 데이터 위치 이동 함수
    ex. df['col'].shift(1)하면 df 데이터의 ['col'] 컬럼 값들이 아래로 한칸씩 이동

# 종가가 한칸씩 이동된 컬럼 생성 
ss_pdr['Lag'] = ss_pdr['Close'].shift(1)

# 결측치 처리 (0번 행 처리) 
ss_pdr['Lag'].fillna(ss_pdr['Close'], inplace=True) # 해당 행의 close 값 불러오기
ss_pdr['Lag'].bfill(inplace=True) # 아래 값이 해당 행의 close 와 같으므로 이렇게도 가능 
ss_pdr['Lag'].fillna(method='bfill', inplace=True) # 이렇게도 가능

# 증감 비율 계산
ss_pdr['Change'] = (ss_pdr['Close']-ss_pdr['Lag'])/ss_pdr['Close']
ss_pdr

  • 주식 문제 정의 예시
    • 주가 변동 그래프
    • 상승한 날과 하락한 날이 각각 며칠씩 되는지 보고싶다
    • 1998 imf/ 2008외한위기/ 2020코로나/ - - 2023.2 위드코로나/ 대표 구속 주가변동
    • 월에 따른 주가변동?
    • 환율과의 상관관계
    • 거래량 폭등이 있었는지 (평소의 2배)
    • 다른 회사의 주가와의 관계
    • 내일 주가가 오를지
      • 선행지수
      • 신기술 개발, 큰 계약, 수상
      • 회사 생보에 대한 정보
      • 재무재표
      • 오너리스크
      • 반도체 가격 사이클
      • 환율
      • 타국 증시 상황
      • 반도체 수요가 높은 회사들의 주가
      • 금리

  • 최고가 최저가 인덱스 찾기 idxmax, idxmin
# 이렇게도 구할수 있지만 
ss_pdr[ss_pdr['High'] == ss_pdr['High'].max()]
# 이런 다 완성되어있는 함수가 있음 
ss_pdr['High'].idxmax()
# 최저가
ss_pdr['High'].idxmin()

  • 한 컬럼 차트 그리기 plot, lineplot
# 종가 차트 그리기 
sns.lineplot(ss_pdr['Close'])
# 위 코드와 동일
sns.lineplot(x= ss_pdr.index, y=ss_pdr['Close'])

# 저가 차트 그리기 
ss_pdr['Low'].plot()


→ 저가차트에서 이상한 부분 확대해보고자 함


  • 특정 기간 plot 하기
# 2018.1~2008.6까지 low 차트
# 거래정지일 (2018.4.30-5.3)
ss_pdr.loc['2018-01-01':'2018-06-30']['Low'].plot()


  • 이동 평균선
    • 지정 기간의 평균 변화를 보여주는 선

pandas.DataFrame.rolling(window=n)

ss_pdr ['MA5'] = ss_pdr['Close'].rolling(window=5).mean()
ss_pdr

→ 0 ~ 3번 행에 결측치 발생 → min_periods 값 지정하여 처리

# window 갯수를 충족하지 못하는 항목 처리 (0~3 행) → 최소값 지정 
ss_pdr ['MA5'] = ss_pdr['Close'].rolling(window=5, min_periods=1).mean()
ss_pdr

# 5, 10, 30 이동평균선을 한 그래프에 그리기 

for num in [5, 10, 30]:
  ss_pdr['Close'].rolling(window=num, min_periods=1).mean().plot(label=num)

plt.legend()
plt.show()

# 2022년 11월 부터 5, 10, 30 이동평균선을 한 그래프에 그리기 

for num in [5, 10, 30]:
  ss_pdr.loc['2022-11-01':]['Close'].rolling(window=num, min_periods=1).mean().plot(label=num)

plt.legend()
plt.show()

  • 캔들스틱 Candel Stick
!pip install mpl_finance
from mpl_finance import candlestick2_ohlc
candlestick2_ohlc?
# 도움말
#
# 결과
# 도움말
Signature: candlestick2_ohlc(ax, opens, highs, lows, closes, width=4, colorup='k', colordown='r', alpha=0.75)
Docstring:
Represent the open, close as a bar line and high low range as a
vertical line.

NOTE: this code assumes if any value open, low, high, close is
missing they all are missing


Parameters
----------
ax : `Axes`
    an Axes instance to plot to
opens : sequence
    sequence of opening values
highs : sequence
    sequence of high values
lows : sequence
    sequence of low values
closes : sequence
    sequence of closing values
width : int
    size of open and close ticks in points
colorup : color
    the color of the lines where close >= open
colordown : color
    the color of the lines where close <  open
alpha : float
    bar transparency

Returns
-------
ret : tuple
    (lineCollection, barCollection)
File:      /usr/local/lib/python3.10/dist-packages/mpl_finance.py
Type:      function

  • 캔들스틱 그리기
r_30 = ss_pdr.iloc[-30:]
fig, ax = plt.subplots()
candlestick2_ohlc(ax, r_30['Open'],
                  r_30['High'], 
                  r_30['Low'], 
                  r_30['Close'],
                  width=.8, 
                  colorup='r',
                  colordown='b',
                  alpha=0.75)
# ========여기가 다름========
ax.plot(r_30.index.astype('str'), 
        r_30['Close'], 
        label='Close',
        lw=0.5)

ax.legend()
plt.xticks(rotation=45)
plt.show()

xticks을 아래처럼 줄 수도 있음

# 범주 표시 
r_30 = ss_pdr.iloc[-30:]
fig, ax = plt.subplots()
candlestick2_ohlc(ax, r_30['Open'],
                  r_30['High'], 
                  r_30['Low'], 
                  r_30['Close'],
                  width=.8, 
                  colorup='r',
                  colordown='b',
                  alpha=0.75)
# ========여기가 다름========
ax.set_xticklabels(r_30.index)
plt.xticks(rotation=45)
plt.show()


  • 특정 컬럼 값의 평균의 2배 이상의 값을 가지는 항목을 표시하기

조건에 해당하는 항목은 1, 그 외 0을 가지는 volume issue 컬럼 생성

# 항목 확인
ss_pdr_new = ss_pdr.loc['2022.11.01':]
mean_vol = ss_pdr_new['Volume'].mean()
ss_pdr_new['Volume_issue'] = ss_pdr_new['Volume'] >= mean_vol * 2
ss_pdr_new['Volume_issue'].replace({True:1, False:0}, inplace=True)
ss_pdr_new['Volume_issue'].value_counts()
#
# 결과
0    178
1      3
Name: Volume_issue, dtype: int64

volume issue가 있었던날의 바 차트를 빨간색으로 표시

  1. volume issue 컬럼으로 Hue
# X: index, y: volume, color: red
fig, ax = plt.subplots(figsize=(15, 5))
ax = sns.barplot(data=ss_pdr_new, x=ss_pdr_new.index, y='Volume', hue='Volume_issue', palette={0:'black', 1:'red'})
plt.xticks(rotation=20)
plt.locator_params(axis='x', nbins=10)
plt.show()

  1. Color Array 생성 (np.where)

    (np.where(조건, 참일때 값, 거짓일때 값))

fig, ax = plt.subplots(figsize=(15, 5))
# color array를 만드는 방법 
volume_colors = np.where(ss_pdr_new['Volume_issue'] == 1, 'red', 'k')
ax = sns.barplot(data=ss_pdr_new, x=ss_pdr_new.index, y='Volume', palette=volume_colors)
plt.xticks(rotation=20)
plt.locator_params(axis='x', nbins=10)
plt.show()

  1. 이슈가 있는 값을 한번 더 그려주는 방법 + 참고선 및 label 추가
fig, ax = plt.subplots(figsize=(15, 5))
ax.bar(ss_pdr_new.index, ss_pdr_new['Volume'], color='k')
ax.bar(ss_pdr_new[ss_pdr_new['Volume_issue']==1].index, ss_pdr_new[ss_pdr_new['Volume_issue']==1]['Volume'], color='red')
left, right = plt.xlim()
ax.hlines(ss_pdr_new['Volume'].mean() * 2, left, right, color='black', ls='--')

plt.ylabel('Volume')
plt.xlabel('Date')
indices_to_label = ss_pdr_new[ss_pdr_new['Volume_issue']==1].index
for index in indices_to_label:
  x_pos = index
  y_pos = ss_pdr_new[ss_pdr_new.index == x_pos]['Volume'].values
  plt.text(x_pos, y_pos, str(x_pos), ha='center', va='bottom')

fig.show()

profile
:D

0개의 댓글