Ana içeriğe atla

Python ile LSTM kullanarak Borsa Tahminleri

Python’da Uzun Kısa Süreli Bellek (LSTM) ağlarını keşfedin ve bunları borsa tahmini için nasıl kullanabileceğinizi öğrenin!
Güncel 16 Nis 2026  · 15 dk. oku

Bu eğitimde, Uzun Kısa Süreli Bellek (Long Short-Term Memory) adı verilen bir zaman serisi modelini nasıl kullanacağınızı öğreneceksiniz. LSTM modelleri, tasarımları gereği özellikle uzun süreli belleği koruma konusunda güçlüdür; bunu ileride göreceksiniz. Bu eğitimde aşağıdaki konulara değineceksiniz:

  • Hisse senedi fiyat hareketlerini tahmin edebilmenin neden gerekli olduğunu anlayın.
  • Verileri indirin – Yahoo Finance’tan hisse senedi verilerini kullanacaksınız.
  • Eğitim-test ayrımı yapın ve bazı veri normalleştirme işlemleri uygulayın.
  • Bir adım ilerisini tahmin etmek için kullanılabilecek birkaç ortalama alma tekniğini gözden geçirin ve uygulayın.
  • Birden fazla adım ilerisini tahmin etmeye olanak tanıdığı için bir LSTM modelini motive edin ve kısaca tartışın.
  • Mevcut verilerle gelecekteki borsa hareketlerini tahmin edin ve görselleştirin

Derin öğrenme veya sinir ağlarına aşina değilseniz, Python ile Derin Öğrenme kursumuza göz atmalısınız. Temelleri ve Keras ile kendi sinir ağınızı nasıl kuracağınızı kapsar. Bu paket, bu eğitimde kullanacağınız TensorFlow’dan farklıdır, ancak fikir aynıdır.

Neden Zaman Serisi Modellerine İhtiyaç Duyarsınız?

Hisse senedi alıcısı olarak, kâr etmek için hangi zamanlarda alım-satım yapacağınıza makul şekilde karar verebilmek adına hisse senedi fiyatlarını doğru biçimde modellemek istersiniz. İşte zaman serisi modellemesi burada devreye girer. Bir veri dizisinin geçmişine bakarak dizinin gelecekteki öğelerini doğru şekilde tahmin edebilecek iyi makine öğrenmesi modellerine ihtiyacınız vardır.

Uyarı: Borsa fiyatları son derece öngörülemez ve oynaktır. Bu, verilerde zaman içinde hisse senedi fiyatlarını neredeyse mükemmele yakın modellemenize izin verecek tutarlı kalıpların bulunmadığı anlamına gelir. Bunu benden değil, Princeton Üniversitesi ekonomisti Burton Malkiel’den alın: 1973 tarihli “A Random Walk Down Wall Street” kitabında, eğer piyasa gerçekten verimliyse ve bir hisse fiyatı tüm faktörleri kamuya açıklandıkları anda derhal yansıtıyorsa, gözleri bağlı bir maymunun gazetedeki hisse listesine dart atması, herhangi bir yatırım uzmanı kadar başarılı olmalıdır, diye savunur.

Yine de bunun tamamen stokastik ya da rastgele bir süreç olduğuna ve makine öğrenmesi için hiç umut olmadığına tümüyle inanmaya gerek yok. En azından, yaptığınız tahminlerin verinin gerçek davranışıyla korelasyon göstermesini sağlayacak şekilde veriyi modelleyip modelleyemeyeceğinize bakalım. Başka bir deyişle, geleceğin tam hisse değerlerine değil, hisse fiyat hareketlerine (yakın gelecekte yükselip yükselmeyeceğine ya da düşüp düşmeyeceğine) ihtiyacınız var.

# Make sure that you have all these libaries available to run the code successfully
from pandas_datareader import data
import matplotlib.pyplot as plt
import pandas as pd
import datetime as dt
import urllib.request, json
import os
import numpy as np
import tensorflow as tf # This code has been tested with TensorFlow 1.6
from sklearn.preprocessing import MinMaxScaler

Verileri İndirme

Aşağıdaki kaynaklardan veri kullanacaksınız:

  1. Alpha Vantage Stock API. Başlamadan önce bir API anahtarına ihtiyacınız var; bunu ücretsiz olarak buradan edinebilirsiniz. Ardından bu anahtarı api_key değişkenine atayabilirsiniz. Bu eğitim, American Airlines hissesine ait 20 yıllık geçmiş veriyi getirir. İsteğe bağlı olarak, geçmiş piyasa verileriyle çalışma konusundaki en iyi uygulamalar için bu başlangıç kılavuzuna göz atabilirsiniz.

  2. Bu sayfadaki verileri kullanın. Zip dosyasındaki Stocks klasörünü proje ana klasörünüze kopyalayın.

Hisse fiyatları birden fazla türde gelir. Bunlar:

  • Open: Günün açılış fiyatı
  • Close: Günün kapanış fiyatı
  • High: Gün içindeki en yüksek fiyat
  • Low: Gün içindeki en düşük fiyat

Alpha Vantage’tan veri alma

Önce verileri Alpha Vantage’tan yükleyeceksiniz. Tahminler yapmak için American Airlines hisse fiyatlarını kullanacağınızdan, sembolü "AAL" olarak belirliyorsunuz. Ek olarak, son 20 yıl içinde American Airlines’a ait tüm hisse senedi verilerini içeren bir JSON dosyası döndürecek bir url_string ve veriyi kaydedeceğiniz file_to_save tanımlıyorsunuz. Bu dosyanın adlandırılmasına yardımcı olması için önceden tanımladığınız ticker değişkenini kullanacaksınız.

Sonraki adımda bir koşul belirleyeceksiniz: Veriyi daha önce kaydetmediyseniz, url_string içinde belirlediğiniz URL’den veriyi alacaksınız; tarih, low, high, volume, close, open değerlerini bir pandas DataFrame’i df’e kaydedip file_to_save dosyasına yazacaksınız. Ancak veri zaten varsa, doğrudan CSV’den yükleyeceksiniz.

Kaggle’dan veri alma

Kaggle’da bulunan veriler CSV dosyalarının bir koleksiyonudur ve herhangi bir ön işleme gerek yoktur; bu nedenle veriyi doğrudan bir Pandas DataFrame’e yükleyebilirsiniz.

data_source = 'kaggle' # alphavantage or kaggle

