シンギュラリティ実験ノート

購入した1000ドルPCで何がどこまでできるのか実験した記録です。

株価の成長率を求めるPythonスクリプトをAIに頼んでみた

デスクトップで簡単に生成AIを動かせるソフトJanの紹介の続きである。Janで使用できる生成AIの中にPythonのコーディングが得意そうなモデルがあったので試してみることにした。お題としては繰り返しとなって恐縮だが株価の成長率を求めるスクリプトを頼むことにした。

Ubuntu環境への導入

Janはマルチな環境で動く。Mac M1 M2 M3、Mac(Intel)、WindowsLinuxで動く。驚くことにMobileつまりスマホでも動かそうとしているようで、時期は不明だがComming Soonとなっており楽しみである。今回はUbuntu22.04.4LTSに導入してみた。

導入手順はシンプルで以下の3ステップだ。

  1. JanのページにあるLinux(AppImage)のボタンを押す(ダウンロードが開始される)
  2. ダウンロードが終了したら、ダウンロードしたAppImageファイルに実行権を与える
  3. AppImageファイルを起動する

AppImageファイルは解凍不要でこの中にアプリ環境が全て入っていて便利である。ステップ2以降の具体的なコマンドは以下のようになる。「ダウンロード」はダウンロードしたディレクトリ名に読み替えてほしい。起動してもしlibfuse2に関するエラーが出たらlibfuse2をインストールすれば解決するはずだ。

$ cd ダウンロード
$ chmod ugo+x jan-linux-x86_64-0.4.7.AppImage
$ ./jan-linux-x86_64-0.4.7.AppImage
$ sudo apt install libfuse2
$ ./jan-linux-x86_64-0.4.7.AppImage

Janが無事に立ち上がったらモデルをダウンロードする。今回私がダウンロードしたのは「Wizard Coder Python 13B Q5」だ。

実行結果

これまでRスクリプトをAIに依頼した経験などを踏まえて、できるだけ具体的に指示をしてみた。できればAIに一発で動くスクリプトを作成して欲しいからだ。結果的にはプログラム仕様書のような形になった。そういえば若い頃は自分でこんな仕様書を書いたりしてたなーと思い、少し感傷的な気分になる。。

スクリプト仕様書

依頼してから2分くらいは考えていただろうか。回答は英語であったが以下のようにスクリプトを作成してくれた。

Wizard Coderの回答

AIが作成したスクリプトの全体は以下の通りであった。

import yfinance as yf
import pandas as pd
import numpy as np
from sklearn.metrics import r2_score
import datetime
import matplotlib.pyplot as plt
import os

def calculate_stock_data(ticker):
    try:
        stock_data = yf.download(ticker, period='10y', interval='mo')
    except ValueError as e:
        print("Invalid ticker code")
        return
    
    stock_data = stock_data.reset_index()
    stock_data['years'] = (stock_data['Date'].apply(lambda x: (x - pd.to_datetime('2019-01-01')) / np.timedelta64(365, 'D')).dt.days)
    stock_data['log_start'] = np.log(stock_data['Open'])
    
    if len(stock_data) == 0:
        print("No data found for the given ticker")
        return
    
    x = stock_data['years'][:12]
    y = stock_data['log_start'][:12]
    
    coefs = np.polyfit(x, y, 1)
    m, b = coefs[0], coefs[1]
    
    r2_score_value = r2_score(y, [b + m * xi for xi in x])
    yearly_rate = (m - 1) / 0.01
    
    ycalc = [b + m * xi for xi in stock_data['years']]
    plt.plot(stock_data['years'], stock_data['log_start'])
    plt.plot(stock_data['years'], ycalc)
    
    plt.xlabel('Years')
    plt.ylabel('Log Start Price')
    plt.legend(['{} stock price'.format(ticker), 'Theory: $b * m^x$, R2={:.02f}, Yearly rate={:.1%}'.format(r2_score_value, yearly_rate)]);
    
    today = datetime.datetime.today().strftime('%Y%m%d')
    plt.savefig(os.path.join(os.getcwd(), '{}-{}.png'.format(ticker, today))で

出来上がったスクリプトには明らかにおかしい点がある。Rスクリプトを頼んだ時も同じだったが、処理3の経過日数を実数の年に変換する処理、処理4の株価データを対数変換して、取得した係数を逆に指数変換する処理である。指数対数変換は人間も苦手な人が多いと思うが、AIも苦手のようだ。この辺りは大手術であったが私がなんとか直した。なお一点だけAIに謝らなければいけない点があった。この記事を書いている時に気づいたが、年利Rを求める式を私が間違えて指示していた。100で割るのではなく、掛けなければいけない。AI君申し訳ない(ペコリ)。しかしAI君は私のミスに気づいたらしく正しいRの計算式に直してくれていた。その点は褒めてあげないといけないだろう。

私が直して動作確認したスクリプトが以下である。

import yfinance as yf
import pandas as pd
import numpy as np
from sklearn.metrics import r2_score
import math
import datetime
import matplotlib.pyplot as plt

def calculate_stock_data(ticker):
    try:
        stock_data = yf.download(ticker, period='10y', interval='1mo')
    except ValueError as e:
        print("Invalid ticker code")
        return
    
    stock_data = stock_data.reset_index()
    stock_data['days'] = [stock_data['Date'][i] - stock_data['Date'][0] for i in range(0,(len(stock_data)))]
    
    if len(stock_data) == 0:
        print("No data found for the given ticker")
        return
    
    x = stock_data['days'].dt.days / 365.25
    y = stock_data['Open']
    
    logm, logb  = np.polyfit(x, np.log(y), 1)
    m = math.exp(logm)
    b = math.exp(logb)
    r2_score_value = r2_score(y, [b * math.pow(m, i) for i in x])
    yearly_rate = (m - 1) / 0.01
    
    ycalc = [b * math.pow(m, i) for i in x]
    plt.plot(x, stock_data['Open'])
    plt.plot(x, ycalc)
    
    plt.xlabel('Years')
    plt.ylabel('Stock Price')
    plt.legend(['{}'.format(ticker), 'R={:.1f}, R2={:.02f}'.format(yearly_rate, r2_score_value)]);
    
    today = datetime.datetime.today().strftime('%Y%m%d')
    plt.savefig('{}-{}.png'.format(ticker, today))

Jupyter labで動作確認した結果がこちらである。

NVIDIAの株価で動作確認

NVIDIAの資産総額がアマゾンを抜いて3位になったそうなのでテストに使ってみた。成長率が62.1%とすごいことになっている。

まとめ

バグなしで動くスクリプトではなかったが、数分考えただけでスラスラとこれだけのスクリプトを返すのはたいしたものだ。私はPythonのコーディングを一から行うのは正直しんどいが、動かないところをデバッグするくらいならできるので、これだけ作成してくれるとありがたい。またAI君のコーディングで勉強になるところもいくつかあった。プログラム開発の現場ではコーディングできるAIをどんどん活用するべきだろう。逆にそうしなければ生き残れないのではないか。

話は変わるが、AIに書いてもらったスクリプトをブログで記事にする時、「AIが書きました」と明記しないといけないのだろうか。AIが書いたスクリプト著作権は誰にあるのだろうか。よくわからないが、今回作成したスクリプトは自由に使っていただいて結構である。ただしまだバグはあるかもしれないので、自己責任ということでお願いしたい。