機械学習とディープラーニング技術を用いた株価予測(Pythonコード付き)

はじめに

株式市場がどのように機能するかを予測することは、最も困難なことの一つです。 予測には非常に多くの要因があります–物理的要因と物理学的、合理的、非合理的な行動など。 これらのすべての側面は、株価が揮発性と高い精度で予測することは非常に困難にするために結合します。

この分野で機械学習をゲームチェンジャーとして使うことはできますか? 組織に関する最新の発表、四半期ごとの収益結果などの機能を使用します。 機械学習技術は、これまでに見たことのないパターンや洞察を発掘する可能性があり、これらを使用して確実に正確な予測を行うことができます。

株価予測、LSTM、機械学習

この記事では、上場企業の株価に関する過去のデータを扱います。 平均化や線形回帰のような単純なアルゴリズムから始めて、この会社の将来の株価を予測するための機械学習アルゴリズムのミックスを実装し、Auto ARIMAやLSTMのような高度な技術に移ります。

この記事の背後にあるコアアイデアは、これらのアルゴリズムがどのように実装されているかを紹介することです。 私は簡単に技術を説明し、必要に応じて概念をブラッシュアップするための関連するリンクを提供します。 あなたが時系列の世界への新人である場合、私は最初に次の記事を読むことをお勧めします:

  • 時系列予測を作成するための包括的な初心者ガイド
  • 時系列モデリングに関する完全なチュートリアル
  • 無料コース:Pythonを使用した時系列予測

時系列予測を実践するプロジェクト

時系列予測&モデリングは、データ分析において重要な役割を果たしています。 時系列分析は、計量経済学&運用研究などの分野で広く使用されている統計の専門分野です。

時系列は分析&データサイエンスで広く使用されています。 これはあなたのために特別に設計された時系列の問題であり、課題はトラフィックを予測することです。

今すぐ練習

あなたはあなたのデータサイエンスの旅を開始する場所を探している初心者ですか? あなたのためだけにキュレーションされた知識とデータサイエンスの学習の完全な包括的なコースを提示! このコースでは、機械学習の基礎から、ML、深層学習、時系列の高度な概念まで、すべてをカバーしています。

  • 認定AI&ML Blackbelt+プログラム

目次

    1. 問題文の理解
    2. 移動平均
    3. 線形回帰
    4. k-最近傍
    5. 自動ARIMA
    6. Prophet
    7. 長期短期記憶(LSTM)
    8. 長期記憶(LSTM)
    9. 長期記憶(LSTM)
    10. 長期記憶(LSTM)
    11. 長期記憶(Lstm)
    12. )

問題文の理解

この記事の実装部分についてはすぐに説明しますが、最初に解決しようとしていることを確立することが重要です。 基本的な分析と技術的な分析–広く、株式市場の分析は二つの部分に分かれています。

  • ファンダメンタル分析は、現在の事業環境と財務実績に基づいて、当社の将来の収益性を分析することを含みます。
  • 一方、テクニカル分析には、チャートを読んだり、統計数値を使用して株式市場の動向を特定したりすることが含まれます。

ご想像のとおり、私たちの焦点はテクニカル分析の部分になります。 私たちはQuandlのデータセットを使用します(ここではさまざまな株式の履歴データを見つけることができます)、この特定のプロジェクトでは、「Tata Global Beverages」のデー ダイブする時間!

注:ここでは、コードに使用したデータセットです:ダウンロード

私たちは、最初のデータセットをロードし、問題のターゲット変数を定義します:

#import packagesimport pandas as pdimport numpy as np#to plot within notebookimport matplotlib.pyplot as plt%matplotlib inline#setting figure sizefrom matplotlib.pylab import rcParamsrcParams = 20,10#for normalizing datafrom sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler(feature_range=(0, 1))#read the filedf = pd.read_csv('NSE-TATAGLOBAL(1).csv')#print the headdf.head()

データセットには、date、open、high、low、last、close、total_trade_quantity、およびturnoverという複数の変数があります。

  • 始値と終値は、特定の日に株式が取引される開始価格と最終価格を表します。
  • 高値、安値、最終は、その日の株式の最大値、最小値、および最終価格を表します。
  • 総取引数量は、その日に購入または売却された株式の数であり、売上高(Lacs)は、特定の日に特定の会社の売上高です。

