質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.64%

python3,エラー,株価予想,ディープラーニング

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 1,016

Mario5226

score 8

開発環境
jupyter note book
株価予想をする本を読んで書いてみましたが、改善しません。

# 扱いやすくするためにindexを通常の列に戻す
temporary_data_excess_returns = data_with_excess_returns.reset_index()  

# read financial data
financial_data = pd.read_pickle(f'{DATA_CHAPTER1}financial_data_all.pickle')

# 利用しない列を削除
financial_data.drop(
    columns=['発行済株式数', '日時'],
    inplace=True
)  

# 決算発表当日の株価データとマージできるように、株価データに決算発表日を張る
group_by_security = temporary_data_excess_returns.groupby('SC')

temporary_list = []
for security, values in tqdm(group_by_security):
    # 財務データから決算発表日を取得 
    # 例: array(
    #         ['2016-05-11T00:00:00.000000000',
    #          '2017-05-11T00:00:00.000000000'],
    #         dtype='datetime64[ns]'
    #     )
    announcement_dates = financial_data[
        '決算発表日(本決算)'
    ][
        financial_data.SC == security
    ].dropna().unique() 
    # 古い順にソートしてnp.arrayに戻す
    announcement_dates = pd.Series(announcement_dates).sort_values().values

    # 収益率データの「日時」が含まれる決算期を意味するカテゴリカル変数を作る。
    # 例: 「日時」が2016-05-11より前 → 欠損値、 
    #     「日時」が2016-05-11~2017-05-10 → 2016-05-11、など

temporary_data_excess_returns = pd.concat(temporary_list)
temporary_data_excess_returns.rename(
    columns={'announcement_date':'決算発表日(日時)'},
    inplace=True
)
del temporary_list

# 財務データを決算発表日について一意にする
financial_data = financial_data.groupby(
    ['SC', '決算発表日(本決算)']
).first().reset_index()

excess_returns_with_financial_data = pd.merge(
    temporary_data_excess_returns,
    financial_data,
    left_on=['SC','名称', '決算発表日(日時)'],
    right_on=['SC','名称', '決算発表日(本決算)'],
    how='left'
)
excess_returns_with_financial_data.set_index(
    ['SC', '日時'],
    inplace=True,
    verify_integrity=True
)

del temporary_data_excess_returns


このコードを実行すると

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-46-089790d4229f> in <module>
     34     #     「日時」が2016-05-112017-05-102016-05-11、など
     35 
---> 36 temporary_data_excess_returns = pd.concat(temporary_list)
     37 temporary_data_excess_returns.rename(
     38     columns={'announcement_date':'決算発表日(日時)'},

~\Anaconda3\lib\site-packages\pandas\core\reshape\concat.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, sort, copy)
    253         verify_integrity=verify_integrity,
    254         copy=copy,
--> 255         sort=sort,
    256     )
    257 

~\Anaconda3\lib\site-packages\pandas\core\reshape\concat.py in __init__(self, objs, axis, join, join_axes, keys, levels, names, ignore_index, verify_integrity, copy, sort)
    302 
    303         if len(objs) == 0:
--> 304             raise ValueError("No objects to concatenate")
    305 
    306         if keys is None:

ValueError: No objects to concatenate