if data_source == 'alphavantage':
    # ====================== Loading Data from Alpha Vantage ==================================

    api_key = '<your API key>'

    # American Airlines stock market prices
    ticker = "AAL"

    # JSON file with all the stock market data for AAL from the last 20 years
    url_string = "https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=%s&outputsize=full&apikey=%s"%(ticker,api_key)

    # Save data to this file
    file_to_save = 'stock_market_data-%s.csv'%ticker

    # If you haven't already saved data,
    # Go ahead and grab the data from the url
    # And store date, low, high, volume, close, open values to a Pandas DataFrame
    if not os.path.exists(file_to_save):
        with urllib.request.urlopen(url_string) as url:
            data = json.loads(url.read().decode())
            # extract stock market data
            data = data['Time Series (Daily)']
            df = pd.DataFrame(columns=['Date','Low','High','Close','Open'])
            for k,v in data.items():
                date = dt.datetime.strptime(k, '%Y-%m-%d')
                data_row = [date.date(),float(v['3. low']),float(v['2. high']),
                            float(v['4. close']),float(v['1. open'])]
                df.loc[-1,:] = data_row
                df.index = df.index + 1
        print('Data saved to : %s'%file_to_save)        
        df.to_csv(file_to_save)

    # If the data is already there, just load it from the CSV
    else:
        print('File already exists. Loading data from CSV')
        df = pd.read_csv(file_to_save)

else:

    # ====================== Loading Data from Kaggle ==================================
    # You will be using HP's data. Feel free to experiment with other data.
    # But while doing so, be careful to have a large enough dataset and also pay attention to the data normalization
    df = pd.read_csv(os.path.join('Stocks','hpq.us.txt'),delimiter=',',usecols=['Date','Open','High','Low','Close'])
    print('Loaded data from the Kaggle repository')
Data saved to : stock_market_data-AAL.csv

Veri keşfi

Burada, DataFrame’e topladığınız veriyi yazdıracaksınız. Ayrıca verinin tarihe göre sıralandığından emin olun; çünkü zaman serisi modellemesinde verinin sırası kritik önemdedir.

# Sort DataFrame by date
df = df.sort_values('Date')

# Double check the result
df.head()
  Date Open High Low Close
0 1970-01-02 0.30627 0.30627 0.30627 0.30627
1 1970-01-05 0.30627 0.31768 0.30627 0.31385
2 1970-01-06 0.31385 0.31385 0.30996 0.30996
3 1970-01-07 0.31385 0.31385 0.31385 0.31385
4 1970-01-08 0.31385 0.31768 0.31385 0.31385

Veri görselleştirme

Şimdi, elinizde ne tür veriler olduğuna bakalım. Zaman içinde çeşitli örüntülerin oluştuğu veriler istiyorsunuz.

plt.figure(figsize = (18,9))
plt.plot(range(df.shape[0]),(df['Low']+df['High'])/2.0)
plt.xticks(range(0,df.shape[0],500),df['Date'].loc[::500],rotation=45)
plt.xlabel('Date',fontsize=18)
plt.ylabel('Mid Price',fontsize=18)
plt.show()

Bu grafik zaten çok şey söylüyor. Bu şirketi diğerlerine tercih etmemin belirli nedeni, zaman içinde çok farklı hisse fiyatı davranışları barındırmasıdır. Bu, öğrenmeyi daha sağlam hale getirecek ve çeşitli durumlar için tahminlerin ne kadar iyi olduğunu test etme şansı verecektir.

Dikkat edilmesi gereken bir başka nokta da 2017’ye yakın değerlerin çok daha yüksek olması ve 1970’lere yakın değerlere kıyasla daha fazla dalgalanmasıdır. Bu nedenle, zaman aralığı boyunca verinin benzer değer aralıklarında davrandığından emin olmanız gerekir. Bunu veri normalleştirme aşamasında ele alacaksınız.

Veriyi Eğitim ve Test Kümesine Ayırma

Gün içinde kaydedilen en yüksek ve en düşük fiyatların ortalaması alınarak hesaplanan orta fiyatı kullanacaksınız.

# First calculate the mid prices from the highest and lowest
high_prices = df.loc[:,'High'].as_matrix()
low_prices = df.loc[:,'Low'].as_matrix()
mid_prices = (high_prices+low_prices)/2.0

Şimdi eğitim ve test verilerini ayırabilirsiniz. Eğitim verisi zaman serisinin ilk 11.000 veri noktası, geri kalanı ise test verisi olacaktır.

train_data = mid_prices[:11000]
test_data = mid_prices[11000:]

Veriyi Normalize Etme

Şimdi veriyi normalize etmek için bir ölçekleyici tanımlamanız gerekiyor. MinMaxScalar, tüm verileri 0 ile 1 aralığına ölçekler. Ayrıca eğitim ve test verilerini [data_size, num_features] şeklinde yeniden şekillendirebilirsiniz.

# Scale the data to be between 0 and 1
# When scaling remember! You normalize both test and train data with respect to training data
# Because you are not supposed to have access to test data
scaler = MinMaxScaler()
train_data = train_data.reshape(-1,1)
test_data = test_data.reshape(-1,1)

Daha önce yaptığınız, farklı zaman dönemlerindeki verilerin farklı değer aralıklarına sahip olduğu gözlemi nedeniyle, tam seriyi pencerelere bölerek normalleştirme yapıyorsunuz. Bunu yapmazsanız, eski veriler 0’a yakın olacak ve öğrenme sürecine fazla katkı sağlamayacaktır. Burada pencere boyutu olarak 2500 seçiyorsunuz.

İpucu: Pencere boyutunu seçerken çok küçük olmamasına dikkat edin. Pencereli normalleştirme yaptığınızda, her pencere bağımsız olarak normalize edildiği için her pencerenin en sonunda bir kırılma oluşturabilir.

Bu örnekte 4 veri noktası bundan etkilenecektir. Ancak elinizde 11.000 veri noktası olduğuna göre, 4 nokta bir sorun yaratmayacaktır.

# Train the Scaler with training data and smooth data
smoothing_window_size = 2500
for di in range(0,10000,smoothing_window_size):
    scaler.fit(train_data[di:di+smoothing_window_size,:])
    train_data[di:di+smoothing_window_size,:] = scaler.transform(train_data[di:di+smoothing_window_size,:])

# You normalize the last bit of remaining data
scaler.fit(train_data[di+smoothing_window_size:,:])
train_data[di+smoothing_window_size:,:] = scaler.transform(train_data[di+smoothing_window_size:,:])

Veriyi tekrar [data_size] şekline geri döndürün

# Reshape both train and test data
train_data = train_data.reshape(-1)

# Normalize test data
test_data = scaler.transform(test_data).reshape(-1)

Artık veriyi üssel hareketli ortalama ile yumuşatabilirsiniz. Bu, hisse fiyatlarının doğasında bulunan girintili çıkıntılı yapıyı azaltarak daha düzgün bir eğri elde etmenize yardımcı olur.

Not: Yalnızca eğitim verisini yumuşatmalısınız.

# Now perform exponential moving average smoothing
# So the data will have a smoother curve than the original ragged data
EMA = 0.0
gamma = 0.1
for ti in range(11000):
  EMA = gamma*train_data[ti] + (1-gamma)*EMA
  train_data[ti] = EMA

