<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>예측 Archives - JIN&#039;s BOT</title>
	<atom:link href="https://jinsbot.com/tag/%EC%98%88%EC%B8%A1/feed/" rel="self" type="application/rss+xml" />
	<link>https://jinsbot.com/tag/예측/</link>
	<description>Coding + Engineering</description>
	<lastBuildDate>Sun, 22 Sep 2024 11:24:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6.2</generator>
<site xmlns="com-wordpress:feed-additions:1">158124120</site>	<item>
		<title>30분만에 나스닥 기업 주가 예측</title>
		<link>https://jinsbot.com/%ec%a3%bc%ea%b0%80-%ec%98%88%ec%b8%a1-%eb%82%98%ec%8a%a4%eb%8b%a5/</link>
					<comments>https://jinsbot.com/%ec%a3%bc%ea%b0%80-%ec%98%88%ec%b8%a1-%eb%82%98%ec%8a%a4%eb%8b%a5/#respond</comments>
		
		<dc:creator><![CDATA[geniuskpj]]></dc:creator>
		<pubDate>Sat, 01 Oct 2022 05:01:46 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Deep learning]]></category>
		<category><![CDATA[LSTM]]></category>
		<category><![CDATA[PYTHON]]></category>
		<category><![CDATA[TENSORFLOW]]></category>
		<category><![CDATA[예측]]></category>
		<category><![CDATA[주가]]></category>
		<category><![CDATA[코딩]]></category>
		<guid isPermaLink="false">https://jinsbot.com/?p=768</guid>

					<description><![CDATA[<p>주가 예측 서론 회사에서 주가 예측 과 관련된 코딩 공모전을 열었다. 제대로 인공신경망 모델을 만들기 위해서는 설계, 튜닝에 상당한 시간을 투자해야한다. 현생이 바쁘기 때문에 순위는 일찌감치 포기했다. 다만 구현 난이도가 궁금해서 인터넷 상 코드를 테스트해 보았다. Github 가 보편화된 이후로 코딩 실력은 필요한 코드를 얼마나 빠르게 찾아 응용할 수 있는지에 달렸다. 다행히 주가 예측 에 [&#8230;]</p>
<p>The post <a href="https://jinsbot.com/%ec%a3%bc%ea%b0%80-%ec%98%88%ec%b8%a1-%eb%82%98%ec%8a%a4%eb%8b%a5/">30분만에 나스닥 기업 주가 예측</a> appeared first on <a href="https://jinsbot.com">JIN&#039;s BOT</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2 class="wp-block-heading">주가 예측 서론</h2>
<p>회사에서 주가 예측 과 관련된 코딩 공모전을 열었다.</p>
<p>제대로 인공신경망 모델을 만들기 위해서는</p>
<p>설계, 튜닝에 상당한 시간을 투자해야한다.</p>
<p>현생이 바쁘기 때문에 순위는 일찌감치 포기했다.</p>
<p>다만 구현 난이도가 궁금해서 인터넷 상 코드를 테스트해 보았다.</p>
<p>Github 가 보편화된 이후로 코딩 실력은 필요한 코드를</p>
<p>얼마나 빠르게 찾아 응용할 수 있는지에 달렸다.</p>
<p>다행히 주가 예측 에 대한 코드는 인터넷에 차고 넘친다.</p>
<p><strong>코드 선택 기준</strong></p>
<ul>
<li>Tensorflow 로 작성될 것</li>
<li>VM에서 학습 가능한 복잡도</li>
<li>논문 수준의 분석, 설계 필요없음</li>
<li>20년도 이후 비교적 최신 코드</li>
</ul>
<p>많은 코드들 중에 위 조건에 해당하는 코드를 탐색했다.</p>
<p>주가 예측에는 보편적으로 LSTM , GRU , ARIMA 등이 사용되는데</p>
<p>데이터셋의 종류, 형태에 따라 성능이 달라진다.</p>
<p>그리고 LSTM + GRU , LSTM + ARIMA , ARIMA + GRU 처럼</p>
<p>하이브리드로 구성될 때 성능이 향상된다.</p>
<p>이중에서 LSTM + GRU 에 해당하는 코드들을 찾아봤다.</p>
<p>둘 다 <a href="https://www.kaggle.com/code/vineethars/stock-prediction-lstm-gru" target="_blank" rel="noreferrer noopener">RNN</a>이기때문에 hybrid 로 만들기 쉽고</p>
<p>tensorflow 로 구현하기도 쉽다.</p>
<p><a href="https://web.archive.org/web/20240529091126/https://www.kaggle.com/code/vineethars/stock-prediction-lstm-gru" target="_blank" rel="noreferrer noopener">Kaggle 원본 코드</a>는 링크로 첨부하니 참고하길 바란다.</p>
<h2 class="wp-block-heading">본론</h2>
<h3 class="wp-block-heading">모듈 및 데이터 임포트</h3>
<p>코드에서 사용되는 모듈들과 설명</p>
<ul>
<li>pandas : CSV를 사용하기 쉬운 dataframe , series로 변환,저장</li>
<li>numpy : 데이터 가공</li>
<li>sklearn : 학습에 필요한 utility 제공</li>
<li>tensorflow : 실질적으로 학습을 진행</li>
<li>matplotlib : plot 에 사용</li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
import os
os.environ['TF_ENABLE_ONEDNN_OPTS']='0'
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.layers import LSTM, GRU
from keras.callbacks import EarlyStopping,ModelCheckpoint
from sklearn.preprocessing import MinMaxScaler

#import data
org_df={}
dflist=['AAPL','AMD','ATVI','CSCO','EBAY','GOOGL','INTC','MSFT','MU','NTGR','NVDA','SBUX','STX','TSM','WDC']
for i in range(1,16):
    org_df[i]=pd.read_csv(f"/dataset/{dflist[i-1]}.csv")</pre>
<h3 class="wp-block-heading">전처리</h3>
<p>우선 데이터를 별도로 어떻게 전처리 할것인지 정해야 한다.</p>
<p>sklearn 에서 제공하는 MinMaxScaler 를 사용해</p>
<p>0에서 1 사이의 값을 가지도록 정규화 했다.</p>
<p>데이터의 노이즈가 심하지 않아 필터는 적용하지않았다.</p>
<p>data는 6개의 column을 가지는데 원본 저자는 <strong>종가</strong>만 학습에 사용했다.</p>
<p>다른 데이터로 accuracy를 올릴 수도 있지만 학습,튜닝에 오랜시간이 걸린다.</p>
<p>또한 volume을 제외한 column 들은 종가와 유사하기때문에</p>
<p>accuracy를 올리는데 효율적이지 못하다.</p>
<p>단순하게 k개의 사전데이터로 다음 날을 예측하도록 input을 구성했다.</p>
<figure class="wp-block-image size-full is-resized"><a href="https://jinsbot.com/wp-content/uploads/2024/09/prediction.webp"><img fetchpriority="high" decoding="async" class="aligncenter size-full wp-image-771" src="https://jinsbot.com/wp-content/uploads/2024/09/prediction.webp" alt="" width="768" height="346" srcset="https://jinsbot.com/wp-content/uploads/2024/09/prediction.webp 768w, https://jinsbot.com/wp-content/uploads/2024/09/prediction-300x135.webp 300w, https://jinsbot.com/wp-content/uploads/2024/09/prediction-150x68.webp 150w" sizes="(max-width: 768px) 100vw, 768px" /></a><br />
<noscript><br />
<img data-lazy-fallback="1" fetchpriority="high" decoding="async" src="https://web.archive.org/web/20240529091126im_/https://jinsbot.com/wp-content/uploads/2022/10/prediction.jpg" alt="주가 예측 개념도" class="wp-image-798" width="750" height="338" srcset="https://web.archive.org/web/20240529091126im_/https://jinsbot.com/wp-content/uploads/2022/10/prediction.jpg 750w, https://web.archive.org/web/20240529091126im_/https://jinsbot.com/wp-content/uploads/2022/10/prediction-300x135.jpg 300w, https://web.archive.org/web/20240529091126im_/https://jinsbot.com/wp-content/uploads/2022/10/prediction-150x68.jpg 150w" sizes="(max-width: 750px) 100vw, 750px"/><br />
</noscript></figure>
<p>따라서 위 그림 대로 Input 과 Output 데이터를 가공한다.</p>
<p>train set과 validation set을 나누어주기 위해서는 train_test_split을 사용하거나</p>
<p>model.fit에서 validation_split 옵션을 사용하면 된다.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def create_dataset(dataset, time_step=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-time_step-1):
        a = dataset[i:(i+time_step)]    
        dataX.append(a)
        dataY.append(dataset[i + time_step])
    return np.array(dataX), np.array(dataY)

t_step=10
scaler=MinMaxScaler(feature_range=(0,1))
scaled=scaler.fit_transform(np.array(org_df[1]['Close']).reshape(-1,1))
X_train,y_train=create_dataset(scaled,t_step)
# X_train,X_val,y_train,y_val=train_test_split(X_train,y_train,test_size=0.3,random_state=0)</pre>
<h3 class="wp-block-heading">신경망 구축 및 학습</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def custom_loss(y_true, y_pred):
    mae = tf.keras.losses.MeanAbsoluteError()
    return mae(y_true, y_pred)/np.mean(abs(y_true))

callbacks = [EarlyStopping(monitor='val_loss',
                                           patience=15,min_delta=0.01),
             ModelCheckpoint(filepath='best_model.h5',
                                             monitor='val_loss',
                                             save_best_only=True, restore_best_weights=True)]
model=Sequential()
model.add(LSTM(32,return_sequences=True,input_shape=(t_step,1)))
model.add(LSTM(32,return_sequences=True))
model.add(Dropout(0.2))

model.add(GRU(32,return_sequences=True))
model.add(Dropout(0.2))

model.add(GRU(32,return_sequences=True))
model.add(GRU(32))
model.add(Dropout(0.2))

model.add(Dense(1))

model.compile(loss=custom_loss,optimizer='adam' , metrics = [ "mae",'mse'],run_eagerly=True)
model.summary()


history=model.fit(X_train,y_train,validation_split=0.3,epochs=100,batch_size=64,verbose=0,callbacks=callbacks)
# history=model.fit(X_train,y_train,validation_data=(X_val,y_val),epochs=100,batch_size=64,verbose=1,callbacks=callbacks)
print('done')</pre>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Model: "sequential_6"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 lstm_12 (LSTM)              (None, 10, 32)            4352      
                                                                 
 lstm_13 (LSTM)              (None, 10, 32)            8320      
                                                                 
 dropout_18 (Dropout)        (None, 10, 32)            0         
                                                                 
 gru_18 (GRU)                (None, 10, 32)            6336      
                                                                 
 dropout_19 (Dropout)        (None, 10, 32)            0         
                                                                 
 gru_19 (GRU)                (None, 10, 32)            6336      
                                                                 
 gru_20 (GRU)                (None, 32)                6336      
                                                                 
 dropout_20 (Dropout)        (None, 32)                0         
                                                                 
 dense_6 (Dense)             (None, 1)                 33        
                                                                 
=================================================================</pre>
<p>LSTM과 GRU가 같이 배치된 하이브리드 모델이다.</p>
<p>학습의 속도, accuracy는 모델의 배치,shape에도 크게 영향 받으나 절대적인 법칙은 없다.</p>
<p>성능을 보면서 적절하게 변경하면 된다.</p>
<p>원본 코드와 다르게 레이어를 배치해 봤지만 원본대로 하는게 가장 정확도가 높다.</p>
<p>loss는 mse, mae 등 여러가지를 사용할 수 있는데 코드에 나온것처럼</p>
<p>새로운 loss function을 정의해도 된다.</p>
<p>물론, mae와 mse 를 섞는 등 다른 평가 요소를 사용하여 성능을 더 개선할 수 있다.</p>
<p>코드수행에 생각보다 시간이 걸리는데 EarlyStopping callback을 통해</p>
<p>학습을 조기 중단시킬 수 있다.</p>
<p>혹은 processpool executor를 사용하여 수행속도를 올릴 수 있다.</p>
<p>마지막으로 model.fit을 통해 학습을 수행하는데</p>
<p>epochs, batch_size 등 각종 parameter의 튜닝이 필요하다.</p>
<p>이러한 hyper parameter는 keras의 tuner를 사용해도 되고</p>
<p>단순한 반복문을 만들어 기록해도 된다.</p>
<p>verbose를 1로 두면 학습 과정을 지켜볼 수 있습니다.</p>
<p>epoch별 loss값을 지켜보면 학습이 정상진행되는지 알 수 있기때문에 신경망을 설계할 때 유용하다.</p>
<p>다음 코드를 통해 학습이 잘됐는지 plot해보자.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">hh=history.history
epochs=range(len(hh['loss']))
plt.plot(epochs,hh['loss'],label='loss')
plt.plot(epochs,hh['val_loss'],label='val_loss')
plt.legend()
plt.show()</pre>
<figure class="wp-block-image size-full"><a href="https://jinsbot.com/wp-content/uploads/2024/09/plot_history.webp"><img decoding="async" class="aligncenter size-full wp-image-770" src="https://jinsbot.com/wp-content/uploads/2024/09/plot_history.webp" alt="" width="372" height="248" srcset="https://jinsbot.com/wp-content/uploads/2024/09/plot_history.webp 372w, https://jinsbot.com/wp-content/uploads/2024/09/plot_history-300x200.webp 300w, https://jinsbot.com/wp-content/uploads/2024/09/plot_history-150x100.webp 150w" sizes="(max-width: 372px) 100vw, 372px" /></a><br />
<noscript><br />
<img data-lazy-fallback="1" decoding="async" width="372" height="248" src="https://web.archive.org/web/20240529091126im_/https://jinsbot.com/wp-content/uploads/2022/10/plot_history.png" alt="주가 예측 history" class="wp-image-826" srcset="https://web.archive.org/web/20240529091126im_/https://jinsbot.com/wp-content/uploads/2022/10/plot_history.png 372w, https://web.archive.org/web/20240529091126im_/https://jinsbot.com/wp-content/uploads/2022/10/plot_history-300x200.png 300w, https://web.archive.org/web/20240529091126im_/https://jinsbot.com/wp-content/uploads/2022/10/plot_history-150x100.png 150w" sizes="(max-width: 372px) 100vw, 372px"/><br />
</noscript></figure>
<p>loss와 validation_loss가 둘 다 수렴하고 있으므로</p>
<p>학습이 어느정도 잘 이루어지고 있다.</p>
<p>과적합이 일어난다면 신경망의 설계,변수를 바꾸거나</p>
<p>정규화를 변경함으로써 해결할 수 있다.</p>
<h3 class="wp-block-heading">주가 예측 값 도출</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="python" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">prd={}
nmae={}
day_to_predict=7
for _,i in enumerate(org_df):
    last_data=scaler[i].fit_transform(np.array(org_df[i]['Close'].iloc[-t_step:]).reshape(-1,1))
    prd_list=[]
    for j in range(day_to_predict):
        last_data=last_data[-t_step:]
        prd_temp=models[i].predict(np.array(last_data).reshape(1,t_step[i],1),verbose=0)
        prd_list.append(prd_temp[0][0])
        last_data=np.append(last_data,pd.Series(prd_temp[0][0]))
    prd[i]=scaler[i].inverse_transform(np.array(prd_list).reshape(-1,1))[:,0]
    nmae[i]=my_loss(test_df[i]['Close'][:7],prd[i])
    print(f'{dflist[i-1]} : {nmae[i]}')

print(f'avg={pd.Series(nmae).mean()}')</pre>
<p>이제 위 코드를 통해 주가 예측 데이터를 도출한다.</p>
<p>루틴을 간단하게 설명하면 다음과 같습니다.</p>
<ol>
<li><strong>마지막 k개</strong>의 데이터를 input으로 만든다.</li>
<li>input을 통해 다음날의 데이터를 예측한다.</li>
<li>예측 데이터를 input 데이터에 덧붙인다.</li>
</ol>
<p>위 과정을 예측하고 싶은만큼 날만큼 반복하여 loss값을 기록한다.</p>
<p>기록된 loss값이나 평균 loss값으로 학습이 잘 이루어졌는지 확인 가능하다.</p>
<h2 class="wp-block-heading">주가 예측 결론</h2>
<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">AAPL : 0.04620344564318657
AMD : 0.11094651371240616
ATVI : 0.0061081573367118835
CSCO : 0.01842576451599598
EBAY : 0.026052556931972504
GOOGL : 0.03204019367694855
INTC : 0.03417059779167175
MSFT : 0.05612574890255928
MU : 0.008338606916368008
NTGR : 0.02389097958803177
NVDA : 0.0929316058754921
SBUX : 0.015276948921382427
STX : 0.07766019552946091
TSM : 0.02993595041334629
WDC : 0.03140253946185112
avg = 0.04063398440678914</pre>
<ul>
<li><strong>평균 오차</strong>: 주가의 4~5%</li>
<li><strong>소요시간</strong>: 코딩 30분 + 학습 30분 (CPU,싱글 코어 기준)</li>
</ul>
<p>약간의 튜닝으로도 성능을 2~3%까지 개선할 수 있다.</p>
<p>30분짜리 코딩치고 주가 예측 결과가 나쁘지 않다.</p>
<p>강화학습, deep learning 등에서 <strong>이론 공부</strong>만으로 시간을 버리는 경우가 많다.</p>
<p>Matlab의 Tuner/Optimizer를 쓰면서 알고리즘을 다 이해하는건 아니듯이</p>
<p>알고리즘 이해에 너무 긴 시간을 쏟을 필요 없다.</p>
<p>차라리 kaggle 등에서 실용적인 코드를 찾아 <strong>직접 해보는것</strong>이 도움이 된다.</p>
<p>여러분들께도 올려드린 코드가 도움이 되길 바란다.</p>
<p>The post <a href="https://jinsbot.com/%ec%a3%bc%ea%b0%80-%ec%98%88%ec%b8%a1-%eb%82%98%ec%8a%a4%eb%8b%a5/">30분만에 나스닥 기업 주가 예측</a> appeared first on <a href="https://jinsbot.com">JIN&#039;s BOT</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jinsbot.com/%ec%a3%bc%ea%b0%80-%ec%98%88%ec%b8%a1-%eb%82%98%ec%8a%a4%eb%8b%a5/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">768</post-id>	</item>
	</channel>
</rss>