と、エラーが出てしまい調べてみていろいろとコードを追加しましたが、改善しません。
どなたか原因分かりませんでしょうか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Mario5226

    2020/02/09 16:12 編集

    確かに言われてみて確認をしてみました。すると数行抜けている場所があり修正してみたところ。また新たなエラーが発生してしまいました。
    以下コード
    # 扱いやすくするためにindexを通常の列に戻す
    temporary_data_excess_returns = data_with_excess_returns.reset_index()

    # read financial data
    financial_data = pd.read_pickle(f'{DATA_CHAPTER1}financial_data_all.pickle')

    # 利用しない列を削除
    financial_data.drop(
    columns=['発行済株式数', '日時'],
    inplace=True
    )

    # 決算発表当日の株価データとマージできるように、株価データに決算発表日を張る
    group_by_security = temporary_data_excess_returns.groupby('SC')

    temporary_list = []
    for security, values in tqdm(group_by_security):
    # 財務データから決算発表日を取得
    # 例: array(
    # ['2016-05-11T00:00:00.000000000',
    # '2017-05-11T00:00:00.000000000'],
    # dtype='datetime64[ns]'
    # )
    announcement_dates = financial_data[
    '決算発表日(本決算)'
    ][
    financial_data.SC == security
    ].dropna().unique()
    # 古い順にソートしてnp.arrayに戻す
    announcement_dates = pd.Series(announcement_dates).sort_values().values

    # 収益率データの「日時」が含まれる決算期を意味するカテゴリカル変数を作る。
    # 例: 「日時」が2016-05-11より前 → 欠損値、
    # 「日時」が2016-05-11~2017-05-10 → 2016-05-11、など
    temporary_list.append(aligned)
    temporary_list.append(aligned)
    aligned = values.assign(
    announcement_date=lambda x: pd.cut(
    x['日時'],
    (
    list(announcement_dates)
    ) + [np.datetime64(values['日時'].max() + pd.offsets.Day())],
    labels=announcement_dates,
    right=False
    ).astype(
    np.datetime64
    )
    )


    temporary_data_excess_returns = pd.concat(temporary_list)
    temporary_data_excess_returns.rename(
    columns={'announcement_date':'決算発表日(日時)'},
    inplace=True
    )
    del temporary_list

    # 財務データを決算発表日について一意にする
    financial_data = financial_data.groupby(
    ['SC', '決算発表日(本決算)']
    ).first().reset_index()

    excess_returns_with_financial_data = pd.merge(
    temporary_data_excess_returns,
    financial_data,
    left_on=['SC','名称', '決算発表日(日時)'],
    right_on=['SC','名称', '決算発表日(本決算)'],
    how='left'
    )
    excess_returns_with_financial_data.set_index(
    ['SC', '日時'],
    inplace=True,
    verify_integrity=True
    )

    del temporary_data_excess_returns

    エラーコード
    ---------------------------------------------------------------------------
    NameError Traceback (most recent call last)
    <ipython-input-14-f40e00edb24f> in <module>
    44 # 例: 「日時」が2016-05-11より前 → 欠損値、
    45 # 「日時」が2016-05-11~2017-05-10 → 2016-05-11、など
    ---> 46 temporary_list.append(aligned)
    47 temporary_list.append(aligned)
    48 aligned = values.assign(

    NameError: name 'aligned' is not defined
    となってしまいました。
    またまた、アドバイスが欲しいです。

    キャンセル

  • meg_

    2020/02/09 16:16

    alignedという変数が未定義のまま使用されているのでエラーが出ます。
    本通りのコードであればバグですね。本当にこの順番でコードが掲載されているのであれば、書籍の訂正が出ていないか確認した方が良いでしょう。

    キャンセル

  • Mario5226

    2020/02/09 16:27

    その前のプログラムやいろいろと送りますが、改善できるようなプログラムを書いていただくようなことは難しいでしょうか。私は知識不足で2週間ほどずっと同じ内容でエラーが起きていて進展がありません。
    面倒だったりお時間がないようでしたら結構ですが、できればお願いしたいのですが。

    キャンセル

回答 1

checkベストアンサー

0

TensorFlowではじめる 株式投資のためのディープラーニング    ですね。(p.92)
本の通りにやったらできましたよ。以下のコードが欠損してますが大丈夫ですか?

    aligned = values.assign(
        announcement_date = lambda x: pd.cut(
            x['日時'],
            (
                list(announcement_dates)
            ) + [np.datetime64(values['日時'].max() + pd.offsets.Day())],
            labels = announcement_dates,
            right=False
        ).astype(
            np.datetime64
        )
    )
    temporary_list.append(aligned)

Notebook を再起動したときは各ブロックのimport したライブラリを、[run] ボタンでリロードしてますか。一応、写経したコードを貼っておきます。
追記)
エラーが出た箇所の、tqdm, datetime のインポート表記を変更・追加をしました。

