import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
import yfinance as yf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
import datetime
import matplotlib
import os
# --- 日本語フォント自動設定 ---
def set_japanese_font():
mac_fonts = ['Hiragino Sans', 'AppleGothic', 'ヒラギノ角ゴシック']
for f in mac_fonts:
try:
plt.rcParams['font.family'] = f
plt.text(0, 0, 'テスト')
return
except:
continue
print("?? 日本語フォントが見つかりません。英数字のみ表示されます。")
set_japanese_font()
# --- 株価データ取得(ホンダ) ---
ticker = '7267.T'
start_date = '2020-01-01'
end_date = '2025-08-29'
data = yf.download(ticker, start=start_date, end=end_date)
if data.empty:
print("? 株価データの取得に失敗しました。")
exit()
close_data = data['Close'].values
date_index = data.index
# --- スケーリング ---
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(close_data.reshape(-1, 1))
# --- データセット作成 ---
def create_dataset(data, time_step=30):
X, Y = [], []
for i in range(len(data) - time_step):
X.append(data[i:i + time_step, 0])
Y.append(data[i + time_step, 0])
return np.array(X), np.array(Y)
time_step = 30
X, y = create_dataset(scaled_data, time_step)
X = X.reshape(X.shape[0], X.shape[1], 1)
# --- モデル構築 ---
model = Sequential()
model.add(LSTM(50, return_sequences=True, input_shape=(time_step, 1)))
model.add(Dropout(0.2))
model.add(LSTM(50))
model.add(Dropout(0.2))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X, y, epochs=100, batch_size=32, verbose=0)
# --- 未来予測(30営業日) ---
future_days = 30
input_seq = scaled_data[-time_step:]
input_seq = input_seq.reshape(1, time_step, 1)
future_predictions = []
for _ in range(future_days):
pred = model.predict(input_seq, verbose=0)
future_predictions.append(pred[0, 0])
input_seq = np.append(input_seq[:, 1:, :], [[[pred[0, 0]]]], axis=1)
# --- スケール戻し ---
future_predictions = scaler.inverse_transform(np.array(future_predictions).reshape(-1, 1)).flatten()
# --- 予測バンド(±標準偏差) ---
recent_std = np.std(close_data[-time_step:]) # 直近30日分の標準偏差
upper_band = future_predictions + recent_std
lower_band = future_predictions - recent_std
# --- 未来日付作成(営業日) ---
last_date = date_index[-1]
future_dates = []
while len(future_dates) < future_days:
last_date += datetime.timedelta(days=1)
if last_date.weekday() < 5:
future_dates.append(last_date)
# --- プロット ---
plt.figure(figsize=(14, 6))
plt.plot(date_index, close_data, label='実際の株価', color='blue')
plt.plot(future_dates, future_predictions, marker='o', label=f'予測株価(未来{future_days}営業日)', color='red')
plt.fill_between(future_dates, lower_band, upper_band, color='pink', alpha=0.3, label='予測バンド (±1σ)')
plt.title('ホンダ 株価予測(未来30営業日)')
plt.xlabel('日付')
plt.ylabel('株価(円)')
plt.legend()
plt.grid()
# --- 保存 ---
output_path = os.path.expanduser('~/Desktop/honda_future_30days_band.png')
plt.savefig(output_path)
print(f"? 予測画像を保存しました:{output_path}")
# --- 最新株価と予測株価表示 ---
print(f"? 最新の実株価: {float(close_data[-1]):.2f} 円")
print(f"? 最終日の予測株価: {float(future_predictions[-1]):.2f} 円")
print(f"? 予測バンド: {float(lower_band[-1]):.2f} 円 〜 {float(upper_band[-1]):.2f} 円")
plt.show()
# ser1@michi-2022MacBook-Pro ~ % python3 /Users/user1/Desktop/q/example.py