# Used for visualization and test purposes
all_mid_data = np.concatenate([train_data,test_data],axis=0)

Ortalama Alma ile Bir Adım İleri Tahmin

Ortalama alma mekanizmaları, gelecekteki hisse fiyatını daha önce gözlemlenen hisse fiyatlarının ortalaması olarak temsil ederek (genellikle bir adım ileri) tahmin yapmanıza olanak tanır. Bunu birden fazla zaman adımı için yapmak oldukça kötü sonuçlar üretebilir. İki ortalama alma tekniğine bakacaksınız: aşağıda standart ortalama ve üssel hareketli ortalama. Her iki algoritmanın ürettiği sonuçları nitel (görsel inceleme) ve nicel (Ortalama Kare Hata) olarak değerlendireceksiniz.

Ortalama Kare Hata (MSE), bir adım ilerideki gerçek değer ile tahmin edilen değer arasındaki Kare Hatanın alınması ve tüm tahminler üzerinde ortalamasının alınmasıyla hesaplanabilir.

Standart ortalama

Bu problemin zorluğunu, önce bunu bir ortalama hesaplama problemi olarak modellemeye çalışarak anlayabilirsiniz. Önce, gelecekteki hisse piyasası fiyatlarını (örneğin xt+1) sabit boyutlu bir pencere içindeki (örneğin xt-N, ..., xt) daha önce gözlemlenen hisse piyasası fiyatlarının ortalaması olarak (örneğin önceki 100 gün) tahmin etmeyi deneyeceksiniz. Sonrasında, biraz daha süslü bir “üssel hareketli ortalama” yöntemini deneyecek ve bunun ne kadar iyi sonuç verdiğini göreceksiniz. Ardından zaman serisi tahmininin “kutsal kasesi”ne, yani Uzun Kısa Süreli Bellek modellerine geçeceksiniz.

Önce normal ortalamanın nasıl çalıştığını göreceksiniz. Yani şöyle diyorsunuz,

normal average

Başka bir deyişle, $t+1$ anındaki tahminin, $t$ ile $t-N$ penceresi içinde gözlemlediğiniz tüm hisse fiyatlarının ortalama değeri olduğunu söylersiniz.

window_size = 100
N = train_data.size
std_avg_predictions = []
std_avg_x = []
mse_errors = []

for pred_idx in range(window_size,N):

    if pred_idx >= N:
        date = dt.datetime.strptime(k, '%Y-%m-%d').date() + dt.timedelta(days=1)
    else:
        date = df.loc[pred_idx,'Date']

    std_avg_predictions.append(np.mean(train_data[pred_idx-window_size:pred_idx]))
    mse_errors.append((std_avg_predictions[-1]-train_data[pred_idx])**2)
    std_avg_x.append(date)

print('MSE error for standard averaging: %.5f'%(0.5*np.mean(mse_errors)))
MSE error for standard averaging: 0.00418

Aşağıdaki ortalama sonuçlara bir göz atın. Hissenin gerçek davranışını oldukça yakından takip ediyorlar. Sırada daha doğru bir bir-adım tahmin yöntemi var.


plt.figure(figsize = (18,9))
plt.plot(range(df.shape[0]),all_mid_data,color='b',label='True')
plt.plot(range(window_size,N),std_avg_predictions,color='orange',label='Prediction')
#plt.xticks(range(0,df.shape[0],50),df['Date'].loc[::50],rotation=45)
plt.xlabel('Date')
plt.ylabel('Mid Price')
plt.legend(fontsize=18)
plt.show()

Peki yukarıdaki grafikler (ve MSE) ne söylüyor?

Çok kısa vadeli tahminler (bir gün sonrası) için o kadar da kötü bir model olmadığı görülüyor. Bu davranış mantıklıdır çünkü hisse fiyatları bir gecede 0’dan 100’e çıkmaz. Şimdi, daha süslü bir ortalama tekniğine, üssel hareketli ortalamaya bakacaksınız.

Üssel hareketli ortalama

İnternette çok karmaşık modeller kullanan ve borsanın neredeyse tam davranışını tahmin eden bazı yazılar görmüş olabilirsiniz. Ancak dikkat! Bunlar yararlı bir şey öğrenildiğinden değil, optik illüzyonlardan kaynaklanır. Aşağıda bu davranışı basit bir ortalama yöntemiyle nasıl tekrar üretebileceğinizi göreceksiniz.

Üssel hareketli ortalama yönteminde, $x_{t+1}$’i şöyle hesaplarsınız:

  • $x\_{t+1} = EMA\_{t} = \gamma \times EMA_{t-1} + (1-\gamma) x_t$ burada $EMA_0 = 0$ ve $EMA$ zaman içinde sürdürdüğünüz üssel hareketli ortalama değeridir.

Yukarıdaki denklem, temelde $t+1$ zaman adımından itibaren üssel hareketli ortalamayı hesaplar ve bunu bir adım ileri tahmin olarak kullanır. $\gamma$, en son tahminin EMA’ya katkısını belirler. Örneğin $\gamma=0.1$, mevcut değerin sadece %10’unu EMA’ya dahil eder. En son değerden yalnızca çok küçük bir pay aldığınız için, ortalamanın çok erken dönemlerde gördüğünüz daha eski değerleri korumasına imkân tanır. Aşağıda, bir adım ilerisini tahmin etmek için kullanıldığında ne kadar iyi göründüğüne bakın.

window_size = 100
N = train_data.size

run_avg_predictions = []
run_avg_x = []

mse_errors = []

running_mean = 0.0
run_avg_predictions.append(running_mean)

decay = 0.5

for pred_idx in range(1,N):

    running_mean = running_mean*decay + (1.0-decay)*train_data[pred_idx-1]
    run_avg_predictions.append(running_mean)
    mse_errors.append((run_avg_predictions[-1]-train_data[pred_idx])**2)
    run_avg_x.append(date)

print('MSE error for EMA averaging: %.5f'%(0.5*np.mean(mse_errors)))
MSE error for EMA averaging: 0.00003

plt.figure(figsize = (18,9))
plt.plot(range(df.shape[0]),all_mid_data,color='b',label='True')
plt.plot(range(0,N),run_avg_predictions,color='orange', label='Prediction')
#plt.xticks(range(0,df.shape[0],50),df['Date'].loc[::50],rotation=45)
plt.xlabel('Date')
plt.ylabel('Mid Price')
plt.legend(fontsize=18)
plt.show()

Üssel hareketli ortalama bu kadar iyiyse neden daha iyi modellere ihtiyacınız var?