もう一つ注意すべきことは、市場が週末と祝日に閉鎖されていることです。上記の表にも注意してください、いくつかの日付値が欠落しています–2/10/2018、6/10/2018、7/10/2018。 このうち、2日は国民の祝日であり、6日と7日は週末に当たる。

損益計算は、通常、その日の株式の終値によって決定されるため、終値を目標変数とみなします。 ターゲット変数をプロットして、データ内でどのように整形されているかを理解しましょう:

#setting index as datedf = pd.to_datetime(df.Date,format='%Y-%m-%d')df.index = df#plotplt.figure(figsize=(16,8))plt.plot(df, label='Close Price history')

今後のセクションでは、これらの変数を探索し、株式の毎日の終値を予測するためにさまざまなテクニックを使用します。

移動平均

はじめに

“平均”は、私たちが日常生活で使用する最も一般的なものの一つです。 例えば、全体的なパフォーマンスを決定するために平均マークを計算したり、今日の温度についてのアイデアを得るために過去数日間の平均気温を見つ だから、これは予測を行うために私たちのデータセットで使用するための良い出発点です。

各日の予測終値は、以前に観測された一連の値の平均になります。 単純平均を使用する代わりに、各予測に最新の値セットを使用する移動平均技術を使用します。 言い換えると、後続の各ステップについて、予測値が考慮され、最も古い観測値がセットから削除されます。 ここでは、これをより明確に理解するのに役立つ簡単な図があります。

この手法をデータセットに実装します。 最初のステップは、Date列とClose price列のみを含むdataframeを作成し、それをtrainとvalidationセットに分割して予測を検証することです。

実装

RMSEをチェックするだけでは、モデルがどのように実行されたかを理解するのに役立ちません。 より直感的な理解を得るためにこれを視覚化してみましょう。 ここでは、予測値と実際の値のプロットを示します。

#plotvalid = 0valid = predsplt.plot(train)plt.plot(valid])

推論

RMSE値は105に近いですが、結果はあまり有望ではありません(プロットから収集できるように)。 予測値は、列車セット内の観測値と同じ範囲です(最初は増加傾向があり、その後は緩やかな減少があります)。

次のセクションでは、一般的に使用される2つの機械学習技術–線形回帰とkNNを見て、それらが株式市場データでどのように機能するかを見ていきます。

線形回帰

はじめに

このデータに実装できる最も基本的な機械学習アルゴリズムは線形回帰です。 線形回帰モデルは、独立変数と従属変数との関係を決定する方程式を返します。

線形回帰の方程式は次のように書くことができます:

ここで、x1、x2、…。xnは独立変数を表し、係数λ1、λ2、…は独立変数を表す。 σ nは重みを表します。 次の記事を参照して、線形回帰をより詳細に調べることができます:

  • 線形、尾根と投げ縄回帰のための包括的な初心者ガイド。

私たちの問題文のために、我々は独立変数のセットを持っていません。 私たちは代わりに日付だけを持っています。 日付列を使用して、日、月、年、月/金などの機能を抽出しましょう。 そして、線形回帰モデルを近似します。

実装

最初にデータセットを昇順に並べ替え、次に別のデータセットを作成して、作成された新しいフィーチャが元のデータに影響を与えないようにします。

#setting index as date valuesdf = pd.to_datetime(df.Date,format='%Y-%m-%d')df.index = df#sortingdata = df.sort_index(ascending=True, axis=0)#creating a separate datasetnew_data = pd.DataFrame(index=range(0,len(df)),columns=)for i in range(0,len(data)): new_data = data new_data = data
#create featuresfrom fastai.structured import add_datepartadd_datepart(new_data, 'Date')new_data.drop('Elapsed', axis=1, inplace=True) #elapsed will be the time stamp

これにより、次のような機能が作成されます:

‘年’、’月’、’週’、’日’、’Dayofweek’、’Dayofyear’、’Is_Month_End’、’Is_Month_Start’、’Is_Quarter_End’、’Is_Quarter_Start’、’Is_Year_End’、および’Is_Year_Start’。注:fastaiライブラリのadd_datepartを使用しました。 インストールされていない場合は、コマンドpip install fastaiを使用するだけです。 それ以外の場合は、pythonの単純なforループを使用してこれらの機能を作成できます。 私は以下の例を示しました。

