見出し画像

初心者がPythonで売上・利益を予測⁇

✅このブログはAidemy Premiumのカリキュラムの一環で、受講修了条件を満たすために公開しています


1.はじめに

データサイエンティストに憧れ、Aidemyにて「データ分析講座」を受講しました。

憧れた理由は、経理系の仕事を長年してきましたが、ベテラン担当者によるExcel職人技からPythonによる科学的なアプローチへ分析スタイルを変えたい!と思ったからです(^_-)-☆

本当は、単純に〇〇さんって凄い!魔法みたい!って言われたいだけかもしれない(;^_^A

2.概要

  • どんな人に読んでほしいか
    経理や経営企画など会社の財務データにかかわる人。
    Pythonをつかったデータ分析に興味のある人。

  • この記事に書くこと、わかること
    Pythonをつかった時系列データ解析の初めの一歩。
    財務データをつかった分析予測の初めの一歩。

  • この記事で扱わないこと、注意点
    売上や利益の予測を扱いますが、予測精度はそれほど高くありません。
    本来であれば、精度を高めるための内容も記載すべきですが、初めの一歩であることをご承知おきください、、、

3.目的

  • ARIMAモデルをつかった時系列解析を行い、売上高と営業利益を予測すること。

  • 解析データとして、某上場企業の有価証券報告書、内閣府の統計データ、某上場企業が所属する某工業会の統計データ、を実際に集めてみること。
    ※入手したデータはすべて公開されているデータです。

  • データの前処理として、データの整形を実際にやってみること。

  • 学習した内容をアウトプットすること。

4.実行環境および支援ツール

  • Python3.9.2

  • Visual Studio Code

  • Jupyter notebook

  • Windows 11 Home

  • ChatGPT4

# バージョン確認コード
!python --version
Python 3.9.2

5.時系列データ解析および分析モデル

時系列データ解析とは?

時系列データ解析は、文字通り「時間の経過と共に収集されたデータのパターンを分析すること」です。これは、過去のデータから未来の動向を予測したり、季節やトレンドなど時間に関連した要因がデータにどのように影響しているかを理解するために使用されます。

例えば、売上データを分析して、将来的な売上の増減を予測したり、消費者の購買行動の季節的な変動を見つけたりすることができます。

分析モデルとは?

分析モデルとは、データの背後にある関係やパターンを数学的な式で表したものです。これを使って、データを理解したり、未来を予測したりすることができます。分析モデルは、データに隠された物語を解き明かすためのツールのようなものです。

ARMAモデル

  • 「自己回帰(AR)」と「移動平均(MA)」の両方の特徴を持つモデルです。

  • 例えば、お店の売上を考えたときに、昨日までの売上が今日の売上に影響する(AR)、そして過去に予測を外した分も考慮に入れる(MA)、といった具合に過去の情報を用いて予測します。

  • ただし、トレンドや季節性などの変動には対応していません。

ARIMAモデル ※今回選択したモデルです。

  • ARMAモデルに「和分(I)」を追加したもので、トレンドのあるデータに適用できます。

  • 「和分」とは、データからトレンドを取り除いて安定した状態にする処理のことです。たとえば、年々売上が増えていくようなトレンドを取り除いて、データをより予測しやすくします。

SARIMAモデル

  • ARIMAモデルに「季節性(S)」の要素を追加したものです。

  • 季節性とは、特定の時期に定期的に起こるパターンのことで、例えば冬にコートがよく売れるといった季節による売上の変動を表します。

  • SARIMAモデルは、これらの季節的な変動も予測に取り入れることができます。

SARIMAXモデル

  • SARIMAモデルに「外生変数(X)」を組み込んだもので、より複雑なデータの分析に適しています。

  • 外生変数とは、予測したい変数に影響を与える可能性がある、外部からの情報や他の指標のことです。例えば、気温や経済指標が売上に影響を与える場合、これらを外生変数としてモデルに組み込むことで、より正確な予測を行うことができます。

  • SARIMAXモデルは、これら外部の情報を考慮に入れることで、現実世界の複雑な現象をより詳細に捉えることができるようになります。

これらのモデルは、時系列データの特徴を捉えるための様々なレンズのようなものです。状況に応じて最適なレンズを選び、データの背後にあるパターンをより鮮明に映し出すことができます。

6.今回解析するデータ

今回は、某上場企業の有価証券報告書より売上や利益といった損益計算書データ、内閣府より各種統計データ、某上場企業が所属する工業会HPより業界規模データを入手しています。

具体的なファイル名は以下になります。
※尚、ダウンロードしたファイル名からは変更しています。

  • E○○○○○_損益計算書.csv

  • E○○○○○_製造原価明細.csv

  • 国内企業物価指数.csv

  • 国民経済計算(GDP統計).csv

  • 賃金構造基本統計調査.csv

  • 日本○○○○システム工業会統計.csv

pl_df = pd.read_csv('./Aidemy_final_assignment/E00000_損益計算書.csv')
cs_df = pd.read_csv('./Aidemy_final_assignment/E00000_製造原価明細.csv')
price_df = pd.read_csv('./Aidemy_final_assignment/国内企業物価指数.csv', skiprows=2, header=None)
gdp_df = pd.read_csv('./Aidemy_final_assignment/国民経済計算(GDP統計).csv', skiprows=5)
wage_df = pd.read_csv('./Aidemy_final_assignment/賃金構造基本統計調査.csv', skiprows=2)
powerDist_df = pd.read_csv('./Aidemy_final_assignment/日本0000システム工業会統計.csv')

今回入手したデータは、すべて年度単位(4月~3月)で、最終的には2013年~2022年までのデータに統一しています。

7.データの読み込みと整形

読み込んだデータは、そのままでは使えないため、データの整形を行います。詳細の説明は割愛しますが、実際に整形したコードを以下に記載します。

# (1)データの読み込みと整形
import pandas as pd
import numpy as np
from statsmodels.tsa.statespace.sarimax import SARIMAX
import matplotlib.pyplot as plt

# データの読み込み
# 6つのファイルを読み込みます。
pl_df = pd.read_csv('./Aidemy_final_assignment/E00000_損益計算書.csv')
cs_df = pd.read_csv('./Aidemy_final_assignment/E00000_製造原価明細.csv')
price_df = pd.read_csv('./Aidemy_final_assignment/国内企業物価指数.csv', skiprows=2, header=None)
gdp_df = pd.read_csv('./Aidemy_final_assignment/国民経済計算(GDP統計).csv', skiprows=5)
wage_df = pd.read_csv('./Aidemy_final_assignment/賃金構造基本統計調査.csv', skiprows=2)
powerDist_df = pd.read_csv('./Aidemy_final_assignment/日本0000システム工業会統計.csv')

# pl_dfのデータ整形
pl_df = pl_df.iloc[:10, 0:6]
pl_df['年度'] = pl_df['年度'].astype(str)

# cs_dfのデータ整形
cs_df = cs_df.iloc[:10, 0:4]
cs_df['年度'] = cs_df['年度'].astype(str)

# price_dfのデータ整形
price_df.columns = ['年度', '国内企業物価指数'] # 新しいカラム名を手動で設定
price_df = price_df.iloc[10:20] # データとして必要な行と列だけに絞る
price_df = price_df.reset_index(drop=True) # インデックスをリセット(オプション)
price_df['年度'] = price_df['年度'].astype(str)

# gdp_dfのデータ整形
gdp_df = gdp_df.drop(index=0) # 最初の行(インデックスが0)を削除
gdp_df = gdp_df.iloc[19:29, [0, 1, 5]] # データとして必要な行と列だけに絞る
gdp_df = gdp_df.reset_index(drop=True) # インデックスをリセット(オプション)
gdp_df.iloc[:, 0] = gdp_df.iloc[:, 0].str.extract('(\d{4})').astype(str) # 年のみを抽出して新しいカラム「年度」として追加
gdp_df.rename(columns={gdp_df.columns[0]: '年度'}, inplace=True)
gdp_df.rename(columns={gdp_df.columns[1]: 'GDP'}, inplace=True)
gdp_df.rename(columns={gdp_df.columns[2]: '民間設備投資'}, inplace=True)

# wage_dfのデータ整形
wage_df = wage_df.drop(index=[0, 44, 45, 46]) # 不要な行を削除
wage_df = wage_df.iloc[37:47, [2, 4]] # データとして必要な行と列だけに絞る
# 文字列に変換し、"-"を削除して"."の前の数字のみを文字列として取得
wage_df.iloc[:, 0] = wage_df.iloc[:, 0].astype(str).str.replace("-", "").str.split(".").str[0] # 年のみを抽出して新しいカラム「年度」として追加
wage_df.rename(columns={wage_df.columns[0]: '年度'}, inplace=True)
wage_df = wage_df.reset_index(drop=True) # インデックスをリセット(オプション)

# powerDist_dfのデータ整形
powerDist_df = powerDist_df.drop(index=[20, 21, 22]) # 不要な行を削除
powerDist_df = powerDist_df.iloc[10:20, [0, 5]] # データとして必要な行と列だけに絞る
powerDist_df.rename(columns={powerDist_df.columns[1]: '業界規模'}, inplace=True)
powerDist_df = powerDist_df.reset_index(drop=True) # インデックスをリセット(オプション)
powerDist_df['年度'] = powerDist_df['年度'].astype(str)
powerDist_df['業界規模'] = powerDist_df['業界規模'].str.replace(',', '')
powerDist_df['業界規模'] = pd.to_numeric(powerDist_df['業界規模'], errors='coerce')


# 単位を「百万円」に統一

# カンマを除去し、数値型に変換するための関数
def convert_column_to_numeric(series):
    return pd.to_numeric(series.str.replace(',', ''), errors='coerce')

# pl_dfを数値型に変換してから1000で割る
pl_df.iloc[:, 1:] = pl_df.iloc[:, 1:].apply(lambda x: convert_column_to_numeric(x)) / 1000
# cs_dfを数値型に変換してから1000で割る
cs_df.iloc[:, 1:] = cs_df.iloc[:, 1:].apply(lambda x: convert_column_to_numeric(x)) / 1000
# GDP列を数値型に変換してから1000倍する
gdp_df.iloc[:, 1] = convert_column_to_numeric(gdp_df.iloc[:, 1]) * 1000
# 民間設備投資列を数値型に変換してから1000倍する
gdp_df.iloc[:, 2] = convert_column_to_numeric(gdp_df.iloc[:, 2]) * 1000

wage_df.iloc[:, 1] = wage_df.iloc[:, 1] / 1000 * 12 # 月平均なので年換算にする。
wage_df.rename(columns={wage_df.columns[1]: '賃金'}, inplace=True)

merged_df = pd.merge(pl_df, cs_df, on='年度', how='inner')
merged_df = pd.merge(merged_df, price_df, on='年度', how='inner')
merged_df = pd.merge(merged_df, gdp_df, on='年度', how='inner')
merged_df = pd.merge(merged_df, wage_df, on='年度', how='inner')
merged_df = pd.merge(merged_df, powerDist_df, on='年度', how='inner')

display(merged_df)

# 'merged_df'を'merged_data.csv'として保存
merged_df.to_csv("./Aidemy_final_assignment/merged_data.csv", index=False, encoding="utf-8-sig")

それほど複雑なデータではないのですが、今回の取り組みの80%程度はデータ整形です(-_-;)

最終的に整形して、解析用に統一したデータは以下になります。

最終的な解析データ

8.データの整理

当初、今回の解析で実現したかったのは、予測する数値(※目的変数といいます)と相関しているだろう数値(※説明変数といいます)を集めて、その関係性を取り込んだ上で、目的変数である売上高と営業利益の未来を予測することです。

ということで、Aidemyさんの講座で学んだ、相関行列を使ってデータ項目(変数)同士の相関を可視化してみます。

# 相関行列を計算
correlation_matrix = merged_df.corr()

plt.figure(figsize=(10,8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.show()

print(correlation_matrix['売上高'].sort_values(ascending=False))
print(correlation_matrix['営業利益'].sort_values(ascending=False))
変数同士の相関性を可視化

上記表と同じ内容ですが、以下のような表示もできます。

売上高         1.000000
経費          0.860778
売上原価        0.857005
業界規模        0.672308
材料費         0.454472
GDP         0.353312
売上総利益       0.308744
労務費         0.285266
賃金          0.262624
販管費         0.252601
営業利益        0.062359
国内企業物価指数    0.029319
民間設備投資      0.014074
Name: 売上高, dtype: float64
営業利益        1.000000
売上総利益       0.758032
民間設備投資      0.377074
業界規模        0.336895
売上高         0.062359
経費         -0.129817
売上原価       -0.346742
材料費        -0.439686
労務費        -0.515419
国内企業物価指数   -0.582676
GDP        -0.615321
賃金         -0.632100
販管費        -0.677548
Name: 営業利益, dtype: float64

ん~なるほどなるほど、、、
でも今の自分のスキルじゃ、ちょっと難しいな~
こんな時は、私のコーディングの友、ChatGPTさんに相談してみよう!(^^♪
※Aidemyさんごめんなさい(-_-;)

今回、添付ファイルの整形済みのデータを用いて、時系列解析をしたいと思います。
データは年単位のデータしかないため、年単位での時系列解析になります。
2013年~2022年までのデータで解析し、2018年~2025年までの売上高と営業利益を予測して、さらにグラフで実績と予測をかぶらせる形で可視化までしたいと思います。
その場合、どのモデルがベターでしょうか?
それを検証するためにも、売上高と営業利益以外の変数が、目的変数である売上高と営業利益とどのくらい相関しているのか検証はしたいです。
SARIMAモデルは外部要因としてを説明変数を加えられると聞きました。
2023年~2025年までの説明変数の数値はないため、実践するとすれば、2020年~2022年までの売上高と営業利益を予測して、実績と予測の差をグラフで重ねて可視化してみることでしょうか?
これができれば、目的変数と説明変数の相関関係を事前解析して、最も関係性の高い説明変数を外部要因として加えてSARIAMモデルで予測するのはどうでしょうか?
ただし、年単位でのデータではSARIAMモデルで予測することにあまり意味がないのであれば、もっとシンプルなARMAやARIMAでも問題ありません。私は分析初心者なので、あまり複雑な分析はまだ厳しいです、、、

ChatGPTさんが以下のように回答してくれました。

SARIMAモデルを理解するために、まずその他のモデルについて説明します。

● ARモデル (自己回帰モデル、AutoRegressive Model)
規則的に値が変化していくモデル。
過去の値から回帰的にある時点の値を推定します。
直前のp個の値を用いて次の値を予測するモデルをAR(p)と表現します。

● MAモデル (移動平均モデル、Moving Average Model)
過去の誤差に影響されるモデル。
過去の誤差を考慮しながらデータの推移を予測します。
直前のq個の値の誤差の影響を受けるモデルをMA(q)と表現します。

● ARMAモデル (自己回帰移動平均モデル、AutoRegressive Moving Average Model)
ARモデルとMAモデルを組み合わせたモデル。ARMA(p,q)と表せます。
ある時点の出力を、過去の出力と現在及び過去の入力に対する和で表現します。

● ARIMAモデル (自己回帰和分移動平均モデル、AutoRegressive Integrated Moving Average Model)
ARMAモデルへ原系列を階差系列に変換し適応させたモデル。
非定常過程(データの平均や分散が時間に依存している過程)にも適応可能です。
d時点前との差分をとった場合のARMA(p,q)で構築したARIMAモデルをARIMA(p,d,q)と表します。

● SARIMAモデル (季節変動自己回帰和分移動平均モデル、Seasonal AutoRegressive Integrated Moving Average Model)
ARIMAモデルを季節周期(s)を持つ時系列データにも拡張できるようにしたモデル。
(p,d,q)のパラメータに加えて(sp,sd,sq,s)のパラメータも持ちます。
-------------------------
ChatGPT
年単位のデータを用いた時系列解析で、特に説明変数(外生変数)の未来の値が不明な状況では、シンプルなモデルを選択することが望ましい場合が多いです。
SARIMAモデルは季節性を持つデータに適用可能で、外生変数を取り入れることができるSARIMAXモデルもありますが、これらのモデルは比較的データの周期性や季節性が明確な場合に最も力を発揮します。
年単位のデータであり、かつ外生変数の未来の値が不明な場合、ARIMAモデルがより適切な選択肢となる可能性が高いです。

ということで、今回の野望は見事に砕け散り、まずはARIMAモデルで解析を進めることになりました、、、めでたしめでたし(;^_^A

9.モデル構築と予測結果の可視化

では、ARIMAモデルでモデルを構築し、売上高と営業利益を予測してみたいと思います。

詳細の説明は割愛しますが、以下にコードを記載します。

import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
import matplotlib.dates as mdates

# データインデックスの頻度を毎年4月開始に設定
merged_df.index = pd.DatetimeIndex(merged_df.index, freq='AS-APR')

# 日本語対応フォントへの変更
plt.rcParams['font.family'] = 'Meiryo'  # Windowsの場合

# グラフを2つ描画するための準備
fig, ax = plt.subplots(2, 1, figsize=(10, 8))

# 実データのプロット (2013年〜2022年)
ax[0].plot(merged_df.index.to_numpy(), merged_df['売上高'].to_numpy(), label='売上高実データ', color='blue')
ax[1].plot(merged_df.index.to_numpy(), merged_df['営業利益'].to_numpy(), label='営業利益実データ', color='black')

# '売上高'に対するARIMAモデルのフィッティング
model_sales = ARIMA(merged_df['売上高'], order=(1,1,0))
results_sales = model_sales.fit()

# 予測のプロット (2018年〜2025年)
# ここで、予測の開始点を実データの終わりの2年前に設定
pred_start_year = merged_df.index[-5]  # 実データの終わりから2年前
pred_end_year = merged_df.index[-1] + pd.DateOffset(years=3)  # 予測の終わり (2025年)

# 売上高の予測
pred_sales = results_sales.get_prediction(start=pred_start_year, end=pred_end_year)
pred_ci_sales = pred_sales.conf_int()

# 売上高の予測値とその信頼区間のプロット
ax[0].plot(pred_sales.predicted_mean.index.to_numpy(), pred_sales.predicted_mean.to_numpy(), label='売上高予測', color='red', linestyle='--')
ax[0].fill_between(pred_ci_sales.index, pred_ci_sales.iloc[:, 0], pred_ci_sales.iloc[:, 1], color='pink', alpha=0.2)
ax[0].set_title('売上高')
ax[0].set_xlabel('年度')
ax[0].set_ylabel('金額(百万円)')
ax[0].legend()
ax[0].grid(color='gray', linestyle='--', linewidth=0.5)

# '営業利益'に対するARIMAモデルのフィッティング
model_profit = ARIMA(merged_df['営業利益'], order=(1,1,1))
results_profit = model_profit.fit()

# 営業利益の予測
pred_profit = results_profit.get_prediction(start=pred_start_year, end=pred_end_year)
pred_ci_profit = pred_profit.conf_int()

# 営業利益の予測値とその信頼区間のプロット
ax[1].plot(pred_profit.predicted_mean.index.to_numpy(), pred_profit.predicted_mean.to_numpy(), label='営業利益予測', color='green', linestyle='--')
ax[1].fill_between(pred_ci_profit.index, pred_ci_profit.iloc[:, 0], pred_ci_profit.iloc[:, 1], color='lightgreen', alpha=0.2)
ax[1].set_title('営業利益')
ax[1].set_xlabel('年度')
ax[1].set_ylabel('金額(百万円)')
ax[1].legend()
ax[1].grid(color='gray', linestyle='--', linewidth=0.5)

# X軸の日付フォーマットを年度だけにする
years_fmt = mdates.DateFormatter('%Y')
ax[0].xaxis.set_major_formatter(years_fmt)
ax[1].xaxis.set_major_formatter(years_fmt)

# X軸の目盛りを手動で設定
years = pd.date_range(start=merged_df.index.min(), end=merged_df.index.max() + pd.DateOffset(years=3), freq='AS-APR')
ax[0].set_xticks(years)
ax[1].set_xticks(years)

# グリッド線の表示
for a in ax:
    a.grid(True)

plt.tight_layout()
plt.show()

さてさて、予測結果は如何に!

売上高と営業利益の実績及び予測結果

ん~なんか微妙ですね、、、
ARIMAモデルの特徴をちょっと思い出してみましょう。

ARMAモデル

  • 「自己回帰(AR)」と「移動平均(MA)」の両方の特徴を持つモデルです。

  • 例えば、お店の売上を考えたときに、昨日までの売上が今日の売上に影響する(AR)、そして過去に予測を外した分も考慮に入れる(MA)、といった具合に過去の情報を用いて予測します。

  • ただし、トレンドや季節性などの変動には対応していません。

ARIMAモデル

  • ARMAモデルに「和分(I)」を追加したもので、トレンドのあるデータに適用できます。

  • 「和分」とは、データからトレンドを取り除いて安定した状態にする処理のことです。たとえば、年々売上が増えていくようなトレンドを取り除いて、データをより予測しやすくします。

今回選択したARIMAモデルは、過去の実績、予測と実績の差、トレンドや季節性、を加味して予測しているモデルです。
ただ、今回は年単位のデータなので、季節性は加味されていないはずです。

また、今回のモデル構築過程で、以下のパラメーターも調整しています。

# '売上高'に対するARIMAモデルのフィッティング
model_sales = ARIMA(merged_df['売上高'], order=(1,1,0))

# '営業利益'に対するARIMAモデルのフィッティング
model_profit = ARIMA(merged_df['営業利益'], order=(1,1,1))

ARIMAモデルのorder引数の意味
ARIMAモデルのorder引数は、モデルの構成要素を指定するために使用されます。order引数は(p, d, q)という形式のタプルで指定され、各要素は以下の意味を持ちます:

p: 自己回帰(AR)項の次数。モデルが過去の自己の値にどれだけ依存するかを示します。具体的には、過去のp個の観測値を現在の値の予測に使用します。

d: 差分(I)の次数。データを定常にするために必要な差分の回数です。差分を取ることで、データのトレンドや季節性を除去し、時間に依存しない定常過程に変換します。

q: 移動平均(MA)項の次数。モデルが過去の予測誤差にどれだけ依存するかを示します。具体的には、過去のq個の予測誤差を現在の値の予測に使用します。

ちょっとわかりずらいので、もう少しかみ砕きます💦

P=1(自己回帰項の意味)
p=1 で設定された自己回帰(AR)項は、直前の1年分のデータ(例えば、2020年のデータ)を使用して、次の年(例えば、2021年)の値を予測することを意味します。この場合、モデルは直前の年の値が現在の年の値にどの程度影響を与えるかを考慮しています。

d=1(差分の取り方)
d=1 は、各年のデータ値から前年のデータ値を引いた結果を分析に使用します。これにより、データのトレンド(長期的な増加や減少)を取り除き、データをより定常的(時間の経過とともに統計的特性が変わらない)なものに変換します。例えば、ある年のデータが100、翌年が105であれば、1階差分は105 - 100 = 5 となります。この差分データに基づいて分析を行います。

q=1(移動平均項の意味)
q=1 は、モデルが直前の1時点の予測誤差(予測値と実際の値との差)を使用して現在の値を予測することを意味します。これは、モデルが過去の予測誤差から学習して、その情報を使って現在の予測を改善しようとするアプローチです。例えば、2020年の実データと2020年のモデルによる予測値との差(誤差)を考慮して、2021年の値を予測します。q=1 の設定では、直前の1年分の予測誤差のみを考慮します。

ARIMAモデルでは、これらの操作を通じて、時系列データの内在するパターンや特性を捉え、未来の値をより正確に予測しようとします。

どうでしょう、、、
理解できましたか?
かく言う私も、ChatGPTさんにご指導いただきやっと理解できました(;^_^A

それで、以下のコードを見ていただくと、q=0に調整しています。
q=1ではアラートが出てしまい、移動平均の用を足さないとお叱りを受けました、、、

# '売上高'に対するARIMAモデルのフィッティング
model_sales = ARIMA(merged_df['売上高'], order=(1,1,0))

原因はよく理解できていないのですが、今回のデータでは予測値と実績値の差を考慮しても意味がないということなのかな~と自分なりに解釈しています(;^_^A

実際に予測値と実績値を考慮して調整したんだろうな~という2020年度の売上高は期待を大きく裏切られています。

つまり、今回選択したARIMAモデルは、過去の実績、予測と実績の差、トレンドや季節性、を加味して予測するモデルなのですが、実績値がそれらの影響外の要因で変動しているということだと推測できます。

10.今後の課題

解析結果から、今回選択したARIMAモデルでは予測の精度に問題があることがわかります。やはり、当初想定していた、予測する数値(目的変数)と相関している数値(説明変数)の関係性を取り込んだ上で、目的変数である売上高と営業利益の未来を予測する必要がありそうです、、、

11.終わりに

やはり、アウトプットすることが一番の学びであることを改めて実感しています。まだまだ初心者レベルですが、最初の一歩を踏み出しましたので、あとは転がり落ちる、、、いやいやどんどんスピードを増して転がり続ける(学び続ける)だけです!

今回の課題を踏まえて、再挑戦します!

PS. 一番の驚きは、ChatGPTの登場でプログラミングのハードルがとても下がったことを実感したことです。

この記事が気に入ったらサポートをしてみませんか?