True dağılımını takip eden kusursuz bir çizgiye oturduğunu görüyorsunuz (ve çok düşük MSE ile de doğrulanıyor). Pratik açıdan bakıldığında, yalnızca ertesi günün hisse piyasa değeriyle pek bir şey yapamazsınız. Şahsen benim istediğim, ertesi günün tam hisse piyasası fiyatı değil de, önümüzdeki 30 günde hisse fiyatları yükselecek mi yoksa düşecek mi? Bunu yapmayı deneyin ve EMA yönteminin yetersizliğini ortaya çıkarın.

Şimdi, pencereler halinde tahmin yapmayı deneyin (örneğin yalnızca ertesi gün yerine, sonraki 2 günlük pencereyi tahmin edin). O zaman EMA’nın ne kadar hataya sapabileceğini fark edeceksiniz. İşte bir örnek:

Gelecekte birden fazla adımı tahmin edin

Somutlaştırmak için, diyelim ki değerler $x_t=0.4$, $EMA=0.5$ ve $\gamma = 0.5$

  • Diyelim ki aşağıdaki denklemle çıktı elde ediyorsunuz
    • Xt+1 = EMAt = γ × EMAt-1 + (1 - γ)Xt
    • Dolayısıyla xt+1 = 0.5 × 0.5 + (1-0.5) × 0.4 = 0.45
    • Yani Xt+1 = EMAt = 0.45
  • Sonraki tahmin Xt+2 şöyle olur,
    • Xt+2 = γ × EMAt + (1-γ)Xt+1
    • Yani Xt+2 = γ × EMA_t + (1-γ) EMAt = EMAt
    • Bu örnekte de Xt+2 = Xt+1 = 0.45

Dolayısıyla, gelecekte kaç adım tahmin yaparsanız yapın, tüm gelecekteki tahmin adımları için aynı cevabı almaya devam edeceksiniz.

İşe yarar çıktılar elde etmek için bir çözüm, momentum tabanlı algoritmalara bakmaktır. Bunlar, (kesin değerlere değil) geçmiş yakın değerlerin yükselip yükselmediğine veya düşüp düşmediğine göre tahmin yapar. Örneğin, son birkaç gündür fiyatlar düşüyorsa, ertesi gün fiyatın muhtemelen daha düşük olacağını söyleyeceklerdir ki bu mantıklı gelir. Ancak siz daha karmaşık bir model kullanacaksınız: bir LSTM modeli.

Bu modeller, zaman serisi tahmini alanını kasıp kavuruyor çünkü zaman serisi verilerini modellemede çok iyiler. Veride gizli kalıplar olup olmadığını ve bunlardan yararlanıp yararlanamayacağınızı göreceksiniz.

LSTM’lere Giriş: Uzağa Dönük Hisse Hareketi Tahminleri

Uzun-kısa süreli bellek modelleri son derece güçlü zaman serisi modelleridir. Geleceğe yönelik keyfi sayıda adımı tahmin edebilirler. Bir LSTM modülü (veya hücresi) hem uzun hem kısa vadeli veriyi modellemesine olanak tanıyan 5 temel bileşene sahiptir.

  • Hücre durumu (ct) - Kısa ve uzun vadeli anıları depolayan hücrenin iç belleğini temsil eder.
  • Gizli durum (ht) - Gelecekteki hisse senedi fiyatlarını tahmin etmek için sonunda kullandığınız, mevcut girdi, önceki gizli durum ve mevcut hücre girdisine göre hesaplanan çıktı durum bilgisidir. Ayrıca, gizli durum bir sonraki tahmini yapmak için hücre durumunda depolanan kısa veya uzun vadeli anıları ya da her ikisini birden seçmeye karar verebilir.
  • Giriş kapısı (it) - Mevcut girdiden hücre durumuna ne kadar bilginin akacağını belirler.
  • Unutma kapısı (ft) - Mevcut girdi ile önceki hücre durumundan ne kadar bilginin mevcut hücre durumuna akacağını belirler.
  • Çıkış kapısı (ot) - Mevcut hücre durumundan gizli duruma ne kadar bilginin akacağını belirler; böylece gerekirse LSTM yalnızca uzun vadeli anıları veya kısa ve uzun vadeli anıları seçebilir.

Bir hücre aşağıda resmedilmiştir:

Bu öğelerin her birinin hesaplanmasına ilişkin denklemler aşağıdaki gibidir.

  • it = σ(WixXt + Wihht-1 + bi)
  • $\tilde{c}\_t = \sigma(W\_{cx}x\_t + W\_{ch}h_{t-1} + b_c)$
  • $f\_t = \sigma(W\_{fx}x\_t + W\_{fh}h_{t-1}+b_f)$
  • $c_t = f\_t c\_{t-1} + i_t \tilde{c}_t$
  • $o\_t = \sigma(W\_{ox}x\_t + W\_{oh}h_{t-1}+b_o)$
  • $h_t = o_t tanh(c_t)$

Daha iyi (daha teknik) bir LSTM anlayışı için bu makaleye başvurabilirsiniz.

TensorFlow, zaman serisi modellerini uygulamak için güzel bir API (RNN API) sunar. Uygulamalarınızda bunu kullanacaksınız.

Veri üretici

Önce modelinizi eğitmek için bir veri üretici uygulayacaksınız. Bu veri üreticide, art arda elde edilen num_unrollings adet girdi veri grubunu çıktısı ile birlikte veren .unroll_batches(...) adlı bir yöntem bulunacak; burada bir veri grubu [batch_size, 1] boyutundadır. Ardından her girdi veri grubunun karşılık gelen bir çıktı veri grubu olacaktır.

Örneğin num_unrollings=3 ve batch_size=4 ise sarılmış veri kümeleri şöyle görünebilir,

  • girdi verisi: $[x_0,x_10,x_20,x_30], [x_1,x_11,x_21,x_31], [x_2,x_12,x_22,x_32]$
  • çıktı verisi: $[x_1,x_11,x_21,x_31], [x_2,x_12,x_22,x_32], [x_3,x_13,x_23,x_33]$

Veri artırma

Ayrıca, modelinizi sağlamlaştırmak için, $x\_t$’nin çıktısını her zaman $x\_{t+1}$ olarak yapmayacaksınız. Bunun yerine, küçük bir pencere boyutuna sahip $x\_{t+1},x\_{t+2},\ldots,x_{t+N}$ kümesinden rastgele bir çıktı örnekleyeceksiniz.

Burada şu varsayımı yapıyorsunuz:

  • $x\_{t+1},x\_{t+2},\ldots,x_{t+N}$ birbirinden çok uzak olmayacaktır

Şahsen bunun hisse hareketi tahminleri için makul bir varsayım olduğunu düşünüyorum.

Aşağıda bir veri grubunun görsel olarak nasıl oluşturulduğunu gösteriyorsunuz.