from IPython.core.display import display

from os import path
import re
import pandas as pd
import numpy as np
from tqdm.notebook import tqdm
import datetime

# データの保存場所を指定
# この場合は、C:/Users/hoge/Anaconda3/linear_regression/ を読み書きする

WORK_DIR = 'C:/Users/hoge/Anaconda3/linear_regression/'
DATA_DIR = 'C:/Users/hoge/Anaconda3/linear_regression/data/'
DATA_CHAPTER1 = 'C:/Users/hoge/Anaconda3/data/download_data/'

daily_data = pd.read_pickle(f"{DATA_CHAPTER1}daily_data.pickle")

# 銘柄ごとに計算するため、証券コード(SC)で集計する
groups = daily_data.groupby('SC')

data_set = []
for security, values in tqdm(groups):
    # 全体の10%以上の取引日で取引のない銘柄は無視する
    if values['株価'].isnull().sum() > values.shape[0]*0.1:
        continue

    # 一時的に market_value 列を作って計算する
    # 証券コード(SC)12 は株価指数を表しているので、単純に指数値を入れる
    if security in {1, 2}:
        values = values.assign(market_value = lambda x: x['株価'])
    else:
        values = values.assign(market_value = lambda x: x['時価総額(百万円)'])

    # calculation return
    values = values.sort_values('日時') # 時系列でソート
    values['収益率'] = values['market_value'].pct_change() # 変化率の計算
    values.drop(columns = ['market_value']) # 一時的な列を削除
    data_set.append(values)

daily_data_adj = pd.concat(data_set) # 銘柄ごとに計算したものを結合

# 極端な値を外れ値として削除。ここでは上下 0.1% を外れ値とする
threshold = 0.001

lower = daily_data_adj['収益率'].quantile(threshold)
upper = daily_data_adj['収益率'].quantile(1-threshold)

daily_data_adj = daily_data_adj[
    (lower < daily_data_adj['収益率']) & (daily_data_adj['収益率'] < upper)
].copy()

#############################################################

jgb_path = f'{DATA_DIR}risk_free_rate/jgbcm_all.csv'
risk_free_rate = pd.read_csv(
    jgb_path,
    skiprows=1,
    usecols=['基準日', '10年'],
    parse_dates=['基準日'],
    encoding='sjis',
    index_col=['基準日'],
    na_values='-'
)

risk_free_rate = risk_free_rate['10年'].apply(
    # 半年複利(%表記)を日時対数収益率に変換
    lambda x: np.log(1 + 0.01 * 0.5 * x) / 125
).apply(
    # 単利へ変換
    lambda x: np.exp(x) -1
)
risk_free_rate.rename('安全資産利子率', inplace=True)
risk_free_rate.index.rename('日時', inplace=True)

risk_free_rate = pd.DataFrame(risk_free_rate)

# 出力して結果を確認
display(risk_free_rate.dropna().head())

############################################################

stock_return_and_risk_free_return = pd.merge(
    daily_data_adj[daily_data_adj['SC'] > 2],
    risk_free_rate, on='日時'
)

# SC と日時を index にする
stock_return_and_risk_free_return.set_index(
    ['SC', '日時'],
    verify_integrity=True,
    inplace=True
)
# 出力して結果を確認
display(stock_return_and_risk_free_return.head())

############################################################

# 日時で集計
group_by_date = stock_return_and_risk_free_return.groupby('日時')

data_with_market_returns = []
for date, values in tqdm(group_by_date):
    sum_of_market_capital = values['時価総額(百万円)'].sum()
    values = values.assign(
        # retuen がすべて null なら null にする
        市場収益率 = lambda x: (
            x['収益率'] * (x['時価総額(百万円)'] / sum_of_market_capital)
        ).sum(
            min_count=1
        )
    )
    data_with_market_returns.append(values)

