売電料金減ってる・・・?
ソーラーパネルを積んで数年経ちますが、昔に比べて売電料金が減っている気がする。
とはいえ、過去のデータを取っていないので、具体的にどうなっているのか・・・と考えた時に、カテエネのサイトから見れるのではと思いました。
カテエネを見ると、過去3年分くらいまではCSVで取得できるようでした。
これを使って、過去のデータを解析するとともに、将来の売電料金を予想させてみました。
カテエネからのCSVダウンロード方法
売電契約を選択し、全ての期間 にチェックしてダウンロードをクリック
カテエネから取得できるCSVのデータ
- 過去3年分がまとまったCSVがダウンロードできる
- Shift_JISエンコード
- 1行目には不要な説明があるので読み飛ばした方が良い
将来を予測させるためのモデル
時系列データの解析に適したモデルとしてARIMAモデルを使用しました。ARIMAは過去のデータに基づいて将来を予測する統計モデルで、特にトレンドや季節性を持つデータに対して有効です。
SARIMAモデル(季節性ARIMA)は、季節性のパターンを考慮する点でARIMAよりも適していますが、今回は単純なARIMAモデルを試しました。
コード
pandas
matplotlib
statsmodels
をインストールし、以下のようなコードを書いて実行します
import os
import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.tsa.arima.model import ARIMA
DATA_DIR = 'data' # CSVファイルが保存されているディレクトリ
DIST_DIR = 'dist' # 出力ディレクトリ
TARGET_COLUMN = '再生可能エネルギーからの電力受給契約'
DATE_COLUMN = 0
PRICE_COLUMN = 12
def load_and_filter_csv_files(directory):
"""
ディレクトリ内のすべてのCSVファイルを読み込み、
特定の条件に一致するデータをフィルタリングして結合します。
Parameters:
directory (str): CSVファイルが保存されているディレクトリのパス。
Returns:
DataFrame: フィルタリングされたデータを含むデータフレーム。
"""
all_data = pd.DataFrame()
for filename in os.listdir(directory):
if filename.endswith('.csv'):
filepath = os.path.join(directory, filename)
try:
df = pd.read_csv(filepath, encoding='shift_jis', skiprows=1, header=0)
df = df.dropna(subset=[df.columns[DATE_COLUMN], df.columns[PRICE_COLUMN], df.columns[5]])
df = df[df[df.columns[5]] == TARGET_COLUMN]
filtered_df = df.iloc[:, [DATE_COLUMN, PRICE_COLUMN]]
all_data = pd.concat([all_data, filtered_df])
except Exception as e:
print(f"Error reading {filename}: {e}")
return all_data
def preprocess_data(df):
"""
データフレームを前処理し、日付をインデックスに設定し、頻度情報を追加します。
Parameters:
df (DataFrame): 前処理するデータフレーム。
Returns:
DataFrame: 前処理されたデータフレーム。
"""
df.columns = ['date', 'price']
df['date'] = pd.to_datetime(df['date'], format='%Y%m')
df['price'] = df['price'].astype(str).str.replace(',', '').astype(float)
df.sort_values('date', inplace=True)
df.set_index('date', inplace=True)
df.index.freq = 'MS'
return df
def train_arima_model(df):
"""
ARIMAモデルをトレーニングします。
Parameters:
df (DataFrame): トレーニングに使用するデータフレーム。
Returns:
ARIMAResultsWrapper: トレーニングされたARIMAモデル。
"""
model = ARIMA(df['price'], order=(5, 1, 0))
model_fit = model.fit()
return model_fit
def predict_future_prices(model_fit, df, months=12):
"""
トレーニングされたARIMAモデルを使用して、将来の売電料金を予測します。
Parameters:
model_fit (ARIMAResultsWrapper): トレーニングされたARIMAモデル。
df (DataFrame): 元のデータフレーム。
months (int): 予測する月数。
Returns:
DataFrame: 予測された売電料金を含むデータフレーム。
"""
forecast = model_fit.get_forecast(steps=months)
forecast_dates = [df.index.max() + pd.DateOffset(months=i) for i in range(1, months + 1)]
future_df = pd.DataFrame({'date': forecast_dates, 'predicted_price': forecast.predicted_mean})
return future_df
def plot_predictions(df, future_df):
"""
実際の売電料金と予測された売電料金をプロットし、画像として保存します。
Parameters:
df (DataFrame): 実際の売電料金を含むデータフレーム。
future_df (DataFrame): 予測された売電料金を含むデータフレーム。
"""
if not os.path.exists(DIST_DIR):
os.makedirs(DIST_DIR)
output_file = os.path.join(DIST_DIR, 'price_prediction.png')
# 日本語フォントの設定
font_path = '/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc' # macOSの例
prop = fm.FontProperties(fname=font_path)
plt.figure(figsize=(10, 6))
plt.plot(df.index, df['price'], label='実際の売電料金')
plt.plot(future_df['date'], future_df['predicted_price'], label='予測売電料金', linestyle='--')
plt.xlabel('日付', fontproperties=prop)
plt.ylabel('売電料金 (円)', fontproperties=prop)
plt.title('売電料金の予測', fontproperties=prop)
plt.legend(prop=prop)
plt.grid(True)
plt.savefig(output_file)
plt.show()
def predict():
"""
データを読み込み、前処理し、ARIMAモデルをトレーニングし、
将来の売電料金を予測してプロットします。
"""
# データの読み込みとフィルタリング
all_data = load_and_filter_csv_files(DATA_DIR)
if all_data.empty:
print("No data found.")
return
# データの前処理
processed_data = preprocess_data(all_data)
# モデルのトレーニング
model_fit = train_arima_model(processed_data)
# 将来の売電料金を予測
future_predictions = predict_future_prices(model_fit, processed_data, months=12)
# 予測結果をグラフとして出力
plot_predictions(processed_data, future_predictions)
rye なら、predict
を [project.scripts]
に定義すれば以下のように実行できます
$ rye run predict
実行するとグラフ画像が作成されて表示されます
予測させてみた実際のデータ
雪国なので冬の売電はかなり落ち込みますね
過去3年のデータしか無いのでイマイチですが・・・
たぶん1月はもっと低いはず
SARIMAのほうが良かったかな・・・
まとめ
グラフを見ると、ここ3年くらいでは売電は過剰に減っているという感じでも無さそうでした。
予測に関しては、より長期的なデータや、気候変動、電力市場の変化などの外部要因も考慮に入れることで、さらに精度の高い予測が可能になるかもしれません。
また、SARIMAモデルなど、他の時系列モデルも今度試してみようと思います。