class DataGeneratorSeq(object):

    def __init__(self,prices,batch_size,num_unroll):
        self._prices = prices
        self._prices_length = len(self._prices) - num_unroll
        self._batch_size = batch_size
        self._num_unroll = num_unroll
        self._segments = self._prices_length //self._batch_size
        self._cursor = [offset * self._segments for offset in range(self._batch_size)]

    def next_batch(self):

        batch_data = np.zeros((self._batch_size),dtype=np.float32)
        batch_labels = np.zeros((self._batch_size),dtype=np.float32)

        for b in range(self._batch_size):
            if self._cursor[b]+1>=self._prices_length:
                #self._cursor[b] = b * self._segments
                self._cursor[b] = np.random.randint(0,(b+1)*self._segments)

            batch_data[b] = self._prices[self._cursor[b]]
            batch_labels[b]= self._prices[self._cursor[b]+np.random.randint(0,5)]

            self._cursor[b] = (self._cursor[b]+1)%self._prices_length

        return batch_data,batch_labels

    def unroll_batches(self):

        unroll_data,unroll_labels = [],[]
        init_data, init_label = None,None
        for ui in range(self._num_unroll):

            data, labels = self.next_batch()    

            unroll_data.append(data)
            unroll_labels.append(labels)

        return unroll_data, unroll_labels

    def reset_indices(self):
        for b in range(self._batch_size):
            self._cursor[b] = np.random.randint(0,min((b+1)*self._segments,self._prices_length-1))



dg = DataGeneratorSeq(train_data,5,5)
u_data, u_labels = dg.unroll_batches()

for ui,(dat,lbl) in enumerate(zip(u_data,u_labels)):   
    print('\n\nUnrolled index %d'%ui)
    dat_ind = dat
    lbl_ind = lbl
    print('\tInputs: ',dat )
    print('\n\tOutput:',lbl)
Unrolled index 0
    Inputs:  [0.03143791 0.6904868  0.82829314 0.32585657 0.11600105]

    Output: [0.08698314 0.68685144 0.8329321  0.33355275 0.11785509]


Unrolled index 1
    Inputs:  [0.06067836 0.6890754  0.8325337  0.32857886 0.11785509]

    Output: [0.15261841 0.68685144 0.8325337  0.33421066 0.12106793]


Unrolled index 2
    Inputs:  [0.08698314 0.68685144 0.8329321  0.33078218 0.11946969]

    Output: [0.11098009 0.6848606  0.83387965 0.33421066 0.12106793]


Unrolled index 3
    Inputs:  [0.11098009 0.6858036  0.83294916 0.33219692 0.12106793]

    Output: [0.132895   0.6836884  0.83294916 0.33219692 0.12288672]


Unrolled index 4
    Inputs:  [0.132895   0.6848606  0.833369   0.33355275 0.12158521]

    Output: [0.15261841 0.6836884  0.83383167 0.33355275 0.12230608]

Hiperparametreleri tanımlama

Bu bölümde birkaç hiperparametre tanımlayacaksınız. D girdinin boyutsallığıdır. Oldukça basittir; önceki hisse fiyatını girdi olarak alır ve bir sonrakini tahmin edersiniz, bu da 1 olmalıdır.

Sonra num_unrollings var; bu, LSTM modelini optimize etmek için kullanılan zaman içinde geriye yayılım (BPTT) ile ilgili bir hiperparametredir. Bu, tek bir optimizasyon adımı için kaç kesintisiz zaman adımını ele aldığınızı belirtir. Bunu, tek bir zaman adımına bakarak optimize etmek yerine, ağı num_unrollings zaman adımına bakarak optimize etmek olarak düşünebilirsiniz. Ne kadar büyük olursa o kadar iyidir.

Ardından batch_size gelir. Yığın boyutu, tek bir zaman adımında kaç veri örneğini dikkate aldığınızı ifade eder.

Sonrasında num_nodes tanımlarsınız; bu, her hücredeki gizli nöron sayısını temsil eder. Bu örnekte üç katmanlı bir LSTM yapısı olduğunu görebilirsiniz.

D = 1 # Dimensionality of the data. Since your data is 1-D this would be 1
num_unrollings = 50 # Number of time steps you look into the future.
batch_size = 500 # Number of samples in a batch
num_nodes = [200,200,150] # Number of hidden nodes in each layer of the deep LSTM stack we're using
n_layers = len(num_nodes) # number of layers
dropout = 0.2 # dropout amount

tf.reset_default_graph() # This is important in case you run this multiple times

Girdi ve çıktıları tanımlama

Sonraki adımda eğitim girdileri ve etiketleri için yer tutucular tanımlarsınız. Bu oldukça basittir; her biri tek bir veri yığını içeren girdi yer tutucularından oluşan bir listeniz vardır. Ve bu liste, tek bir optimizasyon adımı için bir defada kullanılacak num_unrollings yer tutucu içerir.

# Input data.
train_inputs, train_outputs = [],[]

# You unroll the input over time defining placeholders for each time step
for ui in range(num_unrollings):
    train_inputs.append(tf.placeholder(tf.float32, shape=[batch_size,D],name='train_inputs_%d'%ui))
    train_outputs.append(tf.placeholder(tf.float32, shape=[batch_size,1], name = 'train_outputs_%d'%ui))

LSTM ve regresyon katmanının parametrelerini tanımlama

Üç katmanlı bir LSTM ve, son LSTM hücresinin çıktısını alıp bir sonraki zaman adımı tahminini üreten w ve b ile gösterilen bir doğrusal regresyon katmanınız olacak. Oluşturduğunuz üç LSTMCell nesnesini kapsüllemek için TensorFlow’daki MultiRNNCell’i kullanabilirsiniz. Ayrıca, performansı artırıp aşırı uyumu azaltan drop-out uygulamalı LSTM hücrelerine de sahip olabilirsiniz.

lstm_cells = [
    tf.contrib.rnn.LSTMCell(num_units=num_nodes[li],
                            state_is_tuple=True,
                            initializer= tf.contrib.layers.xavier_initializer()
                           )
 for li in range(n_layers)]

drop_lstm_cells = [tf.contrib.rnn.DropoutWrapper(
    lstm, input_keep_prob=1.0,output_keep_prob=1.0-dropout, state_keep_prob=1.0-dropout
) for lstm in lstm_cells]
drop_multi_cell = tf.contrib.rnn.MultiRNNCell(drop_lstm_cells)
multi_cell = tf.contrib.rnn.MultiRNNCell(lstm_cells)

w = tf.get_variable('w',shape=[num_nodes[-1], 1], initializer=tf.contrib.layers.xavier_initializer())
b = tf.get_variable('b',initializer=tf.random_uniform([1],-0.1,0.1))

LSTM çıktısını hesaplayıp son tahmini elde etmek için regresyon katmanına besleme

