2023. 11. 19. 22:59ㆍML&DL/Data Analysis
[삼성전자 주가 예측 모델 구현하기]
데이터
- FinanceDataReader를 활용한 주가 데이터셋
- https://financedata.github.io/posts/finance-data-reader-users-guide.html
FinanceDataReader 사용자 안내서
FinanceDataReader 사용자 안내서
financedata.github.io
데이터 컬럼
- Open: 시가
- High: 고가
- Low: 저가
- Close: 종가
- Volume: 거래량
- Change: 대비
💻 실습
* 라이브러리 import
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
import os
%matplotlib inline
warnings.filterwarnings('ignore')
plt.rcParams['font.family'] = 'NanumGothic'
* FinanceDataReader는 주가 데이터를 가져올 수 있는 패키지
!pip install finance-datareader
import FinanceDataReader as fdr
* 데이터 불러오기
- 기업별로 코드가 다르다.
import FinanceDataReader as fdr
# KRX stock symbol list
stocks = fdr.StockListing('KRX') # 코스피, 코스닥, 코넥스 전체
stocks = fdr.StockListing('KOSPI') # 코스피
stocks = fdr.StockListing('KOSDAQ') # 코스닥
stocks = fdr.StockListing('KONEX') # 코넥스
# NYSE, NASDAQ, AMEX stock symbol list
stocks = fdr.StockListing('NYSE') # 뉴욕거래소
stocks = fdr.StockListing('NASDAQ') # 나스닥
stocks = fdr.StockListing('AMEX') # 아멕스
# S&P 500 symbol list
sp500 = fdr.StockListing('S&P500')
# 기타 주요 거래소 상장종목 리스트
stocks = fdr.StockListing('SSE') # 상해 거래소
stocks = fdr.StockListing('SZSE') # 신천 거래소
stocks = fdr.StockListing('HKEX') # 홍콩거래소
stocks = fdr.StockListing('TSE') # 도쿄 증권거래소
stocks = fdr.StockListing('HOSE') # 호치민 증권거래소
=> 거래소 리스트 stocks 으로 확인 가능
- 자세한 정보
https://github.com/FinanceData/FinanceDataReader
GitHub - FinanceData/FinanceDataReader: Financial data reader
Financial data reader. Contribute to FinanceData/FinanceDataReader development by creating an account on GitHub.
github.com
* 삼성전자 데이터
samsung = fdr.DataReader('005930')
samsung.tail()
samsung.tail()

* Apple 데이터
apple = fdr.DataReader('AAPL')
apple.tail()
- 특정 시점 이후 데이터 불러오기
- 2017년 이후
apple = fdr.DataReader('AAPL', '2017')
apple.head()

- 특정 범위 데이터 ex) 1980-01-01 ~ 2019-12-30
ford = fdr.DataReader('F', '1980-01-01', '2019-12-30')
ford.head()
* 삼성전자 주가 데이터 분석
stock = fdr.DataReader('005930')
stock.head()

* 년/월/일 분리
stock['Year'] = stock.index.year
stock['Month'] = stock.index.month
stock['Day'] = stock.index.day
stock.head()

* 년도별/ 월별 피봇 테이블
stock.groupby(['Year', 'Month']).mean()

* 주식 가격 시각화
plt.figure(figsize=(16, 9))
sns.lineplot(y=stock['Close'], x=stock.index)
plt.xlabel('time')
plt.ylabel('price')

# 1990~2000, 2000~2010, 2010~2015, 2015~2020
time_steps = [['1990', '2000'],
['2000', '2010'],
['2010', '2015'],
['2015', '2020']]
fig, axes = plt.subplots(2, 2)
fig.set_size_inches(16, 9)
for i in range(4):
ax = axes[i//2, i%2]
df = stock.loc[(stock.index > time_steps[i][0]) & (stock.index < time_steps[i][1])]
sns.lineplot(y=df['Close'], x=df.index, ax=ax)
ax.set_title(f'{time_steps[i][0]}~{time_steps[i][1]}')
ax.set_xlabel('time')
ax.set_ylabel('price')
plt.tight_layout()
plt.show()

* 스케일러
- 수치 데이터 정규화해줌
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scale_cols = ['Open', 'High', 'Low', 'Close', 'Volume']
scaled = scaler.fit_transform(stock[scale_cols])
scaled
df = pd.DataFrame(scaled, columns=scale_cols)
* train/ test 데이터 분할
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(df.drop('Close', 1), df['Close'], test_size=0.2, random_state=0, shuffle=False)
* shape 확인
x_train.shape, y_train.shape
((4800, 4), (4800,))
x_test.shape, y_test.shape
((1200, 4), (1200,))
import tensorflow as tf
def windowed_dataset(series, window_size, batch_size, shuffle):
series = tf.expand_dims(series, axis=-1)
ds = tf.data.Dataset.from_tensor_slices(series)
ds = ds.window(window_size + 1, shift=1, drop_remainder=True)
ds = ds.flat_map(lambda w: w.batch(window_size + 1))
if shuffle:
ds = ds.shuffle(1000)
ds = ds.map(lambda w: (w[:-1], w[-1]))
return ds.batch(batch_size).prefetch(1)
WINDOW_SIZE=20
BATCH_SIZE=32
train_data = windowed_dataset(y_train, WINDOW_SIZE, BATCH_SIZE, True)
test_data = windowed_dataset(y_test, WINDOW_SIZE, BATCH_SIZE, False)
* 모델 학습
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, Conv1D, Lambda
from tensorflow.keras.losses import Huber
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
model = Sequential([
# 1차원 feature map 생성합니다. filters는 32로, kernel_size는 5로 지정해주세요.
Conv1D(filters=32, kernel_size=5,
padding="causal",
activation="relu",
input_shape=[WINDOW_SIZE, 1]),
# LSTM과 Dense 레이러를 사용해주세요. 활성함수는 각각 tanh와 relu로 지정합니다.
LSTM(16, activation='relu'),
Dense(16, activation="relu"),
Dense(1),
])
loss = Huber()
optimizer = Adam(0.0005)
model.compile(loss=Huber(), optimizer=optimizer, metrics=['mse'])
earlystopping = EarlyStopping(monitor='val_loss', patience=10)
filename = os.path.join('tmp', 'ckeckpointer.ckpt')
checkpoint = ModelCheckpoint(filename,
save_weights_only=True,
save_best_only=True,
monitor='val_loss',
verbose=1)
history = model.fit(train_data,
validation_data=(test_data),
epochs=50,
callbacks=[checkpoint, earlystopping])
* 모델 예측
pred = model.predict(test_data)
plt.figure(figsize=(12, 9))
plt.plot(np.asarray(y_test)[20:], label='actual')
plt.plot(pred, label='prediction')
plt.legend()
plt.show()

=> 실제 주가값(actual)과 예측 주가 값(prediction)이 차이가 크지 않은 것을 확인할 수 있음

'ML&DL > Data Analysis' 카테고리의 다른 글
[분류] 학생 데이터 분석 & 성적 등급 예측 모델 (1) | 2023.11.19 |
---|---|
[분류] 심부전증 데이터 분석 & 예측 모델 (1) | 2023.11.19 |