これとは別に、予測に関連すると思われる独自の機能セットを追加することができます。 たとえば、私の仮説は、週の最初と最後の日が潜在的に他の日よりもはるかに多くの株式の終値に影響を与える可能性があるということです。 そのため、特定の日が月曜日/金曜日か火曜日/水曜日/木曜日かを識別する機能を作成しました。 これは、次のコード行を使用して行うことができます:

new_data = 0for i in range(0,len(new_data)): if (new_data == 0 or new_data == 4): new_data = 1 else: new_data = 0

曜日が0または4の場合、列の値は1になり、それ以外の場合は0になります。 同様に、複数のフィーチャを作成できます。 あなたは株価を予測するのに役立つことができる機能のためのいくつかのアイデアを持っている場合は、コメント欄で共有してくださ

ここで、データをtrainとvalidationセットに分割して、モデルのパフォーマンスを確認します。

#split into train and validationtrain = new_datavalid = new_datax_train = train.drop('Close', axis=1)y_train = trainx_valid = valid.drop('Close', axis=1)y_valid = valid#implement linear regressionfrom sklearn.linear_model import LinearRegressionmodel = LinearRegression()model.fit(x_train,y_train)

#make predictions and find the rmsepreds = model.predict(x_valid)rms=np.sqrt(np.mean(np.power((np.array(y_valid)-np.array(preds)),2)))rms
121.16291596523156

RMSE値は以前の手法よりも高く、線形回帰の実行が不十分であることが明確に示されています。 プロットを見て、線形回帰がうまくいかなかった理由を理解しましょう:

#plotvalid = 0valid = predsvalid.index = new_data.indextrain.index = new_data.indexplt.plot(train)plt.plot(valid])

推論

線形回帰は単純な手法であり、解釈が非常に簡単ですが、いくつかの明らかな欠点があります。 回帰アルゴリズムを使用する際の1つの問題は、モデルが日付と月の列に適合しすぎていることです。 予測ポイントからの以前の値を考慮する代わりに、モデルは月前の同じ日付、または年前の同じ日付/月の値を考慮します。

上記のプロットからわかるように、2016年1月と2017年1月には株価が下落しました。 このモデルは、2018年1月にも同じことを予測しています。 線形回帰手法は、独立した特徴が目標値を決定するのに有用であるBig Mart salesなどの問題に対してうまく実行できます。

k-最近傍

はじめに

ここで使用できるもう一つの興味深いMLアルゴリズムはkNN(k最近傍)です。 独立変数に基づいて、kNNは新しいデータ点と古いデータ点の類似性を求めます。 これを簡単な例で説明しましょう。

11人の身長と年齢を考えてみましょう。 与えられた特徴(’Age’と’Height’)に基づいて、テーブルは以下に示すようにグラフィカルな形式で表すことができます:

ID#11の重みを決定するために、kNNはこのIDの最近傍の重みを考慮します。 ID#11の重みは、その近傍の平均であると予測されます。 今のところ3つの隣人(k=3)を考慮すると、ID#11の重みは次のようになります= (77+72+60)/3 = 69.66 kg。

kNNの詳細な理解については、次の記事を参照してください:

  • k-最近傍点の紹介: 簡略化された

  • 回帰のためのK-最近傍アルゴリズムの実用的な紹介

最後のセクションから同じ列車と検証セットを使用した実装

#importing librariesfrom sklearn import neighborsfrom sklearn.model_selection import GridSearchCVfrom sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler(feature_range=(0, 1))

:

#scaling datax_train_scaled = scaler.fit_transform(x_train)x_train = pd.DataFrame(x_train_scaled)x_valid_scaled = scaler.fit_transform(x_valid)x_valid = pd.DataFrame(x_valid_scaled)#using gridsearch to find the best parameterparams = {'n_neighbors':}knn = neighbors.KNeighborsRegressor()model = GridSearchCV(knn, params, cv=5)#fit the model and make predictionsmodel.fit(x_train,y_train)preds = model.predict(x_valid)

結果