Bu bölümde önce, LSTM hücresinin hücre durumunu (c) ve gizli durumunu (h) tutacak TensorFlow değişkenlerini oluşturursunuz. Ardından, train_inputs listesini [num_unrollings, batch_size, D] şekline dönüştürürsünüz; bu, tf.nn.dynamic_rnn işleviyle çıktıları hesaplamak için gereklidir. Daha sonra tf.nn.dynamic_rnn işleviyle LSTM çıktıları hesaplanır ve çıktı tekrar num_unrolling tensörden oluşan bir listeye bölünür. tahminlerle gerçek hisse fiyatları arasındaki kayıp.

# Create cell state and hidden state variables to maintain the state of the LSTM
c, h = [],[]
initial_state = []
for li in range(n_layers):
  c.append(tf.Variable(tf.zeros([batch_size, num_nodes[li]]), trainable=False))
  h.append(tf.Variable(tf.zeros([batch_size, num_nodes[li]]), trainable=False))
  initial_state.append(tf.contrib.rnn.LSTMStateTuple(c[li], h[li]))

# Do several tensor transofmations, because the function dynamic_rnn requires the output to be of
# a specific format. Read more at: https://www.tensorflow.org/api_docs/python/tf/nn/dynamic_rnn
all_inputs = tf.concat([tf.expand_dims(t,0) for t in train_inputs],axis=0)

# all_outputs is [seq_length, batch_size, num_nodes]
all_lstm_outputs, state = tf.nn.dynamic_rnn(
    drop_multi_cell, all_inputs, initial_state=tuple(initial_state),
    time_major = True, dtype=tf.float32)

all_lstm_outputs = tf.reshape(all_lstm_outputs, [batch_size*num_unrollings,num_nodes[-1]])

all_outputs = tf.nn.xw_plus_b(all_lstm_outputs,w,b)

split_outputs = tf.split(all_outputs,num_unrollings,axis=0)

Kayıp hesaplama ve iyileştirici

Şimdi kaybı hesaplayacaksınız. Ancak, kayıp hesaplanırken benzersiz bir özellik olduğunu not etmelisiniz. Her bir tahmin ve gerçek çıktı yığını için Ortalama Kare Hata’yı hesaplarsınız. Ve bu ortalama kare kayıpların hepsini (ortalamasını değil) birlikte toplarsınız. Son olarak, sinir ağını optimize etmek için kullanacağınız iyileştiriciyi tanımlarsınız. Bu durumda, oldukça yeni ve iyi performans gösteren Adam’ı kullanabilirsiniz.

# When calculating the loss you need to be careful about the exact form, because you calculate
# loss of all the unrolled steps at the same time
# Therefore, take the mean error or each batch and get the sum of that over all the unrolled steps

print('Defining training Loss')
loss = 0.0
with tf.control_dependencies([tf.assign(c[li], state[li][0]) for li in range(n_layers)]+
                             [tf.assign(h[li], state[li][1]) for li in range(n_layers)]):
  for ui in range(num_unrollings):
    loss += tf.reduce_mean(0.5*(split_outputs[ui]-train_outputs[ui])**2)

print('Learning rate decay operations')
global_step = tf.Variable(0, trainable=False)
inc_gstep = tf.assign(global_step,global_step + 1)
tf_learning_rate = tf.placeholder(shape=None,dtype=tf.float32)
tf_min_learning_rate = tf.placeholder(shape=None,dtype=tf.float32)

learning_rate = tf.maximum(
    tf.train.exponential_decay(tf_learning_rate, global_step, decay_steps=1, decay_rate=0.5, staircase=True),
    tf_min_learning_rate)

# Optimizer.
print('TF Optimization operations')
optimizer = tf.train.AdamOptimizer(learning_rate)
gradients, v = zip(*optimizer.compute_gradients(loss))
gradients, _ = tf.clip_by_global_norm(gradients, 5.0)
optimizer = optimizer.apply_gradients(
    zip(gradients, v))

print('\tAll done')
Defining training Loss
Learning rate decay operations
TF Optimization operations
    All done

Tahminle ilgili hesaplamalar

Burada tahminle ilgili TensorFlow işlemlerini tanımlarsınız. İlk olarak girdi beslemek için bir yer tutucu (sample_inputs) tanımlayın, sonra eğitim aşamasına benzer şekilde tahmin için durum değişkenlerini (sample_c ve sample_h) tanımlayın. Son olarak tf.nn.dynamic_rnn işleviyle tahmini hesaplayın ve ardından çıktıyı regresyon katmanından (w ve b) geçirin. Ayrıca hücre durumu ve gizli durumu sıfırlayan reset_sample_state işlemini de tanımlamalısınız. Her tahmin dizisine başladığınızda bu işlemi çalıştırmalısınız.

print('Defining prediction related TF functions')

sample_inputs = tf.placeholder(tf.float32, shape=[1,D])

# Maintaining LSTM state for prediction stage
sample_c, sample_h, initial_sample_state = [],[],[]
for li in range(n_layers):
  sample_c.append(tf.Variable(tf.zeros([1, num_nodes[li]]), trainable=False))
  sample_h.append(tf.Variable(tf.zeros([1, num_nodes[li]]), trainable=False))
  initial_sample_state.append(tf.contrib.rnn.LSTMStateTuple(sample_c[li],sample_h[li]))

reset_sample_states = tf.group(*[tf.assign(sample_c[li],tf.zeros([1, num_nodes[li]])) for li in range(n_layers)],
                               *[tf.assign(sample_h[li],tf.zeros([1, num_nodes[li]])) for li in range(n_layers)])

sample_outputs, sample_state = tf.nn.dynamic_rnn(multi_cell, tf.expand_dims(sample_inputs,0),
                                   initial_state=tuple(initial_sample_state),
                                   time_major = True,
                                   dtype=tf.float32)

with tf.control_dependencies([tf.assign(sample_c[li],sample_state[li][0]) for li in range(n_layers)]+
                              [tf.assign(sample_h[li],sample_state[li][1]) for li in range(n_layers)]):  
  sample_prediction = tf.nn.xw_plus_b(tf.reshape(sample_outputs,[1,-1]), w, b)

print('\tAll done')
Defining prediction related TF functions
    All done

LSTM’yi çalıştırma

Burada birkaç dönem boyunca hisse fiyat hareketlerini eğitip tahmin edeceksiniz ve zamanla tahminlerin daha iyi mi daha kötü mü olduğuna bakacaksınız. Aşağıdaki prosedürü izlersiniz.

  • Modeli değerlendirmek için zaman serisi üzerinde bir başlangıç noktaları kümesi (test_points_seq) tanımlayın
  • Her dönem için
    • Eğitim verisinin tam dizi uzunluğu boyunca
      • num_unrollings adet sarılmış veri grubu oluşturun
      • Sarılmış veri gruplarıyla sinir ağını eğitin
    • Ortalama eğitim kaybını hesaplayın
    • Test kümesindeki her başlangıç noktası için
      • Test noktasından önce bulunan önceki num_unrollings veri noktası üzerinden yineleme yaparak LSTM durumunu güncelleyin
      • Önceki tahmini mevcut girdi olarak kullanarak art arda n_predict_once adım için tahmin yapın
      • Tahmin edilen n_predict_once nokta ile bu zaman damgalarındaki gerçek hisse fiyatları arasındaki MSE kaybını hesaplayın
