株価予測2　Chapter2

[Aidemy](https://aidemy.net/)　2020/10/30
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、株価予測の2つ目の投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。

今回学ぶこと
・③日経平均株価の時系列データを取得する
・④株価の上下を予測するモデルを作成する

#③日経平均株価の時系列データを取得する
##時系列データ取得の流れ
ⅰ　株価の時系列データを取得し、DataFrame化
ⅱ　データの「終値」以外の項目を削除し、日付でソート
ⅲ　ツイートデータと時系列データを結合

###ⅰ　株価の時系列データを取得し、DataFrame化
・今回も__「pd.read_csv()」__を使うのだが、URLからcsvを取得するので、「スクレイピング1」で学んだ__urllib.requestモジュール__を使ってURLを指定する必要がある。そのため、これらの処理をまとめた「read_csv」関数を自分で作成する。
・まずURLを__urllib.request.urlopen()__で開き、それを__read()__で読み込み、__decode('shift_jis')__でデコードする。ここまで行ったら通常のcsvファイルと同様に__「pd.read_csv」__でDataFrameとして取得できる。

・コード
![スクリーンショット 2020-10-20 17.14.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/0da07343-7a46-3fff-d60c-770f44145055.png)

###ⅱ　データの「終値」以外の項目を削除し、日付でソート
・今回の予測では__「データ日付」__と__「終値」__のみを使うので、__それ以外を削除する__。また、データを__日付でソート__したいので、「データ日付」を__index化してソートする__。
・__「pd.to_datetime()」__で「データ日付」を時系列データとして扱う。また__「set_index()」__でこれをindexにする。
・今回使わないデータである__['始値','高値','安値']__は__「drop()」__で削除し、__「sort_index(ascending=True)」__で日付を昇順（古い順）で並べ替える。

・コード
![スクリーンショット 2020-10-20 18.24.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/4a9c4570-8437-04a6-d587-ff97facb7744.png)

###ⅲ　ツイートデータと時系列データを結合
・前々項で作成し、前項で整理した時系列データ__「df」__と、Chapter1で作成しPN値と紐付けしたツイートデータ__「df_tweets」__を__「join()」__で結合し、__「dropna()」__でNaNを削除する。それを__「to_csv()」__で「table.csv」として保存する。

・コード![スクリーンショット 2020-10-20 18.40.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/e66eda5b-959c-bb46-2e0b-fa7d9051bc85.png)

・出力結果（一部のみ）
![スクリーンショット 2020-10-20 20.46.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/aa5858a1-5c91-ee4a-45ee-552af3524028.png)


#④日毎のsentimentから、次の日の株価の上下を予測するモデルを作成する。
##株価予測の流れ
ⅰ　データを分割し、indexが「日付」、columnが「pn値」「終値」のデータを作る
ⅱ　indexが「日付」、columnが「pn値」「終値」のデータを作る
ⅲ　訓練データについて株価（終了値）とPN値の前日との差を算出する
ⅳ　i日目の直近三日間の株価（終了値）とPN値の差を取得し、特徴量として算出する
Ⅴ　特徴量からモデルを作る

###ⅰ　データを分割し標準化を行う
・今回は__「テクニカル分析」__で株価予測を行う。この方法では、__過去3日間の平均株価の時系列の変化（差）とPN値の変化（差）__を特徴量として次の日の株価の上下の予測を行う。
・はじめに、前項で作った、一日ごとの「PN値」「終値」が格納されたデータ「table」を__訓練データとテストデータに分割する__。分割には__「train_test_split()」__を使う。「X」には__PN値__を格納し、「y」には__終値__を格納する。
・次に訓練データ（のPN値）を__標準化__し、__訓練データの平均と分散を使って__テストデータも標準化する。

・コード
![スクリーンショット 2020-10-20 21.00.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/357457ce-fada-27d0-5b33-d5ac361ee6ec.png)

###ⅱ　indexが「日付」、columnが「pn値」「終値」のデータを作る
・標準化まで行ったら、次は訓練データとテストデータを__DataFrame化__する。columnは__「PN値」「終値」__とし、それぞれ__「標準化したX」と「y」__を格納する。また、__indexは日付とする__。
・次項以降でも使えるように、作成したDataFrameをcsvとして保存する。

・コード
![スクリーンショット 2020-10-20 21.18.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/c3ac1bf6-3672-a46c-3808-a91f5aa3b484.png)

###ⅲ　訓練データについて株価（終了値）とPN値の前日との差を算出する
・__過去3日間のPN値と終値の変化（差）を算出することが目的__なので、まずは__一日あたりの変化を算出できるようにデータを処理する__。
・まずは前項で作成したdf_train.csvを開く。また、直後にこのDataFrameを分割するので、要素ごとに格納できるように空のリストを準備しておく。具体的には、日付を格納する「exchange_dates」、PN値を格納する「pn_rates」、１つ前の行のPN値との差を求めた「pn_rates_diff」、同様に株価（終値）を格納する「exchange_rates」、１つ前の行の株価との差を求めた「exchange_rates_diff」を空のリストとして用意しておく。
・加えて、前日のPN値、終値である「prev_pn」「prev_exch」も準備しておく。

・ここまで行ったら、__DataFrameを分割していく__。一日ずつ扱いたいので、__一行ずつ取り出す__。各行について、__「,」で分割__していき、1列目が日付、2列目がPN値、3列目が株価となっているので、それぞれ__先に作った空のリストに格納していく__。
・同様に、１つ前の行のPN値/株価との差を求めたものを、空のリストに格納する。
・for文の最後で__「prev_pn」「prev_exch」__に__現在の値を入れる__ことで、次の繰り返しの時には前日のデータとして扱える。

・コード
![スクリーンショット 2020-10-20 22.52.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/b6651f43-d78a-eeca-d4c8-ea7c2817b9c4.png)


###ⅳ　i日目の直近三日間の株価（終了値）とPN値の差を取得し、特徴量として算出する
・一日あたりの変化を記述できたら、同じように__3日ごとの変化も記述していく__。
・インデックス番号（日付）の指定のために、まずは__何日ごとに区切るか__の値を変数「INPUT_LEN」に格納する。同様に、直近三日間の変化を格納する「tr_input_mat」、基準となる日（i日目）の株価の上下を格納する「tr_angle_mat」をそれぞれ空のリストとして準備しておく。
・次に、PN値の変化データの長さ「data_len」の範囲内にある任意の__i日目について__、__INPUT_LEN日間のPN値と株価の変化__をtmp_arrという空のリストに併せて格納し、これを一つ上の次元の「tr_input_mat」に格納する。
・同様に、i日目の株価の変化（exchange_rates_diff）について、__プラスなら「1」マイナスなら「0」__として、株価の上下を格納する「tr_angle_mat」に格納する。

・ここまでで作成した、「tr_input_mat」と「tr_angle_mat」を__NumPy形式にして__、__「train_feature_arr」__(学習データ)、__「train_label_arr」__(教師ラベル)とすることで、ようやくモデルに渡せるデータが完成。

・ここまでの説明と以下のコードは全て訓練データについてのものだが、モデルの作成には当然テストデータも必要なので、__テストデータについてもⅲとⅳを同じように行う必要がある__。

・コード
![スクリーンショット 2020-10-20 22.52.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698700/f317e233-7a1d-5ff0-0309-9a124d78c65d.png)


###Ⅴ　特徴量からモデルを作る
・訓練データとテストデータの学習データと教師ラベルを作ったら、これらを使ってついにモデルを構築することができる。
・予測モデルは__ロジスティック回帰、SVM、ランダムフォレストで作成__し、それぞれの予測精度を比べる。
・（復習）モデルの学習は__「model.fit()」__、適用は__「model.format()」__で行う。

#まとめ
・時系列データの取得は、日経平均株価の時系列データを__URLで取得__し、デコードなどの必要な処理を行ったら__csvファイルで取得__する。取得したら、__使わない列は削除する__。
・株価予測モデルの作成では、まず__モデルに渡すデータを作成する必要がある__。__「i日目の直近三日間の株価（終了値）の差とPN値の差」__が学習データ、__「株価が上がったか下がったか」__が教師ラベルとなるので、頑張ってこれらを作成する。
・モデルの作成自体は__「model.fit()」__で良い。

今回は以上です。最後まで読んでいただき、ありがとうございました。