#rmserms=np.sqrt(np.mean(np.power((np.array(y_valid)-np.array(preds)),2)))rms
115.17086550026721

RMSE値に大きな違いはありませんが、予測値と実際値のプロットはより明確な理解を提供する必要があります。

#plotvalid = 0valid = predsplt.plot(valid])plt.plot(train)

推論

RMSE値は線形回帰モデルとほぼ同様で、プロットは同じパターンを示します。 線形回帰と同様に、kNNは過去数年間のパターンであったため、2018年1月にも低下していることを確認しました。 このデータセットでは回帰アルゴリズムがうまく機能していないと言うことができます。

先に進んで、この株価予測の課題に直面したときにどのように実行されるかを調べるために、いくつかの時系列予測技術を見てみましょう。

Auto ARIMA

はじめに

ARIMAは、時系列予測のための非常に一般的な統計手法です。 ARIMAモデルは、将来の値を予測するために、過去の値を考慮に入れます。 ARIMAには3つの重要なパラメータがあります:

  • p(次の値を予測するために使用される過去の値)
  • q(将来の値を予測するために使用される過去の予測誤差)
  • d(差分の順序)

ARIMAのパラメータ調整には多くの時間がかかります。 したがって、最小のエラーを提供する(p、q、d)の最良の組み合わせを自動的に選択するauto ARIMAを使用します。 Auto ARIMAの仕組みの詳細については、この記事を参照してください:

  • Auto ARIMAを使用した高性能時系列モデルの構築

実装

from pyramid.arima import auto_arimadata = df.sort_index(ascending=True, axis=0)train = datavalid = datatraining = trainvalidation = validmodel = auto_arima(training, start_p=1, start_q=1,max_p=3, max_q=3, m=12,start_P=0, seasonal=True,d=1, D=1, trace=True,error_action='ignore',suppress_warnings=True)model.fit(training)forecast = model.predict(n_periods=248)forecast = pd.DataFrame(forecast,index = valid.index,columns=)

結果

rms=np.sqrt(np.mean(np.power((np.array(valid)-np.array(forecast)),2)))rms
44.954584993246954
#plotplt.plot(train)plt.plot(valid)plt.plot(forecast)

推論

前に見たように、自動ARIMAモデルは過去のデータを使用して時系列のパターンを理解します。 これらの値を使用して、モデルはシリーズの増加傾向を捉えました。 この手法を使用した予測は、以前に実装された機械学習モデルよりもはるかに優れていますが、これらの予測はまだ実際の値に近くありません。

プロットから明らかなように、モデルはシリーズの傾向を捉えていますが、季節的な部分には焦点を当てていません。 次のセクションでは、系列の傾向と季節性の両方を考慮した時系列モデルを実装します。

Prophet

はじめに

在庫予測データセットに実装できる多くの時系列手法がありますが、これらの手法のほとんどは、モデルを近似する前に大量のデータ Facebookによって設計され、開拓されたProphetは、データの前処理を必要とせず、実装が非常に簡単な時系列予測ライブラリです。 Prophetの入力は、dateとtarget(dsとy)の2つの列を持つdataframeです。

Prophetは、過去のデータの季節性をキャプチャしようとし、データセットが大きい場合にうまく機能します。 ここでは、シンプルで直感的な方法で預言者を説明する興味深い記事です:

  • Facebookの預言者を使用して、迅速かつ正確な時系列予測を生成します。

実装

#importing prophetfrom fbprophet import Prophet#creating dataframenew_data = pd.DataFrame(index=range(0,len(df)),columns=)for i in range(0,len(data)): new_data = data new_data = datanew_data = pd.to_datetime(new_data.Date,format='%Y-%m-%d')new_data.index = new_data#preparing datanew_data.rename(columns={'Close': 'y', 'Date': 'ds'}, inplace=True)#train and validationtrain = new_datavalid = new_data#fit the modelmodel = Prophet()model.fit(train)#predictionsclose_prices = model.make_future_dataframe(periods=len(valid))forecast = model.predict(close_prices)

結果

#rmseforecast_valid = forecastrms=np.sqrt(np.mean(np.power((np.array(valid)-np.array(forecast_valid)),2)))rms
57.494461930575149
#plotvalid = 0valid = forecast_valid.valuesplt.plot(train)plt.plot(valid])