epochs = 30
valid_summary = 1 # Interval you make test predictions

n_predict_once = 50 # Number of steps you continously predict for

train_seq_length = train_data.size # Full length of the training data

train_mse_ot = [] # Accumulate Train losses
test_mse_ot = [] # Accumulate Test loss
predictions_over_time = [] # Accumulate predictions

session = tf.InteractiveSession()

tf.global_variables_initializer().run()

# Used for decaying learning rate
loss_nondecrease_count = 0
loss_nondecrease_threshold = 2 # If the test error hasn't increased in this many steps, decrease learning rate

print('Initialized')
average_loss = 0

# Define data generator
data_gen = DataGeneratorSeq(train_data,batch_size,num_unrollings)

x_axis_seq = []

# Points you start your test predictions from
test_points_seq = np.arange(11000,12000,50).tolist()

for ep in range(epochs):       

    # ========================= Training =====================================
    for step in range(train_seq_length//batch_size):

        u_data, u_labels = data_gen.unroll_batches()

        feed_dict = {}
        for ui,(dat,lbl) in enumerate(zip(u_data,u_labels)):            
            feed_dict[train_inputs[ui]] = dat.reshape(-1,1)
            feed_dict[train_outputs[ui]] = lbl.reshape(-1,1)

        feed_dict.update({tf_learning_rate: 0.0001, tf_min_learning_rate:0.000001})

        _, l = session.run([optimizer, loss], feed_dict=feed_dict)

        average_loss += l

    # ============================ Validation ==============================
    if (ep+1) % valid_summary == 0:

      average_loss = average_loss/(valid_summary*(train_seq_length//batch_size))

      # The average loss
      if (ep+1)%valid_summary==0:
        print('Average loss at step %d: %f' % (ep+1, average_loss))

      train_mse_ot.append(average_loss)

      average_loss = 0 # reset loss

      predictions_seq = []

      mse_test_loss_seq = []

      # ===================== Updating State and Making Predicitons ========================
      for w_i in test_points_seq:
        mse_test_loss = 0.0
        our_predictions = []

        if (ep+1)-valid_summary==0:
          # Only calculate x_axis values in the first validation epoch
          x_axis=[]

        # Feed in the recent past behavior of stock prices
        # to make predictions from that point onwards
        for tr_i in range(w_i-num_unrollings+1,w_i-1):
          current_price = all_mid_data[tr_i]
          feed_dict[sample_inputs] = np.array(current_price).reshape(1,1)    
          _ = session.run(sample_prediction,feed_dict=feed_dict)

        feed_dict = {}

        current_price = all_mid_data[w_i-1]

        feed_dict[sample_inputs] = np.array(current_price).reshape(1,1)

        # Make predictions for this many steps
        # Each prediction uses previous prediciton as it's current input
        for pred_i in range(n_predict_once):

          pred = session.run(sample_prediction,feed_dict=feed_dict)

          our_predictions.append(np.asscalar(pred))

          feed_dict[sample_inputs] = np.asarray(pred).reshape(-1,1)

          if (ep+1)-valid_summary==0:
            # Only calculate x_axis values in the first validation epoch
            x_axis.append(w_i+pred_i)

          mse_test_loss += 0.5*(pred-all_mid_data[w_i+pred_i])**2

        session.run(reset_sample_states)

        predictions_seq.append(np.array(our_predictions))

        mse_test_loss /= n_predict_once
        mse_test_loss_seq.append(mse_test_loss)

        if (ep+1)-valid_summary==0:
          x_axis_seq.append(x_axis)

      current_test_mse = np.mean(mse_test_loss_seq)

      # Learning rate decay logic
      if len(test_mse_ot)>0 and current_test_mse > min(test_mse_ot):
          loss_nondecrease_count += 1
      else:
          loss_nondecrease_count = 0

      if loss_nondecrease_count > loss_nondecrease_threshold :
            session.run(inc_gstep)
            loss_nondecrease_count = 0
            print('\tDecreasing learning rate by 0.5')

      test_mse_ot.append(current_test_mse)
      print('\tTest MSE: %.5f'%np.mean(mse_test_loss_seq))
      predictions_over_time.append(predictions_seq)
      print('\tFinished Predictions')
Initialized
Average loss at step 1: 1.703350
    Test MSE: 0.00318
    Finished Predictions
  ...
  ...
  ...
Average loss at step 30: 0.033753
    Test MSE: 0.00243
    Finished Predictions

Tahminleri Görselleştirme

Eğitim miktarı arttıkça MSE kaybının azaldığını görebilirsiniz. Bu, modelin faydalı bir şey öğrendiğinin iyi bir göstergesidir. Bulgularınızı nicelleştirmek için, ağın MSE kaybını standart ortalama alma yaparken elde ettiğiniz MSE kaybıyla (0,004) karşılaştırabilirsiniz. LSTM’nin standart ortalama almadan daha iyi performans sergilediğini görebilirsiniz. Ve standart ortalamanın (mükemmel olmasa da) gerçek hisse fiyatı hareketlerini makul ölçüde takip ettiğini biliyorsunuz.

best_prediction_epoch = 28 # replace this with the epoch that you got the best results when running the plotting code

plt.figure(figsize = (18,18))
plt.subplot(2,1,1)
plt.plot(range(df.shape[0]),all_mid_data,color='b')

# Plotting how the predictions change over time
# Plot older predictions with low alpha and newer predictions with high alpha
start_alpha = 0.25
alpha  = np.arange(start_alpha,1.1,(1.0-start_alpha)/len(predictions_over_time[::3]))
for p_i,p in enumerate(predictions_over_time[::3]):
    for xval,yval in zip(x_axis_seq,p):
        plt.plot(xval,yval,color='r',alpha=alpha[p_i])

plt.title('Evolution of Test Predictions Over Time',fontsize=18)
plt.xlabel('Date',fontsize=18)
plt.ylabel('Mid Price',fontsize=18)
plt.xlim(11000,12500)

plt.subplot(2,1,2)

# Predicting the best test prediction you got
plt.plot(range(df.shape[0]),all_mid_data,color='b')
for xval,yval in zip(x_axis_seq,predictions_over_time[best_prediction_epoch]):
    plt.plot(xval,yval,color='r')

plt.title('Best Test Predictions Over Time',fontsize=18)
plt.xlabel('Date',fontsize=18)
plt.ylabel('Mid Price',fontsize=18)
plt.xlim(11000,12500)
plt.show() 

Mükemmel olmasa da, LSTM’ler çoğu zaman hisse fiyatı davranışını doğru tahmin edebiliyor gibi görünüyor. Unutmayın, yaklaşık 0 ile 1,0 aralığında tahminler yapıyorsunuz (yani gerçek hisse fiyatları değil). Bu sorun değil; çünkü fiyatların kendisini değil, hisse fiyatı hareketini tahmin ediyorsunuz.

Son Notlar

Umarım bu eğitim size faydalı olmuştur. Benim için de ödüllendirici bir deneyimdi. Bu eğitimde, hisse fiyatı hareketlerini doğru tahmin edebilen bir model tasarlamanın ne kadar zor olabileceğini öğrendim. Hisse fiyatlarını neden modellemeniz gerektiğine dair bir motivasyonla başladınız. Bunu veri indirmeye ilişkin açıklama ve kod izledi. Ardından, bir adım ilerisini tahmin etmeye olanak tanıyan iki ortalama alma tekniğine baktınız. Daha sonra, gelecekte birden fazla adımı tahmin etmeniz gerektiğinde bu yöntemlerin beyhude olduğunu gördünüz. Akabinde, LSTM’leri kullanarak geleceğe dönük çok sayıda adım için nasıl tahmin yapabileceğinizi tartıştınız. Son olarak, sonuçları görselleştirdiniz ve modelinizin (mükemmel olmasa da) hisse fiyatı hareketlerini doğru tahmin etmede oldukça iyi olduğunu gördünüz.

Derin öğrenme hakkında daha fazla bilgi edinmek isterseniz, mutlaka Python ile Derin Öğrenme kursumuza göz atın. Temelleri ve Keras ile kendi sinir ağınızı nasıl kuracağınızı kapsar. Bu, bu eğitimde kullanılacak TensorFlow’dan farklı bir pakettir, ancak fikir aynıdır.

Burada, bu eğitimden çıkarılacak birkaç ders sıralıyorum.

  1. Hisse fiyatı/hareketi tahmini son derece zor bir görevdir. Şahsen, dışarıdaki hiçbir hisse tahmin modelinin sorgusuz sualsiz kabullenilip körü körüne güvenilmemesi gerektiğini düşünüyorum. Ancak, modeller çoğu zaman hisse fiyatı hareketini doğru tahmin edebilir, ama her zaman değil.

  2. Gerçek hisse fiyatlarıyla mükemmel şekilde çakışan tahmin eğrileri gösteren yazılara aldanmayın. Bu, basit bir ortalama tekniğiyle de tekrarlanabilir ve pratikte işe yaramaz. Daha makul olan, hisse fiyatı hareketlerini tahmin etmektir.

  3. Modelin hiperparametreleri, elde ettiğiniz sonuçlara son derece duyarlıdır. Bu nedenle, hiperparametreler üzerinde bazı optimizasyon tekniklerini (örneğin, Izgara arama / Rastgele arama) çalıştırmak çok iyi olacaktır. Aşağıda en kritik hiperparametrelerden bazılarını listeledim:

    • İyileştiricinin öğrenme oranı
    • Katman sayısı ve her katmandaki gizli birim sayısı
    • İyileştirici. Ben Adam’ın en iyi performansı verdiğini gördüm
    • Model türü. GRU/ Standart LSTM/ Peephole’lu LSTM deneyebilir ve performans farkını değerlendirebilirsiniz
  4. Bu eğitimde hatalı bir şey yaptınız (veri setinin küçük olması nedeniyle)! Yani, öğrenme oranını düşürmek için test kaybını kullandınız. Bu, test kümesi hakkında bilgiyi dolaylı olarak eğitim prosedürüne sızdırır. Bunu ele almanın daha iyi yolu, ayrı bir doğrulama kümesine (test kümesinden farklı) sahip olmak ve öğrenme oranını doğrulama kümesi performansına göre düşürmektir.

Benimle iletişime geçmek isterseniz, thushv@gmail.com adresine e-posta atabilir veya LinkedIn’de bağlantı kurabilirsiniz.

Referanslar

Hisse tahminleri için LSTM’lerin nasıl kullanılacağını anlamak üzere bu depoya başvurdum. Ancak ayrıntılar, referansta bulunan uygulamadan büyük ölçüde farklı olabilir.

SSS

LSTM modelleri borsayı kesin olarak doğru tahmin edebilir mi?

Hayır, LSTM modelleri kesin doğru tahmin garantisi veremez; çünkü borsa son derece dalgalıdır ve geçmiş verilerin ötesindeki faktörlerden etkilenir. LSTM’ler eğilimleri ve örüntüleri belirlemeye yardımcı olabilir, ancak finansal kararlar için tek başına güvenilmemelidir.

Normalleştirme, hisse verilerinde LSTM tahminlerini nasıl iyileştirir?

Normalleştirme, veri değerlerinin benzer bir aralıkta yer almasını sağlayarak aykırı değerlerin etkisini azaltır ve model performansını iyileştirir. LSTM’nin mutlak değerlere değil, örüntülere odaklanmasına yardımcı olur; bu da eğitim için kritik önemdedir.

LSTM’lere geçmeden önce neden üssel hareketli ortalama (EMA) kullanılır?

Üssel hareketli ortalama, hisse verilerindeki dalgalanmaları yumuşatarak eğilimleri daha net görmenizi sağlar. Bu adım bir karşılaştırma tabanı sunar ve basit yöntemlerin LSTM’lere kıyasla sınırlamalarını ortaya koyar.

Bu eğitimdeki yaklaşımın bazı sınırlamaları nelerdir?

Bu eğitim, yeterli ve temiz geçmiş verilere erişimi varsayar. Modelin performansı, seçilen hiperparametreler, veri ön işleme adımları ve gerçek dünya hisse hareketlerinin öngörülemez doğasıyla da sınırlıdır.

LSTM modeli, bireysel şirketlerin hisse hareketlerini eşit derecede iyi tahmin edebilir mi?

Zorunlu değil. Modelin doğruluğu, volatilite ve likidite gibi hisse verisinin özelliklerine bağlıdır. En iyi sonuçlara ulaşmak için her bir hisse için test ve ince ayar gerekir.


Thushan Ganegedara's photo
Author
Thushan Ganegedara
Konular

Python ve Derin Öğrenme hakkında daha fazlasını öğrenin

Kurs

Python ile Deep Learning'e Giriş

4 sa
262.5K
Python'da Keras 2.0 kullanarak sinir ağlarının temellerini ve derin öğrenme modellerinin nasıl oluşturulacağını öğrenin.
Ayrıntıları GörRight Arrow
Kursa Başla
Devamını GörRight Arrow