data_with_market_returns = pd.concat(data_with_market_returns)

display(data_with_market_returns.head())

############################################################
data_with_excess_returns = data_with_market_returns.assign(
    超過収益率 = lambda x: x['収益率'] -x['安全資産利子率'],
    市場超過収益率 = lambda x: x['市場収益率'] -x['安全資産利子率']
)

###########################################################
# 扱いやすくするために index を通常の列に戻す
temporary_data_excess_returns = data_with_excess_returns.reset_index()

# read financial data
financial_data = pd.read_pickle(
    f'{DATA_CHAPTER1}financial_data_all.pickle'
)

# 利用しない列を削除
financial_data.drop(
    columns=['発行済株式数', '日時'],
    inplace=True
)

# 決算発表日の株価データとマージできるように、株価データに決算発表日を張る
group_by_security = temporary_data_excess_returns.groupby('SC')

temporary_list = []
for security, values in tqdm(group_by_security):

    # 財務データから決算発表日を取得
    # 例: array(
    #         ['2016-05-11T00:00:00.000000000', '2017-05-T00:00:00.000000000'],
    #         dtype='datetime64[ns]'
    #         )
    announcement_dates = financial_data[
            '決算発表日(本決算)'
        ][
            financial_data.SC == security
        ].dropna().unique()

    # 古いソートにして np.array に戻す
    announcement_dates = pd.Series(announcement_dates).sort_values().values

    # 収益率データの「日時」が含まれる決算期を意味するカテゴリカル変数を作る
    # 例:「日時」が 2016-05-11 より前 → 欠損値、
    #   「日時」が 2016-05-112017-05-112016-05-11、など 

    aligned = values.assign(
        announcement_date = lambda x: pd.cut(
            x['日時'],
            (
                list(announcement_dates)
            ) + [np.datetime64(values['日時'].max() + pd.offsets.Day())],
            labels = announcement_dates,
            right=False
        ).astype(
            np.datetime64
        )
    )
    temporary_list.append(aligned)

temporary_data_excess_returns = pd.concat(temporary_list)
temporary_data_excess_returns.rename(
    columns = {'announcement_date':'決算発表日(日時)'},
    inplace=True
)
del temporary_list

# 財務データを決算発表日について一意にする
financial_data = financial_data.groupby(
    ['SC', '決算発表日(本決算)']
).first().reset_index()

excess_returns_with_financial_data = pd.merge(
    temporary_data_excess_returns,
    financial_data,
    left_on=['SC', '名称', '決算発表日(日時)'],
    right_on=['SC', '名称', '決算発表日(本決算)'],
    how='left'
)

excess_returns_with_financial_data.set_index(
    ['SC', '日時'],
    inplace=True,
    verify_integrity=True
)

del temporary_data_excess_returns

# データを pickle で保存
excess_returns_with_financial_data.to_pickle(
    f'{DATA_DIR}excess_returns_with_financial_data.pickle'
)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/02/13 17:55 編集

    データは2年前までさかのぼってダウンロードできるはずです。
    欠損値はisnull()メソッドで例外処理されてるようです。私も詳しくありません。
    逆にあまりたくさんのcsv ファイルを一気に処理しようとするとメモリクラッシュすることもあるので考え物です。
    追記) P.139 のポートフォリオの予測リターンの今月に入っての急落ぶりには目を疑います。

    キャンセル

  • 2020/02/13 19:49

    そうなんですね。なんか結局なにもできずに困ってます。
    jupyter notebookの更新などをして全てバージョン最新にしたのですが。だめなんですよね。

    キャンセル

  • 2020/02/15 06:34

    昨日データを新たに買い直して本と全く同じデータでやったらできました。おそらくデータの時系列が違かったことが原因と考えられます。
    いままでいろいろとありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る