推論

Prophet(ほとんどの時系列予測技術と同様)は、過去のデータから傾向と季節性をキャプチャしようとします。 このモデルは通常、時系列データセットではうまく機能しますが、この場合は評判にはなりません。

結局のところ、株価は特定の傾向や季節性を持っていません。 それは現在市場で何が起こっているのかに大きく依存し、したがって価格が上昇したり下落したりします。 したがって、ARIMA、SARIMA、Prophetのような予測技術は、この特定の問題に対して良い結果を示さないでしょう。

私たちは先に行くと、別の高度な技術を試してみましょう–長期短期記憶(LSTM)。

長期短期記憶(LSTM)

はじめに

Lstmはシーケンス予測問題に広く使用されており、非常に効果的であることが証明されています。 彼らがうまく機能する理由は、LSTMが重要な過去の情報を保存し、そうでない情報を忘れることができるからです。 LSTMには3つのゲートがあります:

  • 入力ゲート: 入力ゲートはセル状態に情報を追加します
  • 忘れゲート:モデルで不要になった情報を削除します
  • 出力ゲート:LSTMの出力ゲートは、出力として表示する情報を選

LSTMとそのアーキテクチャの詳細については、以下の記事を参照してください:

  • 長期短期記憶の概要

今のところ、私たちはブラックボックスとしてLSTMを実装し、私たちの特定のデータのパフォーマンスをチェックしてみましょう。

実装

#importing required librariesfrom sklearn.preprocessing import MinMaxScalerfrom keras.models import Sequentialfrom keras.layers import Dense, Dropout, LSTM#creating dataframedata = df.sort_index(ascending=True, axis=0)new_data = pd.DataFrame(index=range(0,len(df)),columns=)for i in range(0,len(data)): new_data = data new_data = data#setting indexnew_data.index = new_data.Datenew_data.drop('Date', axis=1, inplace=True)#creating train and test setsdataset = new_data.valuestrain = datasetvalid = dataset#converting dataset into x_train and y_trainscaler = MinMaxScaler(feature_range=(0, 1))scaled_data = scaler.fit_transform(dataset)x_train, y_train = , for i in range(60,len(train)): x_train.append(scaled_data) y_train.append(scaled_data)x_train, y_train = np.array(x_train), np.array(y_train)x_train = np.reshape(x_train, (x_train.shape,x_train.shape,1))# create and fit the LSTM networkmodel = Sequential()model.add(LSTM(units=50, return_sequences=True, input_shape=(x_train.shape,1)))model.add(LSTM(units=50))model.add(Dense(1))model.compile(loss='mean_squared_error', optimizer='adam')model.fit(x_train, y_train, epochs=1, batch_size=1, verbose=2)#predicting 246 values, using past 60 from the train datainputs = new_data.valuesinputs = inputs.reshape(-1,1)inputs = scaler.transform(inputs)X_test = for i in range(60,inputs.shape): X_test.append(inputs)X_test = np.array(X_test)X_test = np.reshape(X_test, (X_test.shape,X_test.shape,1))closing_price = model.predict(X_test)closing_price = scaler.inverse_transform(closing_price)

結果

rms=np.sqrt(np.mean(np.power((valid-closing_price),2)))rms
11.772259608962642
#for plottingtrain = new_datavalid = new_datavalid = closing_priceplt.plot(train)plt.plot(valid])

推論

うわー! LSTMモデルは、LSTM層の数の変更、ドロップアウト値の追加、エポック数の増加など、さまざまなパラメータに対して調整することができます。 しかし、lstmからの予測は、株価が増減するかどうかを特定するのに十分ですか? 確かにない!

記事の冒頭で述べたように、株価は、会社に関するニュースや、会社のdemonetizationや合併/demergerなどの要因の影響を受けます。 多くの場合、事前に予測することは不可能であることができるだけでなく、特定の無形の要因があります。

エンドノート

時系列予測は、私がこれらの記事を書いている間に実現したように、非常に興味深い分野です。 コミュニティには複雑な分野であるという認識があり、そこには真実の粒がありますが、基本的な技術のこつを得ればそれほど難しくありません。

コメントを残す

メールアドレスが公開されることはありません。